"Fossies" - the Fresh Open Source Software Archive

Member "dosemu-1.4.0/setup/parser/parser.y" (4 May 2007, 9044 Bytes) of package /linux/misc/old/dosemu-1.4.0.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Bison source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 /* 
    2  * (C) Copyright 1992, ..., 2007 the "DOSEMU-Development-Team".
    3  *
    4  * for details see file COPYING.DOSEMU in the DOSEMU distribution
    5  */
    6 
    7 %{
    8 #include <stdlib.h>
    9 #include <stdio.h>
   10 #include <string.h>
   11 #include <sys/stat.h>
   12 #include <unistd.h>
   13 #include <stdarg.h>
   14 
   15 #define SERIAL(v) (((YYSTYPE *)(&(v)))->u.serial)
   16 
   17 static char *parsedfile = 0;
   18 static char *updatefile = 0;
   19 static char *activefile = 0;
   20 
   21 static int errors = 0;
   22 static int updatemode = 0;
   23 static int option_t = 0;
   24 static int option_rc = 0;
   25 
   26 static char *dosemurc_varlist[] = {
   27     "_debug", "_timint", "_mathco", "_cpu", "_pci", "_xms", "_ems", "_ems_frame",
   28     "_features", "_mapping",
   29     "_emusys", "_emuini",
   30     "_term_char_set", "_term_color", "_term_updfreq", "_escchar", "_layout",
   31     "_X_updfreq", "_X_title", "_X_icon_name", "_X_keycode", "_X_blinkrate",
   32     "_X_font", "_X_mitshm", "_X_sharecmap", "_X_fixed_aspect", "_X_aspect_43",
   33     "_X_lin_filt", "_X_bilin_filt", "_X_mode13fact", "_X_winsize", "_X_gamma",
   34     "_X_vgaemu_memsize", "_X_lfb", "_X_pm_interface", "_X_mgrab_key", "_X_vesamode",
   35     "_speaker",
   36     "_com1", "_com2", "_com3", "_com4", "_mouse", "_mouse_dev", "_mouse_flags", "_mouse_baud",
   37     "_printer", "_printer_timeout", "_ports",
   38     "_ipxsupport", "_novell_hack", "_vnet",
   39     "_sound", "_sb_base", "_sb_irq", "_sb_dma", "_sb_hdma", "_sb_dsp", "_sb_mixer", "_mpu_base",
   40     "_hogthreshold", "_dpmi", "_vbootfloppy", "_hdimage", "_ttylocks",
   41     "_aspi",
   42     NULL
   43 };
   44 
   45     /* external procedures */
   46 extern int yylex(); /* exact argument types depend on the way you call bison */
   47 
   48     /* variables in lexer.l */
   49 extern int line_count;
   50 extern FILE* yyin;
   51 extern void yyrestart(FILE *input_file);
   52 
   53     /* local procedures */
   54 static void yyerror(char *, ...);
   55 static void handle_assignment(char *typ, char *var, char *s);
   56 static char *joinstrings(char *frmt, ...);
   57 
   58 %}
   59 
   60 %start lines
   61 
   62 %union {
   63     char *s_value;
   64     struct {
   65         int dummy;
   66         int serial;
   67     } __attribute__((packed)) u;
   68 };
   69 
   70 %token <s_value> INTEGER L_OFF L_ON L_AUTO
   71 %token <s_value> REAL
   72 %token <s_value> STRING STRING1 VARIABLE
   73 %type  <s_value> expression strarglist strarglist_item
   74 %left AND_OP OR_OP XOR_OP SHR_OP SHL_OP
   75 %left NOT_OP /* logical NOT */
   76 %left EQ_OP GE_OP LE_OP '=' '<' '>' NEQ_OP
   77     /*
   78     %left STR_EQ_OP STR_NEQ_OP
   79     */
   80 %left L_AND_OP L_OR_OP
   81 %left '+' '-'
   82 %left '*' '/'
   83 %left UMINUS UPLUS BIT_NOT_OP
   84 
   85 %%
   86 
   87 
   88 lines:        line
   89         | lines line
   90         ;
   91 
   92 line:         VARIABLE '=' '(' expression ')' {handle_assignment("N ", $1, joinstrings("(%s)",$4,0));}
   93         | VARIABLE '=' strarglist  {handle_assignment("S ", $1, $3);}
   94         ;
   95 
   96 expression:   INTEGER
   97         | REAL
   98         | VARIABLE      {$$ = joinstrings("$%s",$1,0);}
   99         | expression '+' expression {$$ = joinstrings("%s + %%s",$1,$3,0);}
  100         | expression '-' expression {$$ = joinstrings("%s - %%s",$1,$3,0);}
  101         | expression '*' expression {$$ = joinstrings("%s * %%s",$1,$3,0);}
  102         | expression '/' expression {$$ = joinstrings("%s / %%s",$1,$3,0);}
  103         | '-' expression %prec UMINUS {$$ = joinstrings("-%s",$2,0);}
  104         | '+' expression %prec UPLUS {$$ = joinstrings("+%s",$2,0);}
  105         | expression AND_OP expression {$$ = joinstrings("%s & %%s",$1,$3,0);}
  106         | expression OR_OP expression {$$ = joinstrings("%s | %%s",$1,$3,0);}
  107         | expression XOR_OP expression {$$ = joinstrings("%s ^ %%s",$1,$3,0);}
  108         | BIT_NOT_OP expression %prec BIT_NOT_OP {$$ = joinstrings("~%s",$2,0);}
  109         | expression SHR_OP expression {$$ = joinstrings("%s >> %%s",$1,$3,0);}
  110         | expression SHL_OP expression {$$ = joinstrings("%s << %%s",$1,$3,0);}
  111         | expression EQ_OP expression {$$ = joinstrings("%s == %%s",$1,$3,0);}
  112         | expression NEQ_OP expression {$$ = joinstrings("%s != %%s",$1,$3,0);}
  113         | expression GE_OP expression {$$ = joinstrings("%s >= %%s",$1,$3,0);}
  114         | expression LE_OP expression {$$ = joinstrings("%s <= %%s",$1,$3,0);}
  115         | expression '<' expression {$$ = joinstrings("%s < %%s",$1,$3,0);}
  116         | expression '>' expression {$$ = joinstrings("%s > %%s",$1,$3,0);}
  117         | expression L_AND_OP expression {$$ = joinstrings("%s && %%s",$1,$3,0);}
  118         | expression L_OR_OP expression {$$ = joinstrings("%s || %%s",$1,$3,0);}
  119         | NOT_OP expression {$$ = joinstrings("!%s",$2,0);}
  120         | '(' expression ')'    {$$ = joinstrings("(%s)",$2,0);}
  121         ;
  122 
  123 strarglist:   strarglist_item
  124         | strarglist ',' strarglist_item {$$ = joinstrings("%s, %s", $1,$3,0);}
  125 
  126 strarglist_item:  STRING        {$$ = joinstrings("\"%s\"",$1,0);}
  127         | STRING1       {$$ = joinstrings("'%s'",$1,0);}
  128         | VARIABLE      {$$ = joinstrings("$%s",$1,0);}
  129         ;
  130 
  131 %%
  132 
  133 struct updaterec {
  134     struct updaterec *next;
  135     char *var;
  136     char *s;
  137     int taken;
  138 };
  139 
  140 static struct updaterec *update_head = 0;
  141 
  142 static struct updaterec *lookup_update(char *var)
  143 {
  144     struct updaterec *rec = update_head;
  145     while (rec) {
  146         if (!strcmp(rec->var,var) && !rec->taken) {
  147             rec->taken = 1;
  148             return rec;
  149         }
  150         rec = rec->next;
  151     }
  152     return 0;
  153 }
  154 
  155 static int valid_var(char *var)
  156 {
  157     char **s = dosemurc_varlist;
  158     if (!option_rc || !var) return 1;
  159     while (*s) {
  160         if (!strcmp(*s, var)) return 1;
  161         s++;
  162     }
  163     return 0;
  164 }
  165 
  166 static void handle_assignment(char *typ, char *var, char *s)
  167 {
  168     if (!option_t || !typ) typ = "";
  169     if (!valid_var(var)) {
  170         if (var) {
  171             free(var);
  172             free(s);
  173         }
  174         return;
  175     }
  176     if (!var) {
  177         /* flush not yet taken updates */
  178         struct updaterec *rec = update_head;
  179         if (!updatemode) return;
  180         while (rec) {
  181             if (!rec->taken) {
  182                 printf("%s$%s = %s\n", typ, rec->var, rec->s);
  183             }
  184             rec = rec->next;
  185         }
  186         return;
  187     }
  188     switch (updatemode) {
  189         case 0: {
  190             printf("%s$%s = %s\n", typ, var, s);
  191             free(var), free(s);
  192             break;
  193         }
  194         case 1: {
  195             struct updaterec *rec = malloc(sizeof(struct updaterec));
  196             rec->var = var;
  197             rec->s = s;
  198             rec->taken = 0;
  199             rec->next = update_head;
  200             update_head = rec;
  201             break;
  202         }
  203         case 2: {
  204             char *s_ = s;
  205             struct updaterec *rec = lookup_update(var);
  206             if (rec) s_ = rec->s;
  207             printf("%s$%s = %s\n", typ, var, s_);
  208             free(var), free(s);
  209             break;
  210         }
  211     }
  212 }
  213 
  214 
  215 static char *joinstrings(char *frmt, ...)
  216 {
  217     va_list ap;
  218     char buf[4096];
  219     char *s;
  220     va_start(ap, frmt);
  221 
  222     vsprintf(buf, frmt, ap);
  223     while ((s = va_arg(ap, char *)) !=0) {
  224         free(s);
  225     }
  226     va_end(ap);
  227     return s = strdup(buf);
  228 }
  229 
  230 static void yyerror(char* string, ...)
  231 {
  232   va_list vars;
  233   va_start(vars, string);
  234   fprintf(stderr, "Error in %s: (line %.3d) ", activefile, line_count);
  235   vfprintf(stderr, string, vars);
  236   fprintf(stderr, "\n");
  237   va_end(vars);
  238   errors++;
  239 }
  240 
  241 static void usage(void)
  242 {
  243     fprintf(stderr,"
  244 USAGE:
  245   parser [-r] [-t] -p filetoparse [-u updatesfile]
  246 
  247   It works as follows: First step is to parse a given /etc/dosemu.conf or
  248   .dosemurc (-r) and get all variables extracted, each variable at one line.
  249   For this you use
  250 
  251     parser [-r] -p /etc/dosemu.conf >tmpfile
  252 
  253   If -t is also set, then 'N ' for numeric and 'S ' for string prefixes each
  254   variable assigment.
  255 
  256   In the second (or any number of additional steps) you merge any changed/new
  257   variable line in to the config file via
  258 
  259     parser [-r] -p /etc/dosemu.conf -u vars_to_update >tmpfile.out
  260     mv -f tmpfile.out /etc/dosemu.conf
  261 
  262   You need to supply the changed/added variables in vars_to_update, and this
  263   in the same format you got them in 'tmpfile', but without the -t generated
  264   type-prefixes ('N ' or 'S ').
  265 
  266   The parser currently cannot handle comments, hence those are lost :-(
  267 "
  268     );
  269     exit(1);
  270 }
  271 
  272 static int filesize(char *name)
  273 {
  274     struct stat s;
  275     if (stat(name, &s)) return -1;
  276     return (int)s.st_size;
  277 }
  278 
  279 static int valid_file(char *name)
  280 {
  281     return ((name[0] == '-') || (filesize(name) > 0));
  282 }
  283 
  284 int main(int argc, char **argv)
  285 {
  286     int ret = 0;
  287     int stdin_in_use = 0;
  288     int valid_parsedfile;
  289     char c;
  290 #if YYDEBUG != 0
  291     extern int yydebug;
  292     yydebug  = 1;
  293 #endif
  294 
  295     optind = 0;
  296     while ((c = getopt(argc, argv, "p:u:rt")) !=EOF) {
  297         switch (c) {
  298             case 'p': parsedfile = optarg; break;
  299             case 'u': updatefile = optarg; break;
  300             case 't': option_t = 1; break;
  301             case 'r': option_rc = 1; break;
  302             default: usage();
  303         }
  304     }
  305 
  306     if (!parsedfile) usage();
  307     valid_parsedfile = valid_file(parsedfile);
  308     if (updatefile && valid_file(updatefile)) {
  309         activefile = updatefile;
  310         if (updatefile[0] == '-') {
  311             yyin = stdin;
  312             stdin_in_use = 1;
  313             activefile = "STDIN";
  314         }
  315         else yyin = fopen(updatefile, "r");
  316         if (yyin < 0) {
  317             fprintf(stderr, "cannot open file %s\n", updatefile);
  318             exit(1);
  319         }
  320         if (valid_parsedfile) updatemode = 1;
  321         ret = yyparse();
  322         if (yyin != stdin) fclose(yyin);
  323         if (ret) {
  324             yyerror("finished parsing updates with %d errors\n", errors);
  325             exit(ret);
  326         }
  327         if (valid_parsedfile) updatemode = 2;
  328     }
  329     if (valid_parsedfile) {
  330         activefile = parsedfile;
  331         if (parsedfile[0] == '-') {
  332             if (stdin_in_use) {
  333                 fprintf(stderr, "stdin already in use by -u\n");
  334                 exit(1);
  335             }
  336             activefile = "STDIN";
  337             yyin = stdin;
  338         }
  339         else yyin = fopen(parsedfile, "r");
  340         if (yyin < 0) {
  341             fprintf(stderr, "cannot open file %s\n", parsedfile);
  342             exit(1);
  343         }
  344         if (updatemode) yyrestart(yyin);
  345         ret = yyparse();
  346         if (yyin != stdin) fclose(yyin);
  347         if (ret) {
  348             yyerror("finished parsing with %d errors\n", errors);
  349             exit(ret);
  350         }
  351         handle_assignment(0,0,0);
  352     }
  353     return ret;
  354 }
  355