Logo Search packages:      
Sourcecode: uncrustify version File versions

void fix_symbols ( void   ) 

Change CT_INCDEC_AFTER + WORD to CT_INCDEC_BEFORE Change number/word + CT_ADDR to CT_ARITH Change number/word + CT_STAR to CT_ARITH Change number/word + CT_NEG to CT_ARITH Change word + ( to a CT_FUNCTION Cahnge struct/union/enum + CT_WORD => CT_TYPE Force parens on return.

TODO: This could be done earlier.

Patterns detected: STRUCT/ENUM/UNION + WORD :: WORD => TYPE WORD + '(' :: WORD => FUNCTION

A word before an open paren is a function call or definition. CT_WORD => CT_FUNC_CALL or CT_FUNC_DEF

Check a paren pair to see if it is a cast. Note that SPAREN and FPAREN have already been marked.

Change the paren pair after a function/macrofunc. CT_PAREN_OPEN => CT_FPAREN_OPEN

2nd pass - handle variable definitions REVISIT: We need function params marked to do this (?)

A variable definition is possible after at the start of a statement that starts with: QUALIFIER, TYPE, or WORD

Definition at line 147 of file combine.cpp.

References chunk_t::brace_level, chunk_get_next_ncnl(), chunk_get_prev_ncnl(), fix_casts(), fix_enum_struct_union(), fix_typedef(), fix_var_def(), flag_parens(), chunk_t::flags, chunk_t::level, mark_class_ctor(), mark_define_expressions(), mark_exec_sql(), mark_function(), mark_function_type(), mark_namespace(), mark_template_func(), mark_variable_definition(), chunk_t::parent_type, pawn_add_virtual_semicolons(), set_paren_parent(), and chunk_t::type.

Referenced by uncrustify_file().

{
   chunk_t *pc;
   chunk_t *next;
   chunk_t *prev;
   chunk_t *tmp;
   chunk_t dummy;


   mark_define_expressions();

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

   prev = &dummy;
   pc   = chunk_get_head();
   next = chunk_get_next_ncnl(pc);

   while ((pc != NULL) && (next != NULL))
   {
      /* D stuff */
      if ((next->type == CT_PAREN_OPEN) &&
          ((pc->type == CT_CAST) ||
           (pc->type == CT_DELEGATE) ||
           (pc->type == CT_ALIGN)))
      {
         /* mark the parenthesis parent */
         tmp = set_paren_parent(next, pc->type);

         /* For a D cast - convert the next item */
         if ((pc->type == CT_CAST) && (tmp != NULL))
         {
            if (tmp->type == CT_STAR)
            {
               tmp->type = CT_DEREF;
            }
            else if (tmp->type == CT_AMP)
            {
               tmp->type = CT_ADDR;
            }
            else if (tmp->type == CT_MINUS)
            {
               tmp->type = CT_NEG;
            }
            else if (tmp->type == CT_PLUS)
            {
               tmp->type = CT_POS;
            }
         }

         /* For a delegate, mark previous words as types and the item after the
          * close paren as a variable def
          */
         if (pc->type == CT_DELEGATE)
         {
            if (tmp != NULL)
            {
               tmp->parent_type = CT_DELEGATE;
               if (tmp->level == tmp->brace_level)
               {
                  tmp->flags |= PCF_VAR_1ST_DEF;
               }
            }

            for (tmp = chunk_get_prev_ncnl(pc); tmp != NULL; tmp = chunk_get_prev_ncnl(tmp))
            {
               if ((tmp->type == CT_SEMICOLON) ||
                   (tmp->type == CT_BRACE_OPEN) ||
                   (tmp->type == CT_VBRACE_OPEN))
               {
                  break;
               }
               make_type(tmp);
            }
         }
      }

      /* A [] in C# and D only follows a type */
      if ((pc->type == CT_TSQUARE) &&
          ((cpd.lang_flags & (LANG_D | LANG_CS)) != 0))
      {
         if ((prev != NULL) && (prev->type == CT_WORD))
         {
            prev->type = CT_TYPE;
         }
         if ((next != NULL) && (next->type == CT_WORD))
         {
            next->flags |= PCF_VAR_1ST_DEF;
         }
      }

      if ((pc->type == CT_SQL_EXEC) ||
          (pc->type == CT_SQL_BEGIN) ||
          (pc->type == CT_SQL_END))
      {
         mark_exec_sql(pc);
      }

      /* Handle the typedef */
      if (pc->type == CT_TYPEDEF)
      {
         fix_typedef(pc);
      }
      else
      {
         if ((next->type == CT_ENUM) ||
             (next->type == CT_STRUCT) ||
             (next->type == CT_UNION))
         {
            if ((next->flags & PCF_IN_TYPEDEF) == 0)
            {
               fix_enum_struct_union(next);
            }
         }
      }

      if ((pc->type == CT_WORD) &&
          (next->type == CT_ANGLE_OPEN) &&
          (next->parent_type == CT_TEMPLATE))
      {
         mark_template_func(pc, next);
      }

      if ((pc->type == CT_SQUARE_CLOSE) &&
          (next->type == CT_PAREN_OPEN))
      {
         flag_parens(next, 0, CT_FPAREN_OPEN, CT_NONE, false);
      }

      if (pc->type == CT_ASSIGN)
      {
         mark_lvalue(pc);
      }

      if (pc->parent_type == CT_ASSIGN &&
          ((pc->type == CT_BRACE_OPEN) ||
           (pc->type == CT_SQUARE_OPEN)))
      {
         /* Mark everything in here as in assign */
         flag_parens(pc, PCF_IN_ARRAY_ASSIGN, pc->type, CT_NONE, false);
      }

      if (pc->type == CT_D_TEMPLATE)
      {
         set_paren_parent(next, pc->type);
      }

      /**
       * A word before an open paren is a function call or definition.
       * CT_WORD => CT_FUNC_CALL or CT_FUNC_DEF
       */
      if ((pc->type == CT_WORD) && (next->type == CT_PAREN_OPEN))
      {
         pc->type = CT_FUNCTION;
      }
      if ((cpd.lang_flags & LANG_PAWN) != 0)
      {
         if ((pc->type == CT_FUNCTION) && (pc->brace_level > 0))
         {
            pc->type = CT_FUNC_CALL;
         }
         if ((pc->type == CT_STATE) &&
             (next != NULL) &&
             (next->type == CT_PAREN_OPEN))
         {
            set_paren_parent(next, pc->type);
         }
      }
      else
      {
         if (pc->type == CT_FUNCTION)
         {
            mark_function(pc);
         }
      }

      /* Detect C99 member stuff */
      if ((pc->type == CT_MEMBER) &&
          ((prev->type == CT_COMMA) ||
           (prev->type == CT_BRACE_OPEN)))
      {
         pc->type          = CT_C99_MEMBER;
         next->parent_type = CT_C99_MEMBER;
      }

      /* Mark function parens and braces */
      if ((pc->type == CT_FUNC_DEF) ||
          (pc->type == CT_FUNC_CALL) ||
          (pc->type == CT_FUNC_PROTO))
      {
         tmp = next;
         if (tmp->type == CT_SQUARE_OPEN)
         {
            tmp = set_paren_parent(tmp, pc->type);
         }

         tmp = flag_parens(tmp, 0, CT_FPAREN_OPEN, pc->type, false);
         if (tmp != NULL)
         {
            if (tmp->type == CT_BRACE_OPEN)
            {
               if ((pc->flags & PCF_IN_CONST_ARGS) == 0)
               {
                  set_paren_parent(tmp, pc->type);
               }
            }
            else if ((tmp->type == CT_SEMICOLON) && (pc->type == CT_FUNC_PROTO))
            {
               tmp->parent_type = pc->type;
            }
         }
      }

      /* Mark the braces in: "for_each_entry(xxx) { }" */
      if ((pc->type == CT_BRACE_OPEN) &&
          (prev->type == CT_FPAREN_CLOSE) &&
          (prev->parent_type == CT_FUNC_CALL) &&
          ((pc->flags & PCF_IN_CONST_ARGS) == 0))
      {
         set_paren_parent(pc, CT_FUNC_CALL);
      }

      /* Check for a close paren followed by an open paren, which means that
       * we are on a function type declaration (C/C++ only?).
       * Note that typedefs are already taken card of.
       */
      if ((next != NULL) &&
          ((pc->flags & PCF_IN_TYPEDEF) == 0) &&
          (pc->parent_type != CT_CAST) &&
          ((pc->flags & PCF_IN_PREPROC) == 0) &&
          chunk_is_str(pc, ")", 1) &&
          chunk_is_str(next, "(", 1))
      {
         if ((cpd.lang_flags & LANG_D) != 0)
         {
            flag_parens(next, 0, CT_FPAREN_OPEN, CT_FUNC_CALL, false);
         }
         else
         {
            mark_function_type(pc);
         }
      }

      if ((pc->type == CT_CLASS) && (pc->level == pc->brace_level))
      {
         /* do other languages name the ctor the same as the class? */
         if ((cpd.lang_flags & LANG_CPP) != 0)
         {
            mark_class_ctor(pc);
         }
      }

      if (pc->type == CT_NAMESPACE)
      {
         mark_namespace(pc);
      }

      /*TODO: Check for stuff that can only occur at the start of an statement */

      if ((cpd.lang_flags & LANG_D) == 0)
      {
         /**
          * Check a paren pair to see if it is a cast.
          * Note that SPAREN and FPAREN have already been marked.
          */
         if ((pc->type == CT_PAREN_OPEN) &&
             (pc->parent_type == CT_NONE) &&
             ((next->type == CT_WORD) ||
              (next->type == CT_TYPE) ||
              (next->type == CT_STRUCT) ||
              (next->type == CT_QUALIFIER) ||
              (next->type == CT_ENUM) ||
              (next->type == CT_UNION)) &&
             (prev->type != CT_SIZEOF) &&
             ((pc->flags & PCF_IN_TYPEDEF) == 0))
         {
            fix_casts(pc);
         }
      }

      /* Check for stuff that can only occur at the start of an expression */
      if ((pc->flags & PCF_EXPR_START) != 0)
      {
         /* Change STAR, MINUS, and PLUS in the easy cases */
         if (pc->type == CT_STAR)
         {
            pc->type = CT_DEREF;
         }
         if (pc->type == CT_MINUS)
         {
            pc->type = CT_NEG;
         }
         if (pc->type == CT_PLUS)
         {
            pc->type = CT_POS;
         }
         if (pc->type == CT_INCDEC_AFTER)
         {
            pc->type = CT_INCDEC_BEFORE;
            //fprintf(stderr, "%s: %d> changed INCDEC_AFTER to INCDEC_BEFORE\n", __func__, pc->orig_line);
         }
         if (pc->type == CT_AMP)
         {
            //fprintf(stderr, "Changed AMP to ADDR on line %d\n", pc->orig_line);
            pc->type = CT_ADDR;
         }
      }

      /* Detect a variable definition that starts with struct/enum/union */
      if (((pc->flags & PCF_IN_TYPEDEF) == 0) &&
          (prev->parent_type != CT_CAST) &&
          ((prev->flags & PCF_IN_FCN_DEF) == 0) &&
          ((pc->type == CT_STRUCT) ||
           (pc->type == CT_UNION) ||
           (pc->type == CT_ENUM)))
      {
         tmp = next;
         if (tmp->type == CT_TYPE)
         {
            tmp = chunk_get_next_ncnl(tmp);
         }
         if ((tmp != NULL) && (tmp->type == CT_BRACE_OPEN))
         {
            tmp = chunk_skip_to_match(tmp);
            tmp = chunk_get_next_ncnl(tmp);
         }
         if ((tmp != NULL) && (chunk_is_star(tmp) || (tmp->type == CT_WORD)))
         {
            mark_variable_definition(tmp);
         }
      }

      /**
       * Change the paren pair after a function/macrofunc.
       * CT_PAREN_OPEN => CT_FPAREN_OPEN
       */
      if (pc->type == CT_MACRO_FUNC)
      {
         flag_parens(next, PCF_IN_FCN_CALL, CT_FPAREN_OPEN, CT_MACRO_FUNC, false);
      }

      /* Change CT_STAR to CT_PTR_TYPE or CT_ARITH or SYM_DEREF */
      if (pc->type == CT_STAR)
      {
         pc->type = (prev->type == CT_ARITH) ? CT_DEREF : CT_ARITH;
      }

      if (pc->type == CT_AMP)
      {
         pc->type = CT_ARITH;
      }

      if ((pc->type == CT_MINUS) ||
          (pc->type == CT_PLUS))
      {
         if ((prev->type == CT_POS) || (prev->type == CT_NEG))
         {
            pc->type = (pc->type == CT_MINUS) ? CT_NEG : CT_POS;
         }
         else if (prev->type == CT_OC_CLASS)
         {
            pc->type = CT_NEG;
         }
         else
         {
            pc->type = CT_ARITH;
         }
      }

      prev = pc;
      pc   = next;
      next = chunk_get_next_ncnl(next);
   }

   pawn_add_virtual_semicolons();
   process_returns();

   /**
    * 2nd pass - handle variable definitions
    * REVISIT: We need function params marked to do this (?)
    */
   pc = chunk_get_head();
   while (pc != NULL)
   {
      /**
       * A variable definition is possible after at the start of a statement
       * that starts with: QUALIFIER, TYPE, or WORD
       */
      if (((pc->flags & PCF_STMT_START) != 0) &&
          ((pc->type == CT_QUALIFIER) ||
           (pc->type == CT_TYPE) ||
           (pc->type == CT_WORD)) &&
          (pc->parent_type != CT_ENUM)) // TODO: why this check?
      {
         pc = fix_var_def(pc);
      }
      else
      {
         pc = chunk_get_next_ncnl(pc);
      }
   }

   /* 3rd pass - flag comments.
    * Not done in first 2 loops because comments are skipped
    */
   for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc))
   {
      if ((pc->type == CT_COMMENT) || (pc->type == CT_COMMENT_CPP))
      {
         prev = chunk_get_prev(pc);
         next = chunk_get_next(pc);

         if (!chunk_is_newline(prev) &&
             ((next == NULL) || (next->type == CT_NEWLINE)))
         {
            pc->flags |= PCF_RIGHT_COMMENT;
         }
      }
   }
}


Generated by  Doxygen 1.6.0   Back to index