"Fossies" - the Fresh Open Source Software Archive

Member "postal-0.76/expand.cpp" (10 Apr 2008, 5421 Bytes) of package /linux/privat/postal-0.76.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "expand.cpp" see the Fossies "Dox" file reference documentation.

    1 #include "expand.h"
    2 // for strdup() and strtok()
    3 #include <cstring>
    4 // for random()
    5 #include <cstdlib>
    6 #include <stdio.h>
    7 
    8 typedef char * PCHAR;
    9 
   10 NamePattern::NamePattern(const char *match, const char *replace)
   11  : m_match(strdup(match))
   12  , m_replace(strdup(replace))
   13  , m_conv_len(strlen(m_replace))
   14  , m_convert(new PCHAR[m_conv_len])
   15  , m_conv_item_len(new int[m_conv_len])
   16  , m_next_value(new int[m_conv_len])
   17  , m_no_seq(false)
   18  , m_next(NULL)
   19 {
   20   regcomp(&m_match_regex, m_match, REG_NOSUB);
   21   int i;
   22   for(i = 0; i < m_conv_len; i++)
   23     m_next_value[i] = 0;
   24   int pos = 0;
   25   bool paren = false;
   26   bool escape = false;
   27   bool hyphen = false;
   28 
   29   char buf[1024];
   30   int buf_pos = 0;
   31 
   32   for(i = 0; replace[i]; i++)
   33   {
   34     switch(replace[i])
   35     {
   36     case '.':
   37       if(!paren)
   38       {
   39         m_convert[pos] = NULL;
   40         m_conv_item_len[pos] = 0;
   41         pos++;
   42       }
   43       else
   44       {
   45         buf[buf_pos] = '.';
   46         buf_pos++;
   47       }
   48     break;
   49     case '[':
   50       if(paren)
   51       {
   52         if(!escape)
   53         {
   54           printf("Unmatched brackets in \"%s\".\n", replace);
   55           exit(1);
   56         }
   57         else
   58         {
   59           buf[buf_pos] = '[';
   60           buf_pos++;
   61         }
   62       }
   63       else
   64       {
   65         paren = true;
   66       }
   67     break;
   68     case ']':
   69       if(!paren)
   70       {
   71         printf("Unmatched brackets in \"%s\".\n", replace);
   72         exit(1);
   73       }
   74       if(!escape)
   75       {
   76         if(hyphen)
   77         {
   78           printf("Unfinished hyphen in \"%s\".\n", replace);
   79           exit(1);
   80         }
   81         buf[buf_pos] = '\0';
   82         m_convert[pos] = strdup(buf);
   83         m_conv_item_len[pos] = strlen(m_convert[pos]);
   84         pos++;
   85         buf_pos = 0;
   86         paren = false;
   87         break;
   88       } // if escape then fall-through
   89     case '-':
   90       if(!paren)
   91       {
   92         printf("Misplaced hyphen in \"%s\".\n", replace);
   93         exit(1);
   94       }
   95       hyphen = true;
   96     break;
   97     default:
   98       if(paren)
   99       {
  100         if(!hyphen)
  101         {
  102           buf[buf_pos] = replace[i];
  103           buf_pos++;
  104           if(buf_pos == sizeof(buf))
  105           {
  106             printf("Out of buffer space for \"%s\".\n", replace);
  107             exit(1);
  108           }
  109         }
  110         else
  111         {
  112           for(char c = buf[buf_pos - 1] + 1; c <= replace[i] && c < 127; c++)
  113           {
  114             buf[buf_pos] = c;
  115             buf_pos++;
  116             if(buf_pos == sizeof(buf))
  117             {
  118               printf("Out of buffer space for \"%s\".\n", replace);
  119               exit(1);
  120             }
  121           }
  122           hyphen = false;
  123         }
  124       }
  125       else
  126       {
  127         printf("Can't parse replace string \"%s\".\n", replace);
  128         exit(1);
  129       }
  130     } // end switch
  131   } // end for
  132   m_conv_len = pos;
  133 }
  134 
  135 NamePattern::~NamePattern()
  136 {
  137   for(int i = 0; i < m_conv_len; i++)
  138     delete m_convert[i];
  139   delete m_convert;
  140   delete m_conv_item_len;
  141   delete m_next_value;
  142   regfree(&m_match_regex);
  143   delete m_match;
  144   delete m_replace;
  145 }
  146 
  147 int NamePattern::expand(string &output, const string &input, bool sequential)
  148 {
  149   int i;
  150   if(sequential && m_no_seq)
  151   {
  152     for(i = 0; i < m_conv_len; i++)
  153       m_next_value[i] = 0;
  154     m_no_seq = false;
  155     return 1;
  156   }
  157   if(regexec(&m_match_regex, input.c_str(), 0, NULL, 0))
  158   {
  159     if(m_next)
  160       return m_next->expand(output, input, sequential);
  161     else
  162       return 1;
  163   }
  164   output = input;
  165   for(i = 0; i < m_conv_len; i++)
  166   {
  167     if(m_convert[i])
  168     {
  169       if(!sequential)
  170       {
  171         output[i] = m_convert[i][random()%m_conv_item_len[i]];
  172       }
  173       else
  174       {
  175         output[i] = m_convert[i][m_next_value[i]];
  176       }
  177     }
  178   }
  179   if(sequential)
  180   {
  181     for(i = m_conv_len - 1; i >= 0; i--)
  182     {
  183       if(m_convert[i])
  184       {
  185         m_next_value[i]++;
  186         if(m_next_value[i] >= m_conv_item_len[i])
  187           m_next_value[i] = 0;
  188         else
  189           return 0;
  190       }
  191     }
  192     m_no_seq = true;
  193   }
  194   return 0;
  195 }
  196 
  197 NameExpand::NameExpand(const char *filename)
  198  : m_no_seq(true)
  199  , m_names(NULL)
  200 {
  201   if(!filename || strcmp(filename, "-") == 0)
  202   {
  203     return;
  204   }
  205   FILE *fp = fopen(filename, "r");
  206   if(!fp)
  207   {
  208     printf("Can't open config file \"%s\".  Doing no expansion.\n", filename);
  209     return;
  210   }
  211   char match[1024];
  212   NamePattern *np = NULL, *old_np = NULL;
  213   while(fgets(match, sizeof(match), fp))
  214   {
  215     match[sizeof(match) - 1] = '\0';
  216     strtok(match, "\n");
  217     unsigned int i;
  218     int blank_pos = -1;
  219     for(i = 0; match[i]; i++)
  220     {
  221       if(match[i] == ' ')
  222       {
  223         if(blank_pos != -1)
  224         {
  225           printf("Can't parse pattern line \"%s\".\n", match);
  226           exit(1);
  227         }
  228         blank_pos = i;
  229       }
  230     }
  231     if(blank_pos == -1)
  232     {
  233       printf("Can't parse pattern line \"%s\".\n", match);
  234       exit(1);
  235     }
  236     char *replace = &match[blank_pos + 1];
  237     match[blank_pos] = '\0';
  238     np = new NamePattern(match, replace);
  239     if(!m_names)
  240       m_names = np;
  241     if(old_np)
  242       old_np->AddNext(np);
  243     old_np = np;
  244   }
  245   fclose(fp);
  246 }
  247 
  248 int NameExpand::expand(string &output, const string &input, bool sequential)
  249 {
  250   if(!m_names)
  251   {
  252     if(sequential)
  253     {
  254       if(m_no_seq)
  255       {
  256         m_no_seq = false;
  257         return 1;
  258       }
  259       else
  260       {
  261         output = input;
  262         m_no_seq = true;
  263         return 0;
  264       }
  265     }
  266     output = input;
  267     return 1;
  268   }
  269   return m_names->expand(output, input, sequential);
  270 }