Esempio n. 1
0
void indent_to_column(chunk_t *pc, int column)
{
    if (column < pc->column)
        column = pc->column;

    reindent_line(pc, column);
}
Esempio n. 2
0
/**
 * Split right after the chunk
 */
static void split_before_chunk(chunk_t *pc)
{
   LOG_FMT(LSPLIT, "%s: %s\n", __func__, pc->str.c_str());

   if (!chunk_is_newline(pc) &&
       !chunk_is_newline(chunk_get_prev(pc)))
   {
      newline_add_before(pc);
      reindent_line(pc, pc->brace_level * cpd.settings[UO_indent_columns].n);
      cpd.changes++;
   }
}
Esempio n. 3
0
File: width.cpp Progetto: Limsik/e17
/**
 * Split right after the chunk
 */
static void split_before_chunk(chunk_t *pc)
{
   LOG_FMT(LSPLIT, "%s: %s\n", __func__, pc->str.c_str());

   if (!chunk_is_newline(pc) &&
       !chunk_is_newline(chunk_get_prev(pc)))
   {
      newline_add_before(pc);
      // reindent needs to include the indent_continue value and was off by one
      reindent_line(pc, pc->brace_level * cpd.settings[UO_indent_columns].n +
                    abs(cpd.settings[UO_indent_continue].n) + 1);
      cpd.changes++;
   }
}
Esempio n. 4
0
static void split_template(chunk_t *start)
{
   LOG_FUNC_ENTRY();
   LOG_FMT(LSPLIT, "  %s(%d): start %s\n", __func__, __LINE__, start->text());
   LOG_FMT(LSPLIT, "  %s(%d): back up until the prev is a comma\n", __func__, __LINE__);

   // back up until the prev is a comma
   chunk_t *prev = start;
   while ((prev = chunk_get_prev(prev)) != nullptr)
   {
      LOG_FMT(LSPLIT, "  %s(%d): prev '%s'\n", __func__, __LINE__, prev->text());
      if (chunk_is_newline(prev) || prev->type == CT_COMMA)
      {
         break;
      }
   }

   if (prev != nullptr && !chunk_is_newline(prev))
   {
      LOG_FMT(LSPLIT, "  %s(%d):", __func__, __LINE__);
      LOG_FMT(LSPLIT, " -- ended on [%s] --\n", get_token_name(prev->type));
      chunk_t *pc = chunk_get_next(prev);
      newline_add_before(pc);
      size_t  min_col = 1;
      if (cpd.settings[UO_indent_continue].n == 0)
      {
         min_col += cpd.settings[UO_indent_columns].u;
      }
      else
      {
         min_col += abs(cpd.settings[UO_indent_continue].n);
      }
      reindent_line(pc, min_col);
      cpd.changes++;
   }
} // split_templatefcn_params
Esempio n. 5
0
/**
 * Put spaces on either side of the preproc (#) symbol.
 * This is done by pointing pc->str into pp_str and adjusting the
 * length.
 */
void indent_preproc(void)
{
    chunk_t *pc;
    chunk_t *next;
    int pp_level;
    int pp_level_sub = 0;
    int tmp;

    /* Define a string of 16 spaces + # + 16 spaces */
    static const char *pp_str  = "                #                ";
    static const char *alt_str = "                %:                ";

    /* Scan to see if the whole file is covered by one #ifdef */
    int stage = 0;

    for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc))
    {
        if (chunk_is_comment(pc) || chunk_is_newline(pc))
            continue;

        if (stage == 0)
        {
            /* Check the first PP, make sure it is an #if type */
            if (pc->type != CT_PREPROC)
                break;

            next = chunk_get_next(pc);

            if ((next == NULL) || (next->type != CT_PP_IF))
                break;

            stage = 1;
        }
        else if (stage == 1)
        {
            /* Scan until a PP at level 0 is found - the close to the #if */
            if ((pc->type == CT_PREPROC) &&
                    (pc->pp_level == 0))
                stage = 2;

            continue;
        }
        else if (stage == 2)
        {
            /* We should only see the rest of the preprocessor */
            if ((pc->type == CT_PREPROC) ||
                    ((pc->flags & PCF_IN_PREPROC) == 0))
            {
                stage = 0;
                break;
            }
        }
    }

    if (stage == 2)
    {
        LOG_FMT(LINFO, "The whole file is covered by a #IF\n");
        pp_level_sub = 1;
    }

    for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc))
    {
        if (pc->type != CT_PREPROC)
            continue;

        if (pc->column != 1)
        {
            /* Don't handle preprocessors that aren't in column 1 */
            LOG_FMT(LINFO, "%s: Line %d doesn't start in column 1 (%d)\n",
                    __func__, pc->orig_line, pc->column);
            continue;
        }

        /* point into pp_str */
        if (pc->len == 2)
            /* alternate token crap */
            pc->str = &alt_str[16];
        else
            pc->str = &pp_str[16];

        pp_level = pc->pp_level - pp_level_sub;

        if (pp_level < 0)
            pp_level = 0;
        else if (pp_level > 16)
            pp_level = 16;

        /* Note that the indent is removed by default */
        if ((cpd.settings[UO_pp_indent].a & AV_ADD) != 0)
        {
            /* Need to add some spaces */
            pc->str -= pp_level;
            pc->len += pp_level;
        }
        else if (cpd.settings[UO_pp_indent].a == AV_IGNORE)
        {
            tmp      = (pc->orig_col <= 16) ? pc->orig_col - 1 : 16;
            pc->str -= tmp;
            pc->len += tmp;
        }

        /* Add spacing by adjusting the length */
        if ((cpd.settings[UO_pp_space].a & AV_ADD) != 0)
            pc->len += pp_level;

        next = chunk_get_next(pc);

        if (next != NULL)
            reindent_line(next, pc->len + 1);

        LOG_FMT(LPPIS, "%s: Indent line %d to %d (len %d, next->col %d)\n",
                __func__, pc->orig_line, pp_level, pc->len, next->column);
    }
}
Esempio n. 6
0
/**
 * Change the top-level indentation only by changing the column member in
 * the chunk structures.
 * The level indicator must already be set.
 */
void indent_text(void)
{
    chunk_t            *pc;
    chunk_t            *next;
    chunk_t            *prev       = NULL;
    bool did_newline = true;
    int idx;
    int vardefcol   = 0;
    int indent_size = cpd.settings[UO_indent_columns].n;
    int tmp;
    struct parse_frame frm;
    bool in_preproc = false, was_preproc = false;
    int indent_column;
    int cout_col            = 0;                 // for aligning << stuff
    int cout_level          = 0;                 // for aligning << stuff
    int parent_token_indent = 0;

    memset(&frm, 0, sizeof(frm));

    /* dummy top-level entry */
    frm.pse[0].indent     = 1;
    frm.pse[0].indent_tmp = 1;
    frm.pse[0].type       = CT_EOF;

    pc = chunk_get_head();

    while (pc != NULL)
    {
        /* Handle proprocessor transitions */
        was_preproc = in_preproc;
        in_preproc  = (pc->flags & PCF_IN_PREPROC) != 0;

        if (cpd.settings[UO_indent_brace_parent].b)
            parent_token_indent = token_indent(pc->parent_type);

        /* Clean up after a #define */
        if (!in_preproc)
            while ((frm.pse_tos > 0) && frm.pse[frm.pse_tos].in_preproc)
                indent_pse_pop(frm, pc);

        else
        {
            pf_check(&frm, pc);

            if (!was_preproc)
            {
                /* Transition into a preproc by creating a dummy indent */
                frm.level++;
                indent_pse_push(frm, pc);

                frm.pse[frm.pse_tos].indent     = 1 + indent_size;
                frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
            }
        }

        if ((cout_col > 0) &&
                (chunk_is_semicolon(pc) ||
                 (pc->level < cout_level)))
        {
            cout_col   = 0;
            cout_level = 0;
        }

        /**
         * Handle non-brace closures
         */

        int old_pse_tos;

        do
        {
            old_pse_tos = frm.pse_tos;

            /* End anything that drops a level
             * REVISIT: not sure about the preproc check
             */
            if (!chunk_is_newline(pc) &&
                    !chunk_is_comment(pc) &&
                    ((pc->flags & PCF_IN_PREPROC) == 0) &&
                    (frm.pse[frm.pse_tos].level > pc->level))
                indent_pse_pop(frm, pc);

            if (frm.pse[frm.pse_tos].level == pc->level)
            {
                /* process virtual braces closes (no text output) */
                if ((pc->type == CT_VBRACE_CLOSE) &&
                        (frm.pse[frm.pse_tos].type == CT_VBRACE_OPEN))
                {
                    indent_pse_pop(frm, pc);
                    frm.level--;
                    pc = chunk_get_next(pc);
                }

                /* End any assign operations with a semicolon on the same level */
                if ((frm.pse[frm.pse_tos].type == CT_ASSIGN) &&
                        (chunk_is_semicolon(pc) ||
                         (pc->type == CT_COMMA) ||
                         (pc->type == CT_BRACE_OPEN)))
                    indent_pse_pop(frm, pc);

                /* End any CPP class colon crap */
                if ((frm.pse[frm.pse_tos].type == CT_CLASS_COLON) &&
                        ((pc->type == CT_BRACE_OPEN) ||
                         chunk_is_semicolon(pc)))
                    indent_pse_pop(frm, pc);

                /* a case is ended with another case or a close brace */
                if ((frm.pse[frm.pse_tos].type == CT_CASE) &&
                        ((pc->type == CT_BRACE_CLOSE) ||
                         (pc->type == CT_CASE)))
                    indent_pse_pop(frm, pc);

                /* a return is ended with a semicolon */
                if ((frm.pse[frm.pse_tos].type == CT_RETURN) &&
                        chunk_is_semicolon(pc))
                    indent_pse_pop(frm, pc);

                /* Close out parens and squares */
                if ((frm.pse[frm.pse_tos].type == (pc->type - 1)) &&
                        ((pc->type == CT_PAREN_CLOSE) ||
                         (pc->type == CT_SPAREN_CLOSE) ||
                         (pc->type == CT_FPAREN_CLOSE) ||
                         (pc->type == CT_SQUARE_CLOSE) ||
                         (pc->type == CT_ANGLE_CLOSE)))
                {
                    indent_pse_pop(frm, pc);
                    frm.paren_count--;
                }
            }
        }
        while (old_pse_tos > frm.pse_tos);

        /* Grab a copy of the current indent */
        indent_column = frm.pse[frm.pse_tos].indent_tmp;

        if (!chunk_is_newline(pc) && !chunk_is_comment(pc))
        {
            LOG_FMT(LINDPC, " -=[ %.*s ]=- top=%d %s %d/%d\n",
                    pc->len, pc->str,
                    frm.pse_tos,
                    get_token_name(frm.pse[frm.pse_tos].type),
                    frm.pse[frm.pse_tos].indent_tmp,
                    frm.pse[frm.pse_tos].indent);
        }

        /**
         * Handle stuff that can affect the current indent:
         *  - brace close
         *  - vbrace open
         *  - brace open
         *  - case         (immediate)
         *  - labels       (immediate)
         *  - class colons (immediate)
         *
         * And some stuff that can't
         *  - open paren
         *  - open square
         *  - assignment
         *  - return
         */

        if (pc->type == CT_BRACE_CLOSE)
        {
            if (frm.pse[frm.pse_tos].type == CT_BRACE_OPEN)
            {
                indent_pse_pop(frm, pc);
                frm.level--;

                /* Update the indent_column if needed */
                if (!cpd.settings[UO_indent_braces].b &&
                        (parent_token_indent == 0))
                    indent_column = frm.pse[frm.pse_tos].indent_tmp;

                if ((pc->parent_type == CT_IF) ||
                        (pc->parent_type == CT_ELSE) ||
                        (pc->parent_type == CT_ELSEIF) ||
                        (pc->parent_type == CT_DO) ||
                        (pc->parent_type == CT_WHILE) ||
                        (pc->parent_type == CT_SWITCH) ||
                        (pc->parent_type == CT_FOR))
                    indent_column += cpd.settings[UO_indent_brace].n;
            }
        }
        else if (pc->type == CT_VBRACE_OPEN)
        {
            frm.level++;
            indent_pse_push(frm, pc);

            frm.pse[frm.pse_tos].indent     = frm.pse[frm.pse_tos - 1].indent + indent_size;
            frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;

            /* Always indent on virtual braces */
            indent_column = frm.pse[frm.pse_tos].indent_tmp;
        }
        else if (pc->type == CT_BRACE_OPEN)
        {
            frm.level++;
            indent_pse_push(frm, pc);

            if (frm.paren_count != 0)
                /* We are inside ({ ... }) -- indent one tab from the paren */
                frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size;
            else
            {
                /* Use the prev indent level + indent_size. */
                frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;

                /* If this brace is part of a statement, bump it out by indent_brace */
                if ((pc->parent_type == CT_IF) ||
                        (pc->parent_type == CT_ELSE) ||
                        (pc->parent_type == CT_ELSEIF) ||
                        (pc->parent_type == CT_DO) ||
                        (pc->parent_type == CT_WHILE) ||
                        (pc->parent_type == CT_SWITCH) ||
                        (pc->parent_type == CT_FOR))
                {
                    if (parent_token_indent != 0)
                        frm.pse[frm.pse_tos].indent += parent_token_indent - indent_size;
                    else
                    {
                        frm.pse[frm.pse_tos].indent += cpd.settings[UO_indent_brace].n;
                        indent_column += cpd.settings[UO_indent_brace].n;
                    }
                }
                else if (pc->parent_type == CT_CASE)
                {
                    /* The indent_case_brace setting affects the parent CT_CASE */
                    frm.pse[frm.pse_tos].indent_tmp += cpd.settings[UO_indent_case_brace].n;
                    frm.pse[frm.pse_tos].indent     += cpd.settings[UO_indent_case_brace].n;
                }
                else if ((pc->parent_type == CT_CLASS) && !cpd.settings[UO_indent_class].b)
                    frm.pse[frm.pse_tos].indent -= indent_size;
                else if ((pc->parent_type == CT_NAMESPACE) && !cpd.settings[UO_indent_namespace].b)
                    frm.pse[frm.pse_tos].indent -= indent_size;
            }

            if ((pc->flags & PCF_DONT_INDENT) != 0)
            {
                frm.pse[frm.pse_tos].indent = pc->column;
                indent_column = pc->column;
            }
            else
            {
                /**
                 * If there isn't a newline between the open brace and the next
                 * item, just indent to wherever the next token is.
                 * This covers this sort of stuff:
                 * { a++;
                 *   b--; };
                 */
                next = chunk_get_next_ncnl(pc);

                if (!chunk_is_newline_between(pc, next))
                    frm.pse[frm.pse_tos].indent = next->column;

                frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
                frm.pse[frm.pse_tos].open_line  = pc->orig_line;

                /* Update the indent_column if needed */
                if (cpd.settings[UO_indent_braces].n ||
                        (parent_token_indent != 0))
                    indent_column = frm.pse[frm.pse_tos].indent_tmp;
            }
        }
        else if (pc->type == CT_CASE)
        {
            /* Start a case - indent UO_indent_switch_case from the switch level */
            tmp = frm.pse[frm.pse_tos].indent + cpd.settings[UO_indent_switch_case].n;

            indent_pse_push(frm, pc);

            frm.pse[frm.pse_tos].indent     = tmp;
            frm.pse[frm.pse_tos].indent_tmp = tmp - indent_size;

            /* Always set on case statements */
            indent_column = frm.pse[frm.pse_tos].indent_tmp;
        }
        else if (pc->type == CT_LABEL)
        {
            /* Labels get sent to the left or backed up */
            if (cpd.settings[UO_indent_label].n > 0)
                indent_column = cpd.settings[UO_indent_label].n;
            else
                indent_column = frm.pse[frm.pse_tos].indent +
                                cpd.settings[UO_indent_label].n;
        }
        else if (pc->type == CT_CLASS_COLON)
        {
            /* just indent one level */
            indent_pse_push(frm, pc);
            frm.pse[frm.pse_tos].indent     = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size;
            frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;

            indent_column = frm.pse[frm.pse_tos].indent_tmp;

            if (cpd.settings[UO_indent_class_colon].b)
            {
                prev = chunk_get_prev(pc);

                if (chunk_is_newline(prev))
                    frm.pse[frm.pse_tos].indent += 2;
                /* don't change indent of current line */
            }
        }
        else if ((pc->type == CT_PAREN_OPEN) ||
                 (pc->type == CT_SPAREN_OPEN) ||
                 (pc->type == CT_FPAREN_OPEN) ||
                 (pc->type == CT_SQUARE_OPEN) ||
                 (pc->type == CT_ANGLE_OPEN))
        {
            /* Open parens and squares - never update indent_column */
            indent_pse_push(frm, pc);
            frm.pse[frm.pse_tos].indent = pc->column + pc->len;

            if (cpd.settings[UO_indent_func_call_param].b &&
                    (pc->type == CT_FPAREN_OPEN) &&
                    (pc->parent_type == CT_FUNC_CALL))
                frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent + indent_size;

            if ((chunk_is_str(pc, "(", 1) && !cpd.settings[UO_indent_paren_nl].b) ||
                    (chunk_is_str(pc, "[", 1) && !cpd.settings[UO_indent_square_nl].b))
            {
                next = chunk_get_next_nc(pc);

                if (chunk_is_newline(next))
                {
                    int sub = 1;

                    if (frm.pse[frm.pse_tos - 1].type == CT_ASSIGN)
                        sub = 2;

                    frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - sub].indent + indent_size;
                }
            }

            frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
            frm.paren_count++;
        }
        else if (pc->type == CT_ASSIGN)
        {
            /**
             * if there is a newline after the '=', just indent one level,
             * otherwise align on the '='.
             * Never update indent_column.
             */
            next = chunk_get_next(pc);

            if (next != NULL)
            {
                indent_pse_push(frm, pc);

                if (chunk_is_newline(next))
                    frm.pse[frm.pse_tos].indent = frm.pse[frm.pse_tos - 1].indent_tmp + indent_size;
                else
                    frm.pse[frm.pse_tos].indent = pc->column + pc->len + 1;

                frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;
            }
        }
        else if (pc->type == CT_RETURN)
        {
            /* don't count returns inside a () or [] */
            if (pc->level == pc->brace_level)
            {
                indent_pse_push(frm, pc);
                frm.pse[frm.pse_tos].indent     = frm.pse[frm.pse_tos - 1].indent + pc->len + 1;
                frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos - 1].indent;
            }
        }
        else if (chunk_is_str(pc, "<<", 2))
        {
            if (cout_col == 0)
            {
                cout_col   = pc->column;
                cout_level = pc->level;
            }
        }
        else
        {
            /* anything else? */
        }

        /**
         * Indent the line if needed
         */
        if (did_newline && !chunk_is_newline(pc) && (pc->len != 0))
        {
            /**
             * Check for special continuations.
             * Note that some of these could be done as a stack item like
             * everything else
             */

            prev = chunk_get_prev_ncnl(pc);

            if ((pc->type == CT_MEMBER) ||
                    (pc->type == CT_DC_MEMBER) ||
                    ((prev != NULL) &&
                     ((prev->type == CT_MEMBER) ||
                      (prev->type == CT_DC_MEMBER))))
            {
                tmp = cpd.settings[UO_indent_member].n + indent_column;
                LOG_FMT(LINDENT, "%s: %d] member => %d\n",
                        __func__, pc->orig_line, tmp);
                reindent_line(pc, tmp);
            }
            else if (chunk_is_str(pc, "<<", 2) && (cout_col > 0))
            {
                LOG_FMT(LINDENT, "%s: %d] cout_col => %d\n",
                        __func__, pc->orig_line, cout_col);
                reindent_line(pc, cout_col);
            }
            else if ((vardefcol > 0) &&
                     (pc->type == CT_WORD) &&
                     ((pc->flags & PCF_VAR_DEF) != 0) &&
                     (prev != NULL) && (prev->type == CT_COMMA))
            {
                LOG_FMT(LINDENT, "%s: %d] Vardefcol => %d\n",
                        __func__, pc->orig_line, vardefcol);
                reindent_line(pc, vardefcol);
            }
            else if ((pc->type == CT_STRING) && (prev->type == CT_STRING) &&
                     cpd.settings[UO_indent_align_string].b)
            {
                LOG_FMT(LINDENT, "%s: %d] String => %d\n",
                        __func__, pc->orig_line, prev->column);
                reindent_line(pc, prev->column);
            }
            else if (chunk_is_comment(pc))
            {
                LOG_FMT(LINDENT, "%s: %d] comment => %d\n",
                        __func__, pc->orig_line, frm.pse[frm.pse_tos].indent_tmp);
                indent_comment(pc, frm.pse[frm.pse_tos].indent_tmp);
            }
            else if (pc->type == CT_PREPROC)
            {
                /* Preprocs are always in column 1. See indent_preproc() */
                if (pc->column != 1)
                    reindent_line(pc, 1);
            }
            else
            {
                if (pc->column != indent_column)
                {
                    LOG_FMT(LINDENT, "%s: %d] indent => %d [%.*s]\n",
                            __func__, pc->orig_line, indent_column, pc->len, pc->str);
                    reindent_line(pc, indent_column);
                }
            }

            did_newline = false;
        }

        /**
         * Handle variable definition continuation indenting
         */
        if ((pc->type == CT_WORD) &&
                ((pc->flags & PCF_IN_FCN_DEF) == 0) &&
                ((pc->flags & PCF_VAR_1ST_DEF) == PCF_VAR_1ST_DEF))
            vardefcol = pc->column;

        if (chunk_is_semicolon(pc) ||
                ((pc->type == CT_BRACE_OPEN) && (pc->parent_type == CT_FUNCTION)))
            vardefcol = 0;

        /* if we hit a newline, reset indent_tmp */
        if (chunk_is_newline(pc) ||
                (pc->type == CT_COMMENT_MULTI) ||
                (pc->type == CT_COMMENT_CPP))
        {
            frm.pse[frm.pse_tos].indent_tmp = frm.pse[frm.pse_tos].indent;

            /**
             * Handle the case of a multi-line #define w/o anything on the
             * first line (indent_tmp will be 1 or 0)
             */
            if ((pc->type == CT_NL_CONT) &&
                    (frm.pse[frm.pse_tos].indent_tmp <= indent_size))
                frm.pse[frm.pse_tos].indent_tmp = indent_size + 1;

            /* Get ready to indent the next item */
            did_newline = true;
        }

        if (!chunk_is_comment(pc) && !chunk_is_newline(pc))
            prev = pc;

        pc = chunk_get_next(pc);
    }

    /* Throw out any stuff inside a preprocessor - no need to warn */
    while ((frm.pse_tos > 0) && frm.pse[frm.pse_tos].in_preproc)
        indent_pse_pop(frm, pc);

    for (idx = 1; idx <= frm.pse_tos; idx++)
    {
        LOG_FMT(LWARN, "%s:%d Unmatched %s\n",
                cpd.filename, frm.pse[idx].open_line,
                get_token_name(frm.pse[idx].type));
        cpd.error_count++;
    }
}
Esempio n. 7
0
/**
 * Figures out where to split a function def/proto/call
 *
 * For fcn protos and defs. Also fcn calls where level == brace_level:
 *   - find the open fparen
 *     + if it doesn't have a newline right after it
 *       * see if all parameters will fit individually after the paren
 *       * if not, throw a newline after the open paren & return
 *   - scan backwards to the open fparen or comma
 *     + if there isn't a newline after that item, add one & return
 *     + otherwise, add a newline before the start token
 *
 * @param start   the offending token
 * @return        the token that should have a newline
 *                inserted before it
 */
static void split_fcn_params(chunk_t *start)
{
   LOG_FUNC_ENTRY();
   LOG_FMT(LSPLIT, "  %s: ", __func__);

   chunk_t *prev;
   chunk_t *fpo;
   chunk_t *pc;
   int     cur_width = 0;
   int     last_col  = -1;
   int     min_col;

   /* Find the opening fparen */
   fpo = start;
   while (((fpo = chunk_get_prev(fpo)) != NULL) &&
          (fpo->type != CT_FPAREN_OPEN))
   {
      /* do nothing */
   }

   pc      = chunk_get_next_ncnl(fpo);
   min_col = pc->column;

   LOG_FMT(LSPLIT, " mincol=%d, max_width=%d ",
           min_col, cpd.settings[UO_code_width].n - min_col);

   while (pc != NULL)
   {
      if (chunk_is_newline(pc))
      {
         cur_width = 0;
         last_col  = -1;
      }
      else
      {
         if (last_col < 0)
         {
            last_col = pc->column;
         }
         cur_width += (pc->column - last_col) + pc->len();
         last_col   = pc->column + pc->len();

         if ((pc->type == CT_COMMA) ||
             (pc->type == CT_FPAREN_CLOSE))
         {
            cur_width--;
            LOG_FMT(LSPLIT, " width=%d ", cur_width);
            if (((last_col - 1) > cpd.settings[UO_code_width].n) ||
                (pc->type == CT_FPAREN_CLOSE))
            {
               break;
            }
         }
      }
      pc = chunk_get_next(pc);
   }

   /* back up until the prev is a comma */
   prev = pc;
   while ((prev = chunk_get_prev(prev)) != NULL)
   {
      if (chunk_is_newline(prev) || (prev->type == CT_COMMA))
      {
         break;
      }
      last_col -= pc->len();
      if (prev->type == CT_FPAREN_OPEN)
      {
         pc = chunk_get_next(prev);
         if (!cpd.settings[UO_indent_paren_nl].b)
         {
            min_col = pc->brace_level * cpd.settings[UO_indent_columns].n + 1;
            if (cpd.settings[UO_indent_continue].n == 0)
            {
               min_col += cpd.settings[UO_indent_columns].n;
            }
            else
            {
               min_col += abs(cpd.settings[UO_indent_continue].n);
            }
         }
         /* Don't split "()" */
         if (pc->type != c_token_t(prev->type + 1))
         {
            break;
         }
      }
   }
   if ((prev != NULL) && !chunk_is_newline(prev))
   {
      LOG_FMT(LSPLIT, " -- ended on [%s] --\n", get_token_name(prev->type));
      pc = chunk_get_next(prev);
      newline_add_before(pc);
      reindent_line(pc, min_col);
      cpd.changes++;
   }
} // split_fcn_params
Esempio n. 8
0
static void split_fcn_params(chunk_t *start)
{
   LOG_FUNC_ENTRY();
   LOG_FMT(LSPLIT, "%s(%d): '%s'\n", __func__, __LINE__, start->text());

   // Find the opening function parenthesis
   chunk_t *fpo = start;
   LOG_FMT(LSPLIT, "%s(%d): Find the opening function parenthesis\n", __func__, __LINE__);
   while (  ((fpo = chunk_get_prev(fpo)) != nullptr)
         && fpo->type != CT_FPAREN_OPEN)
   {
      // do nothing
      LOG_FMT(LSPLIT, "%s(%d): '%s', orig_col is %zu, level is %zu\n",
              __func__, __LINE__, fpo->text(), fpo->orig_col, fpo->level);
   }

   chunk_t *pc     = chunk_get_next_ncnl(fpo);
   size_t  min_col = pc->column;

   LOG_FMT(LSPLIT, "    mincol is %zu, max_width is %zu\n",
           min_col, cpd.settings[UO_code_width].u - min_col);

   int cur_width = 0;
   int last_col  = -1;
   LOG_FMT(LSPLIT, "%s(%d):look forward until CT_COMMA or CT_FPAREN_CLOSE\n", __func__, __LINE__);
   while (pc != nullptr)
   {
      LOG_FMT(LSPLIT, "%s(%d): pc->text() '%s', type is %s\n",
              __func__, __LINE__, pc->text(), get_token_name(pc->type));
      if (chunk_is_newline(pc))
      {
         cur_width = 0;
         last_col  = -1;
      }
      else
      {
         if (last_col < 0)
         {
            last_col = pc->column;
            LOG_FMT(LSPLIT, "%s(%d): last_col is %d\n",
                    __func__, __LINE__, last_col);
         }
         cur_width += (pc->column - last_col) + pc->len();
         last_col   = pc->column + pc->len();

         LOG_FMT(LSPLIT, "%s(%d): last_col is %d\n",
                 __func__, __LINE__, last_col);
         if (pc->type == CT_COMMA || pc->type == CT_FPAREN_CLOSE)
         {
            cur_width--;
            LOG_FMT(LSPLIT, "%s(%d): cur_width is %d\n",
                    __func__, __LINE__, cur_width);
            if (  ((last_col - 1) > static_cast<int>(cpd.settings[UO_code_width].u))
               || pc->type == CT_FPAREN_CLOSE)
            {
               break;
            }
         }
      }
      pc = chunk_get_next(pc);
   }

   // back up until the prev is a comma
   chunk_t *prev = pc;
   LOG_FMT(LSPLIT, "  %s(%d): back up until the prev is a comma\n", __func__, __LINE__);
   while ((prev = chunk_get_prev(prev)) != nullptr)
   {
      LOG_FMT(LSPLIT, "%s(%d): pc '%s', pc->level is %zu, prev '%s', prev->type is %s\n",
              __func__, __LINE__, pc->text(), pc->level, prev->text(), get_token_name(prev->type));
      if (chunk_is_newline(prev) || prev->type == CT_COMMA)
      {
         LOG_FMT(LSPLIT, "%s(%d): found at %zu\n",
                 __func__, __LINE__, prev->orig_col);
         break;
      }
      LOG_FMT(LSPLIT, "%s(%d): last_col is %d\n",
              __func__, __LINE__, last_col);
      last_col -= pc->len();
      LOG_FMT(LSPLIT, "%s(%d): last_col is %d\n",
              __func__, __LINE__, last_col);
      if (prev->type == CT_FPAREN_OPEN)
      {
         pc = chunk_get_next(prev);
         if (!cpd.settings[UO_indent_paren_nl].b)
         {
            min_col = pc->brace_level * cpd.settings[UO_indent_columns].u + 1;
            LOG_FMT(LSPLIT, "%s(%d): min_col is %zu\n",
                    __func__, __LINE__, min_col);
            if (cpd.settings[UO_indent_continue].n == 0)
            {
               min_col += cpd.settings[UO_indent_columns].u;
            }
            else
            {
               min_col += abs(cpd.settings[UO_indent_continue].n);
            }
            LOG_FMT(LSPLIT, "%s(%d): min_col is %zu\n",
                    __func__, __LINE__, min_col);
         }

         // Don't split "()"
         if (pc->type != c_token_t(prev->type + 1))
         {
            break;
         }
      }
   }
   if (prev != nullptr && !chunk_is_newline(prev))
   {
      LOG_FMT(LSPLIT, "%s(%d): -- ended on [%s] --\n",
              __func__, __LINE__, get_token_name(prev->type));
      LOG_FMT(LSPLIT, "%s(%d): min_col is %zu\n",
              __func__, __LINE__, min_col);
      pc = chunk_get_next(prev);
      newline_add_before(pc);
      reindent_line(pc, min_col);
      cpd.changes++;
   }
} // split_fcn_params
Esempio n. 9
0
/**
 * Generically aligns on '=', '{', '(' and item after ','
 * It scans the first line and picks up the location of those tags.
 * It then scans subsequent lines and adjusts the column.
 * Finally it does a second pass to align everything.
 *
 * Aligns all the '=' signs in stucture assignments.
 * a = {
 *    .a    = 1;
 *    .type = fast;
 * };
 *
 * And aligns on '{', numbers, strings, words.
 * colors[] = {
 *    {"red",   {255, 0,   0}}, {"blue",   {  0, 255, 0}},
 *    {"green", {  0, 0, 255}}, {"purple", {255, 255, 0}},
 * };
 *
 * For the C99 indexed array assignment, the leading []= is skipped (no aligning)
 * struct foo_t bars[] =
 * {
 *    [0] = { .name = "bar",
 *            .age  = 21 },
 *    [1] = { .name = "barley",
 *            .age  = 55 },
 * };
 *
 * NOTE: this assumes that spacing is at the minimum correct spacing (ie force)
 *       if it isn't, some extra spaces will be inserted.
 *
 * @param start   Points to the open brace chunk
 */
static void align_init_brace(chunk_t *start)
{
   int     idx;
   chunk_t *pc;
   chunk_t *next;
   chunk_t *prev;
   chunk_t *num_token = NULL;

   cpd.al_cnt       = 0;
   cpd.al_c99_array = false;

   LOG_FMT(LALBR, "%s: line %d, col %d\n", __func__, start->orig_line, start->orig_col);

   pc = chunk_get_next_ncnl(start);
   pc = scan_ib_line(pc, true);
   if ((pc == NULL) || ((pc->type == CT_BRACE_CLOSE) &&
                        (pc->parent_type == CT_ASSIGN)))
   {
      /* single line - nothing to do */
      return;
   }

   do
   {
      pc = scan_ib_line(pc, false);

      /* debug dump the current frame */
      align_log_al(LALBR, pc->orig_line);

      while (chunk_is_newline(pc))
      {
         pc = chunk_get_next(pc);
      }
   } while ((pc != NULL) && (pc->level > start->level));

   /* debug dump the current frame */
   align_log_al(LALBR, start->orig_line);

   if (cpd.settings[UO_align_on_tabstop].b && (cpd.al_cnt >= 1) &&
       (cpd.al[0].type == CT_ASSIGN))
   {
      int rem = (cpd.al[0].col - 1) % cpd.settings[UO_output_tab_size].n;
      if (rem != 0)
      {
         LOG_FMT(LALBR, "%s: col=%d rem=%d", __func__, cpd.al[0].col, rem);
         cpd.al[0].col += cpd.settings[UO_output_tab_size].n - rem;
      }
   }

   pc  = chunk_get_next(start);
   idx = 0;
   do
   {
      if ((idx == 0) && (pc->type == CT_SQUARE_OPEN))
      {
         pc = chunk_get_next_type(pc, CT_ASSIGN, pc->level);
         pc = chunk_get_next(pc);
         if (pc != NULL)
         {
            LOG_FMT(LALBR, " -%d- skipped '[] =' to %s\n",
                    pc->orig_line, get_token_name(pc->type));
         }
         continue;
      }

      next = pc;
      if (idx < cpd.al_cnt)
      {
         LOG_FMT(LALBR, " (%d) check %s vs %s -- ",
                 idx, get_token_name(pc->type), get_token_name(cpd.al[idx].type));
         if (pc->type == cpd.al[idx].type)
         {
            if ((idx == 0) && cpd.al_c99_array)
            {
               prev = chunk_get_prev(pc);
               if (chunk_is_newline(prev))
               {
                  pc->flags |= PCF_DONT_INDENT;
               }
            }
            LOG_FMT(LALBR, " [%.*s] to col %d\n", pc->len, pc->str, cpd.al[idx].col);

            if (num_token != NULL)
            {
               int col_diff = pc->column - num_token->column;

               reindent_line(num_token, cpd.al[idx].col - col_diff);
               //LOG_FMT(LSYS, "-= %d =- NUM indent [%.*s] col=%d diff=%d\n",
               //        num_token->orig_line,
               //        num_token->len, num_token->str, cpd.al[idx - 1].col, col_diff);

               num_token->flags |= PCF_WAS_ALIGNED;
               num_token         = NULL;
            }

            /* Comma's need to 'fall back' to the previous token */
            if (pc->type == CT_COMMA)
            {
               next = chunk_get_next(pc);
               if ((next != NULL) && !chunk_is_newline(next))
               {
                  //LOG_FMT(LSYS, "-= %d =- indent [%.*s] col=%d len=%d\n",
                  //        next->orig_line,
                  //        next->len, next->str, cpd.al[idx].col, cpd.al[idx].len);

                  if ((idx < (cpd.al_cnt - 1)) &&
                      cpd.settings[UO_align_number_left].b &&
                      ((next->type == CT_NUMBER_FP) ||
                       (next->type == CT_NUMBER) ||
                       (next->type == CT_POS) ||
                       (next->type == CT_NEG)))
                  {
                     /* Need to wait until the next match to indent numbers */
                     num_token = next;
                  }
                  else
                  {
                     reindent_line(next, cpd.al[idx].col + cpd.al[idx].len);
                     next->flags |= PCF_WAS_ALIGNED;
                  }
               }
            }
            else
            {
               /* first item on the line */
               reindent_line(pc, cpd.al[idx].col);
               pc->flags |= PCF_WAS_ALIGNED;

               /* see if we need to right-align a number */
               if ((idx < (cpd.al_cnt - 1)) &&
                   cpd.settings[UO_align_number_left].b)
               {
                  next = chunk_get_next(pc);
                  if ((next != NULL) && !chunk_is_newline(next) &&
                      ((next->type == CT_NUMBER_FP) ||
                       (next->type == CT_NUMBER) ||
                       (next->type == CT_POS) ||
                       (next->type == CT_NEG)))
                  {
                     /* Need to wait until the next match to indent numbers */
                     num_token = next;
                  }
               }
            }
            idx++;
         }
         else
         {
            LOG_FMT(LALBR, " no match\n");
         }
      }
      if (chunk_is_newline(pc) || chunk_is_newline(next))
      {
         idx = 0;
      }
      pc = chunk_get_next(pc);
   } while ((pc != NULL) && (pc->level > start->level));
}
Esempio n. 10
0
/**
 * This renders the chunk list to a file.
 */
void output_text(FILE *pfile)
{
   chunk_t *pc;
   chunk_t *prev;
   int     cnt;
   int     lvlcol;
   bool    allow_tabs;

   cpd.fout = pfile;

   cpd.did_newline = 1;
   cpd.column      = 1;

   if (cpd.bom)
   {
      write_bom(pfile, cpd.enc);
   }

   if (cpd.frag_cols > 0)
   {
      int indent = cpd.frag_cols - 1;

      for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc))
      {
         pc->column        += indent;
         pc->column_indent += indent;
      }
      cpd.frag_cols = 0;
   }

   for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc))
   {
      if (pc->type == CT_NEWLINE)
      {
         for (cnt = 0; cnt < pc->nl_count; cnt++)
         {
            add_char('\n');
         }
         cpd.did_newline = 1;
         cpd.column      = 1;
         LOG_FMT(LOUTIND, " xx\n");
      }
      else if (pc->type == CT_NL_CONT)
      {
         /* FIXME: this really shouldn't be done here! */
         if ((pc->flags & PCF_WAS_ALIGNED) == 0)
         {
            if (cpd.settings[UO_sp_before_nl_cont].a & AV_REMOVE)
            {
               pc->column = cpd.column + (cpd.settings[UO_sp_before_nl_cont].a == AV_FORCE);
            }
            else
            {
               /* Try to keep the same relative spacing */
               prev = chunk_get_prev(pc);
               while ((prev != NULL) && (prev->orig_col == 0) && (prev->nl_count == 0))
               {
                  prev = chunk_get_prev(prev);
               }

               if ((prev != NULL) && (prev->nl_count == 0))
               {
                  int orig_sp = (pc->orig_col - prev->orig_col_end);
                  pc->column = cpd.column + orig_sp;
                  if ((cpd.settings[UO_sp_before_nl_cont].a != AV_IGNORE) &&
                      (pc->column < (cpd.column + 1)))
                  {
                     pc->column = cpd.column + 1;
                  }
               }
            }
         }
         output_to_column(pc->column, (cpd.settings[UO_indent_with_tabs].n == 2));
         add_char('\\');
         add_char('\n');
         cpd.did_newline = 1;
         cpd.column      = 1;
         LOG_FMT(LOUTIND, " \\xx\n");
      }
      else if (pc->type == CT_COMMENT_MULTI)
      {
         if (cpd.settings[UO_cmt_indent_multi].b)
         {
            output_comment_multi(pc);
         }
         else
         {
            output_comment_multi_simple(pc);
         }
      }
      else if (pc->type == CT_COMMENT_CPP)
      {
         pc = output_comment_cpp(pc);
      }
      else if (pc->type == CT_COMMENT)
      {
         pc = output_comment_c(pc);
      }
      else if ((pc->type == CT_JUNK) || (pc->type == CT_IGNORED))
      {
         /* do not adjust the column for junk */
         add_text(pc->str);
      }
      else if (pc->len() == 0)
      {
         /* don't do anything for non-visible stuff */
         LOG_FMT(LOUTIND, " <%d> -", pc->column);
      }
      else
      {
         /* indent to the 'level' first */
         if (cpd.did_newline)
         {
            if (cpd.settings[UO_indent_with_tabs].n == 1)
            {
               /* FIXME: it would be better to properly set column_indent in
                * indent_text(), but this hack for '}' and ':' seems to work. */
               if ((pc->type == CT_BRACE_CLOSE) ||
                   chunk_is_str(pc, ":", 1) ||
                   (pc->type == CT_PREPROC))
               {
                  lvlcol = pc->column;
               }
               else
               {
                  lvlcol = pc->column_indent;
                  if (lvlcol > pc->column)
                  {
                     lvlcol = pc->column;
                  }
               }

               if (lvlcol > 1)
               {
                  output_to_column(lvlcol, true);
               }
            }
            allow_tabs = (cpd.settings[UO_indent_with_tabs].n == 2) ||
                         (chunk_is_comment(pc) &&
                          (cpd.settings[UO_indent_with_tabs].n != 0));

            LOG_FMT(LOUTIND, "  %d> col %d/%d - ", pc->orig_line, pc->column, cpd.column);
         }
         else
         {
            /**
             * Reformatting multi-line comments can screw up the column.
             * Make sure we don't mess up the spacing on this line.
             * This has to be done here because comments are not formatted
             * until the output phase.
             */
            if (pc->column < cpd.column)
            {
               reindent_line(pc, cpd.column);
            }

            /* not the first item on a line */
            prev       = chunk_get_prev(pc);
            allow_tabs = (cpd.settings[UO_align_with_tabs].b &&
                          ((pc->flags & PCF_WAS_ALIGNED) != 0) &&
                          ((prev->column + prev->len() + 1) != pc->column));
            if (cpd.settings[UO_align_keep_tabs].b)
            {
               allow_tabs |= pc->after_tab;
            }
            LOG_FMT(LOUTIND, " %d(%d) -", pc->column, allow_tabs);
         }

         output_to_column(pc->column, allow_tabs);
         add_text(pc->str);
         cpd.did_newline = chunk_is_newline(pc);
      }
   }
}