示例#1
0
/**
 * Scans between two parens and adds additional parens if needed.
 * This function is recursive. If it hits another open paren, it'll call itself
 * with the new bounds.
 *
 * Adds optional parens in an IF or SWITCH conditional statement.
 *
 * This basically just checks for a CT_COMPARE that isn't surrounded by parens.
 * The edges for the compare are the open, close and any CT_BOOL tokens.
 *
 * This only handleds VERY simple patterns:
 *   (!a && b)         => (!a && b)          -- no change
 *   (a && b == 1)     => (a && (b == 1))
 *   (a == 1 || b > 2) => ((a == 1) || (b > 2))
 *
 * FIXME: we really should bail if we transition between a preprocessor and
 *        a non-preprocessor
 */
static void check_bool_parens(chunk_t *popen, chunk_t *pclose, int nest)
{
   chunk_t *pc;
   chunk_t *ref = popen;
   chunk_t *next;
   bool    hit_compare = false;

   LOG_FMT(LPARADD, "%s(%d): popen on %d, col %d, pclose on %d, col %d, level=%d\n",
           __func__, nest,
           popen->orig_line, popen->orig_col,
           pclose->orig_line, pclose->orig_col,
           popen->level);

   pc = popen;
   while (((pc = chunk_get_next_ncnl(pc)) != NULL) && (pc != pclose))
   {
      if ((pc->type == CT_BOOL) ||
          (pc->type == CT_QUESTION) ||
          (pc->type == CT_COND_COLON))
      {
         LOG_FMT(LPARADD2, " -- %s [%.*s] at line %d col %d, level %d\n",
                 get_token_name(pc->type),
                 pc->len, pc->str, pc->orig_line, pc->orig_col, pc->level);
         if (hit_compare)
         {
            hit_compare = false;
            add_parens_between(ref, pc);
         }
         ref = pc;
      }
      else if (pc->type == CT_COMPARE)
      {
         LOG_FMT(LPARADD2, " -- compare [%.*s] at line %d col %d, level %d\n",
                 pc->len, pc->str, pc->orig_line, pc->orig_col, pc->level);
         hit_compare = true;
      }
      else if (chunk_is_paren_open(pc))
      {
         next = chunk_get_next_type(pc, (c_token_t)(pc->type + 1), pc->level);
         if (next != NULL)
         {
            check_bool_parens(pc, next, nest + 1);
            pc = next;
         }
      }
      else if ((pc->type == CT_BRACE_OPEN) ||
               (pc->type == CT_SQUARE_OPEN) ||
               (pc->type == CT_ANGLE_OPEN))
      {
         /* Skip [], {}, and <> */
         pc = chunk_get_next_type(pc, (c_token_t)(pc->type + 1), pc->level);
      }
   }

   if (hit_compare && (ref != popen))
   {
      add_parens_between(ref, pclose);
   }
}
示例#2
0
/**
 * Scans between two parens and adds additional parens if needed.
 * This function is recursive. If it hits another open paren, it'll call itself
 * with the new bounds.
 *
 * Adds optional parens in an IF or SWITCH conditional statement.
 *
 * This basically just checks for a CT_COMPARE that isn't surrounded by parens.
 * The edges for the compare are the open, close and any CT_BOOL tokens.
 *
 * This only handles VERY simple patterns:
 *   (!a && b)         => (!a && b)          -- no change
 *   (a && b == 1)     => (a && (b == 1))
 *   (a == 1 || b > 2) => ((a == 1) || (b > 2))
 *
 * FIXME: we really should bail if we transition between a preprocessor and
 *        a non-preprocessor
 */
static void check_bool_parens(chunk_t *popen, chunk_t *pclose, int nest)
{
   LOG_FUNC_ENTRY();
   chunk_t *pc;
   chunk_t *ref = popen;
   chunk_t *next;
   bool    hit_compare = false;

   LOG_FMT(LPARADD, "%s(%d): popen on %lu, col %lu, pclose on %lu, col %lu, level=%lu\n",
           __func__, nest,
           popen->orig_line, popen->orig_col,
           pclose->orig_line, pclose->orig_col,
           popen->level);

   pc = popen;
   while (((pc = chunk_get_next_ncnl(pc)) != NULL) && (pc != pclose))
   {
      if (pc->flags & PCF_IN_PREPROC)
      {
         LOG_FMT(LPARADD2, " -- bail on PP %s [%s] at line %lu col %lu, level %lu\n",
                 get_token_name(pc->type),
                 pc->text(), pc->orig_line, pc->orig_col, pc->level);
         return;
      }

      if ((pc->type == CT_BOOL) ||
          (pc->type == CT_QUESTION) ||
          (pc->type == CT_COND_COLON) ||
          (pc->type == CT_COMMA))
      {
         LOG_FMT(LPARADD2, " -- %s [%s] at line %lu col %lu, level %lu\n",
                 get_token_name(pc->type),
                 pc->text(), pc->orig_line, pc->orig_col, pc->level);
         if (hit_compare)
         {
            hit_compare = false;
            add_parens_between(ref, pc);
         }
         ref = pc;
      }
      else if (pc->type == CT_COMPARE)
      {
         LOG_FMT(LPARADD2, " -- compare [%s] at line %lu col %lu, level %lu\n",
                 pc->text(), pc->orig_line, pc->orig_col, pc->level);
         hit_compare = true;
      }
      else if (chunk_is_paren_open(pc))
      {
         next = chunk_skip_to_match(pc);
         if (next != NULL)
         {
            check_bool_parens(pc, next, nest + 1);
            pc = next;
         }
      }
      else if ((pc->type == CT_BRACE_OPEN) ||
               (pc->type == CT_SQUARE_OPEN) ||
               (pc->type == CT_ANGLE_OPEN))
      {
         /* Skip [], {}, and <> */
         pc = chunk_skip_to_match(pc);
      }
   }

   if (hit_compare && (ref != popen))
   {
      add_parens_between(ref, pclose);
   }
} // check_bool_parens