Beispiel #1
0
void do_code_width(void)
{
   LOG_FUNC_ENTRY();
   LOG_FMT(LSPLIT, "%s(%d)\n", __func__, __LINE__);

   for (chunk_t *pc = chunk_get_head(); pc != nullptr; pc = chunk_get_next(pc))
   {
      if (  !chunk_is_newline(pc)
         && !chunk_is_comment(pc)
         && pc->type != CT_SPACE
         && is_past_width(pc))
      {
         if (  pc->type == CT_VBRACE_CLOSE // don't break if a vbrace close
            && chunk_is_last_on_line(*pc)) // is the last chunk on its line
         {
            continue;
         }

         bool split_OK = split_line(pc);
         if (split_OK)
         {
            LOG_FMT(LSPLIT, "%s(%d): on orig_line=%zu, orig_col=%zu, for %s\n",
                    __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text());
         }
         else
         {
            LOG_FMT(LSPLIT, "%s(%d): Bailed on orig_line=%zu, orig_col=%zu, for %s\n",
                    __func__, __LINE__, pc->orig_line, pc->orig_col, pc->text());
            break;
         }
      }
   }
}
Beispiel #2
0
static void add_file_header()
{
   if (!chunk_is_comment(chunk_get_head()))
   {
      /*TODO: detect the typical #ifndef FOO / #define FOO sequence */
      tokenize(cpd.file_hdr.data, chunk_get_head());
   }
}
/*
 * the value of after determines:
 *   true:  insert_vbrace_close_after(pc, frm)
 *   false: insert_vbrace_open_before(pc, frm)
 */
static chunk_t *insert_vbrace(chunk_t *pc, bool after,
                              struct parse_frame *frm)
{
    LOG_FUNC_ENTRY();
    chunk_t chunk;
    chunk_t *rv;
    chunk_t *ref;

    chunk.orig_line   = pc->orig_line;
    chunk.parent_type = frm->pse[frm->pse_tos].type;
    chunk.level       = frm->level;
    chunk.brace_level = frm->brace_level;
    chunk.flags       = pc->flags & PCF_COPY_FLAGS;
    chunk.str         = "";
    if (after)
    {
        chunk.type = CT_VBRACE_CLOSE;
        rv         = chunk_add_after(&chunk, pc);
    }
    else
    {
        ref = chunk_get_prev(pc);
        if ((ref->flags & PCF_IN_PREPROC) == 0)
        {
            chunk.flags &= ~PCF_IN_PREPROC;
        }

        while (chunk_is_newline(ref) || chunk_is_comment(ref))
        {
            ref->level++;
            ref->brace_level++;
            ref = chunk_get_prev(ref);
        }

        /* Don't back into a preprocessor */
        if (((pc->flags & PCF_IN_PREPROC) == 0) &&
                (ref->flags & PCF_IN_PREPROC))
        {
            if (ref->type == CT_PREPROC_BODY)
            {
                do
                {
                    ref = chunk_get_prev(ref);
                } while ((ref != NULL) && (ref->flags & PCF_IN_PREPROC));
            }
            else
            {
                ref = chunk_get_next(ref);
            }
        }

        chunk.orig_line = ref->orig_line;
        chunk.column    = ref->column + ref->len() + 1;
        chunk.type      = CT_VBRACE_OPEN;
        rv              = chunk_add_after(&chunk, ref);
    }
    return(rv);
} // insert_vbrace
Beispiel #4
0
/**
 * REVISIT: This needs to be re-checked, maybe cleaned up
 *
 * Indents comments in a (hopefully) smart manner.
 *
 * There are two type of comments that get indented:
 *  - stand alone (ie, no tokens on the line before the comment)
 *  - trailing comments (last token on the line apart from a linefeed)
 *    + note that a stand-alone comment is a special case of a trailing
 *
 * The stand alone comments will get indented in one of three ways:
 *  - column 1:
 *    + There is an empty line before the comment AND the indent level is 0
 *    + The comment was originally in column 1
 *
 *  - Same column as trailing comment on previous line (ie, aligned)
 *    + if originally within TBD (3) columns of the previous comment
 *
 *  - syntax indent level
 *    + doesn't fit in the previous categories
 *
 * Options modify this behavior:
 *  - keep original column (don't move the comment, if possible)
 *  - keep relative column (move out the same amount as first item on line)
 *  - fix trailing comment in column TBD
 *
 * @param pc   The comment, which is the first item on a line
 * @param col  The column if this is to be put at indent level
 */
static void indent_comment(chunk_t *pc, int col)
{
    chunk_t *nl;
    chunk_t *prev;

    LOG_FMT(LCMTIND, "%s: line %d, col %d, level %d: ", __func__,
            pc->orig_line, pc->orig_col, pc->level);

    /* force column 1 comment to column 1 if not changing them */
    if ((pc->orig_col == 1) && !cpd.settings[UO_indent_col1_comment].b)
    {
        LOG_FMT(LCMTIND, "rule 1 - keep in col 1\n");
        pc->column = 1;
        return;
    }

    nl = chunk_get_prev(pc);

    /* outside of any expression or statement? */
    if (pc->level == 0)
    {
        if ((nl != NULL) && (nl->nl_count > 1))
        {
            LOG_FMT(LCMTIND, "rule 2 - level 0, nl before\n");
            pc->column = 1;
            return;
        }
    }

    prev = chunk_get_prev(nl);

    if (chunk_is_comment(prev) && (nl->nl_count == 1))
    {
        int coldiff = prev->orig_col - pc->orig_col;

        if ((coldiff <= 3) && (coldiff >= -3))
        {
            pc->column = prev->column;
            LOG_FMT(LCMTIND, "rule 3 - prev comment, coldiff = %d, now in %d\n",
                    coldiff, pc->column);
            return;
        }
    }

    /* check if special single line comment rule applies */
    if (cpd.settings[UO_indent_sing_line_comments].n > 0 && single_line_comment_indent_rule_applies(pc))
    {
        pc->column = col + cpd.settings[UO_indent_sing_line_comments].n;
        LOG_FMT(LCMTIND, "rule 4 - single line comment indent, now in %d\n", pc->column);
        return;
    }

    LOG_FMT(LCMTIND, "rule 5 - fall-through, stay in %d\n", col);

    pc->column = col;
}
Beispiel #5
0
static chunk_t *align_func_param(chunk_t *start)
{
   AlignStack as;
   chunk_t    *pc = start;

   as.Start(2, 0);

   as.m_star_style = (AlignStack::StarStyle)cpd.settings[UO_align_var_def_star_style].n;
   as.m_amp_style  = (AlignStack::StarStyle)cpd.settings[UO_align_var_def_amp_style].n;

   bool did_this_line = false;
   int  comma_count   = 0;
   int  chunk_count   = 0;

   while ((pc = chunk_get_next(pc)) != NULL)
   {
      chunk_count++;
      if (chunk_is_newline(pc))
      {
         did_this_line = false;
         comma_count   = 0;
         chunk_count   = 0;
      }
      else if (pc->level <= start->level)
      {
         break;
      }
      else if (!did_this_line && (pc->flags & PCF_VAR_DEF))
      {
         if (chunk_count > 1)
         {
            as.Add(pc);
         }
         did_this_line = true;
      }
      else if (comma_count > 0)
      {
         if (!chunk_is_comment(pc))
         {
            comma_count = 2;
            break;
         }
      }
      else if (pc->type == CT_COMMA)
      {
         comma_count++;
      }
   }

   if (comma_count <= 1)
   {
      as.End();
   }

   return(pc);
}
Beispiel #6
0
/**
 * Gets the prev non-comment chunk
 */
chunk_t *chunk_get_prev_nc(chunk_t *cur, chunk_nav_t nav)
{
   chunk_t *pc = cur;

   do
   {
      pc = chunk_get_prev(pc, nav);
   } while ((pc != NULL) && chunk_is_comment(pc));
   return(pc);
}
Beispiel #7
0
/**
 * Gets the next non-NEWLINE and non-comment chunk
 */
chunk_t *chunk_get_next_ncnl(chunk_t *cur, chunk_nav_t nav)
{
   chunk_t *pc = cur;

   do
   {
      pc = chunk_get_next(pc, nav);
   } while ((pc != NULL) && (chunk_is_comment(pc) || chunk_is_newline(pc)));
   return(pc);
}
Beispiel #8
0
/**
 * Gets the prev non-blank chunk
 */
chunk_t *chunk_get_prev_nblank(chunk_t *cur, chunk_nav_t nav)
{
   chunk_t *pc = cur;

   do
   {
      pc = chunk_get_prev(pc, nav);
   } while ((pc != NULL) && (chunk_is_comment(pc) || chunk_is_newline(pc) ||
                             chunk_is_blank(pc)));
   return(pc);
}
Beispiel #9
0
/**
 * Gets the prev non-NEWLINE and non-comment chunk, non-preprocessor chunk
 */
chunk_t *chunk_get_prev_ncnlnp(chunk_t *cur, chunk_nav_t nav)
{
   chunk_t *pc = cur;

   if (chunk_is_preproc(cur))
   {
      do
      {
         pc = chunk_get_prev(pc, nav);
      } while ((pc != NULL) && chunk_is_preproc(pc) &&
               (chunk_is_comment(pc) || chunk_is_newline(pc)));
   }
   else
   {
      do
      {
         pc = chunk_get_prev(pc, nav);
      } while ((pc != NULL) && (chunk_is_comment(pc) ||
                                chunk_is_newline(pc) ||
                                chunk_is_preproc(pc)));
   }
   return(pc);
}
Beispiel #10
0
/**
 * Step forward until a token goes beyond the limit and then call split_line()
 * to split the line at or before that point.
 */
void do_code_width(void)
{
   chunk_t *pc;

   LOG_FMT(LSPLIT, "%s\n", __func__);

   for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc))
   {
      if (!chunk_is_newline(pc) &&
          !chunk_is_comment(pc) &&
          (pc->type != CT_SPACE) &&
          is_past_width(pc))
      {
         split_line(pc);
      }
   }
}
Beispiel #11
0
/**
 * Converts a single virtual brace into a brace
 */
static void convert_vbrace(chunk_t *vbr)
{
   if (vbr == NULL)
   {
      return;
   }
   else if (vbr->type == CT_VBRACE_OPEN)
   {
      vbr->type = CT_BRACE_OPEN;
      vbr->len  = 1;
      vbr->str  = "{";

      /* If the next chunk is a preprocessor, then move the open brace after the
       * preprocessor.
       */
      chunk_t *tmp = chunk_get_next(vbr);
      if ((tmp != NULL) && (tmp->type == CT_PREPROC))
      {
         tmp = chunk_get_next(vbr, CNAV_PREPROC);
         chunk_move_after(vbr, tmp);
         newline_add_after(vbr);
      }
   }
   else if (vbr->type == CT_VBRACE_CLOSE)
   {
      vbr->type = CT_BRACE_CLOSE;
      vbr->len  = 1;
      vbr->str  = "}";

      /* If the next chunk is a comment, followed by a newline, then
       * move the brace after the newline and add another newline after
       * the close brace.
       */
      chunk_t *tmp = chunk_get_next(vbr);
      if (chunk_is_comment(tmp))
      {
         tmp = chunk_get_next(tmp);
         if (chunk_is_newline(tmp))
         {
            chunk_move_after(vbr, tmp);
            newline_add_after(vbr);
         }
      }
   }
}
Beispiel #12
0
/**
 * Changes the initial indent for a line to the given column
 *
 * @param pc      The chunk at the start of the line
 * @param column  The desired column
 */
void reindent_line(chunk_t *pc, int column)
{
    int col_delta;
    int min_col;

    LOG_FMT(LINDLINE, "%s: %d] col %d on %.*s [%s] => %d\n",
            __func__, pc->orig_line, pc->column, pc->len, pc->str,
            get_token_name(pc->type), column);

    if (column == pc->column)
        return;

    col_delta  = column - pc->column;
    pc->column = column;
    min_col    = pc->column;

    do
    {
        min_col += pc->len;
        pc       = chunk_get_next(pc);

        if (pc != NULL)
        {
            if (chunk_is_comment(pc))
            {
                pc->column = pc->orig_col;

                if (pc->column < min_col)
                    pc->column = min_col + 1;

                LOG_FMT(LINDLINE, "%s: set comment on line %d to col %d (orig %d)\n",
                        __func__, pc->orig_line, pc->column, pc->orig_col);
            }
            else
            {
                pc->column += col_delta;

                if (pc->column < min_col)
                    pc->column = min_col;
            }
        }
    }
    while ((pc != NULL) && (pc->nl_count == 0));
}
Beispiel #13
0
void pawn_add_virtual_semicolons(void)
{
   LOG_FUNC_ENTRY();
   chunk_t *prev;
   chunk_t *pc;

   /** Add Pawn virtual semicolons */
   prev = NULL;
   if (cpd.lang_flags & LANG_PAWN)
   {
      pc = chunk_get_head();
      while ((pc = chunk_get_next(pc)) != NULL)
      {
         if (!chunk_is_comment(pc) &&
             !chunk_is_newline(pc) &&
             (pc->type != CT_VBRACE_CLOSE) &&
             (pc->type != CT_VBRACE_OPEN))
         {
            prev = pc;
         }
         if ((prev == NULL) ||
             ((pc->type != CT_NEWLINE) &&
              (pc->type != CT_BRACE_CLOSE) &&
              (pc->type != CT_VBRACE_CLOSE)))
         {
            continue;
         }

         /* we just hit a newline and we have a previous token */
         if (((prev->flags & PCF_IN_PREPROC) == 0) &&
             ((prev->flags & (PCF_IN_ENUM | PCF_IN_STRUCT)) == 0) &&
             (prev->type != CT_VSEMICOLON) &&
             (prev->type != CT_SEMICOLON) &&
             !pawn_continued(prev, prev->brace_level))
         {
            pawn_add_vsemi_after(prev);
            prev = NULL;
         }
      }
   }
}
Beispiel #14
0
static void add_file_footer()
{
   chunk_t *pc = chunk_get_tail();

   /* Back up if the file ends with a newline */
   if ((pc != NULL) && chunk_is_newline(pc))
   {
      pc = chunk_get_prev(pc);
   }
   if ((pc != NULL) &&
       (!chunk_is_comment(pc) || !chunk_is_newline(chunk_get_prev(pc))))
   {
      pc = chunk_get_tail();
      if (!chunk_is_newline(pc))
      {
         LOG_FMT(LSYS, "Adding a newline at the end of the file\n");
         newline_add_after(pc);
      }
      tokenize(cpd.file_ftr.data, NULL);
   }
}
Beispiel #15
0
/**
 * Step forward until a token goes beyond the limit and then call split_line()
 * to split the line at or before that point.
 */
void do_code_width(void)
{
   LOG_FUNC_ENTRY();
   chunk_t *pc;

   LOG_FMT(LSPLIT, "%s\n", __func__);

   for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc))
   {
      if (!chunk_is_newline(pc) &&
          !chunk_is_comment(pc) &&
          (pc->type != CT_SPACE) &&
          is_past_width(pc))
      {
         if (!split_line(pc))
         {
            LOG_FMT(LSPLIT, "%s: Bailed on %lu:%lu %s\n",
                    __func__, pc->orig_line, pc->orig_col, pc->text());
            break;
         }
      }
   }
}
Beispiel #16
0
static bool single_line_comment_indent_rule_applies(chunk_t *start)
{
    chunk_t *pc      = start;
    int nl_count = 0;

    if (!chunk_is_single_line_comment(pc))
        return false;

    /* scan forward, if only single newlines and comments before next line of code, we want to apply */
    while ((pc = chunk_get_next(pc)) != NULL)
    {
        if (chunk_is_newline(pc))
        {
            if (nl_count > 0 || pc->nl_count > 1)
                return false;

            nl_count++;
        }
        else
        {
            nl_count = 0;

            if (!chunk_is_single_line_comment(pc))
            {
                /* here we check for things to run into that we wouldn't want to indent the comment for */
                /* for example, non-single line comment, closing brace */
                if (chunk_is_comment(pc) || chunk_is_closing_brace(pc))
                    return false;

                return true;
            }
        }
    }

    return false;
}