Changeset 416


Ignore:
Timestamp:
Nov 19, 2008, 3:41:49 PM (11 years ago)
Author:
ylafon@…
Message:

really ugly hack to add -l n for wrapping lines

File:
1 edited

Legend:

Unmodified
Added
Removed
  • abnfparser/bap/main.c

    r410 r416  
    5454#define MAXRULE         1000    /* XXX */
    5555
     56#define local_printf(format, args...)                           \
     57  if (!olenlimit) {                                             \
     58    printf( format, ## args );                                  \
     59  } else {                                                      \
     60    charcount += sprintf((charbuf+charcount), format, ## args); \
     61    if (charcount > olenlimit) {                                \
     62      charcut = charbuf+olenlimit;                              \
     63      while (*charcut != ' ' && charcut >= charbuf) {           \
     64        charcut--;                                              \
     65        charcount++;                                            \
     66      }                                                         \
     67      if (charcut != charbuf) {                                 \
     68        *charcut++ = 0;                                         \
     69        printf("%s\n", charbuf);                                \
     70        if (*charbuf == ';') {                                  \
     71          memmove(charbuf+2, charcut, charcount - olenlimit);   \
     72          *(charbuf+1) = ' ';                                   \
     73          charcount -= (olenlimit-1);                           \
     74        } else {                                                \
     75          memmove(charbuf+1, charcut, charcount - olenlimit);   \
     76          *charbuf = ' ';                                       \
     77          charcount -= olenlimit;                               \
     78        }                                                       \
     79      }                                                         \
     80    }                                                           \
     81    charcut = strchr(charbuf, '\n');                            \
     82    if (charcut) {                                              \
     83      printf("%s", charbuf);                                    \
     84      charcount = 0;                                            \
     85    }                                                           \
     86  }
     87   
     88
     89char *charbuf = NULL;
     90char *charcut = NULL;
     91int charcount = 0;
     92
    5693struct rule *rules = NULL;
    5794char *input_file; /* of current input file */
     
    66103int canon = 1;          /* canonify */
    67104int asxml = 0;    /* output XML */
     105int olenlimit = 0;   /* 0 for unlimited, might be any other value */
    68106
    69107int yyparse(void);
     
    72110usage(void)
    73111{
    74         fprintf(stderr, "Bill's ABNF Parser version %s\n", versionstring);
    75         fprintf(stderr, "usage: bap [-cikntq] [ file ]\n");
    76         fprintf(stderr, " parse ABNF grammar from file or stdin\n");
    77         fprintf(stderr, " -c      : include rule definition line # in comment\n");
    78         fprintf(stderr, " -k      : add comments for printable characters specified as %%x\n");
    79         fprintf(stderr, " -n      : don't \"canonify\" result\n");
    80         fprintf(stderr, " -i file : read predefined rules from \"file\"\n");
    81         fprintf(stderr, " -t      : include type info in result\n");
    82         fprintf(stderr, " -q      : don't print parsed grammar\n");
    83         fprintf(stderr, " -S name : name rule as production start\n");
    84         fprintf(stderr, " -x      : output XML\n");
    85         exit(1);
     112  fprintf(stderr, "Bill's ABNF Parser version %s\n", versionstring);
     113  fprintf(stderr, "usage: bap [-cikntq] [ file ]\n");
     114  fprintf(stderr, " parse ABNF grammar from file or stdin\n");
     115  fprintf(stderr, " -c      : include rule definition line # in comment\n");
     116  fprintf(stderr, " -k      : add comments for printable characters specified as %%x\n");
     117  fprintf(stderr, " -n      : don't \"canonify\" result\n");
     118  fprintf(stderr, " -i file : read predefined rules from \"file\"\n");
     119  fprintf(stderr, " -t      : include type info in result\n");
     120  fprintf(stderr, " -q      : don't print parsed grammar\n");
     121  fprintf(stderr, " -S name : name rule as production start\n");
     122  fprintf(stderr, " -x      : output XML\n");
     123  fprintf(stderr, " -l num  : limit the length of each line to \"num\" char.\n");
     124  exit(1);
    86125}
    87126
     
    89128main(int argc, char **argv)
    90129{
    91         int ch;
    92         int rc = 0;
    93         struct rule *r;
    94         fn_list *pre_input = NULL;
     130  int ch;
     131  int rc = 0;
     132  struct rule *r;
     133  fn_list *pre_input = NULL;
    95134 
    96135#ifdef YYDEBUG
    97         extern int yydebug;
    98 
    99         yydebug = 0;
     136  extern int yydebug;
     137
     138  yydebug = 0;
    100139#endif
    101         hcreate(MAXRULE);
    102 
    103         while ((ch = getopt(argc, argv, "cdi:kntqS:x")) != -1) {
    104                 switch (ch) {
    105                 case 'c':
    106                         cflag++;
    107                         break;
    108 
    109                 case 'd':
     140  hcreate(MAXRULE);
     141
     142  while ((ch = getopt(argc, argv, "cdi:kntqS:xl:")) != -1) {
     143    switch (ch) {
     144    case 'c':
     145      cflag++;
     146      break;
     147
     148    case 'd':
    110149#ifdef YYDEBUG
    111                         yydebug = 1;
     150      yydebug = 1;
    112151#else
    113                         fprintf(stderr, "Rebuild with -DYYDEBUG to use -d.\n");
     152      fprintf(stderr, "Rebuild with -DYYDEBUG to use -d.\n");
    114153#endif
    115                         break;
    116 
    117                 case 'k':
    118                         c2flag++;
    119                         break;
    120 
    121                 case 'n':
    122                         canon = 0;
    123                         break;
    124 
    125                 case 'i': {
    126                         fn_list *ifile = calloc(sizeof(fn_list), 1);
    127                         ifile->filename = optarg;
    128                         ifile->next = pre_input;
    129                         pre_input = ifile;
    130                         break;
    131                 }
     154      break;
     155
     156    case 'k':
     157      c2flag++;
     158      break;
     159
     160    case 'n':
     161      canon = 0;
     162      break;
     163
     164    case 'i': {
     165      fn_list *ifile = calloc(sizeof(fn_list), 1);
     166      ifile->filename = optarg;
     167      ifile->next = pre_input;
     168      pre_input = ifile;
     169      break;
     170    }
    132171     
    133                 case 't':
    134                         tflag++;
    135                         break;
    136 
    137                 case 'p':
    138                         permissive = 0;
    139                         break;
    140 
    141                 case 'q':
    142                         qflag++;
    143                         break;
    144 
    145                 case 'S':
    146                         top_rule_name = optarg;
    147                         break;
     172    case 't':
     173      tflag++;
     174      break;
     175
     176    case 'p':
     177      permissive = 0;
     178      break;
     179
     180    case 'q':
     181      qflag++;
     182      break;
     183
     184    case 'S':
     185      top_rule_name = optarg;
     186      break;
    148187     
    149                 case 'x':
    150                         asxml = 1;
    151                         break;
    152 
    153                 default:
    154                         usage();
    155                 }
    156         }
    157         argc -= optind;
    158         argv += optind;
    159 
    160         if (argc > 1)
    161                 usage();
    162 
    163         predefine(pre_input);   
     188    case 'x':
     189      asxml = 1;
     190      break;
     191
     192    case 'l':
     193      olenlimit = atoi(optarg);
     194      break;
     195
     196    default:
     197      usage();
     198    }
     199  }
     200  argc -= optind;
     201  argv += optind;
     202
     203  if (argc > 1)
     204    usage();
     205
     206  if (olenlimit) {
     207    charbuf = (char *) calloc (8192, sizeof(char));
     208  }
     209  predefine(pre_input);   
    164210 
    165         /* Parse the grammar, perhaps spouting errors. */
    166         parse_from((argc > 0)? argv[0] : NULL);
    167 
    168         /* If we're not quiet, then output the grammar again. */
    169         if (!qflag) {
    170                 if (canon)
    171                         canonify(rules);
     211  /* Parse the grammar, perhaps spouting errors. */
     212  parse_from((argc > 0)? argv[0] : NULL);
     213
     214  /* If we're not quiet, then output the grammar again. */
     215  if (!qflag) {
     216    if (canon)
     217      canonify(rules);
    172218    if (!asxml) {
    173                 for (r = rules; r; r = r->next) {
    174                         if (r->predefined) {
    175                                 /* do not output */
    176                         }
    177                         else if (r->rule) {
    178                                 printf("%s = ", r->name);
    179                                 printobj(r->rule, tflag);
    180                                 if (cflag)
    181                                         printf(" ; line %d", r->line);
    182                                 printf("\n");
    183                         } else {
    184                                 printf("; %s UNDEFINED\n", r->name);
    185                         }
    186                         if (r->next == rules)
    187                                 break;
    188                 }
    189                 for (r = rules; r; r = r->next) {
    190                         if (r->used == 0
    191                                 && r->predefined == 0
    192                                 && r->rule
    193                                 && strcmp(r->name, top_rule_name))
    194                                 printf("; %s defined but not used\n", r->name);
    195                         if (r->next == rules)
    196                                 break;
    197                 }
     219      for (r = rules; r; r = r->next) {
     220        if (r->predefined) {
     221          /* do not output */
     222        }
     223        else if (r->rule) {
     224          local_printf("%s = ", r->name);
     225          printobj(r->rule, tflag);
     226          if (cflag)
     227            local_printf(" ; line %d", r->line);
     228          local_printf("\n");
     229        } else {
     230          local_printf("; %s UNDEFINED\n", r->name);
     231        }
     232        if (r->next == rules)
     233          break;
     234      }
     235      for (r = rules; r; r = r->next) {
     236        if (r->used == 0
     237            && r->predefined == 0
     238            && r->rule
     239            && strcmp(r->name, top_rule_name))
     240          local_printf("; %s defined but not used\n", r->name);
     241        if (r->next == rules)
     242          break;
     243      }
    198244    }
    199245    else {
    200       printf("<abnf xmlns='tag:greenbytes.de,2008:abnf'>\n");
    201                 for (r = rules; r; r = r->next) {
    202                         if (r->predefined) {
    203                                 /* do not output */
    204                         }
    205                         else if (r->rule) {
    206           printf("  <rule name='%s'", r->name);
    207                                 if (cflag)
    208                                         printf(" line='%d'", r->line);
    209           printf(">");
    210                                 printobjasxml(r->rule, 2);
    211           printf("\n  </rule>\n");
    212                         } else {
    213                                 printf("  <undefined name='%s'/>\n", r->name);
    214                         }
    215                         if (r->next == rules)
    216                                 break;
    217                 }
    218       printf("</abnf>\n");
    219     }
    220         }
     246      local_printf("<abnf xmlns='tag:greenbytes.de,2008:abnf'>\n");
     247      for (r = rules; r; r = r->next) {
     248        if (r->predefined) {
     249          /* do not output */
     250        }
     251        else if (r->rule) {
     252          local_printf("  <rule name='%s'", r->name);
     253          if (cflag)
     254            local_printf(" line='%d'", r->line);
     255          local_printf(">");
     256          printobjasxml(r->rule, 2);
     257          local_printf("\n  </rule>\n");
     258        } else {
     259          local_printf("  <undefined name='%s'/>\n", r->name);
     260        }
     261        if (r->next == rules)
     262          break;
     263      }
     264      local_printf("</abnf>\n");
     265    }
     266  }
    221267 
    222         rc = summary();
    223         hdestroy();
    224         exit(rc);
     268  rc = summary();
     269  hdestroy();
     270  exit(rc);
    225271}
    226272
     
    228274canonify(struct rule *rules)
    229275{
    230         struct rule *r;
    231 
    232         for (r = rules; r; r = r->next) {
    233                 if (r->rule)
    234                         canonify_r(&r->rule);
    235                 if (r->next == rules)
    236                         break;
    237         }
     276  struct rule *r;
     277
     278  for (r = rules; r; r = r->next) {
     279    if (r->rule)
     280      canonify_r(&r->rule);
     281    if (r->next == rules)
     282      break;
     283  }
    238284}
    239285
     
    242288canonify_r(struct object **op)
    243289{
    244         struct object *o = *op;
    245         while (o) {
    246                 switch (o->type) {
    247                 case T_ALTERNATION:
    248                         canonify_r(&o->u.alternation.left);
    249                         canonify_r(&o->u.alternation.right);
    250                         break;
    251                 case T_RULE:
    252                         /* nothing to do */
    253                         break;
    254                 case T_GROUP:
    255                         canonify_r(&o->u.e.e.group);
    256                         break;
    257                 case T_TERMSTR:
    258                         while (o->next && o->next->type == T_TERMSTR &&
    259                             o->u.e.repetition.lo == 1 && o->u.e.repetition.hi == 1 &&
    260                             o->next->u.e.repetition.lo == 1 && o->next->u.e.repetition.hi == 1 &&
    261                             ((o->u.e.e.termstr.flags & F_CASESENSITIVE) ==
    262                              (o->next->u.e.e.termstr.flags & F_CASESENSITIVE))) {
    263                                 int len = strlen(o->u.e.e.termstr.str) + strlen(o->next->u.e.e.termstr.str);
    264                                 char *p = malloc(len + 1);
    265                                 strcpy(p, o->u.e.e.termstr.str);
    266                                 strcat(p, o->next->u.e.e.termstr.str);
    267                                 free(o->u.e.e.termstr.str);
    268                                 o->u.e.e.termstr.str = p;
    269                                 /* XXX leak o->next */
    270                                 o->next = o->next->next;
    271                         }
    272                         if (o->u.e.e.termstr.flags & F_CASESENSITIVE) {
    273                                 int anybad = 0;
    274                                 char *p;
    275                                 for (p = o->u.e.e.termstr.str; *p; p++) {
    276                                         if (isalpha(*p) || *p == '"' || !isprint(*p)) {
    277                                                 anybad = 1;
    278                                                 break;
    279                                         }
    280                                 }
    281                                 if (anybad == 0)
    282                                         o->u.e.e.termstr.flags &= ~F_CASESENSITIVE;
    283                         }
    284                 case T_TERMRANGE:
    285                 case T_PROSE:
    286                 default:
    287                         /* nothing to do */
    288                         break;
    289                 }
    290                 o = o->next;
    291         }
     290  struct object *o = *op;
     291  while (o) {
     292    switch (o->type) {
     293    case T_ALTERNATION:
     294      canonify_r(&o->u.alternation.left);
     295      canonify_r(&o->u.alternation.right);
     296      break;
     297    case T_RULE:
     298      /* nothing to do */
     299      break;
     300    case T_GROUP:
     301      canonify_r(&o->u.e.e.group);
     302      break;
     303    case T_TERMSTR:
     304      while (o->next && o->next->type == T_TERMSTR &&
     305             o->u.e.repetition.lo == 1 && o->u.e.repetition.hi == 1 &&
     306             o->next->u.e.repetition.lo == 1 && o->next->u.e.repetition.hi == 1 &&
     307             ((o->u.e.e.termstr.flags & F_CASESENSITIVE) ==
     308              (o->next->u.e.e.termstr.flags & F_CASESENSITIVE))) {
     309        int len = strlen(o->u.e.e.termstr.str) + strlen(o->next->u.e.e.termstr.str);
     310        char *p = malloc(len + 1);
     311        strcpy(p, o->u.e.e.termstr.str);
     312        strcat(p, o->next->u.e.e.termstr.str);
     313        free(o->u.e.e.termstr.str);
     314        o->u.e.e.termstr.str = p;
     315        /* XXX leak o->next */
     316        o->next = o->next->next;
     317      }
     318      if (o->u.e.e.termstr.flags & F_CASESENSITIVE) {
     319        int anybad = 0;
     320        char *p;
     321        for (p = o->u.e.e.termstr.str; *p; p++) {
     322          if (isalpha(*p) || *p == '"' || !isprint(*p)) {
     323            anybad = 1;
     324            break;
     325          }
     326        }
     327        if (anybad == 0)
     328          o->u.e.e.termstr.flags &= ~F_CASESENSITIVE;
     329      }
     330    case T_TERMRANGE:
     331    case T_PROSE:
     332    default:
     333      /* nothing to do */
     334      break;
     335    }
     336    o = o->next;
     337  }
    292338}
    293339
     
    295341printrep(struct range *rep)
    296342{
    297         if (rep->lo == 1 && rep->hi == 1)
    298                 return;
    299         if (rep->lo > 0)
    300                 printf("%d", rep->lo);
    301         if (rep->lo == rep->hi) {
    302                 if (rep->lo == 0)
    303                         printf("0");
    304                 return;
    305         }
    306         printf("*");
    307         if (rep->hi != -1)
    308                 printf("%d", rep->hi);
     343  if (rep->lo == 1 && rep->hi == 1)
     344    return;
     345  if (rep->lo > 0)
     346    local_printf("%d", rep->lo);
     347  if (rep->lo == rep->hi) {
     348    if (rep->lo == 0)
     349      local_printf("0");
     350    return;
     351  }
     352  local_printf("*");
     353  if (rep->hi != -1)
     354    local_printf("%d", rep->hi);
    309355}
    310356
     
    312358printobj(object *o, int tflag)
    313359{
    314         /* T_GROUP means don't put grouping characters
    315         * around the top level. */
    316         printobj_r(o, T_GROUP, tflag);
     360  /* T_GROUP means don't put grouping characters
     361  * around the top level. */
     362  printobj_r(o, T_GROUP, tflag);
    317363}
    318364
     
    320366printobjasxml(object *o, int indent)
    321367{
    322         /* T_GROUP means don't put grouping characters
    323         * around the top level. */
    324         printobjasxml_r(o, T_GROUP, indent);
     368  /* T_GROUP means don't put grouping characters
     369  * around the top level. */
     370  printobjasxml_r(o, T_GROUP, indent);
    325371}
    326372
     
    343389printobj_r(object *o, int parenttype, int tflag)
    344390{
    345         int iterating = 0;
    346 
    347         /* Put parenthesis around concatenations */
    348         if (parenttype != T_GROUP && o->next) {
    349                 iterating = 1;
    350                 printf("( ");
    351         }
    352         while (o) {
    353                 switch (o->type) {
    354                 case T_ALTERNATION:
    355                         if (tflag)
    356                                 printf("{ALTERNATION}");
    357                         if (o->next)
    358                                 printf("( ");
    359                         printobj_r(o->u.alternation.left, o->type, tflag);
    360                         printf(" / ");
    361                         printobj_r(o->u.alternation.right, o->type, tflag);
    362                         if (o->next)
    363                                 printf(" )");
    364                         break;
    365                 case T_RULE: /* identation to delimit the code change */
    366                   if (tflag)
    367                     printf("{RULE}");
    368                   if (o->u.e.islist) {
    369                     if (o->u.e.repetition.lo == 0) {
    370                       printf("[ ( \",\" / ");
    371                       if (o->u.e.e.rule.rule) {
    372                         printf("%s", o->u.e.e.rule.rule->name);
    373                         o->u.e.e.rule.rule->used = 1;
    374                       } else {
    375                         printf("%s", o->u.e.e.rule.name);
    376                       }
    377                       printf(" ) *( OWS \",\" [ OWS ");
    378                       printf("%s", (o->u.e.e.rule.rule) ?
    379                             o->u.e.e.rule.rule->name :
    380                             o->u.e.e.rule.name);
    381                       printf(" ] ) ]");
    382                     } else if (o->u.e.repetition.lo == 1) {
    383                       printf(" *( \",\" OWS ) ");
    384                       if (o->u.e.e.rule.rule) {
    385                         printf("%s", o->u.e.e.rule.rule->name);
    386                         o->u.e.e.rule.rule->used = 1;
    387                       } else {
    388                         printf("%s", o->u.e.e.rule.name);
    389                       }
    390                       printf(" *( OWS \",\" [ OWS ");
    391                       printf("%s", (o->u.e.e.rule.rule) ?
    392                             o->u.e.e.rule.rule->name :
    393                             o->u.e.e.rule.name);
    394                       printf(" ] )");
    395                     }
    396                     else {
    397                       printf("TODO: something is wrong");
    398                     }
    399                   } else {
    400                     printrep(&o->u.e.repetition);
    401                     if (o->u.e.e.rule.rule) {
    402                       printf("%s", o->u.e.e.rule.rule->name);
    403                       o->u.e.e.rule.rule->used = 1;
    404                     }
    405                     else {
    406                       printf("%s", o->u.e.e.rule.name);
    407                     }
    408                   }
    409                   break;
    410                 case T_GROUP:
    411                   if (tflag)
    412                     printf("{GROUP}");
    413                   if (o->u.e.islist) {
    414                     if (o->u.e.repetition.lo == 0) {
    415                       printf("[ ( \",\" / ");
    416                       printobj_r(o->u.e.e.group, o->type, tflag);
    417                       printf(" ) *( OWS \",\" [ OWS ");
    418                       printobj_r(o->u.e.e.group, o->type, tflag);
    419                       printf(" ] ) ]");
    420                     }
    421                     else if (o->u.e.repetition.lo == 1) {
    422                       printf("*( \",\" OWS ) ");
    423                       printobj_r(o->u.e.e.group, o->type, tflag);
    424                       printf(" *( OWS \",\" [ OWS ");
    425                       printobj_r(o->u.e.e.group, o->type, tflag);
    426                       printf(" ] )");
    427                     }
    428                     else {
    429                       printf("TODO: something is wrong");
    430                     }
    431                   } else {
    432                     if (o->u.e.repetition.lo == 0 &&
    433                         o->u.e.repetition.hi == 1) {
    434                       if (!NOBRACKET(o->u.e.e.group))
    435                         printf("[ ");
    436                     } else {
    437                       printrep(&o->u.e.repetition);
    438                       if (!NOPAREN(o->u.e.e.group))
    439                         printf("( ");
    440                     }
    441                     printobj_r(o->u.e.e.group, o->type, tflag);
    442                     if (o->u.e.repetition.lo == 0 &&
    443                         o->u.e.repetition.hi == 1) {
    444                       if (!NOBRACKET(o->u.e.e.group))
    445                         printf(" ]");
    446                     } else {
    447                       if (!NOPAREN(o->u.e.e.group))
    448                         printf(" )");
    449                     }
    450                   }
    451                   break;
    452                 case T_TERMSTR:
    453                         if (tflag)
    454                                 printf("{TERMSTR}");
    455                         printrep(&o->u.e.repetition);
    456                         if (o->u.e.e.termstr.flags & F_CASESENSITIVE) {
    457                                 unsigned char *p = (unsigned char*)o->u.e.e.termstr.str;
    458                                 char sep;
    459                                 int allprintable = 1;
    460                                 printf("%%");
    461                                 sep = 'x';
    462                                 while (*p) {
    463                                         if (!isgraph(*p)) allprintable = 0;
    464                                         printf("%c%02X", sep, *p++);
    465                                         sep = '.';
    466                                 }
    467                                 if (c2flag && allprintable)
    468                                         printf(" ; %s\n", o->u.e.e.termstr.str);
    469                         } else {
    470                                 printf("%c%s%c", '"', o->u.e.e.termstr.str, '"');
    471                         }
    472                         break;
    473                 case T_TERMRANGE:
    474                         if (tflag)
    475                                 printf("{TERMRANGE}");
    476                         printrep(&o->u.e.repetition);
    477                         printf("%%x%02X-%02X",
    478                                 o->u.e.e.termrange.lo,
    479                                 o->u.e.e.termrange.hi);
    480                         /* XXX isprint does not handle non-ASCII */
    481                         if (c2flag &&
    482                             isprint(o->u.e.e.termrange.lo) &&
    483                             isprint(o->u.e.e.termrange.hi)) {
    484                                 printf(" ; '%c'-'%c'\n",
    485                                         o->u.e.e.termrange.lo,
    486                                         o->u.e.e.termrange.hi);
    487                         }
    488                         break;
    489                 case T_PROSE:
    490                         if (tflag)
    491                                 printf("{PROSE}");
    492                         printrep(&o->u.e.repetition);
    493                         printf("<%s>", o->u.e.e.proseval);
    494                         break;
    495                 default:
    496                         printf("{UNKNOWN OBJECT TYPE %d}", o->type);
    497                         break;
    498                 }
    499                 if (o->next)
    500                         printf(" ");
    501                 o = o->next;
    502         }
    503         if (iterating)
    504                 printf(" )");
     391  int iterating = 0;
     392
     393  /* Put parenthesis around concatenations */
     394  if (parenttype != T_GROUP && o->next) {
     395    iterating = 1;
     396    local_printf("( ");
     397  }
     398  while (o) {
     399    switch (o->type) {
     400    case T_ALTERNATION:
     401      if (tflag)
     402        local_printf("{ALTERNATION}");
     403      if (o->next)
     404        local_printf("( ");
     405      printobj_r(o->u.alternation.left, o->type, tflag);
     406      local_printf(" / ");
     407      printobj_r(o->u.alternation.right, o->type, tflag);
     408      if (o->next)
     409        local_printf(" )");
     410      break;
     411    case T_RULE: /* identation to delimit the code change */
     412      if (tflag)
     413        local_printf("{RULE}");
     414      if (o->u.e.islist) {
     415        if (o->u.e.repetition.lo == 0) {
     416          local_printf("[ ( \",\" / ");
     417          if (o->u.e.e.rule.rule) {
     418            local_printf("%s", o->u.e.e.rule.rule->name);
     419            o->u.e.e.rule.rule->used = 1;
     420          } else {
     421            local_printf("%s", o->u.e.e.rule.name);
     422          }
     423          local_printf(" ) *( OWS \",\" [ OWS ");
     424          local_printf("%s", (o->u.e.e.rule.rule) ?
     425                o->u.e.e.rule.rule->name :
     426                o->u.e.e.rule.name);
     427          local_printf(" ] ) ]");
     428        } else if (o->u.e.repetition.lo == 1) {
     429          local_printf(" *( \",\" OWS ) ");
     430          if (o->u.e.e.rule.rule) {
     431            local_printf("%s", o->u.e.e.rule.rule->name);
     432            o->u.e.e.rule.rule->used = 1;
     433          } else {
     434            local_printf("%s", o->u.e.e.rule.name);
     435          }
     436          local_printf(" *( OWS \",\" [ OWS ");
     437          local_printf("%s", (o->u.e.e.rule.rule) ?
     438                o->u.e.e.rule.rule->name :
     439                o->u.e.e.rule.name);
     440          local_printf(" ] )");
     441        }
     442        else {
     443          local_printf("TODO: something is wrong");
     444        }
     445      } else {
     446        printrep(&o->u.e.repetition);
     447        if (o->u.e.e.rule.rule) {
     448          local_printf("%s", o->u.e.e.rule.rule->name);
     449          o->u.e.e.rule.rule->used = 1;
     450        }
     451        else {
     452          local_printf("%s", o->u.e.e.rule.name);
     453        }
     454      }
     455      break;
     456    case T_GROUP:
     457      if (tflag)
     458        local_printf("{GROUP}");
     459      if (o->u.e.islist) {
     460        if (o->u.e.repetition.lo == 0) {
     461          local_printf("[ ( \",\" / ");
     462          printobj_r(o->u.e.e.group, o->type, tflag);
     463          local_printf(" ) *( OWS \",\" [ OWS ");
     464          printobj_r(o->u.e.e.group, o->type, tflag);
     465          local_printf(" ] ) ]");
     466        }
     467        else if (o->u.e.repetition.lo == 1) {
     468          local_printf("*( \",\" OWS ) ");
     469          printobj_r(o->u.e.e.group, o->type, tflag);
     470          local_printf(" *( OWS \",\" [ OWS ");
     471          printobj_r(o->u.e.e.group, o->type, tflag);
     472          local_printf(" ] )");
     473        }
     474        else {
     475          local_printf("TODO: something is wrong");
     476        }
     477      } else {
     478        if (o->u.e.repetition.lo == 0 &&
     479            o->u.e.repetition.hi == 1) {
     480          if (!NOBRACKET(o->u.e.e.group))
     481            local_printf("[ ");
     482        } else {
     483          printrep(&o->u.e.repetition);
     484          if (!NOPAREN(o->u.e.e.group))
     485            local_printf("( ");
     486        }
     487        printobj_r(o->u.e.e.group, o->type, tflag);
     488        if (o->u.e.repetition.lo == 0 &&
     489            o->u.e.repetition.hi == 1) {
     490          if (!NOBRACKET(o->u.e.e.group))
     491            local_printf(" ]");
     492        } else {
     493          if (!NOPAREN(o->u.e.e.group))
     494            local_printf(" )");
     495        }
     496      }
     497      break;
     498    case T_TERMSTR:
     499      if (tflag)
     500        local_printf("{TERMSTR}");
     501      printrep(&o->u.e.repetition);
     502      if (o->u.e.e.termstr.flags & F_CASESENSITIVE) {
     503        unsigned char *p = (unsigned char*)o->u.e.e.termstr.str;
     504        char sep;
     505        int allprintable = 1;
     506        local_printf("%%");
     507        sep = 'x';
     508        while (*p) {
     509          if (!isgraph(*p)) allprintable = 0;
     510          local_printf("%c%02X", sep, *p++);
     511          sep = '.';
     512        }
     513        if (c2flag && allprintable)
     514          local_printf(" ; %s\n", o->u.e.e.termstr.str);
     515      } else {
     516        local_printf("%c%s%c", '"', o->u.e.e.termstr.str, '"');
     517      }
     518      break;
     519    case T_TERMRANGE:
     520      if (tflag)
     521        local_printf("{TERMRANGE}");
     522      printrep(&o->u.e.repetition);
     523      local_printf("%%x%02X-%02X",
     524             o->u.e.e.termrange.lo,
     525             o->u.e.e.termrange.hi);
     526      /* XXX isprint does not handle non-ASCII */
     527      if (c2flag &&
     528          isprint(o->u.e.e.termrange.lo) &&
     529          isprint(o->u.e.e.termrange.hi)) {
     530        local_printf(" ; '%c'-'%c'\n",
     531               o->u.e.e.termrange.lo,
     532               o->u.e.e.termrange.hi);
     533      }
     534      break;
     535    case T_PROSE:
     536      if (tflag)
     537        local_printf("{PROSE}");
     538      printrep(&o->u.e.repetition);
     539      local_printf("<%s>", o->u.e.e.proseval);
     540      break;
     541    default:
     542      local_printf("{UNKNOWN OBJECT TYPE %d}", o->type);
     543      break;
     544    }
     545    if (o->next)
     546      local_printf(" ");
     547    o = o->next;
     548  }
     549  if (iterating)
     550    local_printf(" )");
    505551}
    506552
     
    509555  while (*c) {
    510556    if (*c == '&') {
    511       printf("&amp;");
     557      local_printf("&amp;");
    512558    }
    513559    else if (*c == '<') {
    514       printf("&lt;");
     560      local_printf("&lt;");
    515561    }
    516562    else {
    517       printf("%c", *c);
     563      local_printf("%c", *c);
    518564    }
    519565    c += 1;
     
    524570printobjasxml_r(object *o, int parenttype, int indent)
    525571{
    526         while (o) {
    527                 switch (o->type) {
    528                 case T_ALTERNATION:
    529       printf("<alternation>\n");
    530       printf("<alternative>");
     572  while (o) {
     573    switch (o->type) {
     574    case T_ALTERNATION:
     575      local_printf("<alternation>\n");
     576      local_printf("<alternative>");
    531577      printobjasxml_r(o->u.alternation.left, o->type, indent + 2);
    532       printf("</alternative>\n");
    533       printf("<alternative>");
    534                         printobjasxml_r(o->u.alternation.right, o->type, indent + 2);
    535       printf("</alternative>\n");
    536       printf("</alternation>\n");
    537                         break;
    538                 case T_RULE:
    539                         if (o->u.e.islist) {
    540         printf("<list min='%d' max='%d'>\n", o->u.e.repetition.lo, o->u.e.repetition.hi);
    541                           if (o->u.e.e.rule.rule) {
    542                                   printf("<rule ref='%s'/>", o->u.e.e.rule.rule->name);
    543                                   o->u.e.e.rule.rule->used = 1;
    544                           }
     578      local_printf("</alternative>\n");
     579      local_printf("<alternative>");
     580      printobjasxml_r(o->u.alternation.right, o->type, indent + 2);
     581      local_printf("</alternative>\n");
     582      local_printf("</alternation>\n");
     583      break;
     584    case T_RULE:
     585      if (o->u.e.islist) {
     586        local_printf("<list min='%d' max='%d'>\n", o->u.e.repetition.lo, o->u.e.repetition.hi);
     587        if (o->u.e.e.rule.rule) {
     588          local_printf("<rule ref='%s'/>", o->u.e.e.rule.rule->name);
     589          o->u.e.e.rule.rule->used = 1;
     590        }
    545591        else {
    546                                   printf("<rule ref='%s'/>", o->u.e.e.rule.name);
     592          local_printf("<rule ref='%s'/>", o->u.e.e.rule.name);
    547593        }
    548         printf("</list>\n");
     594        local_printf("</list>\n");
    549595      }
    550596      else {
    551                           if (o->u.e.e.rule.rule) {
    552                                   printf("<rule min='%d' max='%d' ref='%s'/>", o->u.e.repetition.lo, o->u.e.repetition.hi, o->u.e.e.rule.rule->name);
    553                                   o->u.e.e.rule.rule->used = 1;
    554                           }
     597        if (o->u.e.e.rule.rule) {
     598          local_printf("<rule min='%d' max='%d' ref='%s'/>", o->u.e.repetition.lo, o->u.e.repetition.hi, o->u.e.e.rule.rule->name);
     599          o->u.e.e.rule.rule->used = 1;
     600        }
    555601        else {
    556                                   printf("<rule min='%d' max='%d' ref='%s'/>", o->u.e.repetition.lo, o->u.e.repetition.hi, o->u.e.e.rule.name);
     602          local_printf("<rule min='%d' max='%d' ref='%s'/>", o->u.e.repetition.lo, o->u.e.repetition.hi, o->u.e.e.rule.name);
    557603        }
    558604      }
    559                         break;
    560                 case T_GROUP:
     605      break;
     606    case T_GROUP:
    561607      if (o->u.e.islist) {
    562         printf("<list min='%d' max='%d'>\n", o->u.e.repetition.lo, o->u.e.repetition.hi);
     608        local_printf("<list min='%d' max='%d'>\n", o->u.e.repetition.lo, o->u.e.repetition.hi);
    563609        printobjasxml_r(o->u.e.e.group, o->type, indent + 2);
    564         printf("</list>");
     610        local_printf("</list>");
    565611      }
    566612      else {
    567         printf("<group min='%d' max='%d'>\n", o->u.e.repetition.lo, o->u.e.repetition.hi);
    568                         printobjasxml_r(o->u.e.e.group, o->type, indent + 2);
    569                 printf("</group>");
    570       }
    571                         break;
    572                 case T_TERMSTR:
    573       printf("<term min='%d' max='%d'>", o->u.e.repetition.lo, o->u.e.repetition.hi);
    574                         if (o->u.e.e.termstr.flags & F_CASESENSITIVE) {
    575                                 unsigned char *p = (unsigned char*)o->u.e.e.termstr.str;
    576                                 char sep;
    577                                 int allprintable = 1;
    578                                 printf("%%");
    579                                 sep = 'x';
    580                                 while (*p) {
    581                                         if (!isgraph(*p)) allprintable = 0;
    582                                         printf("%c%02X", sep, *p++);
    583                                         sep = '.';
    584                                 }
    585                         } else {
    586         printf("\"");
     613        local_printf("<group min='%d' max='%d'>\n", o->u.e.repetition.lo, o->u.e.repetition.hi);
     614        printobjasxml_r(o->u.e.e.group, o->type, indent + 2);
     615        local_printf("</group>");
     616      }
     617      break;
     618    case T_TERMSTR:
     619      local_printf("<term min='%d' max='%d'>", o->u.e.repetition.lo, o->u.e.repetition.hi);
     620      if (o->u.e.e.termstr.flags & F_CASESENSITIVE) {
     621        unsigned char *p = (unsigned char*)o->u.e.e.termstr.str;
     622        char sep;
     623        int allprintable = 1;
     624        local_printf("%%");
     625        sep = 'x';
     626        while (*p) {
     627          if (!isgraph(*p)) allprintable = 0;
     628          local_printf("%c%02X", sep, *p++);
     629          sep = '.';
     630        }
     631      } else {
     632        local_printf("\"");
    587633        escaped(o->u.e.e.termstr.str);
    588         printf("\"");
    589                 }
    590       printf("</term>");
    591                         break;
    592                 case T_TERMRANGE:
    593       printf("<termrange min='%d' max='%d'>", o->u.e.repetition.lo, o->u.e.repetition.hi);
    594                         printf("%%x%02X-%02X",
    595                                 o->u.e.e.termrange.lo,
    596                                 o->u.e.e.termrange.hi);
    597                         /* XXX isprint does not handle non-ASCII */
    598                         if (c2flag &&
    599                             isprint(o->u.e.e.termrange.lo) &&
    600                             isprint(o->u.e.e.termrange.hi)) {
    601                                 printf(" ; '%c'-'%c'\n",
    602                                         o->u.e.e.termrange.lo,
    603                                         o->u.e.e.termrange.hi);
    604                         }
    605       printf("</termrange>");
    606                         break;
    607                 case T_PROSE:
    608       printf("<prose min='%d' max='%d'>", o->u.e.repetition.lo, o->u.e.repetition.hi);
    609                         escaped(o->u.e.e.proseval);
    610       printf("</prose>");
    611                         break;
    612                 default:
    613                         printf("{UNKNOWN OBJECT TYPE %d}", o->type);
    614                         break;
    615                 }
    616                 if (o->next)
    617                         printf(" ");
    618                 o = o->next;
    619         }
     634        local_printf("\"");
     635      }
     636      local_printf("</term>");
     637      break;
     638    case T_TERMRANGE:
     639      local_printf("<termrange min='%d' max='%d'>", o->u.e.repetition.lo, o->u.e.repetition.hi);
     640      local_printf("%%x%02X-%02X",
     641             o->u.e.e.termrange.lo,
     642             o->u.e.e.termrange.hi);
     643      /* XXX isprint does not handle non-ASCII */
     644      if (c2flag &&
     645          isprint(o->u.e.e.termrange.lo) &&
     646          isprint(o->u.e.e.termrange.hi)) {
     647        local_printf(" ; '%c'-'%c'\n",
     648               o->u.e.e.termrange.lo,
     649               o->u.e.e.termrange.hi);
     650      }
     651      local_printf("</termrange>");
     652      break;
     653    case T_PROSE:
     654      local_printf("<prose min='%d' max='%d'>", o->u.e.repetition.lo, o->u.e.repetition.hi);
     655      escaped(o->u.e.e.proseval);
     656      local_printf("</prose>");
     657      break;
     658    default:
     659      local_printf("{UNKNOWN OBJECT TYPE %d}", o->type);
     660      break;
     661    }
     662    if (o->next)
     663      local_printf(" ");
     664    o = o->next;
     665  }
    620666}
    621667
     
    623669findrule(char *name)
    624670{
    625         char *lowername;
    626         char *p, *q;
    627         ENTRY *e;
    628         ENTRY search;
    629         struct rule *r;
    630 
    631         lowername = malloc(strlen(name) + 1);
    632         for (p = name, q = lowername; *p; p++, q++)
    633                 if (isupper(*p))
    634                         *q = tolower(*p);
    635                 else
    636                         *q = *p;
    637         *q = '\0';
    638         search.key = lowername;
    639         search.data = NULL;
    640         e = hsearch(search, FIND);
    641         if (e == NULL) {
    642                 r = calloc(1, sizeof(struct rule));
    643                 r->name = name;
    644                 r->lowername = lowername;
    645                 search.data = r;
    646                 e = hsearch(search, ENTER);
    647                 if (e == NULL) {
    648                         fprintf(stderr, "hash table full -- increase MAXRULE\n");
    649                         exit(1);
    650                 }
    651                 if (rules) {
    652                         r->next = rules;
    653                         r->prev = rules->prev;
    654                         rules->prev->next = r;
    655                         rules->prev = r;
    656                 } else {
    657                         rules = r->next = r->prev = r;
    658                 }
    659                 return r;
    660         } else {
    661                 free(lowername);
    662                 return (struct rule *)e->data;
    663         }
     671  char *lowername;
     672  char *p, *q;
     673  ENTRY *e;
     674  ENTRY search;
     675  struct rule *r;
     676
     677  lowername = malloc(strlen(name) + 1);
     678  for (p = name, q = lowername; *p; p++, q++)
     679    if (isupper(*p))
     680      *q = tolower(*p);
     681    else
     682      *q = *p;
     683  *q = '\0';
     684  search.key = lowername;
     685  search.data = NULL;
     686  e = hsearch(search, FIND);
     687  if (e == NULL) {
     688    r = calloc(1, sizeof(struct rule));
     689    r->name = name;
     690    r->lowername = lowername;
     691    search.data = r;
     692    e = hsearch(search, ENTER);
     693    if (e == NULL) {
     694      fprintf(stderr, "hash table full -- increase MAXRULE\n");
     695      exit(1);
     696    }
     697    if (rules) {
     698      r->next = rules;
     699      r->prev = rules->prev;
     700      rules->prev->next = r;
     701      rules->prev = r;
     702    } else {
     703      rules = r->next = r->prev = r;
     704    }
     705    return r;
     706  } else {
     707    free(lowername);
     708    return (struct rule *)e->data;
     709  }
    664710}
    665711
    666712void
    667713parse_from(char *filename) {
    668         extern FILE *yyin;
    669         FILE *fin = NULL;
     714  extern FILE *yyin;
     715  FILE *fin = NULL;
    670716 
    671         if (filename != NULL) {
    672                 fin = fopen (filename, "rt");
    673                 if (!fin) {
    674                         fprintf(stderr, "input file not found: %s\n", filename);
    675                         exit(1);
    676                 }
     717  if (filename != NULL) {
     718    fin = fopen (filename, "rt");
     719    if (!fin) {
     720      fprintf(stderr, "input file not found: %s\n", filename);
     721      exit(1);
     722    }
    677723   
    678                 input_file = filename;
    679                 yyin = fin;
    680         }
    681         else {
    682                 yyin = stdin;
    683                 input_file = "stdin";
    684         }
     724    input_file = filename;
     725    yyin = fin;
     726  }
     727  else {
     728    yyin = stdin;
     729    input_file = "stdin";
     730  }
    685731 
    686         scanreset();
    687         yyparse();
     732  scanreset();
     733  yyparse();
    688734 
    689         if (fin) fclose(fin); 
     735  if (fin) fclose(fin); 
    690736}
    691737
    692738void
    693739predefine(fn_list *ifile) {
    694         struct rule *r;
    695         for (;ifile; ifile = ifile->next) {
    696                 parse_from(ifile->filename);
    697         }
     740  struct rule *r;
     741  for (;ifile; ifile = ifile->next) {
     742    parse_from(ifile->filename);
     743  }
    698744 
    699         for (r = rules; r; r = r->next) {
    700                 /* struct without rule definitions are created when names are used
    701                 they are != null when the rule was actually defined */
    702                 if (r->rule)
    703                         r->predefined = 1;
    704                 else
    705                         r->used = 1;
    706 
    707                 if (r->next == rules)
    708                         break;
    709         }
     745  for (r = rules; r; r = r->next) {
     746    /* struct without rule definitions are created when names are used
     747       they are != null when the rule was actually defined */
     748    if (r->rule)
     749      r->predefined = 1;
     750    else
     751      r->used = 1;
     752
     753    if (r->next == rules)
     754      break;
     755  }
    710756}
    711757
    712758int
    713759summary(void) {
    714         extern int yyerrors;
    715         if (yyerrors > 0) {
    716                 fflush(stdout);
    717                 fprintf(stderr, "parsing failed: %d errors encountered\n", yyerrors);
    718         }
    719         return yyerrors;
    720 }
    721 
     760  extern int yyerrors;
     761  if (yyerrors > 0) {
     762    fflush(stdout);
     763    fprintf(stderr, "parsing failed: %d errors encountered\n", yyerrors);
     764  }
     765  return yyerrors;
     766}
     767
Note: See TracChangeset for help on using the changeset viewer.