Exemple #1
0
static size_t preproc_start(parse_frame_t *frm, chunk_t *pc)
{
   LOG_FUNC_ENTRY();
   chunk_t *next;
   size_t  pp_level = cpd.pp_level;

   // Get the type of preprocessor and handle it
   next = chunk_get_next_ncnl(pc);
   if (next != nullptr)
   {
      cpd.in_preproc = next->type;

      // If we are in a define, push the frame stack.
      if (cpd.in_preproc == CT_PP_DEFINE)
      {
         pf_push(frm);

         // a preproc body starts a new, blank frame
         memset(frm, 0, sizeof(*frm));
         frm->level       = 1;
         frm->brace_level = 1;

         // TODO: not sure about the next 3 lines
         frm->pse_tos                 = 1;
         frm->pse[frm->pse_tos].type  = CT_PP_DEFINE;
         frm->pse[frm->pse_tos].stage = brace_stage_e::NONE;
      }
      else
      {
         // Check for #if, #else, #endif, etc
         pp_level = pf_check(frm, pc);
      }
   }
   return(pp_level);
}
Exemple #2
0
/*****************************************************************************
 * Shared Open code
 *****************************************************************************/
static inline bool check_Property( demux_t *p_demux, const char **pp_psz,
                                   bool(*pf_check)(demux_t *, const char *) )
{
    while( *pp_psz )
    {
        if( pf_check( p_demux, *pp_psz ) )
            return true;
        pp_psz++;
    }
    return false;
}
static int preproc_start(struct parse_frame *frm, chunk_t *pc)
{
    LOG_FUNC_ENTRY();
    chunk_t *next;
    int     pp_level = cpd.pp_level;

    /* Get the type of preprocessor and handle it */
    next = chunk_get_next_ncnl(pc);
    if (next != NULL)
    {
        cpd.in_preproc = next->type;

        /**
         * If we are in a define, push the frame stack.
         */
        if (cpd.in_preproc == CT_PP_DEFINE)
        {
            pf_push(frm);

            /* a preproc body starts a new, blank frame */
            memset(frm, 0, sizeof(*frm));
            frm->level       = 1;
            frm->brace_level = 1;

            /*TODO: not sure about the next 3 lines */
            frm->pse_tos                 = 1;
            frm->pse[frm->pse_tos].type  = CT_PP_DEFINE;
            frm->pse[frm->pse_tos].stage = BS_NONE;
        }
        else
        {
            /* Check for #if, #else, #endif, etc */
            pp_level = pf_check(frm, pc);
        }
    }
    return(pp_level);
}
Exemple #4
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++;
    }
}