freebsd-dev/lib/libforms/parser.y

532 lines
11 KiB
Plaintext
Raw Normal View History

%{
/*-
* Copyright (c) 1995
* Paul Richards. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* verbatim and that no modifications are made prior to this
* point in the file.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Paul Richards.
* 4. The name Paul Richards may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY PAUL RICHARDS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PAUL RICHARDS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <strhash.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <forms.h>
#include <err.h>
#include "internal.h"
char *cpstr(char *);
extern int yyleng;
int lineno = 1;
int charno = 1;
int off;
char *fieldname;
char *defname;
char *formname;
char *startname;
char *colortable;
int formattr;
char *text;
char *label;
char *function;
char *up, *down, *left, *right, *next;
int height, width;
int y, x;
int width;
int limit;
int attr;
int selattr;
int type;
int lbl_flag;
int selected, no_options=0;
extern FILE *outf;
extern hash_table *global_bindings;
struct MenuList {
char *option;
struct MenuList *next;
};
struct MenuList *cur_menu;
struct MenuList *menu_list;
struct MenuList *menu;
struct pair_node {
char *foreground;
char *background;
struct pair_node *next;
};
struct pair_node *pair_list;
struct pair_node *cur_pair;
struct pair_node *pair;
struct color_table {
char *tablename;
struct pair_node *pairs;
struct color_table *next;
};
struct color_table *color_table;
struct color_table *cur_table;
struct color_table *color_tables;
struct Form *form;
struct Field *field_inst_list;
struct Field *field;
struct Field *cur_field;
%}
%union {
int ival;
char *sval;
}
%token <ival> FORM
%token <ival> COLORTABLE
%token <ival> COLOR
%token <ival> BLACK
%token <ival> RED
%token <ival> GREEN
%token <ival> YELLOW
%token <ival> BLUE
%token <ival> MAGENTA
%token <ival> CYAN
%token <ival> WHITE
%token <ival> PAIR
%token <sval> NAME
%token <sval> STRING
%token <ival> AT
%token <ival> AS
%token <ival> HEIGHT
%token <ival> EQUALS
%token <ival> NUMBER
%token <ival> WIDTH
%token <ival> STARTFIELD
%token <ival> COMMA
%token <ival> LBRACE
%token <ival> RBRACE
%token <ival> TEXT
%token <ival> ATTR
%token <ival> SELATTR
%token <ival> DEFAULT
%token <ival> LABEL
%token <ival> LIMIT
%token <ival> SELECTED
%token <ival> OPTIONS
%token <ival> ACTION
%token <ival> FUNC
%token <ival> LINK
%token <ival> UP
%token <ival> DOWN
%token <ival> LEFT
%token <ival> RIGHT
%token <ival> NEXT
%token <ival> DEF
%type <sval> a_color
%start spec
%%
spec: /* empty */
| spec fields
| spec forms
| spec colours
;
colours: COLOR NAME
{
color_table = malloc(sizeof (struct color_table));
if (!color_table) {
fprintf(stderr, "Couldn't allocate memory for a color table\n");
exit (1);
}
color_table->tablename = cpstr($2);
}
LBRACE color_pairs RBRACE
{
color_table->pairs = pair_list;
cur_pair = 0;
form_bind_tuple(global_bindings, color_table->tablename, FT_COLTAB, color_table);
}
;
color_pairs: /* empty */
| color_pairs pair
;
pair: PAIR EQUALS a_color
{
pair = malloc(sizeof (struct pair_node));
if (!pair) {
fprintf(stderr, "Couldn't allocate memory for a color pair\n");
exit(1);
}
pair->foreground = cpstr($3);
}
COMMA a_color
{
pair->background = cpstr($6);
if (!cur_pair) {
pair_list = pair;
cur_pair = pair;
} else {
cur_pair->next = pair;
cur_pair = pair;
}
}
;
a_color: BLACK
{ $$ = "COLOR_BLACK"; }
| RED
{ $$ = "COLOR_RED"; }
| GREEN
{ $$ = "COLOR_GREEN"; }
| YELLOW
{ $$ = "COLOR_YELLOW"; }
| BLUE
{ $$ = "COLOR_BLUE"; }
| MAGENTA
{ $$ = "COLOR_MAGENTA"; }
| CYAN
{ $$ = "COLOR_CYAN"; }
| WHITE
{ $$ = "COLOR_WHITE"; }
;
forms: FORM NAME
{ formname = cpstr($2); }
AT coord
{
form = malloc(sizeof (struct Form));
if (!form) {
fprintf(stderr,"Failed to allocate memory for form\n");
exit(1);
}
form->bindings = hash_create(0);
if (!form->bindings)
errx(1, "Failed to allocate hash table for form");
form->y = y;
form->x = x;
}
LBRACE formspec RBRACE
{
form->startfield = startname;
form->colortable = colortable;
form->height = height;
form->width = width;
form->attr = formattr;
form_bind_tuple(global_bindings, formname, FT_FORM, form);
}
;
formspec: height width startfield colortable formattr fieldlocs
;
startfield: /* empty */
{ startname = 0;
printf("Warning: No start field specified for form %s\n", formname);
}
| STARTFIELD EQUALS NAME
{ startname = cpstr($3); }
;
colortable: /*empty */
{ colortable = 0; }
| COLORTABLE EQUALS NAME
{ colortable = cpstr($3); }
;
formattr: /* empty */
{ formattr = 0; }
| ATTR EQUALS NUMBER
{ formattr = $3; }
;
fieldlocs: /* empty */
| fieldlocs field_at
;
field_at: NAME
{ fieldname = cpstr($1); }
field_def AT coord
{
field = malloc(sizeof (struct Field));
if (!field) {
fprintf(stderr,"Failed to allocate memory for form field\n");
exit(1);
}
if (!defname)
field->defname = fieldname;
else
field->defname = defname;
field->y = y;
field->x = x;
}
links
{
field->fup = up;
field->fdown = down;
field->fleft = left;
field->fright = right;
field->fnext = next;
up = 0;
down = 0;
left = 0;
right = 0;
next = 0;
form_bind_tuple(form->bindings, fieldname, FT_FIELD_INST, field);
}
;
fields: NAME
{ defname = cpstr($1); }
field_spec
{ define_field(defname); }
;
field_def: /* empty */
{ defname = 0; }
| LBRACE NAME
{ defname = cpstr($2); }
RBRACE
| field_spec
{ defname = fieldname; define_field(defname); }
;
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
;
textfield: TEXT EQUALS STRING
{ type = FF_TEXT; text = cpstr($3); }
;
inputfield: inputspec
{ type = FF_INPUT; }
;
inputspec: LABEL EQUALS STRING limit
{ lbl_flag = 1; label = cpstr($3); }
| DEFAULT EQUALS STRING limit
{ lbl_flag = 0; label = cpstr($3); }
;
limit: /* empty */
| LIMIT EQUALS NUMBER
{ limit = $3; }
menufield: SELECTED EQUALS NUMBER OPTIONS EQUALS menuoptions
{ type = FF_MENU; selected = $3; }
;
menuoptions: menuoption
| menuoptions COMMA menuoption
;
menuoption: STRING
{
menu = malloc(sizeof(struct MenuList));
if (!menu) {
err(1, "Couldn't allocate memory for menu option\n");
}
menu->option = cpstr($1);
if (!cur_menu) {
menu_list = menu;
cur_menu = menu;
} else {
cur_menu->next = menu;
cur_menu = menu;
}
}
;
actionfield: ACTION EQUALS STRING FUNC EQUALS NAME
{ type = FF_ACTION; text = cpstr($3); function = cpstr($6); }
;
height: /* empty */
{ height = 0; }
| HEIGHT EQUALS NUMBER
{ height = $3; }
;
width: /* empty */
{ width = 0; }
| WIDTH EQUALS NUMBER
{ width = $3; }
;
attr: /* empty */
{ attr = 0; }
| ATTR EQUALS NUMBER
{ attr = $3; }
;
selattr: /* empty */
{ selattr = 0; }
| SELATTR EQUALS NUMBER
{ selattr = $3; }
;
coord: NUMBER COMMA NUMBER
{ y = $1; x = $3; }
;
%%
void
yyerror (char *error)
{
fprintf(stderr, "%s at line %d\n",error, lineno);
exit(1);
}
char *
cpstr(char *ostr)
{
char *nstr;
nstr = malloc(strlen(ostr)+1);
if (!nstr) {
fprintf(stderr, "Couldn't allocate memory for string\n");
exit(1);
}
strcpy(nstr, ostr);
return (nstr);
}
void
define_field(char *defname)
{
struct Field *field;
struct MenuList *menu_options;
int no_options;
field = malloc(sizeof (struct Field));
if (!field) {
fprintf(stderr,"Failed to allocate memory for form field\n");
exit(1);
}
field->defname = defname;
field->type = type;
field->height = height;
field->width = width;
field->attr = attr;
field->selattr = selattr;
switch (type) {
case FF_TEXT:
field->field.text = malloc(sizeof (struct TextField));
if (!field->field.text) {
fprintf(stderr,
"Failed to allocate memory for text field\n");
exit (1);
}
field->field.text->text = text;
break;
case FF_INPUT:
field->field.input = malloc(sizeof (struct InputField));
if (!field->field.input) {
fprintf(stderr,
"Failed to allocate memory for input field\n");
exit (1);
}
field->field.input->lbl_flag = lbl_flag;
field->field.input->label = label;
field->field.input->limit = limit;
break;
case FF_MENU:
printf("field type %s = %d\n", defname,field->type);
field->field.menu = malloc(sizeof (struct MenuField));
if (!field->field.menu) {
fprintf(stderr,
"Failed to allocate memory for menu field\n");
exit (1);
}
field->field.menu->selected = selected;
menu_options = menu_list;
field->field.menu->no_options = 0;
field->field.menu->options = 0;
for (; menu_options; menu_options = menu_options->next) {
no_options = add_menu_option(field->field.menu,
menu_options->option);
if (!no_options)
err(1, "Couldn't add menu option");
}
field->field.menu->no_options = no_options;
cur_menu = 0;
break;
case FF_ACTION:
field->field.action = malloc(sizeof (struct ActionField));
if (!field->field.action) {
fprintf(stderr,
"Failed to allocate memory for action field\n");
exit (1);
}
field->field.action->text = text;
field->field.action->fn = (void *) function;
break;
default:
break;
}
form_bind_tuple(global_bindings, defname, FT_FIELD_DEF, field);
width=0;
height = 0;
attr=0;
selattr=0;
limit=0;
}