Пример #1
0
void logmask_from_string(const char *str, log_mask_t &mask)
{
   if (str == nullptr)
   {
      return;
   }

   logmask_set_all(mask, false);  // Start with a clean mask

   // If the first character is 'a' or 'A', set all severities
   if (unc_toupper(*str) == 'A')
   {
      logmask_set_all(mask, true);
      str++;
   }

   char *ptmp;
   bool was_dash   = false;
   int  last_level = -1;
   while (*str != 0)         // check string until termination character
   {
      if (unc_isspace(*str)) // ignore spaces and go on with next character
      {
         str++;
         continue;
      }

      if (unc_isdigit(*str))
      {
         int level = strtoul(str, &ptmp, 10);
         str = ptmp;

         logmask_set_sev(mask, static_cast<log_sev_t>(level), true);
         if (was_dash)
         {
            for (int idx = last_level + 1; idx < level; idx++)
            {
               logmask_set_sev(mask, static_cast<log_sev_t>(idx), true);
            }
            was_dash = false;
         }

         last_level = level;
      }
      else if (*str == '-') // a dash marks all bits until the next number
      {
         was_dash = true;
         str++;
      }
      else  // probably a comma
      {
         last_level = -1;
         was_dash   = false;
         str++;
      }
   }
} // logmask_from_string
void print_universal_indent_cfg(FILE *pfile)
{
   const group_map_value *p_grp;
   const char            *p_name;

   /* Dump the header and the categories */
   fprintf(pfile, "[header]\n");

   /* Add all the categories */
   char ch = '=';
   int  idx;

   fprintf(pfile, "categories");
   for (idx = 0; idx < UG_group_count; idx++)
   {
      p_grp = get_group_name(idx);
      if (p_grp != NULL)
      {
         fprintf(pfile, "%c%s", ch, p_grp->short_desc);
         ch = '|';
      }
   }
   fprintf(pfile, "\n");

   fprintf(pfile,
           "cfgFileParameterEnding=cr\n"
           "configFilename=TechPlayers.cfg\n");


   /* Add all the recognized file extensions */
   ch  = '=';
   idx = 0;
   fprintf(pfile, "fileTypes");
   while ((p_name = get_file_extension(idx)) != NULL)
   {
      fprintf(pfile, "%c*%s", ch, p_name);
      ch = '|';
   }
   fprintf(pfile, "\n");

   /* Add the rest of the constant file header */
   fprintf(pfile,
           "indenterFileName=TechPlayers\n"
           "indenterName=TechPlayers (C, C++, C#, ObjectiveC, D, Java, Pawn, VALA)\n"
           "inputFileName=indentinput\n"
           "inputFileParameter=\"-f \"\n"
           "manual=http://TechPlayers.sourceforge.net/config.txt\n"
           "outputFileName=indentoutput\n"
           "outputFileParameter=\"-o \"\n"
           "stringparaminquotes=false\n"
           "parameterOrder=ipo\n"
           "showHelpParameter=-h\n"
           "stringparaminquotes=false\n"
           "useCfgFileParameter=\"-c \"\n"
           "version=%s\n",
           TechPlayers_VERSION);

   /* Now add each option */
   for (idx = 0; idx < UG_group_count; idx++)
   {
      p_grp = get_group_name(idx);
      if (p_grp == NULL)
      {
         continue;
      }

      for (option_list_cit it = p_grp->options.begin(); it != p_grp->options.end(); it++)
      {
         const option_map_value *option = get_option_name(*it);

         // Create a better readable name from the options name
         // by replacing '_' by a space and use some upper case characters.
         char *optionNameReadable = new char[strlen(option->name) + 1];
         strcpy(optionNameReadable, option->name);

         bool was_space = true;
         for (char *character = optionNameReadable; *character != 0; character++)
         {
            if (*character == '_')
            {
               *character = ' ';
               was_space  = true;
            }
            else if (was_space)
            {
               *character = unc_toupper(*character);
               was_space  = false;
            }
         }

         fprintf(pfile, "\n[%s]\n", optionNameReadable);
         fprintf(pfile, "Category=%d\n", idx);
         fprintf(pfile, "Description=\"<html>");

         const char *tmp = option->short_desc;
         ch = 0;

         /* Output the decription which may contain forbidden chars */
         while (*tmp != 0)
         {
            switch (*tmp)
            {
            case '<':
               fprintf(pfile, "&lt;");
               break;

            case '>':
               fprintf(pfile, "&gt;");
               break;

            case '&':
               fprintf(pfile, "&amp;");
               break;

            case '\n':
               fprintf(pfile, "<BR>");
               break;

            default:
               fputc(*tmp, pfile);
            }
            tmp++;
         }

         fprintf(pfile, "</html>\"\n");


         // Handle some options independent of their type and most by their type.
         switch (option->id)
         {
         // Indenting with tabs selector becomes a multiple selector and not only a number. Also its default enabled.
         case UO_indent_with_tabs:
            fprintf(pfile, "Enabled=true\n");
            fprintf(pfile, "EditorType=multiple\n");
            fprintf(pfile, "Choices=\"%s=0|%s=1|%s=2\"\n", option->name, option->name, option->name);
            fprintf(pfile, "ChoicesReadable=\"Spaces only|Indent with tabs, align with spaces|Indent and align with tabs\"\n");
            fprintf(pfile, "ValueDefault=%d\n", cpd.settings[option->id].n);
            break;

         // All not specially handled options are created only dependent by their type.
         default:
            fprintf(pfile, "Enabled=false\n");
            switch (option->type)
            {
            case AT_BOOL:
               // [align_keep_tabs]
               // Category=3
               // Description=<html>Whether to keep non-indenting tabs</html>
               // Value=0
               // ValueDefault=0
               // EditorType=boolean
               // TrueFalse="align_keep_tabs=true|align_keep_tabs=false"
               fprintf(pfile, "EditorType=boolean\n");
               fprintf(pfile, "TrueFalse=%s=true|%s=false\n", option->name, option->name);
               fprintf(pfile, "ValueDefault=%d\n", cpd.settings[option->id].n);
               break;

            case AT_IARF:
               fprintf(pfile, "EditorType=multiple\n");
               fprintf(pfile, "Choices=\"%s=ignore|%s=add|%s=remove|%s=force\"\n",
                       option->name, option->name, option->name, option->name);
               fprintf(pfile, "ChoicesReadable=\"Ignore %s|Add %s|Remove %s|Force %s\"\n",
                       optionNameReadable, optionNameReadable, optionNameReadable, optionNameReadable);
               fprintf(pfile, "ValueDefault=%d\n", cpd.settings[option->id].n);
               // [nl_after_switch]
               // Category=4
               // Description=<html>Add or remove newline after 'switch'</html>
               // Value=3
               // ValueDefault=-1
               // Enabled=true
               // EditorType=multiple
               // Choices="nl_after_switch=ignore|nl_after_switch=add|nl_after_switch=remove|nl_after_switch=force"
               break;

            case AT_NUM:
               // [align_assign_span]
               // CallName="align_assign_span="
               // Category=3
               // Description="<html>The span for aligning on '=' in assignments (0=don't align)</html>"
               // EditorType=numeric
               // Enabled=false
               // MaxVal=300
               // MinVal=0
               // Value=0
               // ValueDefault=0
               fprintf(pfile, "EditorType=numeric\n");
               fprintf(pfile, "CallName=\"%s=\"\n", option->name);
               fprintf(pfile, "MinVal=%d\n", option->min_val);
               fprintf(pfile, "MaxVal=%d\n", option->max_val);
               fprintf(pfile, "ValueDefault=%d\n", cpd.settings[option->id].n);
               break;

            case AT_LINE:
               // [newlines]
               // Category=0
               // Description=<html>The type of line endings</html>
               // Value=0
               // ValueDefault=-1
               // Enabled=true
               // EditorType=multiple
               // Choices="newlines=auto|newlines=lf|newlines=crlf|newlines=cr"
               fprintf(pfile, "EditorType=multiple\n");
               fprintf(pfile, "Choices=\"%s=lf|%s=crlf|%s=cr|%s=auto\"\n",
                       option->name, option->name, option->name, option->name);
               fprintf(pfile, "ChoicesReadable=\"Newlines Unix|Newlines Win|Newlines Mac|Newlines Auto\"\n");
               fprintf(pfile, "ValueDefault=%d\n", cpd.settings[option->id].n);
               break;

            case AT_POS:
               // [pos_bool]
               // Category=5
               // Description=<html>The position of boolean operators in wrapped expressions</html>
               // Enabled=false
               // Value=0
               // ValueDefault=-1
               // EditorType=multiple
               // Choices="pos_bool=ignore|pos_bool=lead|pos_bool=trail"
               fprintf(pfile, "EditorType=multiple\n");
               fprintf(pfile, "Choices=\"%s=ignore|%s=lead|%s=lead_break|%s=lead_force|%s=trail|%s=trail_break|%s=trail_force\"\n",
                       option->name, option->name, option->name, option->name,
                       option->name, option->name, option->name);
               fprintf(pfile, "ChoicesReadable=\"Ignore %s|Lead %s|Lead Break %s|Lead Force %s|Trail %s|Trail Break %s|Trail Force %s\"\n",
                       optionNameReadable, optionNameReadable, optionNameReadable,
                       optionNameReadable, optionNameReadable, optionNameReadable,
                       optionNameReadable);
               fprintf(pfile, "ValueDefault=%d\n", cpd.settings[option->id].n);
               break;

            case AT_STRING:
               {
                  fprintf(pfile, "CallName=%s=\n", option->name);
                  fprintf(pfile, "EditorType=string\n");
                  string     val_string;
                  const char *val_str;
                  val_string = op_val_to_string(option->type, cpd.settings[option->id]);
                  val_str    = val_string.c_str();
                  fprintf(pfile, "ValueDefault=%s\n", val_str);
               }
               break;

            default:
               break;
            }
         }
         delete [] optionNameReadable;
      }
   }
}
Пример #3
0
/**
 * Count the number of characters in the number.
 * The next bit of text starts with a number (0-9 or '.'), so it is a number.
 * Count the number of characters in the number.
 *
 * This should cover all number formats for all languages.
 * Note that this is not a strict parser. It will happily parse numbers in
 * an invalid format.
 *
 * For example, only D allows underscores in the numbers, but they are
 * allowed in all formats.
 *
 * @param pc   The structure to update, str is an input.
 * @return     Whether a number was parsed
 */
static bool parse_number(tok_ctx& ctx, chunk_t& pc)
{
   int  tmp;
   bool is_float;
   bool did_hex = false;

   /* A number must start with a digit or a dot, followed by a digit */
   if (!is_dec(ctx.peek()) &&
       ((ctx.peek() != '.') || !is_dec(ctx.peek(1))))
   {
      return(false);
   }

   is_float = (ctx.peek() == '.');
   if (is_float && (ctx.peek(1) == '.'))
   {
      return(false);
   }

   /* Check for Hex, Octal, or Binary
    * Note that only D and Pawn support binary, but who cares?
    */
   if (ctx.peek() == '0')
   {
      pc.str.append(ctx.get());  /* store the '0' */

      switch (unc_toupper(ctx.peek()))
      {
      case 'X':               /* hex */
         did_hex = true;
         do
         {
            pc.str.append(ctx.get());  /* store the 'x' and then the rest */
         } while (is_hex_(ctx.peek()));
         break;

      case 'B':               /* binary */
         do
         {
            pc.str.append(ctx.get());  /* store the 'b' and then the rest */
         } while (is_bin_(ctx.peek()));
         break;

      case '0':                /* octal or decimal */
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
         do
         {
            pc.str.append(ctx.get());
         } while (is_oct_(ctx.peek()));
         break;

      default:
         /* either just 0 or 0.1 or 0UL, etc */
         break;
      }
   }
   else
   {
      /* Regular int or float */
      while (is_dec_(ctx.peek()))
      {
         pc.str.append(ctx.get());
      }
   }

   /* Check if we stopped on a decimal point & make sure it isn't '..' */
   if ((ctx.peek() == '.') && (ctx.peek(1) != '.'))
   {
      pc.str.append(ctx.get());
      is_float = true;
      if (did_hex)
      {
         while (is_hex_(ctx.peek()))
         {
            pc.str.append(ctx.get());
         }
      }
      else
      {
         while (is_dec_(ctx.peek()))
         {
            pc.str.append(ctx.get());
         }
      }
   }

   /* Check exponent
    * Valid exponents per language (not that it matters):
    * C/C++/D/Java: eEpP
    * C#/Pawn:      eE
    */
   tmp = unc_toupper(ctx.peek());
   if ((tmp == 'E') || (tmp == 'P'))
   {
      is_float = true;
      pc.str.append(ctx.get());
      if ((ctx.peek() == '+') || (ctx.peek() == '-'))
      {
         pc.str.append(ctx.get());
      }
      while (is_dec_(ctx.peek()))
      {
         pc.str.append(ctx.get());
      }
   }

   /* Check the suffixes
    * Valid suffixes per language (not that it matters):
    *        Integer       Float
    * C/C++: uUlL64        lLfF
    * C#:    uUlL          fFdDMm
    * D:     uUL           ifFL
    * Java:  lL            fFdD
    * Pawn:  (none)        (none)
    *
    * Note that i, f, d, and m only appear in floats.
    */
   while (1)
   {
      tmp = unc_toupper(ctx.peek());
      if ((tmp == 'I') || (tmp == 'F') || (tmp == 'D') || (tmp == 'M'))
      {
         is_float = true;
      }
      else if ((tmp != 'L') && (tmp != 'U'))
      {
         break;
      }
      pc.str.append(ctx.get());
   }

   /* skip the Microsoft-specific '64' suffix */
   if ((ctx.peek() == '6') && (ctx.peek(1) == '4'))
   {
      pc.str.append(ctx.get());
      pc.str.append(ctx.get());
   }

   pc.type = is_float ? CT_NUMBER_FP : CT_NUMBER;

   /* If there is anything left, then we are probably dealing with garbage or
    * some sick macro junk. Eat it.
    */
   parse_suffix(ctx, pc);

   return(true);
} // parse_number