From 463e33c94b9b59ed7def0ead63c73742e4e1dd09 Mon Sep 17 00:00:00 2001 From: Paul Richards Date: Wed, 1 Feb 1995 03:22:17 +0000 Subject: [PATCH] Clean up the parser, allow fields to be specified inline and generally make the forms language much less verbose. Add height option for fields and calculate sensible defaults. --- usr.bin/fib/Makefile | 2 +- usr.bin/fib/fib.c | 15 +- usr.bin/fib/lex.l | 2 - usr.bin/fib/parser.y | 524 +++++++++++++++++++++---------------------- 4 files changed, 266 insertions(+), 277 deletions(-) diff --git a/usr.bin/fib/Makefile b/usr.bin/fib/Makefile index 2394c1efeb19..66d8177e359d 100644 --- a/usr.bin/fib/Makefile +++ b/usr.bin/fib/Makefile @@ -6,6 +6,6 @@ LDADD = -ll DPADD = ${LIBL} ${LIBFORMS} CLEANFILES= parser.c lex.c y.tab.h -CFLAGS += -I${.CURDIR} -I. +CFLAGS += -I${.CURDIR} -I. -g .include diff --git a/usr.bin/fib/fib.c b/usr.bin/fib/fib.c index bd161134d35f..5bff74d9aaa6 100644 --- a/usr.bin/fib/fib.c +++ b/usr.bin/fib/fib.c @@ -35,11 +35,24 @@ main(int argc, char **argv) { + FILE *outf; + if (argc != 1) if (!(freopen(*++argv, "r", stdin))) { perror(*argv); exit(1); } if (yyparse()) - exit(2); + exit(1); + + outf = fopen("frm.tab.h", "w"); + if (!outf) { + perror("Couldn't open output file:"); + exit(1); + } + output_forms(outf); + if (fclose(outf) == EOF) { + perror("Error closing output file:"); + exit (1); + } } diff --git a/usr.bin/fib/lex.l b/usr.bin/fib/lex.l index 121f8cd4268f..18c96d5ae8ea 100644 --- a/usr.bin/fib/lex.l +++ b/usr.bin/fib/lex.l @@ -60,7 +60,6 @@ height { return HEIGHT; } width { return WIDTH; } start { return STARTFIELD; } text { return TEXT; } -Field { return FIELD; } attributes { return ATTR; } highlight { return SELATTR; } label { return LABEL; } @@ -70,7 +69,6 @@ selected { return SELECTED; } options { return OPTIONS; } action { return ACTION; } function { return FUNC; } -Link { return LINK; } up { return UP; } down { return DOWN; } left { return LEFT; } diff --git a/usr.bin/fib/parser.y b/usr.bin/fib/parser.y index fd2addd61be0..dc07490005bf 100644 --- a/usr.bin/fib/parser.y +++ b/usr.bin/fib/parser.y @@ -44,16 +44,16 @@ int lineno = 1; int charno = 1; int off; -char *startname; +char *fieldname; +char *defname; char *formname; +char *startname; char *colortable; char *formattr; char *text; char *label; -char *fieldname; char *function; char *up, *down, *left, *right, *next; -char *linkname; int height, width; int y, x; int width; @@ -63,37 +63,28 @@ char *selattr; int type; int lbl_flag; int selected, no_options=0; -FILE *outf; + +extern FILE *outf; struct field_list { char *fieldname; char *defname; char *attr; char *selattr; - struct field field; - struct field_list *next; -}; - -struct field_list *cur_field; -struct field_list *field_list; -struct field_list *field; -struct field_list *cur_form_field; -struct field_list *form_field_list; - -struct link_list { - char *linkname; - char *fieldname; char *up; char *down; char *left; char *right; char *next; - struct link_list *lnext; + struct field field; + struct field_list *next_field; }; -struct link_list *cur_link; -struct link_list *link_list; -struct link_list *link; +struct field_list *cur_field_def; +struct field_list *field_defs; +struct field_list *field; +struct field_list *cur_form_field; +struct field_list *form_field_list; struct form_list { char *formname; @@ -144,6 +135,7 @@ struct color_table *color_tables; char *sval; } +%token FORM %token COLORTABLE %token COLOR %token BLACK @@ -155,7 +147,6 @@ struct color_table *color_tables; %token CYAN %token WHITE %token PAIR -%token FORM %token NAME %token STRING %token AT @@ -168,7 +159,6 @@ struct color_table *color_tables; %token COMMA %token LBRACE %token RBRACE -%token FIELD %token TEXT %token ATTR %token SELATTR @@ -185,6 +175,7 @@ struct color_table *color_tables; %token LEFT %token RIGHT %token NEXT +%token DEF %type a_color @@ -192,19 +183,10 @@ struct color_table *color_tables; %% -spec: colours fields links forms - { - outf = fopen("frm.tab.h", "w"); - if (!outf) { - perror("Couldn't open output file:"); - exit (1); - } - output_forms(outf); - if (fclose(outf) == EOF) { - perror("Error closing output file:"); - exit (1); - } - } +spec: /* empty */ + | spec fields + | spec forms + | spec colours ; colours: COLOR NAME @@ -230,7 +212,7 @@ colours: COLOR NAME } ; -color_pairs: pair +color_pairs: /* empty */ | color_pairs pair ; @@ -246,7 +228,6 @@ pair: PAIR EQUALS a_color COMMA a_color { pair->background = cpstr($6); - fprintf(stderr, "for = %s, back = %s\n", pair->foreground, pair->background); if (!cur_pair) { color_list = pair; cur_pair = pair; @@ -275,77 +256,9 @@ a_color: BLACK { $$ = "COLOR_WHITE"; } ; -fields: field - | fields field - ; - -links: /* empty */ - | link - | links link - ; - -link: LINK NAME - { - linkname = cpstr($2); - fieldname = 0; - up = 0; - down = 0; - left = 0; - right = 0; - next = 0; - } - alias LBRACE connspec RBRACE - { - link = malloc(sizeof (struct link_list)); - if (!link) { - fprintf(stderr,"Failed to allocate memory for link\n"); - exit(1); - } - link->linkname = linkname; - link->fieldname = fieldname; - link->up = up; - link->down = down; - link->left = left; - link->right = right; - link->next = next; - if (!cur_link) { - link_list = link; - cur_link = link; - } else { - cur_link->lnext = link; - cur_link = link; - } - } - ; - -alias: /* empty */ - | AS NAME - { fieldname = cpstr($2); } - ; - -connspec: conns - | connspec conns - ; - -conns: UP EQUALS NAME - { up = cpstr($3); } - | DOWN EQUALS NAME - { down = cpstr($3); } - | LEFT EQUALS NAME - { left = cpstr($3); } - | RIGHT EQUALS NAME - { right = cpstr($3); } - | NEXT EQUALS NAME - { next = cpstr($3); } - ; - -forms: form - | forms form - ; - -form: FORM NAME - { formname = cpstr($2); } - AT coord +forms: FORM NAME + { formname = cpstr($2); } + AT coord LBRACE formspec RBRACE { form = malloc(sizeof (struct form_list)); if (!form) { @@ -354,9 +267,6 @@ form: FORM NAME } form->form.y = y; form->form.x = x; - } - LBRACE formspec RBRACE - { form->startfield = startname; form->formname = formname; form->colortable = colortable; @@ -378,14 +288,6 @@ form: FORM NAME formspec: height width startfield colortable formattr fieldlocs ; -height: HEIGHT EQUALS NUMBER - { height = $3; } - ; - -width: WIDTH EQUALS NUMBER - { width = $3; } - ; - startfield: /* empty */ { startname = 0; printf("Warning: No start field specified for form %s\n", formname); @@ -407,119 +309,86 @@ formattr: /* empty */ ; fieldlocs: /* empty */ - | afield - | fieldlocs afield + | fieldlocs field_at ; -afield: FIELD NAME - { fieldname = cpstr($2); } - AT coord - { +field_at: NAME + { fieldname = cpstr($1); } + field_def AT coord + { field = malloc(sizeof (struct field_list)); if (!field) { fprintf(stderr,"Failed to allocate memory for form field\n"); exit(1); } field->fieldname = fieldname; + if (!defname) + field->defname = fieldname; + else + field->defname = defname; field->field.y = y; field->field.x = x; + } + links + { + field->up = up; + field->down = down; + field->left = left; + field->right = right; + field->next = next; + up = 0; + down = 0; + left = 0; + right = 0; + next = 0; if (!cur_form_field) { form_field_list = field; cur_form_field = field; } else { - cur_form_field->next = field; + cur_form_field->next_field = field; cur_form_field = field; } } ; -coord: NUMBER COMMA NUMBER - { y = $1; x = $3; } +fields: NAME + { defname = cpstr($1); } + field_spec + { define_field(defname, 0); } ; -field: FIELD NAME - { fieldname = cpstr($2); } - LBRACE fieldspec RBRACE - { - field = malloc(sizeof (struct field_list)); - if (!field) { - fprintf(stderr,"Failed to allocate memory for field\n"); - exit(1); - } - field->fieldname = fieldname; - field->field.type = type; - field->field.width = width; - field->attr = attr; - field->selattr = selattr; - switch (type) { - case F_TEXT: - field->field.field.text = malloc(sizeof (struct text_field)); - if (!field->field.field.text) { - fprintf(stderr, - "Failed to allocate memory for text field\n"); - exit (1); - } - field->field.field.text->text = text; - break; - case F_INPUT: - field->field.field.input = malloc(sizeof (struct input_field)); - if (!field->field.field.input) { - fprintf(stderr, - "Failed to allocate memory for input field\n"); - exit (1); - } - field->field.field.input->lbl_flag = lbl_flag; - field->field.field.input->label = label; - field->field.field.input->limit = limit; - break; - case F_MENU: - field->field.field.menu = malloc(sizeof (struct menu_field)); - if (!field->field.field.menu) { - fprintf(stderr, - "Failed to allocate memory for menu field\n"); - exit (1); - } - field->field.field.menu->selected = selected; - field->field.field.menu->no_options = no_options; - no_options = 0; - field->field.field.menu->options = (char **)menu_list; - cur_menu = 0; - break; - case F_ACTION: - field->field.field.action = malloc(sizeof (struct action_field)); - if (!field->field.field.action) { - fprintf(stderr, - "Failed to allocate memory for action field\n"); - exit (1); - } - field->field.field.action->text = text; - field->field.field.action->fn = (void *) function; - break; - default: - break; - } - if (!cur_field) { - field_list = field; - cur_field = field; - } else { - cur_field->next = field; - cur_field = field; - } - width=0; - attr=0; - selattr=0; - limit=0; - } +field_def: /* empty */ + { defname = 0; } + | LBRACE NAME + { defname = cpstr($2); } + RBRACE + | field_spec + { defname = fieldname; define_field(defname, 0); } ; -fieldspec: width attr selattr type +field_spec: LBRACE height width attr selattr type RBRACE + ; + +links: /* empty */ + | links COMMA conns + ; + +conns: UP EQUALS NAME + { up = cpstr($3); } + | DOWN EQUALS NAME + { down = cpstr($3); } + | LEFT EQUALS NAME + { left = cpstr($3); } + | RIGHT EQUALS NAME + { right = cpstr($3); } + | NEXT EQUALS NAME + { next = cpstr($3); } + ; type: textfield | inputfield | menufield | actionfield - | error - { fprintf(stderr, "Uknown field type at %d\n", lineno); } ; textfield: TEXT EQUALS STRING @@ -535,6 +404,7 @@ inputspec: LABEL EQUALS STRING limit | DEFAULT EQUALS STRING limit { lbl_flag = 0; label = cpstr($3); } ; + limit: /* empty */ | LIMIT EQUALS NUMBER { limit = $3; } @@ -570,6 +440,12 @@ actionfield: ACTION EQUALS STRING FUNC EQUALS NAME { type = F_ACTION; text = cpstr($3); function = cpstr($6); } ; +height: /* empty */ + { height = 0; } + | HEIGHT EQUALS NUMBER + { height = $3; } + ; + width: /* empty */ { width = 0; } | WIDTH EQUALS NUMBER @@ -588,6 +464,10 @@ selattr: /* empty */ { selattr = cpstr($3); } ; +coord: NUMBER COMMA NUMBER + { y = $1; x = $3; } + ; + %% yyerror (char *error) @@ -625,12 +505,17 @@ output_field(struct field_list *fields, char *fieldname, FILE *outf) if (!fieldname) { if (!fields->field.width) fields->field.width = strlen(fields->field.field.text->text); + if (!fields->field.height) + calc_field_height(&fields->field, fields->field.field.text->text); + fprintf(outf, "struct text_field %s = {\"%s\"};\n", - fields->fieldname, + fields->defname, fields->field.field.text->text); } break; case F_INPUT: + /* Force height to one regardless */ + fields->field.height = 1; if (!fields->field.width && !fields->field.field.input->limit) { fields->field.width = strlen(fields->field.field.input->label); fields->field.field.input->limit = fields->field.width; @@ -641,15 +526,17 @@ output_field(struct field_list *fields, char *fieldname, FILE *outf) if (fields->field.field.input->limit < fields->field.width) fields->field.width = fields->field.field.input->limit; fprintf(outf, "struct input_field %s = {%d, \"%s\", 0, %d};\n", - (fieldname)?fieldname:fields->fieldname, + (fieldname)?fieldname:fields->defname, (fields->field.field.input->lbl_flag ? 1 : 0), fields->field.field.input->label, fields->field.field.input->limit); break; case F_MENU: + /* Force height to one regardless */ + fields->field.height = 1; if (!fieldname) { fprintf(outf, "char *%s_options[] = {", - fields->fieldname); + fields->defname); menu = (struct menu_list *)fields->field.field.menu->options; lim = 0; for (i=0; i < fields->field.field.menu->no_options - 1; i++) { @@ -664,16 +551,18 @@ output_field(struct field_list *fields, char *fieldname, FILE *outf) fprintf(outf, "\"%s\"};\n", menu->option); } fprintf(outf, "struct menu_field %s = {%d, %d, %s_options};\n", - (fieldname)?fieldname:fields->fieldname, + (fieldname)?fieldname:fields->defname, fields->field.field.menu->no_options, fields->field.field.menu->selected, - fields->fieldname); + fields->defname); break; case F_ACTION: if (!fields->field.width) fields->field.width = strlen(fields->field.field.action->text); + if (!fields->field.height) + calc_field_height(&fields->field, fields->field.field.action->text); fprintf(outf, "struct action_field %s = {\"%s\", &%s};\n", - (fieldname)?fieldname:fields->fieldname, + (fieldname)?fieldname:fields->defname, fields->field.field.action->text, fields->field.field.action->fn); break; @@ -688,7 +577,7 @@ output_forms(FILE *outf) struct field_list *fields; /* Output the general field definitions */ - for (fields = field_list; fields; fields=fields->next) + for (fields = field_defs; fields; fields=fields->next_field) output_field(fields, 0, outf); for(forms=form_list; forms; forms = forms->next) { @@ -718,9 +607,8 @@ output_coltab(struct color_table *coltab, FILE *outf) parse_form(struct form_list *form, FILE *outf) { struct field_list *fields; - struct field_list *def; + struct field_list *defs; struct field_list *info; - struct link_list *links; struct color_table *coltab; char *fieldname; int no_fields = 0; @@ -744,85 +632,67 @@ parse_form(struct form_list *form, FILE *outf) * this form, filling in the link structures and outputing a field * definition for this particular instance. */ - for(fields=form->fields; fields; fields=fields->next) { + for(fields=form->fields; fields; fields=fields->next_field) { - fieldname = fields->fieldname; + /* Fill in link values */ - /* Search links list for an entry for this field */ - for (links = link_list; links; links = links->lnext) { - if (!strcmp(links->linkname, fields->fieldname)) { - /* Check for an alias */ - if (links->fieldname) - fieldname = links->fieldname; - fields->fieldname = links->linkname; - fields->field.up = field_id(links->up, form->fields); - fields->field.down = field_id(links->down, form->fields); - fields->field.left = field_id(links->left, form->fields); - fields->field.right = field_id(links->right, form->fields); - fields->field.next = field_id(links->next, form->fields); + fields->field.up = field_id(fields->up, form->fields); + fields->field.down = field_id(fields->down, form->fields); + fields->field.left = field_id(fields->left, form->fields); + fields->field.right = field_id(fields->right, form->fields); + fields->field.next = field_id(fields->next, form->fields); + + /* Search field list for definition of this field */ + + for(defs=field_defs; defs; defs=defs->next_field) { + if (!strcmp(fields->defname, defs->defname)) break; - } } - for (def = field_list; def; def=def->next) - if (!strcmp(fieldname, def->fieldname)) - break; - if (!def) { + if (!defs) { fprintf(stderr, "%s not found in field definitions, field not output\n", - fieldname); + fields->defname); + fields->fieldname = 0; } else { - fields->field.type = def->field.type; - fields->field.width = def->field.width; - fields->attr = def->attr; - fields->selattr = def->selattr; + fields->field.type = defs->field.type; + fields->field.height = defs->field.height; + fields->field.width = defs->field.width; + fields->attr = defs->attr; + fields->selattr = defs->selattr; + if (strcmp(fields->defname, fields->fieldname)) + output_field(defs, fields->fieldname, outf); } - - if (!links) { - /* No links for this field */ - fields->field.up = -1; - fields->field.down = -1; - fields->field.left = -1; - fields->field.right = -1; - fields->field.next = -1; - fields->defname = fieldname; - } - - if (strcmp(def->fieldname, fields->fieldname)) - output_field(def, fields->fieldname, outf); - - if ((fields->field.type == F_TEXT) - || (fields->field.type == F_ACTION)) - fields->defname = def->fieldname; - else - fields->defname = fields->fieldname; } /* Output the field table for this form */ fprintf(outf, "struct field %s_fields[] = {\n", form->formname); - for(fields=form->fields; fields; fields=fields->next) { - ++no_fields; - fprintf(outf, "\t{%d, %d, %d, %d, %s, %s, ", - fields->field.type, fields->field.y, fields->field.x, - fields->field.width, (fields->attr ? fields->attr : "F_DEFATTR"), - (fields->selattr ? fields->selattr : "F_SELATTR")); - fprintf(outf, "%d, %d, %d, %d, %d, ", - fields->field.next, - fields->field.up, - fields->field.down, - fields->field.left, - fields->field.right); - fprintf(outf, "(struct text_field *)&%s},\n", - fields->defname); + for(fields=form->fields; fields; fields=fields->next_field) { + if (fields->fieldname) { + ++no_fields; + fprintf(outf, "\t{%d, %d, %d, %d, %d, %s, %s, ", + fields->field.type, fields->field.y, fields->field.x, + fields->field.height, fields->field.width, + (fields->attr ? fields->attr : "F_DEFATTR"), + (fields->selattr ? fields->selattr : "F_SELATTR")); + fprintf(outf, "%d, %d, %d, %d, %d, ", + fields->field.next, + fields->field.up, + fields->field.down, + fields->field.left, + fields->field.right); + fprintf(outf, "(struct text_field *)&%s},\n", + fields->fieldname); + } } fprintf(outf, "\t{%d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}\n};\n", F_END); /* If no start field set then find first non-text field */ if (!form->startfield) - for (fields = form->fields; fields; fields = fields->next) + for (fields = form->fields; fields; fields = fields->next_field) if (fields->field.type != F_TEXT) { form->startfield = fields->fieldname; break; @@ -862,7 +732,7 @@ field_id(char *fieldname, struct field_list *field_list) if (!fieldname) return (-1); - for (fields = field_list; fields; fields = fields->next, id++) { + for (fields = field_list; fields; fields = fields->next_field, id++) { if (!strcmp(fieldname, fields->fieldname)) return (id); } @@ -870,3 +740,111 @@ field_id(char *fieldname, struct field_list *field_list) fprintf(stderr, "Field %s, not found in specification\n", fieldname); return (-1); } + +/* Calculate a default height for a field */ + +calc_field_height(struct field *field, char *string) +{ + + int len; + + len = strlen(string); + + if (!width) { + /* + * This is a failsafe, this routine shouldn't be called + * with a width of 0, the width should be determined + * first. + */ + height = 1; + return; + } + + if (len < field->width) { + field->height = 1; + return; + } else + field->height = len / width; + + if ((field->height*width) < len) + field->height++; + + return; +} + +/* Add a field to the pre-defined fields list */ + +define_field(char *defname, char *fieldname) +{ + field = malloc(sizeof (struct field_list)); + if (!field) { + fprintf(stderr,"Failed to allocate memory for form field\n"); + exit(1); + } + field->fieldname = fieldname; + field->defname = defname; + field->field.type = type; + field->field.height = height; + field->field.width = width; + field->attr = attr; + field->selattr = selattr; + switch (type) { + case F_TEXT: + field->field.field.text = malloc(sizeof (struct text_field)); + if (!field->field.field.text) { + fprintf(stderr, + "Failed to allocate memory for text field\n"); + exit (1); + } + field->field.field.text->text = text; + break; + case F_INPUT: + field->field.field.input = malloc(sizeof (struct input_field)); + if (!field->field.field.input) { + fprintf(stderr, + "Failed to allocate memory for input field\n"); + exit (1); + } + field->field.field.input->lbl_flag = lbl_flag; + field->field.field.input->label = label; + field->field.field.input->limit = limit; + break; + case F_MENU: + field->field.field.menu = malloc(sizeof (struct menu_field)); + if (!field->field.field.menu) { + fprintf(stderr, + "Failed to allocate memory for menu field\n"); + exit (1); + } + field->field.field.menu->selected = selected; + field->field.field.menu->no_options = no_options; + no_options = 0; + field->field.field.menu->options = (char **)menu_list; + cur_menu = 0; + break; + case F_ACTION: + field->field.field.action = malloc(sizeof (struct action_field)); + if (!field->field.field.action) { + fprintf(stderr, + "Failed to allocate memory for action field\n"); + exit (1); + } + field->field.field.action->text = text; + field->field.field.action->fn = (void *) function; + break; + default: + break; + } + if (!cur_field_def) { + field_defs = field; + cur_field_def = field; + } else { + cur_field_def->next_field = field; + cur_field_def = field; + } + width=0; + height = 0; + attr=0; + selattr=0; + limit=0; +}