Beispiel #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)
{
    LOG_FUNC_ENTRY();
    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->flags & PCF_IN_PREPROC)
        {
            LOG_FMT(LPARADD2, " -- bail on PP %s [%s] at line %d col %d, level %d\n",
                    get_token_name(pc->type),
                    pc->str.c_str(), 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 %d col %d, level %d\n",
                    get_token_name(pc->type),
                    pc->str.c_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->str.c_str(), 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);
    }
}
Beispiel #2
0
/**
 * Traverse the if chain and see if all can be removed
 */
static void process_if_chain(chunk_t *br_start)
{
   chunk_t *braces[256];
   chunk_t *br_close;
   int     br_cnt = 0;
   chunk_t *pc;
   bool    must_have_braces = false;
   bool    tmp;

   pc = br_start;

   LOG_FMT(LBRCH, "%s: if starts on line %d\n", __func__, br_start->orig_line);

   while (pc != NULL)
   {
      if (pc->type == CT_BRACE_OPEN)
      {
         tmp = can_remove_braces(pc);
         LOG_FMT(LBRCH, "  [%d] line %d - can%s remove %s\n",
                 br_cnt, pc->orig_line, tmp ? "" : "not",
                 get_token_name(pc->type));
         if (!tmp)
         {
            must_have_braces = true;
         }
      }
      else
      {
         tmp = should_add_braces(pc);
         if (tmp)
         {
            must_have_braces = true;
         }
         LOG_FMT(LBRCH, "  [%d] line %d - %s %s\n",
                 br_cnt, pc->orig_line, tmp ? "should add" : "ignore",
                 get_token_name(pc->type));
      }

      braces[br_cnt++] = pc;
      br_close         = chunk_skip_to_match(pc, CNAV_PREPROC);
      if (br_close == NULL)
      {
         break;
      }
      braces[br_cnt++] = br_close;

      pc = chunk_get_next_ncnl(br_close, CNAV_PREPROC);
      if ((pc == NULL) || (pc->type != CT_ELSE))
      {
         break;
      }
      pc = chunk_get_next_ncnl(pc, CNAV_PREPROC);
      if ((pc != NULL) && (pc->type == CT_ELSEIF))
      {
         while ((pc != NULL) && (pc->type != CT_VBRACE_OPEN) && (pc->type != CT_BRACE_OPEN))
         {
            pc = chunk_get_next_ncnl(pc, CNAV_PREPROC);
         }
      }
      if (pc == NULL)
      {
         break;
      }
      if ((pc->type != CT_BRACE_OPEN) && (pc->type != CT_VBRACE_OPEN))
      {
         break;
      }
   }

   if (must_have_braces)
   {
      LOG_FMT(LBRCH, "%s: add braces on lines[%d]:", __func__, br_cnt);
      while (--br_cnt >= 0)
      {
         braces[br_cnt]->flags |= PCF_KEEP_BRACE;
         if ((braces[br_cnt]->type == CT_VBRACE_OPEN) ||
             (braces[br_cnt]->type == CT_VBRACE_CLOSE))
         {
            LOG_FMT(LBRCH, " %d", braces[br_cnt]->orig_line);
            convert_vbrace(braces[br_cnt]);
         }
         else
         {
            LOG_FMT(LBRCH, " {%d}", braces[br_cnt]->orig_line);
         }
         braces[br_cnt] = NULL;
      }
      LOG_FMT(LBRCH, "\n");
   }
   else
   {
      LOG_FMT(LBRCH, "%s: remove braces on lines[%d]:", __func__, br_cnt);
      while (--br_cnt >= 0)
      {
         if ((braces[br_cnt]->type == CT_BRACE_OPEN) ||
             (braces[br_cnt]->type == CT_BRACE_CLOSE))
         {
            LOG_FMT(LBRCH, " {%d}", braces[br_cnt]->orig_line);
            convert_brace(braces[br_cnt]);
         }
         else
         {
            LOG_FMT(LBRCH, " %d", braces[br_cnt]->orig_line);
         }
         braces[br_cnt] = NULL;
      }
      LOG_FMT(LBRCH, "\n");
   }
}
Beispiel #3
0
static void process_if_chain(chunk_t *br_start)
{
   LOG_FUNC_ENTRY();
   chunk_t *braces[256];
   int     br_cnt           = 0;
   bool    must_have_braces = false;

   chunk_t *pc = br_start;

   LOG_FMT(LBRCH, "%s: if starts on line %zu\n", __func__, br_start->orig_line);

   while (pc != NULL)
   {
      if (pc->type == CT_BRACE_OPEN)
      {
         bool tmp = can_remove_braces(pc);
         LOG_FMT(LBRCH, "  [%d] line %zu - can%s remove %s\n",
                 br_cnt, pc->orig_line, tmp ? "" : "not",
                 get_token_name(pc->type));
         if (!tmp)
         {
            must_have_braces = true;
         }
      }
      else
      {
         bool tmp = should_add_braces(pc);
         if (tmp)
         {
            must_have_braces = true;
         }
         LOG_FMT(LBRCH, "  [%d] line %zu - %s %s\n",
                 br_cnt, pc->orig_line, tmp ? "should add" : "ignore",
                 get_token_name(pc->type));
      }

      braces[br_cnt++] = pc;
      chunk_t *br_close = chunk_skip_to_match(pc, CNAV_PREPROC);
      if (br_close == NULL)
      {
         break;
      }
      braces[br_cnt++] = br_close;

      pc = chunk_get_next_ncnl(br_close, CNAV_PREPROC);
      if ((pc == NULL) || (pc->type != CT_ELSE))
      {
         break;
      }

      if (cpd.settings[UO_mod_full_brace_if_chain_only].b)
      {
         // There is an 'else' - we want full braces.
         must_have_braces = true;
      }

      pc = chunk_get_next_ncnl(pc, CNAV_PREPROC);
      if ((pc != NULL) && (pc->type == CT_ELSEIF))
      {
         while ((pc != NULL) && (pc->type != CT_VBRACE_OPEN) && (pc->type != CT_BRACE_OPEN))
         {
            pc = chunk_get_next_ncnl(pc, CNAV_PREPROC);
         }
      }
      if (pc == NULL)
      {
         break;
      }
      if ((pc->type != CT_BRACE_OPEN) && (pc->type != CT_VBRACE_OPEN))
      {
         break;
      }
   }

   if (must_have_braces)
   {
      LOG_FMT(LBRCH, "%s: add braces on lines[%d]:", __func__, br_cnt);
      while (--br_cnt >= 0)
      {
         chunk_flags_set(braces[br_cnt], PCF_KEEP_BRACE);
         if ((braces[br_cnt]->type == CT_VBRACE_OPEN) ||
             (braces[br_cnt]->type == CT_VBRACE_CLOSE))
         {
            LOG_FMT(LBRCH, " %zu", braces[br_cnt]->orig_line);
            convert_vbrace(braces[br_cnt]);
         }
         else
         {
            LOG_FMT(LBRCH, " {%zu}", braces[br_cnt]->orig_line);
         }
         braces[br_cnt] = NULL;
      }
      LOG_FMT(LBRCH, "\n");
   }
   else if (cpd.settings[UO_mod_full_brace_if_chain].b)
   {
      // This might run because either UO_mod_full_brace_if_chain or UO_mod_full_brace_if_chain_only is used.
      // We only want to remove braces if the first one is active.

      LOG_FMT(LBRCH, "%s: remove braces on lines[%d]:", __func__, br_cnt);
      while (--br_cnt >= 0)
      {
         if ((braces[br_cnt]->type == CT_BRACE_OPEN) ||
             (braces[br_cnt]->type == CT_BRACE_CLOSE))
         {
            LOG_FMT(LBRCH, " {%zu}", braces[br_cnt]->orig_line);
            convert_brace(braces[br_cnt]);
         }
         else
         {
            LOG_FMT(LBRCH, " %zu", braces[br_cnt]->orig_line);
         }
         braces[br_cnt] = NULL;
      }
      LOG_FMT(LBRCH, "\n");
   }
} // process_if_chain
Beispiel #4
0
/**
 * Aligns all assignment operators on the same level as first, starting with
 * first.
 *
 * For variable definitions, only consider the '=' for the first variable.
 * Otherwise, only look at the first '=' on the line.
 */
chunk_t *align_assign(chunk_t *first, int span, int thresh)
{
   int     my_level;
   chunk_t *pc;
   int     tmp;
   int     var_def_cnt = 0;
   int     equ_count   = 0;

   if (first == NULL)
   {
      return(NULL);
   }
   my_level = first->level;

   if (span <= 0)
   {
      return(chunk_get_next(first));
   }

   LOG_FMT(LALASS, "%s[%d]: checking %.*s on line %d - span=%d thresh=%d\n",
           __func__, my_level, first->len, first->str, first->orig_line,
           span, thresh);

   AlignStack as;    // regular assigns
   AlignStack vdas;  // variable def assigns

   as.Start(span, thresh);
   as.m_right_align = true;
   vdas.Start(span, thresh);
   vdas.m_right_align = true;

   pc = first;
   while ((pc != NULL) && ((pc->level >= my_level) || (pc->level == 0)))
   {
      /* Don't check inside PAREN or SQUARE groups */
      if ((pc->type == CT_SPAREN_OPEN) ||
          (pc->type == CT_FPAREN_OPEN) ||
          (pc->type == CT_SQUARE_OPEN) ||
          (pc->type == CT_PAREN_OPEN))
      {
         tmp = pc->orig_line;
         pc  = chunk_skip_to_match(pc);
         if (pc != NULL)
         {
            as.NewLines(pc->orig_line - tmp);
            vdas.NewLines(pc->orig_line - tmp);
         }
         continue;
      }

      /* Recurse if a brace set is found */
      if ((pc->type == CT_BRACE_OPEN) ||
          (pc->type == CT_VBRACE_OPEN))
      {
         int myspan;
         int mythresh;

         tmp = pc->orig_line;

         if (pc->parent_type == CT_ENUM)
         {
            myspan   = cpd.settings[UO_align_enum_equ_span].n;
            mythresh = cpd.settings[UO_align_enum_equ_thresh].n;
         }
         else
         {
            myspan   = cpd.settings[UO_align_assign_span].n;
            mythresh = cpd.settings[UO_align_assign_thresh].n;
         }

         pc = align_assign(chunk_get_next_ncnl(pc), myspan, mythresh);
         if (pc != NULL)
         {
            /* do a rough count of the number of lines just spanned */
            as.NewLines(pc->orig_line - tmp);
            vdas.NewLines(pc->orig_line - tmp);
         }
         continue;
      }

      if (chunk_is_newline(pc))
      {
         as.NewLines(pc->nl_count);
         vdas.NewLines(pc->nl_count);

         var_def_cnt = 0;
         equ_count   = 0;
      }
      else if ((pc->flags & PCF_VAR_DEF) != 0)
      {
         var_def_cnt++;
      }
      else if (var_def_cnt > 1)
      {
         /* we hit the second variable def - don't look for assigns */
      }
      else if ((equ_count == 0) && (pc->type == CT_ASSIGN))
      {
         //fprintf(stderr, "%s:  ** %s level=%d line=%d col=%d prev=%d count=%d\n",
         //        __func__, pc->str, pc->level, pc->orig_line, pc->orig_col, prev_equ_type,
         //        equ_count);

         equ_count++;
         if (var_def_cnt != 0)
         {
            vdas.Add(pc);
         }
         else
         {
            as.Add(pc);
         }
      }

      pc = chunk_get_next(pc);
   }

   as.End();
   vdas.End();

   if (pc != NULL)
   {
      LOG_FMT(LALASS, "%s: done on %.*s on line %d\n",
              __func__, pc->len, pc->str, pc->orig_line);
   }
   else
   {
      LOG_FMT(LALASS, "%s: done on NULL\n", __func__);
   }

   return(pc);
}