summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libforms/Makefile3
-rw-r--r--lib/libforms/Makefile.orig12
-rw-r--r--lib/libforms/examples/Makefile10
-rw-r--r--lib/libforms/examples/example.c60
-rw-r--r--lib/libforms/examples/example.frm28
-rw-r--r--lib/libforms/fields.c520
-rw-r--r--lib/libforms/forms.c574
-rw-r--r--lib/libforms/forms.c.orig502
-rw-r--r--lib/libforms/forms.h97
-rw-r--r--lib/libforms/forms.h.orig126
-rw-r--r--lib/libforms/internal.h87
-rw-r--r--lib/libforms/internal.h.orig38
-rw-r--r--lib/libforms/lex.c1606
-rw-r--r--lib/libforms/menu.c58
-rw-r--r--lib/libforms/parser.c1022
-rw-r--r--lib/libforms/parser.y567
-rw-r--r--lib/libforms/y.tab.h46
17 files changed, 4868 insertions, 488 deletions
diff --git a/lib/libforms/Makefile b/lib/libforms/Makefile
index 7ed0abfa1496..5fbe510c6605 100644
--- a/lib/libforms/Makefile
+++ b/lib/libforms/Makefile
@@ -1,8 +1,9 @@
LIB = forms
-SRCS = forms.c
+SRCS = forms.c parser.y lex.l menu.c fields.c
CFLAGS += -I. -I${.CURDIR} -Wall -g
+LDFLAGS += -ll
beforeinstall:
@(cd ${.CURDIR}; cmp -s forms.h ${DESTDIR}/usr/include/forms.h || \
diff --git a/lib/libforms/Makefile.orig b/lib/libforms/Makefile.orig
new file mode 100644
index 000000000000..7ed0abfa1496
--- /dev/null
+++ b/lib/libforms/Makefile.orig
@@ -0,0 +1,12 @@
+LIB = forms
+
+SRCS = forms.c
+
+CFLAGS += -I. -I${.CURDIR} -Wall -g
+
+beforeinstall:
+ @(cd ${.CURDIR}; cmp -s forms.h ${DESTDIR}/usr/include/forms.h || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 forms.h \
+ ${DESTDIR}/usr/include/forms.h;)
+
+.include <bsd.lib.mk>
diff --git a/lib/libforms/examples/Makefile b/lib/libforms/examples/Makefile
index e098b6897c2d..4f0a23fafdd7 100644
--- a/lib/libforms/examples/Makefile
+++ b/lib/libforms/examples/Makefile
@@ -1,7 +1,7 @@
PROG = example
NOMAN = yet
-SRCS = example.c frm.tab.h
+SRCS = example.c
CFLAGS = -g -static
@@ -11,11 +11,7 @@ FORMDIR=${.CURDIR}/../obj
FORMDIR=${.CURDIR}/..
.endif
-LDADD = -L${FORMDIR} -lforms -lncurses -lmytinfo
-
-CLEANFILES += frm.tab.h
-
-frm.tab.h:
- fib example.frm
+LDADD = -L${FORMDIR} -lforms -lncurses -lmytinfo -ll
+DPADD = /usr/lib/libforms.a
.include <bsd.prog.mk>
diff --git a/lib/libforms/examples/example.c b/lib/libforms/examples/example.c
index 120fdb14efd5..f2dad1c9a6a7 100644
--- a/lib/libforms/examples/example.c
+++ b/lib/libforms/examples/example.c
@@ -1,4 +1,4 @@
-/*-
+/*
* Copyright (c) 1995
* Paul Richards. All rights reserved.
*
@@ -33,36 +33,62 @@
*/
#include <stdio.h>
#include "../forms.h"
-#include "frm.tab.h"
main()
{
+ struct Tuple *tuple;
+ struct Form *form;
int res;
initscr();
- initfrm(&example);
- if (!example.window) {
- fprintf(stderr, "\nUnable to initialize forms library.\n");
- endwin();
- exit(1);
+ form_bind_tuple("exit_form", FT_FUNC, &exit_form);
+ form_bind_tuple("cancel_form", FT_FUNC, &cancel_form);
+
+ if (form_load("example.frm") == FS_ERROR)
+ exit(0);;
+
+ form = form_start("example");
+
+ if (!form) {
+ err(-1, "No form returned");
+ exit(0);
}
- keypad(example.window, TRUE);
+
+ keypad(form->window, TRUE);
+ cbreak();
+ noecho();
+
+ tuple = form_get_tuple("example", FT_FORM);
+ if (!tuple)
+ err(0, "No such form");
+ else
+ form = (struct Form *)tuple->addr;
print_status("This is the status line");
- while (!(res = update_form(&example)));
- wclear(example.window);
- wrefresh(example.window);
+ res = form_show("example");
+
+ while (form->status == FS_RUNNING) {
+ do_field(form);
+ wrefresh(form->window);
+ }
+
+ wclear(form->window);
+ wrefresh(form->window);
- if (res == F_DONE) {
+ if (form->status == FS_EXIT) {
printf("You're entries were:\n\n");
- printf("%s\n",input1.input);
- printf("%s\n",input2.input);
- printf("%s\n",menu1.options[example_fields[7].field.menu->selected]);
- } else if (res == F_CANCEL)
+ tuple = form_get_tuple("input1", FT_FIELD_INST);
+ printf("Input 1 = %s\n", ((struct Field *)tuple->addr)->field.input->input);
+ tuple = form_get_tuple("input2", FT_FIELD_INST);
+ printf("Input 2 = %s\n", ((struct Field *)tuple->addr)->field.input->input);
+ tuple = form_get_tuple("menu1", FT_FIELD_INST);
+ res = ((struct Field *)tuple->addr)->field.menu->selected;
+ printf("Menu selected = %d, %s\n", res,
+ ((struct Field *)tuple->addr)->field.menu->options[res]);
+ } else if (form->status == FS_CANCEL)
printf("You cancelled the form\n");
- endfrm(&example);
endwin();
}
diff --git a/lib/libforms/examples/example.frm b/lib/libforms/examples/example.frm
index e2ebd8004a44..d1f5349237bd 100644
--- a/lib/libforms/examples/example.frm
+++ b/lib/libforms/examples/example.frm
@@ -1,9 +1,4 @@
-Colours example {
- pair = red, yellow
- pair = blue, white
-}
-
-field1 { attributes = A_BLINK|A_BOLD text = "This text is bold and flashy" }
+field1 { attributes = 0 text = "This text is bold and flashy" }
field2 {
height = 2
@@ -28,28 +23,27 @@ field7 { selected = 0 options = "Choose", "another", "of", "these" }
field8 { width = 6 action = "EXIT" function = exit_form }
field9 {
- attributes = COLOR_PAIR(1)
- highlight = COLOR_PAIR(1)|A_BOLD
- action = "CANCEL"
- function = cancel_form
+action = "CANCEL"
+function = cancel_form
}
Form example at 0,0 {
height = 25
width = 80
+ start = input1
colortable = example
- attributes = COLOR_PAIR(1)
+ attributes = 0
- Title {attributes = COLOR_PAIR(2) text = "A Simple Demo"} at 0,30
+ Title {attributes = 0 text = "A Simple Demo"} at 0,30
field1 at 3,23
field2 at 7, 2
field4 at 11, 2
field6 at 15, 2
- input1 {field3} at 7,45, next=input2, up=input2, down=input2
- input2 {field5} at 11,45, next=menu1, up=input1, down=menu1
- menu1 {field7} at 15,45, next=quit, up=input2, down=quit
- quit {field8} at 20,20, up=menu1, right=cancel
- cancel {field9} at 20,43, up=input1, down=input1, left=quit, right=input1
+ input1 {field3} at 7,45, next=input2
+ input2 {field5} at 11,45, next=menu1
+ menu1 {field7} at 15,45, next=quit
+ quit {field8} at 20,20, up = menu1, right = cancel
+ cancel {field9} at 20,43, next=input1
}
diff --git a/lib/libforms/fields.c b/lib/libforms/fields.c
new file mode 100644
index 000000000000..3656834003bf
--- /dev/null
+++ b/lib/libforms/fields.c
@@ -0,0 +1,520 @@
+/*-
+ * 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 <ctype.h>
+#include <err.h>
+#include <ncurses.h>
+#include <forms.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "internal.h"
+
+int done=0;
+
+int
+init_field(struct Field *field)
+{
+ struct Tuple *tuple;
+ struct Field *def;
+ int i;
+ int len, lim;
+
+ tuple = form_get_tuple(field->defname, FT_FIELD_DEF);
+ if (!tuple) {
+ warnx("Field definition not found -- skipping field");
+ return (-1);
+ }
+
+ def = (struct Field *)tuple->addr;
+ field->height = def->height;
+ field->width = def->width;
+ field->attr = def->attr;
+ field->selattr = def->selattr;
+ field->type = def->type;
+ switch (field->type) {
+ case FF_INPUT:
+ field->field.input = malloc(sizeof (struct InputField));
+ if (!field->field.input) {
+ warnx("Couldn't allocate memory for input field");
+ return (-1);
+ }
+ field->field.input->limit = def->field.input->limit;
+
+ /* Force height to one regardless, at least for now :-) */
+ field->height = 1;
+ if (!field->width && !field->field.input->limit) {
+ field->width = strlen(def->field.input->label);
+ field->field.input->limit = field->width;
+ } else if (!field->width)
+ field->width = field->field.input->limit;
+ else if (!field->field.input->limit)
+ field->field.input->limit = field->width;
+ if (field->field.input->limit < field->width)
+ field->width = field->field.input->limit;
+
+ field->field.input->input = malloc(field->field.input->limit + 1);
+ if (!field->field.input->input) {
+ warnx("Couldn't allocate memory for input field text");
+ return (-1);
+ }
+ field->field.input->label = malloc(strlen(def->field.input->label)+1);
+ if (!field->field.input->label) {
+ warnx("Couldn't allocate memory for input field label");
+ return (-1);
+ }
+ strncpy(field->field.input->label,
+ def->field.input->label,
+ strlen(def->field.input->label) + 1);
+ field->field.input->lbl_flag = def->field.input->lbl_flag;
+
+ /*
+ * If it's a label then clear the input string
+ * otherwise copy the default there.
+ */
+ if (field->field.input->lbl_flag)
+ field->field.input->input[0] = '\0';
+ else if (field->field.input->label) {
+ strncpy(field->field.input->input,
+ field->field.input->label,
+ field->field.input->limit);
+ field->field.input->input[field->field.input->limit] = 0;
+ }
+ break;
+ case FF_TEXT:
+ field->field.text = malloc(sizeof (struct TextField));
+ if (!field->field.text) {
+ warnx("Couldn't allocate memory for text field");
+ return (FS_ERROR);
+ }
+ if (!field->width)
+ field->width = strlen(def->field.text->text);
+ field->field.text->text = malloc(field->width + 1);
+ if (!field->field.text->text) {
+ warnx("Couldn't allocate memory for text field text");
+ return (FS_ERROR);
+ } else
+ strncpy(field->field.text->text,
+ def->field.text->text,
+ field->width + 1);
+ if (!field->height)
+ calc_field_height(field, field->field.text->text);
+ break;
+ case FF_MENU:
+ field->field.menu = malloc(sizeof (struct MenuField));
+ if (!field->field.menu) {
+ warnx("Couldn't allocate memory for menu field");
+ return (FS_ERROR);
+ }
+ field->field.menu->no_options = 0;
+ field->height = 1;
+ lim = 0;
+ for (i=0; i < def->field.menu->no_options; i++) {
+ field->field.menu->no_options =
+ add_menu_option(field->field.menu,
+ def->field.menu->options[i]);
+ if (!field->field.menu->no_options) {
+ warnx("Couldn't add menu option");
+ return (FS_ERROR);
+ }
+ len = strlen(def->field.menu->options[i]);
+ if (len > lim)
+ lim = len;
+ }
+ if (!field->width)
+ field->width = lim;
+ break;
+ case FF_ACTION:
+ field->field.action = malloc(sizeof (struct ActionField));
+ if (!field->field.action) {
+ warnx("Couldn't allocate memory for action field");
+ return (FS_ERROR);
+ }
+ if (!field->width)
+ field->width = strlen(def->field.action->text);
+ field->field.action->text = malloc(field->width + 1);
+ if (!field->field.action->text) {
+ warnx("Couldn't allocate memory for text field text");
+ return (FS_ERROR);
+ } else
+ strncpy(field->field.action->text,
+ def->field.action->text,
+ field->width + 1);
+ if (!field->height)
+ calc_field_height(field, field->field.action->text);
+ field->field.action->fn = def->field.action->fn;
+ break;
+ default:
+ break;
+ }
+ return (0);
+}
+
+void
+display_field(WINDOW *window, struct Field *field)
+{
+ wattrset(window, field->attr);
+ wmove(window, field->y, field->x);
+ switch (field->type) {
+ case FF_TEXT:
+ display_text(window, field);
+ break;
+ case FF_MENU:
+ display_menu(window, field);
+ break;
+ case FF_INPUT:
+ display_input(window, field);
+ break;
+ case FF_ACTION:
+ display_action(window, field);
+ break;
+ case FF_UNKNOWN:
+ default:
+ break;
+ }
+ wattrset(window, 0);
+ wrefresh(window);
+}
+
+void
+display_text(WINDOW *window, struct Field *field)
+{
+
+ if (print_string(window, field->y, field->x, field->height,
+ field->width, field->field.text->text) == ERR)
+ print_status("Illegal scroll in print_string");
+}
+
+void
+display_input(WINDOW *window, struct Field *field)
+{
+ if (field->field.input->lbl_flag) {
+ if (print_string(window, field->y, field->x, field->height,
+ field->width, field->field.input->label) == ERR)
+ print_status("Illegal scroll in print_string");
+ } else
+ if (print_string(window, field->y, field->x, field->height,
+ field->width, field->field.input->input) == ERR)
+ print_status("Illegal scroll in print_string");
+}
+
+void
+display_menu(WINDOW *window, struct Field *field)
+{
+ if (print_string(window, field->y, field->x,
+ field->height, field->width,
+ field->field.menu->options[field->field.menu->selected]) == ERR)
+ print_status("Illegal scroll in print_string");
+}
+
+void
+display_action(WINDOW *window, struct Field *field)
+{
+ if (print_string(window, field->y, field->x, field->height,
+ field->width,
+ field->field.action->text) == ERR)
+ print_status("Illegal scroll in print_string");
+}
+
+int
+do_action(struct Form *form)
+{
+ struct Field *field = form->current_field;
+ struct Tuple *tuple;
+ int ch;
+ void (* fn)();
+
+ display_action(form->window, field);
+ wmove(form->window, field->y, field->x);
+
+ for (;;) {
+
+ ch = wgetch(form->window);
+
+ if (ch == FK_ACCEPT) {
+ tuple = form_get_tuple(field->field.action->fn, FT_FUNC);
+ if (!tuple) {
+ print_status("No function bound to action");
+ beep();
+ continue;
+ } else {
+ fn = tuple->addr;
+ (*fn)(form);
+ return (FS_OK);
+ }
+ } else
+ ch = do_key_bind(form, ch);
+
+ if (ch == FS_OK)
+ return (FS_OK);
+ else if (ch == FS_ERROR)
+ continue;
+ }
+}
+
+int
+do_menu(struct Form *form)
+{
+ struct Field *field = form->current_field;
+ int ch;
+
+
+ for (;;) {
+
+ display_menu(form->window, field);
+ wmove(form->window, field->y, field->x);
+
+ ch = wgetch(form->window);
+
+ switch (ch) {
+ case ' ':
+ print_status("");
+ field->field.menu->selected++;
+ if (field->field.menu->selected >= field->field.menu->no_options)
+ field->field.menu->selected = 0;
+ break;
+ default:
+ ch = do_key_bind(form, ch);
+ break;
+ }
+
+ if (ch == FS_OK)
+ return (FS_OK);
+ else if (ch == FS_ERROR) {
+ beep();
+ continue;
+ } else {
+ print_status("Hit the space bar to toggle through options");
+ beep();
+ continue;
+ }
+ }
+}
+
+int
+do_field(struct Form *form)
+{
+ struct Field *field = form->current_field;
+ int status;
+
+ switch (field->type) {
+ case FF_TEXT:
+ status = FS_OK;
+ display_text(form->window, field);
+ break;
+ case FF_INPUT:
+ status = do_input(form);
+ break;
+ case FF_MENU:
+ status = do_menu(form);
+ break;
+ case FF_ACTION:
+ status = do_action(form);
+ break;
+ default:
+ status = FF_UNKNOWN;
+ beep();
+ print_status("Unknown field type");
+ form->current_field = form->prev_field;
+ break;
+ }
+
+ return (status);
+}
+
+int
+print_string(WINDOW *window, int y, int x,
+ int height, int fwidth, char *string)
+{
+ int len;
+ int width;
+
+ if (!string)
+ len = -1;
+
+ len = strlen(string);
+
+ if (wmove(window, y, x) == ERR)
+ return (ERR);
+ while (height--) {
+ width = fwidth;
+ while (width--) {
+ if (len-- > 0) {
+ if (waddch(window, *string++) == ERR)
+ return (ERR);
+ } else
+ if (waddch(window, ' ') == ERR)
+ return (ERR);
+ }
+ if (wmove(window, ++y, x) == ERR)
+ return (ERR);
+
+ }
+ return (OK);
+}
+
+void
+print_status(char *msg)
+{
+ if (wmove(stdscr, LINES-1, 0) == ERR) {
+ endwin();
+ exit(1);
+ }
+
+ wclrtoeol(stdscr);
+
+ wstandout(stdscr);
+ if (wprintw(stdscr, "%s",
+ msg) == ERR) {
+ endwin();
+ exit(1);
+ }
+ wstandend(stdscr);
+ wrefresh(stdscr);
+}
+
+
+int
+do_input(struct Form *form)
+{
+ struct Field *field = form->current_field;
+ int len;
+ int disp_off=0, abspos=0, cursor = 0;
+ unsigned int ch;
+
+#define DISPOFF ((len < field->width) ? 0 : len - field->width)
+#define CURSPOS ((len < field->width) ? len : field->width)
+
+ len = strlen(field->field.input->input);
+ display_input(form->window, field);
+
+ cursor = CURSPOS;
+ abspos = cursor;
+
+ for (;;) {
+
+ wmove(form->window, field->y, field->x+cursor);
+ wrefresh(form->window);
+
+ ch = wgetch(form->window);
+ ch = do_key_bind(form, ch);
+
+ /*
+ * If there was a valid motion command then we've
+ * moved to a new field so just return. If the motion
+ * command was invalid then just go around and get another
+ * keystroke. Otherwise, it was not a motion command.
+ */
+
+ if (ch == FS_OK)
+ return (FS_OK);
+ else if (ch == FS_ERROR)
+ continue;
+
+ print_status("");
+
+ if (field->field.input->lbl_flag) {
+ field->field.input->lbl_flag = 0;
+ }
+ if ((ch == FK_CHOME) || (ch == '')) {
+ disp_off = 0;
+ cursor = 0;
+ abspos = 0;
+ } else if ((ch == FK_CEND) || (ch == '')) {
+ disp_off = DISPOFF;
+ abspos = len;
+ cursor = CURSPOS;
+ } else if (ch == FK_CDEL) {
+ if (!(len-abspos))
+ beep();
+ else {
+ bcopy(field->field.input->input+abspos+1,
+ field->field.input->input+abspos,
+ len - abspos);
+ --len;
+ }
+ } else if ((ch == FK_CLEFT) || (ch == FK_CBS) || (ch == '')) {
+ if (!abspos)
+ beep();
+ else {
+ if (ch == FK_CBS) {
+ bcopy(field->field.input->input+abspos,
+ field->field.input->input+abspos-1,
+ len-abspos+1);
+ --len;
+ }
+ --abspos;
+ --cursor;
+ if ((disp_off) && (cursor < 0)) {
+ --disp_off;
+ ++cursor;
+ }
+ }
+ } else if ((ch == FK_CRIGHT) || (ch == '')) {
+ if (abspos == len)
+ beep();
+ else {
+ ++abspos;
+ if (++cursor >= field->width) {
+ ++disp_off;
+ --cursor;
+ }
+ }
+ } else if ((isprint(ch)) && (len < field->field.input->limit)){
+ bcopy(field->field.input->input+abspos,
+ field->field.input->input+abspos+1, len-abspos+1);
+ field->field.input->input[abspos++] = ch;
+ len++;
+ if (++cursor > field->width) {
+ ++disp_off;
+ --cursor;
+ }
+ } else
+ beep();
+ print_string(form->window, field->y, field->x, field->height,
+ field->width, field->field.input->input+disp_off);
+ }
+}
+
+void
+exit_form(struct Form *form)
+{
+ form->status = FS_EXIT;
+}
+
+void
+cancel_form(struct Form *form)
+{
+ form->status = FS_CANCEL;
+}
diff --git a/lib/libforms/forms.c b/lib/libforms/forms.c
index 6787d8ecb1da..a51c95e28932 100644
--- a/lib/libforms/forms.c
+++ b/lib/libforms/forms.c
@@ -1,4 +1,4 @@
-/*-
+/*
* Copyright (c) 1995
* Paul Richards. All rights reserved.
*
@@ -32,48 +32,72 @@
*
*/
-#include <string.h>
+#include <stdio.h>
#include <stdlib.h>
-#include <ctype.h>
#include <forms.h>
+#include <err.h>
#include <ncurses.h>
#include "internal.h"
+extern FILE *yyin;
+
+struct Tuple *fbind_first;
+struct Tuple *fbind_last;
+
unsigned int f_keymap[] = {
- KEY_UP, /* F_UP */
- KEY_DOWN, /* F_DOWN */
- 9, /* F_RIGHT */
- 8, /* F_LEFT */
- 10, /* F_NEXT */
- KEY_LEFT, /* F_CLEFT */
- KEY_RIGHT, /* F_CRIGHT */
- KEY_HOME, /* F_CHOME */
- KEY_END, /* F_CEND */
- 263, /* F_CBS */
- 330, /* F_CDEL */
- 10 /* F_ACCEPT */
+ KEY_UP, /* F_UP */
+ KEY_DOWN, /* F_DOWN */
+ 9, /* F_RIGHT */
+ 8, /* F_LEFT */
+ 10, /* F_NEXT */
+ KEY_LEFT, /* F_CLEFT */
+ KEY_RIGHT, /* F_CRIGHT */
+ KEY_HOME, /* F_CHOME */
+ KEY_END, /* F_CEND */
+ 263, /* F_CBS */
+ 330, /* F_CDEL */
+ 10 /* F_ACCEPT */
};
-int done=0;
-
int
-initfrm(struct form *form)
+form_load(const char *filename)
+{
+ FILE *fd;
+
+ if (!(fd = fopen(filename, "r"))) {
+ warn("Couldn't open forms file %s", filename);
+ return (FS_ERROR);
+ }
+
+ yyin = fd;
+ yyparse();
+
+ if (fclose(fd)) {
+ warn("Couldn't close forms file %s", filename);
+ return (FS_ERROR);
+ }
+
+ return (FS_OK);
+}
+
+struct Form *
+form_start(const char *formname)
{
+ struct Tuple *tuple;
+ struct Form *form;
+ struct Field *field;
- struct field *field = &form->field[0];
- int i;
+ tuple = form_get_tuple(formname, FT_FORM);
- if (has_colors()) {
- start_color();
- if (form->color_table)
- for (i=0; form->color_table[i].f != -1; i++) {
- init_pair(i+1, form->color_table[i].f, form->color_table[i].b);
- }
+ if (!tuple) {
+ warnx("No such form");
+ return (0);
}
- cbreak();
- noecho();
+ form = tuple->addr;
+
+ /* Initialise form */
if (!form->height)
form->height = LINES;
if (!form->width)
@@ -81,422 +105,190 @@ initfrm(struct form *form)
form->window = newwin(form->height, form->width, form->y, form->x);
if (!form->window) {
- print_status("Couldn't open window, closing form");
- return (ERR);
- }
- form->no_fields = 0;
-
- keypad(form->window, TRUE);
-
-
- while (field->type != F_END) {
- if (field->type == F_INPUT) {
- field->field.input->input = malloc(field->field.input->limit);
- if (!field->field.input->input){
- print_status("Couldn't allocate memory, closing form");
- endfrm(form);
- return (ERR);
- }
- /*
- * If it's a label then clear the input string
- * otherwise copy the default string to the input string.
- */
- if (field->field.input->lbl_flag)
- field->field.input->input[0] = '\0';
- else if (field->field.input->label) {
- strncpy(field->field.input->input,
- field->field.input->label,
- field->field.input->limit);
- field->field.input->input[field->field.input->limit] = 0;
- }
- } else if ((field->type != F_TEXT) && (field->type != F_MENU) &&
- (field->type != F_ACTION)) {
- print_status("Unknown field type, closing form");
- endfrm(form);
- return (ERR);
- }
- form->no_fields++;
- field = &form->field[form->no_fields];
+ warnx("Couldn't open window, closing form");
+ return (0);
}
- form->current_field = form->start_field;
- show_form(form);
- return (OK);
-}
-void
-endfrm(struct form *form)
-{
+ tuple = form_get_tuple(form->startfield, FT_FIELD_INST);
+
+ if (!tuple) {
+ warnx("No start field specified");
+ /* XXX should search for better default start */
+ form->current_field = form->fieldlist;
+ } else
+ form->current_field = (struct Field *)tuple->addr;
- struct field *field = &form->field[0];
- int i;
+ form->prev_field = form->current_field;
- delwin(form->window);
+ /* Initialise the field instances */
- for (i=0; i < form->no_fields; i++) {
- if (field->type == F_INPUT)
- free(field->field.input->input);
- field = &form->field[i];
+ for (field = form->fieldlist; field; field = field->next) {
+ init_field(field);
}
+
+ form->status = FS_RUNNING;
+
+ return (form);
}
int
-update_form(struct form *form)
+form_bind_tuple(char *name, TupleType type, void *addr)
{
- show_form(form);
-
- if (form->current_field == -1)
- return (F_CANCEL);
-
- wattrset(form->window, form->field[form->current_field].selattr);
- switch (form->field[form->current_field].type) {
- case F_MENU:
- field_menu(form);
- break;
- case F_INPUT:
- field_input(form);
- break;
- case F_ACTION:
- field_action(form);
- break;
- case F_TEXT:
- default:
- print_status("Error, current field is invalid");
- return (F_CANCEL);
- }
- wattrset(form->window, 0);
+ struct Tuple *tuple;
- return (done);
-}
+ tuple = malloc(sizeof (struct Tuple));
+ if (!tuple) {
+ warn("Couldn't allocate memory for new tuple");
+ return (FS_ERROR);
+ }
-static void
-show_form(struct form *form)
-{
- int i;
- int y, x;
+ tuple->name = name;
+ tuple->type = type;
+ tuple->addr = addr;
+ tuple->next = 0;
- wattrset(form->window, form->attr);
- for (y = 0; y < form->height; y++)
- for (x = 0; x < form->width; x++)
- mvwaddch(form->window, y, x, ' ');
- for (i=0; i < form->no_fields; i++) {
- wattrset(form->window, form->field[i].attr);
- wmove(form->window, form->field[i].y, form->field[i].x);
- switch (form->field[i].type) {
- case F_TEXT:
- disp_text(form, i);
- break;
- case F_MENU:
- disp_menu(form, i);
- break;
- case F_INPUT:
- disp_input(form,i);
- break;
- case F_ACTION:
- disp_action(form,i);
- break;
- case F_END:
- default:
- break;
+ if (!fbind_first) {
+ fbind_first = tuple;
+ fbind_last = tuple;
+ } else {
+ /* Check there isn't already a tuple of this type with this name */
+ if (form_get_tuple(name, type)) {
+ warn("Duplicate tuple name, %s, skipping", name);
+ return (FS_ERROR);
}
+ fbind_last->next = tuple;
+ fbind_last = tuple;
}
- wattrset(form->window, 0);
- wrefresh(form->window);
-}
-
-static void
-disp_text(struct form *form, int index)
-{
-
- struct field *field = &form->field[index];
- if (print_string(form->window, field->y, field->x, field->height,
- field->width, field->field.text->text) == ERR)
- print_status("Illegal scroll in print_string");
+ return (0);
}
-static void
-disp_input(struct form *form, int index)
+struct Tuple *
+form_get_tuple(const char *name, TupleType type)
{
-
- struct field *field = &form->field[index];
-
- if (field->field.input->lbl_flag) {
- if (print_string(form->window, field->y, field->x, field->height,
- field->width, field->field.input->label) == ERR)
- print_status("Illegal scroll in print_string");
- } else
- if (print_string(form->window, field->y, field->x, field->height,
- field->width, field->field.input->input) == ERR)
- print_status("Illegal scroll in print_string");
+ return (form_next_tuple(name, type, fbind_first));
}
-static void
-disp_menu(struct form *form, int index)
+struct Tuple *
+form_next_tuple(const char *name, TupleType type, struct Tuple *tuple)
{
- struct field *field = &form->field[index];
+ for (; tuple; tuple = tuple->next) {
+ if (type != FT_ANY)
+ if (tuple->type != type)
+ continue;
+ if (name)
+ if (strcmp(name, tuple->name))
+ continue;
+ return (tuple);
+ }
- if (print_string(form->window, field->y, field->x, field->height,
- field->width,
- field->field.menu->options[field->field.menu->selected]) == ERR)
- print_status("Illegal scroll in print_string");
+ return (0);
}
-static void
-disp_action(struct form *form, int index)
+int
+form_show(const char *formname)
{
- struct field *field = &form->field[index];
+ struct Tuple *tuple;
+ struct Form *form;
+ struct Field *field;
+ int x, y;
- if (print_string(form->window, field->y, field->x, field->height,
- field->width,
- field->field.action->text) == ERR)
- print_status("Illegal scroll in print_string");
-}
+ tuple = form_get_tuple(formname, FT_FORM);
+ if (!tuple)
+ return (FS_NOBIND);
-static void
-field_action(struct form *form)
-{
+ form = tuple->addr;
- struct field *field = &form->field[form->current_field];
- int ch;
-
- for (;;) {
- disp_action(form, form->current_field);
- wmove(form->window, field->y, field->x);
- ch = wgetch(form->window);
- if (ch == F_ACCEPT) {
- (*field->field.action->fn)();
- return;
- } else if (!next_field(form, ch))
- beep();
- else
- return;
- }
-}
+ /* Clear form */
+ wattrset(form->window, form->attr);
+ for (y=0; y < form->height; y++)
+ for (x=0; x < form->width; x++)
+ mvwaddch(form->window, y, x, ' ');
-static void
-field_menu(struct form *form)
-{
- struct field *field = &form->field[form->current_field];
- int ch;
-
- for (;;) {
- disp_menu(form, form->current_field);
- wmove(form->window, field->y, field->x);
- switch (ch = wgetch(form->window)) {
- case ' ':
- print_status("");
- field->field.menu->selected++;
- if (field->field.menu->selected >= field->field.menu->no_options)
- field->field.menu->selected = 0;
- break;
- default:
- if (!next_field(form, ch)) {
- print_status("Hit the space bar to toggle through options");
- beep();
- } else
- return;
- }
+ for (field = form->fieldlist; field; field = field->next) {
+ display_field(form->window, field);
}
+
+ return (FS_OK);
}
-static int
-next_field(struct form *form, int ch)
+unsigned int
+do_key_bind(struct Form *form, unsigned int ch)
{
+ struct Field *field = form->current_field;
+ struct Tuple *tuple=0;
- struct field *field = &form->field[form->current_field];
+ /* XXX -- check for keymappings here --- not yet done */
- if (ch == F_UP) {
- if (field->up == -1) {
- print_status("Can't go up from here");
- return (0);
+ if (ch == FK_UP) {
+ if (field->fup) {
+ tuple = form_get_tuple(field->fup, FT_FIELD_INST);
+ if (!tuple)
+ print_status("Field to move up to does not exist");
} else
- form->current_field = field->up;
- } else if (ch == F_DOWN) {
- if (field->down == -1) {
- print_status("Can't go down from here");
- return (0);
+ print_status("Can't move up from this field");
+ } else if (ch == FK_DOWN) {
+ if (field->fdown) {
+ tuple = form_get_tuple(field->fdown, FT_FIELD_INST);
+ if (!tuple)
+ print_status("Field to move down to does not exist");
} else
- form->current_field = field->down;
- } else if (ch == F_NEXT) {
- if (field->next == -1) {
- print_status("Can't go to next from here");
- return (0);
+ print_status("Can't move down from this field");
+ } else if (ch == FK_LEFT) {
+ if (field->fleft) {
+ tuple = form_get_tuple(field->fleft, FT_FIELD_INST);
+ if (!tuple)
+ print_status("Field to move left to does not exist");
} else
- form->current_field = field->next;
- } else if (ch == F_RIGHT) {
- if (field->right == -1) {
- print_status("Can't go right from here");
- return (0);
+ print_status("Can't move left from this field");
+ } else if (ch == FK_RIGHT) {
+ if (field->fright) {
+ tuple = form_get_tuple(field->fright, FT_FIELD_INST);
+ if (!tuple)
+ print_status("Field to move right to does not exist");
} else
- form->current_field = field->right;
- } else if (ch == F_LEFT) {
- if (field->left == -1) {
- print_status("Can't go left from here");
- return (0);
+ print_status("Can't move right from this field");
+ } else if (ch == FK_NEXT) {
+ if (field->fnext) {
+ tuple = form_get_tuple(field->fnext, FT_FIELD_INST);
+ if (!tuple)
+ print_status("Field to move to next does not exist");
} else
- form->current_field = field->left;
+ print_status("Can't move next from this field");
} else
- return (0);
-
- print_status("");
- return (1);
-}
-
-static int
-print_string(WINDOW *window, int y, int x,
- int height, int fwidth, char *string)
-{
- int len;
- int width;
-
- if (!string)
- len = -1;
-
- len = strlen(string);
-
- if (wmove(window, y, x) == ERR)
- return (ERR);
- while (height--) {
- width = fwidth;
- while (width--) {
- if (len-- > 0) {
- if (waddch(window, *string++) == ERR)
- return (ERR);
- } else
- if (waddch(window, ' ') == ERR)
- return (ERR);
- }
- if (wmove(window, ++y, x) == ERR)
- return (ERR);
-
+ /* No motion keys pressed */
+ return (ch);
+
+ if (tuple) {
+ form->prev_field = form->current_field;
+ form->current_field = tuple->addr;
+ return (FS_OK);
+ } else {
+ beep();
+ return (FS_ERROR);
}
- return (OK);
-}
+}
void
-print_status(char *msg)
+debug_dump_bindings()
{
- if (wmove(stdscr, LINES-1, 0) == ERR) {
- endwin();
- exit(1);
- }
+ struct Tuple *binds;
- wclrtoeol(stdscr);
-
- wstandout(stdscr);
- if (wprintw(stdscr, "%s",
- msg) == ERR) {
- endwin();
- exit(1);
+ binds = form_get_tuple(0, FT_ANY);
+ while (binds) {
+ printf("%s, %d, %x\n", binds->name, binds->type, (int)binds->addr);
+ binds = form_next_tuple(0, FT_ANY, binds->next);
}
- wstandend(stdscr);
- wrefresh(stdscr);
}
-
-void
-field_input(struct form *form)
+void debug_dump_form(struct Form *form)
{
- struct field *field = &form->field[form->current_field];
- int len;
- int ch;
- int disp_off=0, abspos=0, cursor = 0;
-
-#define DISPOFF ((len < field->width) ? 0 : len - field->width)
-#define CURSPOS ((len < field->width) ? len : field->width)
-
- len = strlen(field->field.input->input);
- disp_input(form, form->current_field);
+ struct Field *field;
- cursor = CURSPOS;
- abspos = cursor;
+ field = form->fieldlist;
- for(;;) {
-
- wmove(form->window, field->y, field->x+cursor);
- wrefresh(form->window);
-
- ch = wgetch(form->window);
- if (next_field(form, ch)) {
- print_string(form->window, field->y, field->x,
- field->height, field->width,
- field->field.input->input+DISPOFF);
- return;
- }
- if (field->field.input->lbl_flag) {
- field->field.input->lbl_flag = 0;
- }
- if ((ch == F_CHOME) || (ch == '')) {
- disp_off = 0;
- cursor = 0;
- abspos = 0;
- } else if ((ch == F_CEND) || (ch == '')) {
- disp_off = DISPOFF;
- abspos = len;
- cursor = CURSPOS;
- } else if (ch == F_CDEL) {
- if (!(len-abspos))
- beep();
- else {
- bcopy(field->field.input->input+abspos+1,
- field->field.input->input+abspos,
- len - abspos);
- --len;
- }
- } else if ((ch == F_CLEFT) || (ch == F_CBS) || (ch == '')) {
- if (!abspos)
- beep();
- else {
- if (ch == F_CBS) {
- bcopy(field->field.input->input+abspos,
- field->field.input->input+abspos-1,
- len-abspos+1);
- --len;
- }
- --abspos;
- --cursor;
- if ((disp_off) && (cursor < 0)) {
- --disp_off;
- ++cursor;
- }
- }
- } else if ((ch == F_CRIGHT) || (ch == '')) {
- if (abspos == len)
- beep();
- else {
- ++abspos;
- if (++cursor == field->width) {
- ++disp_off;
- --cursor;
- }
- }
- } else if ((isprint(ch)) && (len < field->field.input->limit)){
- bcopy(field->field.input->input+abspos,
- field->field.input->input+abspos+1, len-abspos+1);
- field->field.input->input[abspos++] = ch;
- len++;
- if (++cursor > field->width) {
- ++disp_off;
- --cursor;
- }
- } else {
- beep();
- }
- print_string(form->window, field->y, field->x, field->height,
- field->width, field->field.input->input+disp_off);
+ for ( ; field; field = field->next) {
+ printf("%s, %x, next = %x\n", field->defname, (int)field, (int)field->next);
}
- /* Not Reached */
-}
-
-void
-exit_form(void)
-{
- done = F_DONE;
-}
-
-void
-cancel_form(void)
-{
- done = F_CANCEL;
}
diff --git a/lib/libforms/forms.c.orig b/lib/libforms/forms.c.orig
new file mode 100644
index 000000000000..6787d8ecb1da
--- /dev/null
+++ b/lib/libforms/forms.c.orig
@@ -0,0 +1,502 @@
+/*-
+ * 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 <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <forms.h>
+#include <ncurses.h>
+
+#include "internal.h"
+
+unsigned int f_keymap[] = {
+ KEY_UP, /* F_UP */
+ KEY_DOWN, /* F_DOWN */
+ 9, /* F_RIGHT */
+ 8, /* F_LEFT */
+ 10, /* F_NEXT */
+ KEY_LEFT, /* F_CLEFT */
+ KEY_RIGHT, /* F_CRIGHT */
+ KEY_HOME, /* F_CHOME */
+ KEY_END, /* F_CEND */
+ 263, /* F_CBS */
+ 330, /* F_CDEL */
+ 10 /* F_ACCEPT */
+};
+
+int done=0;
+
+int
+initfrm(struct form *form)
+{
+
+ struct field *field = &form->field[0];
+ int i;
+
+ if (has_colors()) {
+ start_color();
+ if (form->color_table)
+ for (i=0; form->color_table[i].f != -1; i++) {
+ init_pair(i+1, form->color_table[i].f, form->color_table[i].b);
+ }
+ }
+ cbreak();
+ noecho();
+
+ if (!form->height)
+ form->height = LINES;
+ if (!form->width)
+ form->width = COLS;
+
+ form->window = newwin(form->height, form->width, form->y, form->x);
+ if (!form->window) {
+ print_status("Couldn't open window, closing form");
+ return (ERR);
+ }
+ form->no_fields = 0;
+
+ keypad(form->window, TRUE);
+
+
+ while (field->type != F_END) {
+ if (field->type == F_INPUT) {
+ field->field.input->input = malloc(field->field.input->limit);
+ if (!field->field.input->input){
+ print_status("Couldn't allocate memory, closing form");
+ endfrm(form);
+ return (ERR);
+ }
+ /*
+ * If it's a label then clear the input string
+ * otherwise copy the default string to the input string.
+ */
+ if (field->field.input->lbl_flag)
+ field->field.input->input[0] = '\0';
+ else if (field->field.input->label) {
+ strncpy(field->field.input->input,
+ field->field.input->label,
+ field->field.input->limit);
+ field->field.input->input[field->field.input->limit] = 0;
+ }
+ } else if ((field->type != F_TEXT) && (field->type != F_MENU) &&
+ (field->type != F_ACTION)) {
+ print_status("Unknown field type, closing form");
+ endfrm(form);
+ return (ERR);
+ }
+ form->no_fields++;
+ field = &form->field[form->no_fields];
+ }
+ form->current_field = form->start_field;
+ show_form(form);
+ return (OK);
+}
+
+void
+endfrm(struct form *form)
+{
+
+ struct field *field = &form->field[0];
+ int i;
+
+ delwin(form->window);
+
+ for (i=0; i < form->no_fields; i++) {
+ if (field->type == F_INPUT)
+ free(field->field.input->input);
+ field = &form->field[i];
+ }
+}
+
+int
+update_form(struct form *form)
+{
+ show_form(form);
+
+ if (form->current_field == -1)
+ return (F_CANCEL);
+
+ wattrset(form->window, form->field[form->current_field].selattr);
+ switch (form->field[form->current_field].type) {
+ case F_MENU:
+ field_menu(form);
+ break;
+ case F_INPUT:
+ field_input(form);
+ break;
+ case F_ACTION:
+ field_action(form);
+ break;
+ case F_TEXT:
+ default:
+ print_status("Error, current field is invalid");
+ return (F_CANCEL);
+ }
+ wattrset(form->window, 0);
+
+ return (done);
+}
+
+static void
+show_form(struct form *form)
+{
+ int i;
+ int y, x;
+
+ wattrset(form->window, form->attr);
+ for (y = 0; y < form->height; y++)
+ for (x = 0; x < form->width; x++)
+ mvwaddch(form->window, y, x, ' ');
+
+ for (i=0; i < form->no_fields; i++) {
+ wattrset(form->window, form->field[i].attr);
+ wmove(form->window, form->field[i].y, form->field[i].x);
+ switch (form->field[i].type) {
+ case F_TEXT:
+ disp_text(form, i);
+ break;
+ case F_MENU:
+ disp_menu(form, i);
+ break;
+ case F_INPUT:
+ disp_input(form,i);
+ break;
+ case F_ACTION:
+ disp_action(form,i);
+ break;
+ case F_END:
+ default:
+ break;
+ }
+ }
+ wattrset(form->window, 0);
+ wrefresh(form->window);
+}
+
+static void
+disp_text(struct form *form, int index)
+{
+
+ struct field *field = &form->field[index];
+
+ if (print_string(form->window, field->y, field->x, field->height,
+ field->width, field->field.text->text) == ERR)
+ print_status("Illegal scroll in print_string");
+}
+
+static void
+disp_input(struct form *form, int index)
+{
+
+ struct field *field = &form->field[index];
+
+ if (field->field.input->lbl_flag) {
+ if (print_string(form->window, field->y, field->x, field->height,
+ field->width, field->field.input->label) == ERR)
+ print_status("Illegal scroll in print_string");
+ } else
+ if (print_string(form->window, field->y, field->x, field->height,
+ field->width, field->field.input->input) == ERR)
+ print_status("Illegal scroll in print_string");
+}
+
+static void
+disp_menu(struct form *form, int index)
+{
+ struct field *field = &form->field[index];
+
+ if (print_string(form->window, field->y, field->x, field->height,
+ field->width,
+ field->field.menu->options[field->field.menu->selected]) == ERR)
+ print_status("Illegal scroll in print_string");
+}
+
+static void
+disp_action(struct form *form, int index)
+{
+ struct field *field = &form->field[index];
+
+ if (print_string(form->window, field->y, field->x, field->height,
+ field->width,
+ field->field.action->text) == ERR)
+ print_status("Illegal scroll in print_string");
+}
+
+static void
+field_action(struct form *form)
+{
+
+ struct field *field = &form->field[form->current_field];
+ int ch;
+
+ for (;;) {
+ disp_action(form, form->current_field);
+ wmove(form->window, field->y, field->x);
+ ch = wgetch(form->window);
+ if (ch == F_ACCEPT) {
+ (*field->field.action->fn)();
+ return;
+ } else if (!next_field(form, ch))
+ beep();
+ else
+ return;
+ }
+}
+
+static void
+field_menu(struct form *form)
+{
+ struct field *field = &form->field[form->current_field];
+ int ch;
+
+ for (;;) {
+ disp_menu(form, form->current_field);
+ wmove(form->window, field->y, field->x);
+ switch (ch = wgetch(form->window)) {
+ case ' ':
+ print_status("");
+ field->field.menu->selected++;
+ if (field->field.menu->selected >= field->field.menu->no_options)
+ field->field.menu->selected = 0;
+ break;
+ default:
+ if (!next_field(form, ch)) {
+ print_status("Hit the space bar to toggle through options");
+ beep();
+ } else
+ return;
+ }
+ }
+}
+
+static int
+next_field(struct form *form, int ch)
+{
+
+ struct field *field = &form->field[form->current_field];
+
+ if (ch == F_UP) {
+ if (field->up == -1) {
+ print_status("Can't go up from here");
+ return (0);
+ } else
+ form->current_field = field->up;
+ } else if (ch == F_DOWN) {
+ if (field->down == -1) {
+ print_status("Can't go down from here");
+ return (0);
+ } else
+ form->current_field = field->down;
+ } else if (ch == F_NEXT) {
+ if (field->next == -1) {
+ print_status("Can't go to next from here");
+ return (0);
+ } else
+ form->current_field = field->next;
+ } else if (ch == F_RIGHT) {
+ if (field->right == -1) {
+ print_status("Can't go right from here");
+ return (0);
+ } else
+ form->current_field = field->right;
+ } else if (ch == F_LEFT) {
+ if (field->left == -1) {
+ print_status("Can't go left from here");
+ return (0);
+ } else
+ form->current_field = field->left;
+ } else
+ return (0);
+
+ print_status("");
+ return (1);
+}
+
+static int
+print_string(WINDOW *window, int y, int x,
+ int height, int fwidth, char *string)
+{
+ int len;
+ int width;
+
+ if (!string)
+ len = -1;
+
+ len = strlen(string);
+
+ if (wmove(window, y, x) == ERR)
+ return (ERR);
+ while (height--) {
+ width = fwidth;
+ while (width--) {
+ if (len-- > 0) {
+ if (waddch(window, *string++) == ERR)
+ return (ERR);
+ } else
+ if (waddch(window, ' ') == ERR)
+ return (ERR);
+ }
+ if (wmove(window, ++y, x) == ERR)
+ return (ERR);
+
+ }
+ return (OK);
+}
+
+void
+print_status(char *msg)
+{
+ if (wmove(stdscr, LINES-1, 0) == ERR) {
+ endwin();
+ exit(1);
+ }
+
+ wclrtoeol(stdscr);
+
+ wstandout(stdscr);
+ if (wprintw(stdscr, "%s",
+ msg) == ERR) {
+ endwin();
+ exit(1);
+ }
+ wstandend(stdscr);
+ wrefresh(stdscr);
+}
+
+
+void
+field_input(struct form *form)
+{
+ struct field *field = &form->field[form->current_field];
+ int len;
+ int ch;
+ int disp_off=0, abspos=0, cursor = 0;
+
+#define DISPOFF ((len < field->width) ? 0 : len - field->width)
+#define CURSPOS ((len < field->width) ? len : field->width)
+
+ len = strlen(field->field.input->input);
+ disp_input(form, form->current_field);
+
+ cursor = CURSPOS;
+ abspos = cursor;
+
+ for(;;) {
+
+ wmove(form->window, field->y, field->x+cursor);
+ wrefresh(form->window);
+
+ ch = wgetch(form->window);
+ if (next_field(form, ch)) {
+ print_string(form->window, field->y, field->x,
+ field->height, field->width,
+ field->field.input->input+DISPOFF);
+ return;
+ }
+ if (field->field.input->lbl_flag) {
+ field->field.input->lbl_flag = 0;
+ }
+ if ((ch == F_CHOME) || (ch == '')) {
+ disp_off = 0;
+ cursor = 0;
+ abspos = 0;
+ } else if ((ch == F_CEND) || (ch == '')) {
+ disp_off = DISPOFF;
+ abspos = len;
+ cursor = CURSPOS;
+ } else if (ch == F_CDEL) {
+ if (!(len-abspos))
+ beep();
+ else {
+ bcopy(field->field.input->input+abspos+1,
+ field->field.input->input+abspos,
+ len - abspos);
+ --len;
+ }
+ } else if ((ch == F_CLEFT) || (ch == F_CBS) || (ch == '')) {
+ if (!abspos)
+ beep();
+ else {
+ if (ch == F_CBS) {
+ bcopy(field->field.input->input+abspos,
+ field->field.input->input+abspos-1,
+ len-abspos+1);
+ --len;
+ }
+ --abspos;
+ --cursor;
+ if ((disp_off) && (cursor < 0)) {
+ --disp_off;
+ ++cursor;
+ }
+ }
+ } else if ((ch == F_CRIGHT) || (ch == '')) {
+ if (abspos == len)
+ beep();
+ else {
+ ++abspos;
+ if (++cursor == field->width) {
+ ++disp_off;
+ --cursor;
+ }
+ }
+ } else if ((isprint(ch)) && (len < field->field.input->limit)){
+ bcopy(field->field.input->input+abspos,
+ field->field.input->input+abspos+1, len-abspos+1);
+ field->field.input->input[abspos++] = ch;
+ len++;
+ if (++cursor > field->width) {
+ ++disp_off;
+ --cursor;
+ }
+ } else {
+ beep();
+ }
+ print_string(form->window, field->y, field->x, field->height,
+ field->width, field->field.input->input+disp_off);
+ }
+ /* Not Reached */
+}
+
+void
+exit_form(void)
+{
+ done = F_DONE;
+}
+
+void
+cancel_form(void)
+{
+ done = F_CANCEL;
+}
diff --git a/lib/libforms/forms.h b/lib/libforms/forms.h
index 36031be3d8b2..636b55c90979 100644
--- a/lib/libforms/forms.h
+++ b/lib/libforms/forms.h
@@ -34,63 +34,89 @@
#include <ncurses.h>
-#define F_END 0
-#define F_TEXT 1
-#define F_ACTION 2
-#define F_INPUT 3
-#define F_MENU 4
+#define FF_UNKNOWN 0
+#define FF_TEXT 1
+#define FF_ACTION 2
+#define FF_INPUT 3
+#define FF_MENU 4
#define F_DEFATTR 0
#define F_SELATTR A_REVERSE
-#define F_DONE 1
-#define F_CANCEL -1
+/* Status values */
+
+#define FS_ERROR -1
+#define FS_OK 0
+#define FS_EXIT 1
+#define FS_CANCEL 2
+#define FS_NOBIND 3
+#define FS_RUNNING 4
+
+
+typedef enum {
+ FT_ANY,
+ FT_FORM,
+ FT_COLTAB,
+ FT_FIELD_INST,
+ FT_FIELD_DEF,
+ FT_FUNC
+} TupleType;
+
+struct Tuple {
+ char *name;
+ int type;
+ void *addr;
+ struct Tuple *next;
+};
struct col_pair {
int f;
int b;
};
-struct form {
+struct Form {
+ int status;
int no_fields;
- int start_field;
- int current_field;
- struct field *field;
+ char *startfield;
+ struct Field *current_field;
+ struct Field *prev_field;
+ struct Field *fieldlist;
int height;
int width;
int y;
int x;
int attr;
- struct col_pair *color_table;
+ char *colortable;
WINDOW *window;
};
-struct text_field {
+struct TextField {
char *text;
};
-struct action_field {
+struct ActionField {
char *text;
- void (* fn)();
+ char *fn;
};
-struct input_field {
+struct InputField {
int lbl_flag;
char *label;
char *input;
int limit;
};
-struct menu_field {
- int no_options;
+struct MenuField {
int selected;
+ int no_options;
char **options;
};
struct help_link {
};
-struct field {
+struct Field {
+ char *defname;
int type;
int y;
int x;
@@ -98,17 +124,19 @@ struct field {
int width;
int attr;
int selattr;
- int next;
- int up;
- int down;
- int left;
- int right;
+ char *fnext;
+ char *fup;
+ char *fdown;
+ char *fleft;
+ char *fright;
+ char *f_keymap;
union {
- struct text_field *text;
- struct action_field *action;
- struct input_field *input;
- struct menu_field *menu;
+ struct TextField *text;
+ struct ActionField *action;
+ struct InputField *input;
+ struct MenuField *menu;
}field;
+ struct Field *next;
/*
struct help_link help;
*/
@@ -118,9 +146,18 @@ struct field {
extern unsigned int keymap[];
/* Externally visible function declarations */
+struct Form *form_start(const char *);
+struct Tuple *form_get_tuple(const char *, TupleType);
+struct Tuple *form_next_tuple(const char *, TupleType, struct Tuple *);
+int form_bind_tuple(char *, TupleType, void *);
+void print_status(char *);
+void exit_form(struct Form *form);
+void cancel_form(struct Form *form);
+
+
+#ifdef not
int update_form(struct form *);
int initfrm(struct form *);
void endfrm(struct form *);
-void exit_form(void);
-void cancel_form(void);
void print_status(char *);
+#endif
diff --git a/lib/libforms/forms.h.orig b/lib/libforms/forms.h.orig
new file mode 100644
index 000000000000..36031be3d8b2
--- /dev/null
+++ b/lib/libforms/forms.h.orig
@@ -0,0 +1,126 @@
+/*-
+ * 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 <ncurses.h>
+
+#define F_END 0
+#define F_TEXT 1
+#define F_ACTION 2
+#define F_INPUT 3
+#define F_MENU 4
+
+#define F_DEFATTR 0
+#define F_SELATTR A_REVERSE
+
+#define F_DONE 1
+#define F_CANCEL -1
+
+struct col_pair {
+ int f;
+ int b;
+};
+
+struct form {
+ int no_fields;
+ int start_field;
+ int current_field;
+ struct field *field;
+ int height;
+ int width;
+ int y;
+ int x;
+ int attr;
+ struct col_pair *color_table;
+ WINDOW *window;
+};
+
+struct text_field {
+ char *text;
+};
+
+struct action_field {
+ char *text;
+ void (* fn)();
+};
+
+struct input_field {
+ int lbl_flag;
+ char *label;
+ char *input;
+ int limit;
+};
+
+struct menu_field {
+ int no_options;
+ int selected;
+ char **options;
+};
+
+struct help_link {
+};
+
+struct field {
+ int type;
+ int y;
+ int x;
+ int height;
+ int width;
+ int attr;
+ int selattr;
+ int next;
+ int up;
+ int down;
+ int left;
+ int right;
+ union {
+ struct text_field *text;
+ struct action_field *action;
+ struct input_field *input;
+ struct menu_field *menu;
+ }field;
+ /*
+ struct help_link help;
+ */
+};
+
+/* Externally visible keymap table for user-definable keymaps */
+extern unsigned int keymap[];
+
+/* Externally visible function declarations */
+int update_form(struct form *);
+int initfrm(struct form *);
+void endfrm(struct form *);
+void exit_form(void);
+void cancel_form(void);
+void print_status(char *);
diff --git a/lib/libforms/internal.h b/lib/libforms/internal.h
index 6895de2f769e..96b099c323ca 100644
--- a/lib/libforms/internal.h
+++ b/lib/libforms/internal.h
@@ -1,38 +1,75 @@
/*
- * Copyright (c) 1995 Paul Richards.
+ * Copyright (c) 1995
+ * Paul Richards. All rights reserved.
*
- * 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.
*
- * This software may be used, modified, copied, distributed, and
- * sold, in both source and binary form provided that the above
- * copyright and these terms are retained, verbatim, as the first
- * lines of this file. Under no circumstances is the author
- * responsible for the proper functioning of this software, nor does
- * the author assume any responsibility for damages incurred with
- * its use.
*/
-#define F_UP f_keymap[0]
-#define F_DOWN f_keymap[1]
-#define F_RIGHT f_keymap[2]
-#define F_LEFT f_keymap[3]
-#define F_NEXT f_keymap[4]
-#define F_CLEFT f_keymap[5]
-#define F_CRIGHT f_keymap[6]
-#define F_CHOME f_keymap[7]
-#define F_CEND f_keymap[8]
-#define F_CBS f_keymap[9]
-#define F_CDEL f_keymap[10]
-#define F_ACCEPT f_keymap[11]
+#define FK_UP f_keymap[0]
+#define FK_DOWN f_keymap[1]
+#define FK_RIGHT f_keymap[2]
+#define FK_LEFT f_keymap[3]
+#define FK_NEXT f_keymap[4]
+#define FK_CLEFT f_keymap[5]
+#define FK_CRIGHT f_keymap[6]
+#define FK_CHOME f_keymap[7]
+#define FK_CEND f_keymap[8]
+#define FK_CBS f_keymap[9]
+#define FK_CDEL f_keymap[10]
+#define FK_ACCEPT f_keymap[11]
+
+extern unsigned int f_keymap[];
/* Private function declarations */
+void display_field(WINDOW *, struct Field *);
+void display_text(WINDOW *, struct Field *);
+void display_input(WINDOW *, struct Field *);
+void display_menu(WINDOW *, struct Field *);
+void display_action(WINDOW *, struct Field *);
+int print_string(WINDOW *, int, int, int, int, char *);
+unsigned int do_key_bind(struct Form *, unsigned int);
+int do_action(struct Form *);
+int do_menu(struct Form *);
+int do_input(struct Form *);
+int init_field(struct Field *);
+
+
+#ifdef not
static void show_form(struct form *);
-static void disp_text(struct form *, int);
-static void disp_menu(struct form *, int);
-static void disp_action(struct form *, int);
-static void disp_input(struct form *, int);
+static void disp_text(struct form *);
+static void disp_menu(struct form *);
+static void disp_action(struct form *);
+static void disp_input(struct form *);
static void field_menu(struct form *);
static void field_input(struct form *);
static void field_action(struct form *);
static int print_string(WINDOW *, int, int, int, int, char *);
static int next_field(struct form *form, int);
+#endif
diff --git a/lib/libforms/internal.h.orig b/lib/libforms/internal.h.orig
new file mode 100644
index 000000000000..6895de2f769e
--- /dev/null
+++ b/lib/libforms/internal.h.orig
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1995 Paul Richards.
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#define F_UP f_keymap[0]
+#define F_DOWN f_keymap[1]
+#define F_RIGHT f_keymap[2]
+#define F_LEFT f_keymap[3]
+#define F_NEXT f_keymap[4]
+#define F_CLEFT f_keymap[5]
+#define F_CRIGHT f_keymap[6]
+#define F_CHOME f_keymap[7]
+#define F_CEND f_keymap[8]
+#define F_CBS f_keymap[9]
+#define F_CDEL f_keymap[10]
+#define F_ACCEPT f_keymap[11]
+
+/* Private function declarations */
+static void show_form(struct form *);
+static void disp_text(struct form *, int);
+static void disp_menu(struct form *, int);
+static void disp_action(struct form *, int);
+static void disp_input(struct form *, int);
+static void field_menu(struct form *);
+static void field_input(struct form *);
+static void field_action(struct form *);
+static int print_string(WINDOW *, int, int, int, int, char *);
+static int next_field(struct form *form, int);
diff --git a/lib/libforms/lex.c b/lib/libforms/lex.c
new file mode 100644
index 000000000000..0ce735f14837
--- /dev/null
+++ b/lib/libforms/lex.c
@@ -0,0 +1,1606 @@
+/* A lexical scanner generated by flex */
+
+/* Scanner skeleton version:
+ * $Header: /home/ncvs/src/usr.bin/lex/skel.c,v 1.1.1.1 1994/08/24 13:10:31 csgr Exp $
+ */
+
+#define FLEX_SCANNER
+
+#include <stdio.h>
+
+
+/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Use prototypes in function declarations. */
+#define YY_USE_PROTOS
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#ifdef __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+
+#ifdef __TURBOC__
+#define YY_USE_CONST
+#endif
+
+
+#ifndef YY_USE_CONST
+#ifndef const
+#define const
+#endif
+#endif
+
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.
+ */
+#define YY_START ((yy_start - 1) / 2)
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". Now included
+ * only for backward compatibility with previous versions of flex.
+ */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ extern int yywrap YY_PROTO(( void ));
+#ifdef __cplusplus
+ }
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/* The funky do-while in the following #define is used to turn the definition
+ * int a single C statement (which needs a semi-colon terminator). This
+ * avoids problems with code like:
+ *
+ * if ( condition_holds )
+ * yyless( 5 );
+ * else
+ * do_something_else();
+ *
+ * Prior to using the do-while the compiler would get upset at the
+ * "else" because it interpreted the "if" statement as being all
+ * done when it reached the ';' after the yyless() call.
+ */
+
+/* Return all but the first 'n' matched characters back to the input stream. */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+ };
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+
+
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+void yyrestart YY_PROTO(( FILE *input_file ));
+void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
+void yy_load_buffer_state YY_PROTO(( void ));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
+void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
+void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
+
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+static void yy_push_state YY_PROTO(( int new_state ));
+static void yy_pop_state YY_PROTO(( void ));
+static int yy_top_state YY_PROTO(( void ));
+
+static void *yy_flex_alloc YY_PROTO(( unsigned int ));
+static void *yy_flex_realloc YY_PROTO(( void *, unsigned int ));
+static void yy_flex_free YY_PROTO(( void * ));
+
+#define yy_new_buffer yy_create_buffer
+
+#define INITIAL 0
+typedef unsigned char YY_CHAR;
+typedef int yy_state_type;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+extern char *yytext;
+#define yytext_ptr yytext
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO(( char *, const char *, int ));
+#endif
+
+#ifdef __cplusplus
+static int yyinput YY_PROTO(( void ));
+#else
+static int input YY_PROTO(( void ));
+#endif
+
+static yy_state_type yy_get_previous_state YY_PROTO(( void ));
+static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
+static int yy_get_next_buffer YY_PROTO(( void ));
+static void yy_fatal_error YY_PROTO(( const char msg[] ));
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yytext_ptr -= yy_more_len; \
+ yyleng = yy_cp - yytext_ptr; \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_END_OF_BUFFER 46
+static const short int yy_accept[188] =
+ { 0,
+ 44, 44, 46, 45, 44, 42, 41, 43, 36, 39,
+ 18, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 37, 38, 44, 41, 43, 39, 40, 40,
+ 40, 40, 16, 15, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 31, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 6, 40, 40, 40, 40, 40, 40, 40, 40, 14,
+
+ 40, 40, 40, 9, 40, 11, 40, 32, 40, 40,
+ 40, 40, 40, 33, 40, 40, 35, 40, 13, 40,
+ 40, 40, 21, 40, 40, 40, 40, 40, 40, 40,
+ 5, 40, 40, 40, 40, 7, 40, 40, 24, 26,
+ 40, 40, 34, 40, 20, 12, 19, 40, 3, 40,
+ 29, 40, 40, 40, 40, 40, 17, 40, 40, 40,
+ 40, 8, 4, 40, 40, 40, 25, 40, 40, 10,
+ 28, 40, 40, 40, 40, 30, 40, 27, 40, 40,
+ 40, 23, 22, 1, 40, 2, 0
+ } ;
+
+static const int yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 4, 5, 1, 1, 6, 1, 6,
+ 6, 1, 1, 7, 1, 1, 1, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 1, 1, 1,
+ 9, 1, 1, 1, 10, 10, 11, 10, 10, 12,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 1, 1, 1, 1, 10, 1, 13, 14, 15, 16,
+
+ 17, 18, 19, 20, 21, 10, 22, 23, 24, 25,
+ 26, 27, 10, 28, 29, 30, 31, 10, 32, 33,
+ 34, 10, 35, 6, 36, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static const int yy_meta[37] =
+ { 0,
+ 1, 1, 2, 3, 1, 4, 1, 4, 1, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 1, 1
+ } ;
+
+static const short int yy_base[191] =
+ { 0,
+ 0, 0, 195, 196, 192, 196, 0, 0, 196, 185,
+ 196, 0, 166, 165, 22, 167, 12, 22, 158, 160,
+ 23, 28, 174, 169, 158, 171, 26, 25, 166, 155,
+ 33, 164, 196, 196, 178, 0, 0, 171, 0, 155,
+ 149, 146, 0, 145, 37, 151, 160, 154, 139, 145,
+ 152, 147, 148, 152, 147, 140, 144, 129, 131, 139,
+ 143, 139, 134, 143, 122, 0, 133, 137, 129, 125,
+ 126, 128, 120, 132, 129, 119, 119, 130, 117, 126,
+ 123, 120, 118, 120, 106, 114, 117, 103, 111, 103,
+ 0, 110, 112, 100, 97, 96, 95, 101, 28, 0,
+
+ 97, 101, 99, 0, 29, 0, 89, 0, 89, 93,
+ 97, 93, 92, 0, 84, 88, 0, 86, 0, 81,
+ 95, 79, 0, 91, 87, 80, 76, 76, 78, 88,
+ 0, 71, 72, 76, 77, 0, 67, 75, 0, 0,
+ 65, 69, 0, 63, 0, 0, 0, 60, 0, 62,
+ 0, 59, 76, 58, 57, 60, 0, 66, 71, 54,
+ 65, 0, 0, 51, 66, 66, 0, 53, 57, 0,
+ 0, 58, 54, 44, 52, 0, 35, 0, 35, 46,
+ 39, 0, 0, 0, 44, 0, 196, 68, 72, 54
+ } ;
+
+static const short int yy_def[191] =
+ { 0,
+ 187, 1, 187, 187, 187, 187, 188, 189, 187, 187,
+ 187, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 187, 187, 187, 188, 189, 187, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 0, 187, 187, 187
+ } ;
+
+static const short int yy_nxt[233] =
+ { 0,
+ 4, 5, 6, 7, 8, 4, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 18, 12, 19, 20, 21,
+ 12, 12, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 12, 32, 33, 34, 42, 46, 48, 52,
+ 54, 63, 61, 53, 55, 47, 62, 49, 56, 74,
+ 43, 44, 67, 68, 64, 127, 132, 39, 128, 133,
+ 186, 185, 184, 183, 182, 181, 180, 75, 36, 36,
+ 179, 36, 37, 178, 37, 37, 177, 176, 175, 174,
+ 173, 172, 171, 170, 169, 168, 167, 166, 165, 164,
+ 163, 162, 161, 160, 159, 158, 157, 156, 155, 154,
+
+ 153, 152, 151, 150, 149, 148, 147, 146, 145, 144,
+ 143, 142, 141, 140, 139, 138, 137, 136, 135, 134,
+ 131, 130, 129, 126, 125, 124, 123, 122, 121, 120,
+ 119, 118, 117, 116, 115, 114, 113, 112, 111, 110,
+ 109, 108, 107, 106, 105, 104, 103, 102, 101, 100,
+ 99, 98, 97, 96, 95, 94, 93, 92, 91, 90,
+ 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,
+ 79, 78, 77, 76, 73, 72, 71, 70, 38, 35,
+ 69, 66, 65, 60, 59, 58, 57, 51, 50, 45,
+ 41, 40, 38, 35, 187, 3, 187, 187, 187, 187,
+
+ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 187
+ } ;
+
+static const short int yy_chk[233] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 15, 17, 18, 21,
+ 22, 28, 27, 21, 22, 17, 27, 18, 22, 45,
+ 15, 15, 31, 31, 28, 99, 105, 190, 99, 105,
+ 185, 181, 180, 179, 177, 175, 174, 45, 188, 188,
+ 173, 188, 189, 172, 189, 189, 169, 168, 166, 165,
+ 164, 161, 160, 159, 158, 156, 155, 154, 153, 152,
+ 150, 148, 144, 142, 141, 138, 137, 135, 134, 133,
+
+ 132, 130, 129, 128, 127, 126, 125, 124, 122, 121,
+ 120, 118, 116, 115, 113, 112, 111, 110, 109, 107,
+ 103, 102, 101, 98, 97, 96, 95, 94, 93, 92,
+ 90, 89, 88, 87, 86, 85, 84, 83, 82, 81,
+ 80, 79, 78, 77, 76, 75, 74, 73, 72, 71,
+ 70, 69, 68, 67, 65, 64, 63, 62, 61, 60,
+ 59, 58, 57, 56, 55, 54, 53, 52, 51, 50,
+ 49, 48, 47, 46, 44, 42, 41, 40, 38, 35,
+ 32, 30, 29, 26, 25, 24, 23, 20, 19, 16,
+ 14, 13, 10, 5, 3, 187, 187, 187, 187, 187,
+
+ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
+ 187, 187
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+static int yy_more_flag = 0;
+static int yy_more_len = 0;
+#define yymore() (yy_more_flag = 1)
+#define YY_MORE_ADJ yy_more_len
+char *yytext;
+# line 1 "lex.l"
+# line 2 "lex.l"
+/*-
+ * 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 <unistd.h>
+
+#include "y.tab.h"
+extern int lineno;
+extern int charno;
+extern int off;
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/* Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = getc( yyin ); \
+ result = c == EOF ? 0 : 1; \
+ buf[0] = (char) c; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+YY_DECL
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+# line 43 "lex.l"
+
+
+ if ( yy_init )
+ {
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yy_start )
+ yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( yy_current_buffer )
+ yy_init_buffer( yy_current_buffer, yyin );
+ else
+ yy_current_buffer =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_load_buffer_state();
+
+ yy_init = 0;
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_more_len = 0;
+ if ( yy_more_flag )
+ {
+ yy_more_len = yyleng;
+ yy_more_flag = 0;
+ }
+ yy_cp = yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 188 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 196 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+
+do_action: /* This label is used only to access EOF actions. */
+
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_USER_ACTION
+# line 44 "lex.l"
+{ return COLORTABLE; }
+ YY_BREAK
+case 2:
+YY_USER_ACTION
+# line 45 "lex.l"
+{ return COLORTABLE; }
+ YY_BREAK
+case 3:
+YY_USER_ACTION
+# line 46 "lex.l"
+{ return COLOR; }
+ YY_BREAK
+case 4:
+YY_USER_ACTION
+# line 47 "lex.l"
+{ return COLOR; }
+ YY_BREAK
+case 5:
+YY_USER_ACTION
+# line 48 "lex.l"
+{ return BLACK; }
+ YY_BREAK
+case 6:
+YY_USER_ACTION
+# line 49 "lex.l"
+{ return RED; }
+ YY_BREAK
+case 7:
+YY_USER_ACTION
+# line 50 "lex.l"
+{ return GREEN; }
+ YY_BREAK
+case 8:
+YY_USER_ACTION
+# line 51 "lex.l"
+{ return YELLOW; }
+ YY_BREAK
+case 9:
+YY_USER_ACTION
+# line 52 "lex.l"
+{ return BLUE; }
+ YY_BREAK
+case 10:
+YY_USER_ACTION
+# line 53 "lex.l"
+{ return MAGENTA; }
+ YY_BREAK
+case 11:
+YY_USER_ACTION
+# line 54 "lex.l"
+{ return CYAN; }
+ YY_BREAK
+case 12:
+YY_USER_ACTION
+# line 55 "lex.l"
+{ return WHITE; }
+ YY_BREAK
+case 13:
+YY_USER_ACTION
+# line 56 "lex.l"
+{ return PAIR; }
+ YY_BREAK
+case 14:
+YY_USER_ACTION
+# line 57 "lex.l"
+{ return FORM; }
+ YY_BREAK
+case 15:
+YY_USER_ACTION
+# line 58 "lex.l"
+{ return AT; }
+ YY_BREAK
+case 16:
+YY_USER_ACTION
+# line 59 "lex.l"
+{ return AS; }
+ YY_BREAK
+case 17:
+YY_USER_ACTION
+# line 60 "lex.l"
+{ return HEIGHT; }
+ YY_BREAK
+case 18:
+YY_USER_ACTION
+# line 61 "lex.l"
+{ return EQUALS; }
+ YY_BREAK
+case 19:
+YY_USER_ACTION
+# line 62 "lex.l"
+{ return WIDTH; }
+ YY_BREAK
+case 20:
+YY_USER_ACTION
+# line 63 "lex.l"
+{ return STARTFIELD; }
+ YY_BREAK
+case 21:
+YY_USER_ACTION
+# line 64 "lex.l"
+{ return TEXT; }
+ YY_BREAK
+case 22:
+YY_USER_ACTION
+# line 65 "lex.l"
+{ return ATTR; }
+ YY_BREAK
+case 23:
+YY_USER_ACTION
+# line 66 "lex.l"
+{ return SELATTR; }
+ YY_BREAK
+case 24:
+YY_USER_ACTION
+# line 67 "lex.l"
+{ return LABEL; }
+ YY_BREAK
+case 25:
+YY_USER_ACTION
+# line 68 "lex.l"
+{ return DEFAULT; }
+ YY_BREAK
+case 26:
+YY_USER_ACTION
+# line 69 "lex.l"
+{ return LIMIT; }
+ YY_BREAK
+case 27:
+YY_USER_ACTION
+# line 70 "lex.l"
+{ return SELECTED; }
+ YY_BREAK
+case 28:
+YY_USER_ACTION
+# line 71 "lex.l"
+{ return OPTIONS; }
+ YY_BREAK
+case 29:
+YY_USER_ACTION
+# line 72 "lex.l"
+{ return ACTION; }
+ YY_BREAK
+case 30:
+YY_USER_ACTION
+# line 73 "lex.l"
+{ return FUNC; }
+ YY_BREAK
+case 31:
+YY_USER_ACTION
+# line 74 "lex.l"
+{ return UP; }
+ YY_BREAK
+case 32:
+YY_USER_ACTION
+# line 75 "lex.l"
+{ return DOWN; }
+ YY_BREAK
+case 33:
+YY_USER_ACTION
+# line 76 "lex.l"
+{ return LEFT; }
+ YY_BREAK
+case 34:
+YY_USER_ACTION
+# line 77 "lex.l"
+{ return RIGHT; }
+ YY_BREAK
+case 35:
+YY_USER_ACTION
+# line 78 "lex.l"
+{ return NEXT; }
+ YY_BREAK
+case 36:
+YY_USER_ACTION
+# line 79 "lex.l"
+{ return COMMA; }
+ YY_BREAK
+case 37:
+YY_USER_ACTION
+# line 80 "lex.l"
+{ return LBRACE; }
+ YY_BREAK
+case 38:
+YY_USER_ACTION
+# line 81 "lex.l"
+{ return RBRACE; }
+ YY_BREAK
+case 39:
+YY_USER_ACTION
+# line 82 "lex.l"
+{ yylval.ival = atoi(yytext); return NUMBER; }
+ YY_BREAK
+case 40:
+YY_USER_ACTION
+# line 83 "lex.l"
+{ yylval.sval = yytext; return NAME; }
+ YY_BREAK
+case 41:
+YY_USER_ACTION
+# line 84 "lex.l"
+{
+ if (yytext[yyleng-1] == '\\') {
+ yymore();
+ } else {
+ input();
+ yylval.sval = yytext+1;
+ return STRING;
+ }
+ }
+ YY_BREAK
+case 42:
+YY_USER_ACTION
+# line 93 "lex.l"
+{ lineno++; }
+ YY_BREAK
+case 43:
+YY_USER_ACTION
+# line 94 "lex.l"
+{ /* Ignored (comment) */; }
+ YY_BREAK
+case 44:
+YY_USER_ACTION
+# line 95 "lex.l"
+{ /* Ignored (white space) */; }
+ YY_BREAK
+case 45:
+YY_USER_ACTION
+# line 96 "lex.l"
+ECHO;
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = yy_cp - yytext_ptr - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between yy_current_buffer and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap() )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of yylex */
+
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+
+static int yy_get_next_buffer()
+ {
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr - 1; /* copy prev. char, too */
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( yy_current_buffer->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a singled characater, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = yy_c_buf_p - yytext_ptr;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+#else
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset = yy_c_buf_p - b->yy_ch_buf;
+
+ b->yy_buf_size *= 2;
+ b->yy_ch_buf = (char *)
+ yy_flex_realloc( (void *) b->yy_ch_buf,
+ b->yy_buf_size );
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read );
+ }
+
+ if ( yy_n_chars == 0 )
+ {
+ if ( number_to_move - YY_MORE_ADJ == 1 )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ /* yytext begins at the second character in yy_ch_buf; the first
+ * character is the one which preceded it before reading in the latest
+ * buffer; it needs to be kept around in case it's a newline, so
+ * yy_get_previous_state() will have with '^' rules active.
+ */
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[1];
+
+ return ret_val;
+ }
+
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+static yy_state_type yy_get_previous_state()
+ {
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 188 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+ }
+
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
+#else
+static yy_state_type yy_try_NUL_trans( yy_current_state )
+yy_state_type yy_current_state;
+#endif
+ {
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 188 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 187);
+
+ return yy_is_jam ? 0 : yy_current_state;
+ }
+
+
+#ifdef YY_USE_PROTOS
+static void yyunput( int c, register char *yy_bp )
+#else
+static void yyunput( c, yy_bp )
+int c;
+register char *yy_bp;
+#endif
+ {
+ register char *yy_cp = yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yy_hold_char;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest = &yy_current_buffer->yy_ch_buf[
+ yy_current_buffer->yy_buf_size + 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while ( source > yy_current_buffer->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += dest - source;
+ yy_bp += dest - source;
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ if ( yy_cp > yy_bp && yy_cp[-1] == '\n' )
+ yy_cp[-2] = '\n';
+
+ *--yy_cp = (char) c;
+
+
+ /* Note: the formal parameter *must* be called "yy_bp" for this
+ * macro to now work correctly.
+ */
+ YY_DO_BEFORE_ACTION; /* set up yytext again */
+ }
+
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+ {
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
+ /* This was really a NUL. */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ yytext_ptr = yy_c_buf_p;
+ ++yy_c_buf_p;
+
+ switch ( yy_get_next_buffer() )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap() )
+ {
+ yy_c_buf_p =
+ yytext_ptr + YY_MORE_ADJ;
+ return EOF;
+ }
+
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+ break;
+
+ case EOB_ACT_LAST_MATCH:
+#ifdef __cplusplus
+ YY_FATAL_ERROR(
+ "unexpected last match in yyinput()" );
+#else
+ YY_FATAL_ERROR(
+ "unexpected last match in input()" );
+#endif
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+ return c;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yyrestart( FILE *input_file )
+#else
+void yyrestart( input_file )
+FILE *input_file;
+#endif
+ {
+ if ( ! yy_current_buffer )
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
+
+ yy_init_buffer( yy_current_buffer, input_file );
+ yy_load_buffer_state();
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+#else
+void yy_switch_to_buffer( new_buffer )
+YY_BUFFER_STATE new_buffer;
+#endif
+ {
+ if ( yy_current_buffer == new_buffer )
+ return;
+
+ if ( yy_current_buffer )
+ {
+ /* Flush out information for old buffer. */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state( void )
+#else
+void yy_load_buffer_state()
+#endif
+ {
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+ }
+
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
+#else
+YY_BUFFER_STATE yy_create_buffer( file, size )
+FILE *file;
+int size;
+#endif
+ {
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ yy_init_buffer( b, file );
+
+ return b;
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer( YY_BUFFER_STATE b )
+#else
+void yy_delete_buffer( b )
+YY_BUFFER_STATE b;
+#endif
+ {
+ if ( b == yy_current_buffer )
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ yy_flex_free( (void *) b->yy_ch_buf );
+ yy_flex_free( (void *) b );
+ }
+
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
+#else
+void yy_init_buffer( b, file )
+YY_BUFFER_STATE b;
+FILE *file;
+#endif
+ {
+ b->yy_input_file = file;
+
+ /* We put in the '\n' and start reading from [1] so that an
+ * initial match-at-newline will be true.
+ */
+
+ b->yy_ch_buf[0] = '\n';
+ b->yy_n_chars = 1;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[1];
+
+ b->yy_is_interactive = file ? isatty( fileno(file) ) : 0;
+
+ b->yy_fill_buffer = 1;
+
+ b->yy_buffer_status = YY_BUFFER_NEW;
+ }
+
+
+#ifdef YY_USE_PROTOS
+static void yy_push_state( int new_state )
+#else
+static void yy_push_state( new_state )
+int new_state;
+#endif
+ {
+ if ( yy_start_stack_ptr >= yy_start_stack_depth )
+ {
+ int new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof( int );
+
+ if ( ! yy_start_stack )
+ yy_start_stack = (int *) yy_flex_alloc( new_size );
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size );
+
+ if ( ! yy_start_stack )
+ YY_FATAL_ERROR(
+ "out of memory expanding start-condition stack" );
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+ }
+
+
+static void yy_pop_state()
+ {
+ if ( --yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+ }
+
+
+static int yy_top_state()
+ {
+ return yy_start_stack[yy_start_stack_ptr - 1];
+ }
+
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error( const char msg[] )
+#else
+static void yy_fatal_error( msg )
+char msg[];
+#endif
+ {
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( 1 );
+ }
+
+
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n - YY_MORE_ADJ; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+
+/* Internal utility routines. */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy( char *s1, const char *s2, int n )
+#else
+static void yy_flex_strncpy( s1, s2, n )
+char *s1;
+const char *s2;
+int n;
+#endif
+ {
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+ }
+#endif
+
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc( unsigned int size )
+#else
+static void *yy_flex_alloc( size )
+unsigned int size;
+#endif
+ {
+ return (void *) malloc( size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc( void *ptr, unsigned int size )
+#else
+static void *yy_flex_realloc( ptr, size )
+void *ptr;
+unsigned int size;
+#endif
+ {
+ return (void *) realloc( ptr, size );
+ }
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free( void *ptr )
+#else
+static void yy_flex_free( ptr )
+void *ptr;
+#endif
+ {
+ free( ptr );
+ }
+# line 96 "lex.l"
diff --git a/lib/libforms/menu.c b/lib/libforms/menu.c
new file mode 100644
index 000000000000..d2beb44b32f6
--- /dev/null
+++ b/lib/libforms/menu.c
@@ -0,0 +1,58 @@
+/*
+ * 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 <forms.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+add_menu_option(struct MenuField *menu, char *option)
+{
+ char **tmp;
+ int len;
+
+ tmp = (char **)realloc(menu->options, (menu->no_options + 1) * sizeof(char**));
+ if (!tmp)
+ return (0);
+ else
+ menu->options = tmp;
+
+ len = strlen(option) + 1;
+ menu->options[menu->no_options] = (char *)malloc(len);
+ if (!menu->options[menu->no_options])
+ return (0);
+ strncpy(menu->options[menu->no_options], option, len);
+
+ return (++menu->no_options);
+}
diff --git a/lib/libforms/parser.c b/lib/libforms/parser.c
new file mode 100644
index 000000000000..c5ca0aa69f9c
--- /dev/null
+++ b/lib/libforms/parser.c
@@ -0,0 +1,1022 @@
+#ifndef lint
+static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
+#endif
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+#define yyclearin (yychar=(-1))
+#define yyerrok (yyerrflag=0)
+#define YYRECOVERING (yyerrflag!=0)
+#define YYPREFIX "yy"
+#line 2 "parser.y"
+/*-
+ * 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 <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;
+
+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;
+#line 106 "parser.y"
+typedef union {
+ int ival;
+ char *sval;
+} YYSTYPE;
+#line 120 "y.tab.c"
+#define FORM 257
+#define COLORTABLE 258
+#define COLOR 259
+#define BLACK 260
+#define RED 261
+#define GREEN 262
+#define YELLOW 263
+#define BLUE 264
+#define MAGENTA 265
+#define CYAN 266
+#define WHITE 267
+#define PAIR 268
+#define NAME 269
+#define STRING 270
+#define AT 271
+#define AS 272
+#define HEIGHT 273
+#define EQUALS 274
+#define NUMBER 275
+#define WIDTH 276
+#define STARTFIELD 277
+#define COMMA 278
+#define LBRACE 279
+#define RBRACE 280
+#define TEXT 281
+#define ATTR 282
+#define SELATTR 283
+#define DEFAULT 284
+#define LABEL 285
+#define LIMIT 286
+#define SELECTED 287
+#define OPTIONS 288
+#define ACTION 289
+#define FUNC 290
+#define LINK 291
+#define UP 292
+#define DOWN 293
+#define LEFT 294
+#define RIGHT 295
+#define NEXT 296
+#define DEF 297
+#define YYERRCODE 256
+short yylhs[] = { -1,
+ 0, 0, 0, 0, 5, 4, 6, 6, 8, 7,
+ 1, 1, 1, 1, 1, 1, 1, 1, 9, 11,
+ 3, 12, 15, 15, 16, 16, 17, 17, 18, 18,
+ 21, 23, 19, 25, 2, 20, 26, 20, 20, 24,
+ 22, 22, 30, 30, 30, 30, 30, 29, 29, 29,
+ 29, 31, 32, 35, 35, 36, 36, 33, 37, 37,
+ 38, 34, 13, 13, 14, 14, 27, 27, 28, 28,
+ 10,
+};
+short yylen[] = { 2,
+ 0, 2, 2, 2, 0, 6, 0, 2, 0, 6,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+ 9, 6, 0, 3, 0, 3, 0, 3, 0, 2,
+ 0, 0, 7, 0, 3, 0, 0, 4, 1, 7,
+ 0, 3, 3, 3, 3, 3, 3, 1, 1, 1,
+ 1, 3, 1, 4, 4, 0, 3, 6, 1, 3,
+ 1, 6, 0, 3, 0, 3, 0, 3, 0, 3,
+ 3,
+};
+short yydefred[] = { 1,
+ 0, 0, 0, 34, 2, 3, 4, 19, 5, 0,
+ 0, 0, 0, 35, 0, 7, 0, 0, 0, 20,
+ 0, 0, 0, 0, 0, 0, 0, 6, 8, 64,
+ 0, 0, 0, 71, 0, 0, 66, 0, 0, 0,
+ 0, 0, 11, 12, 13, 14, 15, 16, 17, 18,
+ 9, 68, 0, 0, 0, 0, 0, 0, 0, 48,
+ 49, 50, 51, 53, 21, 0, 0, 70, 0, 0,
+ 0, 0, 0, 40, 0, 0, 0, 52, 0, 0,
+ 0, 0, 0, 0, 0, 10, 0, 55, 54, 0,
+ 0, 24, 0, 0, 29, 0, 0, 0, 26, 0,
+ 0, 57, 61, 0, 59, 62, 28, 31, 30, 0,
+ 0, 60, 0, 0, 39, 37, 0, 0, 32, 38,
+ 41, 0, 0, 0, 0, 0, 0, 0, 42, 0,
+ 0, 0, 0, 0, 43, 44, 45, 46, 47,
+};
+short yydgoto[] = { 1,
+ 51, 5, 6, 7, 12, 21, 29, 67, 11, 20,
+ 26, 41, 18, 24, 76, 85, 95, 101, 109, 114,
+ 111, 122, 121, 14, 10, 118, 33, 40, 59, 129,
+ 60, 61, 62, 63, 64, 88, 104, 105,
+};
+short yysindex[] = { 0,
+ -252, -261, -240, 0, 0, 0, 0, 0, 0, -248,
+ -234, -237, -225, 0, -236, 0, -219, -214, -212, 0,
+ -259, -216, -205, -196, -204, -192, -186, 0, 0, 0,
+ -185, -183, -194, 0, -225, -187, 0, -182, -180, -224,
+ -188, -214, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, -179, -177, -176, -175, -174, -173, -178, 0,
+ 0, 0, 0, 0, 0, -172, -171, 0, -167, -166,
+ -164, -165, -162, 0, -163, -149, -187, 0, -191, -191,
+ -170, -169, -157, -161, -168, 0, -159, 0, 0, -158,
+ -155, 0, -152, -154, 0, -153, -147, -145, 0, -150,
+ -143, 0, 0, -151, 0, 0, 0, 0, 0, -147,
+ -148, 0, -263, -142, 0, 0, -236, -146, 0, 0,
+ 0, -141, -211, -144, -139, -138, -136, -135, 0, -137,
+ -129, -128, -127, -126, 0, 0, 0, 0, 0,
+};
+short yyrindex[] = { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, -249, 0, 0, 0, 0, -238, 0, 0,
+ 0, 0, 0, -231, 0, 0, 0, 0, 0, 0,
+ 0, 0, -217, 0, -258, 0, 0, 0, 0, 0,
+ 0, -257, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -254, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -266, 0, 0, -134, -134,
+ 0, 0, 0, 0, -267, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ -133, 0, 0, -132, 0, 0, 0, 0, 0, 0,
+ -122, 0, -249, 0, 0, 0, 0, 0, 0, 0,
+ 0, -239, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+short yygindex[] = { 0,
+ 51, 0, 0, 0, 0, 0, 0, 0, 0, 16,
+ 0, 0, 109, 103, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 39, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 71, 0, 42,
+};
+#define YYTABLESIZE 152
+short yytable[] = { 63,
+ 65, 27, 25, 23, 2, 116, 3, 8, 27, 17,
+ 63, 65, 27, 25, 23, 25, 4, 63, 63, 65,
+ 28, 63, 65, 63, 65, 23, 63, 23, 9, 33,
+ 13, 63, 63, 63, 63, 63, 15, 63, 19, 63,
+ 33, 16, 65, 65, 65, 65, 65, 17, 65, 67,
+ 65, 67, 67, 67, 22, 67, 54, 67, 30, 55,
+ 56, 23, 57, 69, 58, 25, 69, 69, 31, 69,
+ 34, 69, 43, 44, 45, 46, 47, 48, 49, 50,
+ 124, 125, 126, 127, 128, 32, 35, 36, 39, 37,
+ 38, 65, 52, 53, 87, 68, 69, 70, 71, 72,
+ 73, 74, 78, 79, 75, 80, 77, 82, 84, 81,
+ 83, 92, 93, 94, 96, 97, 99, 90, 98, 100,
+ 91, 102, 103, 106, 107, 108, 110, 86, 117, 130,
+ 113, 135, 119, 120, 131, 132, 123, 133, 134, 136,
+ 137, 138, 139, 42, 66, 56, 22, 58, 36, 115,
+ 89, 112,
+};
+short yycheck[] = { 258,
+ 258, 269, 269, 258, 257, 269, 259, 269, 268, 273,
+ 269, 269, 280, 280, 269, 282, 269, 276, 277, 277,
+ 280, 280, 280, 282, 282, 280, 276, 282, 269, 269,
+ 279, 281, 282, 283, 284, 285, 271, 287, 275, 289,
+ 280, 279, 281, 282, 283, 284, 285, 273, 287, 281,
+ 289, 283, 284, 285, 274, 287, 281, 289, 275, 284,
+ 285, 276, 287, 281, 289, 278, 284, 285, 274, 287,
+ 275, 289, 260, 261, 262, 263, 264, 265, 266, 267,
+ 292, 293, 294, 295, 296, 282, 279, 274, 283, 275,
+ 274, 280, 275, 274, 286, 275, 274, 274, 274, 274,
+ 274, 280, 270, 270, 277, 270, 278, 270, 258, 275,
+ 274, 269, 274, 282, 274, 274, 269, 288, 274, 274,
+ 290, 275, 270, 269, 275, 269, 278, 77, 271, 274,
+ 279, 269, 117, 280, 274, 274, 278, 274, 274, 269,
+ 269, 269, 269, 35, 42, 280, 280, 280, 271, 111,
+ 80, 110,
+};
+#define YYFINAL 1
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+#define YYMAXTOKEN 297
+#if YYDEBUG
+char *yyname[] = {
+"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"FORM","COLORTABLE","COLOR",
+"BLACK","RED","GREEN","YELLOW","BLUE","MAGENTA","CYAN","WHITE","PAIR","NAME",
+"STRING","AT","AS","HEIGHT","EQUALS","NUMBER","WIDTH","STARTFIELD","COMMA",
+"LBRACE","RBRACE","TEXT","ATTR","SELATTR","DEFAULT","LABEL","LIMIT","SELECTED",
+"OPTIONS","ACTION","FUNC","LINK","UP","DOWN","LEFT","RIGHT","NEXT","DEF",
+};
+char *yyrule[] = {
+"$accept : spec",
+"spec :",
+"spec : spec fields",
+"spec : spec forms",
+"spec : spec colours",
+"$$1 :",
+"colours : COLOR NAME $$1 LBRACE color_pairs RBRACE",
+"color_pairs :",
+"color_pairs : color_pairs pair",
+"$$2 :",
+"pair : PAIR EQUALS a_color $$2 COMMA a_color",
+"a_color : BLACK",
+"a_color : RED",
+"a_color : GREEN",
+"a_color : YELLOW",
+"a_color : BLUE",
+"a_color : MAGENTA",
+"a_color : CYAN",
+"a_color : WHITE",
+"$$3 :",
+"$$4 :",
+"forms : FORM NAME $$3 AT coord $$4 LBRACE formspec RBRACE",
+"formspec : height width startfield colortable formattr fieldlocs",
+"startfield :",
+"startfield : STARTFIELD EQUALS NAME",
+"colortable :",
+"colortable : COLORTABLE EQUALS NAME",
+"formattr :",
+"formattr : ATTR EQUALS NUMBER",
+"fieldlocs :",
+"fieldlocs : fieldlocs field_at",
+"$$5 :",
+"$$6 :",
+"field_at : NAME $$5 field_def AT coord $$6 links",
+"$$7 :",
+"fields : NAME $$7 field_spec",
+"field_def :",
+"$$8 :",
+"field_def : LBRACE NAME $$8 RBRACE",
+"field_def : field_spec",
+"field_spec : LBRACE height width attr selattr type RBRACE",
+"links :",
+"links : links COMMA conns",
+"conns : UP EQUALS NAME",
+"conns : DOWN EQUALS NAME",
+"conns : LEFT EQUALS NAME",
+"conns : RIGHT EQUALS NAME",
+"conns : NEXT EQUALS NAME",
+"type : textfield",
+"type : inputfield",
+"type : menufield",
+"type : actionfield",
+"textfield : TEXT EQUALS STRING",
+"inputfield : inputspec",
+"inputspec : LABEL EQUALS STRING limit",
+"inputspec : DEFAULT EQUALS STRING limit",
+"limit :",
+"limit : LIMIT EQUALS NUMBER",
+"menufield : SELECTED EQUALS NUMBER OPTIONS EQUALS menuoptions",
+"menuoptions : menuoption",
+"menuoptions : menuoptions COMMA menuoption",
+"menuoption : STRING",
+"actionfield : ACTION EQUALS STRING FUNC EQUALS NAME",
+"height :",
+"height : HEIGHT EQUALS NUMBER",
+"width :",
+"width : WIDTH EQUALS NUMBER",
+"attr :",
+"attr : ATTR EQUALS NUMBER",
+"selattr :",
+"selattr : SELATTR EQUALS NUMBER",
+"coord : NUMBER COMMA NUMBER",
+};
+#endif
+#ifdef YYSTACKSIZE
+#undef YYMAXDEPTH
+#define YYMAXDEPTH YYSTACKSIZE
+#else
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
+#else
+#define YYSTACKSIZE 500
+#define YYMAXDEPTH 500
+#endif
+#endif
+int yydebug;
+int yynerrs;
+int yyerrflag;
+int yychar;
+short *yyssp;
+YYSTYPE *yyvsp;
+YYSTYPE yyval;
+YYSTYPE yylval;
+short yyss[YYSTACKSIZE];
+YYSTYPE yyvs[YYSTACKSIZE];
+#define yystacksize YYSTACKSIZE
+#line 434 "parser.y"
+
+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);
+}
+
+/* Calculate a default height for a field */
+
+void
+calc_field_height(struct Field *field, char *string)
+{
+
+ int len;
+
+ len = strlen(string);
+
+ if (!field->width) {
+ /*
+ * This is a failsafe, this routine shouldn't be called
+ * with a width of 0, the width should be determined
+ * first.
+ */
+ field->height = 1;
+ return;
+ }
+
+ if (len < field->width) {
+ field->height = 1;
+ return;
+ } else
+ field->height = len / field->width;
+
+ if ((field->height*field->width) < len)
+ field->height++;
+
+ return;
+}
+
+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(defname, FT_FIELD_DEF, field);
+ width=0;
+ height = 0;
+ attr=0;
+ selattr=0;
+ limit=0;
+}
+#line 531 "y.tab.c"
+#define YYABORT goto yyabort
+#define YYREJECT goto yyabort
+#define YYACCEPT goto yyaccept
+#define YYERROR goto yyerrlab
+int
+yyparse()
+{
+ register int yym, yyn, yystate;
+#if YYDEBUG
+ register char *yys;
+ extern char *getenv();
+
+ if (yys = getenv("YYDEBUG"))
+ {
+ yyn = *yys;
+ if (yyn >= '0' && yyn <= '9')
+ yydebug = yyn - '0';
+ }
+#endif
+
+ yynerrs = 0;
+ yyerrflag = 0;
+ yychar = (-1);
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+ *yyssp = yystate = 0;
+
+yyloop:
+ if (yyn = yydefred[yystate]) goto yyreduce;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ }
+ if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, shifting to state %d\n",
+ YYPREFIX, yystate, yytable[yyn]);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ yychar = (-1);
+ if (yyerrflag > 0) --yyerrflag;
+ goto yyloop;
+ }
+ if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+ yyn = yytable[yyn];
+ goto yyreduce;
+ }
+ if (yyerrflag) goto yyinrecovery;
+#ifdef lint
+ goto yynewerror;
+#endif
+yynewerror:
+ yyerror("syntax error");
+#ifdef lint
+ goto yyerrlab;
+#endif
+yyerrlab:
+ ++yynerrs;
+yyinrecovery:
+ if (yyerrflag < 3)
+ {
+ yyerrflag = 3;
+ for (;;)
+ {
+ if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ goto yyloop;
+ }
+ else
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: error recovery discarding state %d\n",
+ YYPREFIX, *yyssp);
+#endif
+ if (yyssp <= yyss) goto yyabort;
+ --yyssp;
+ --yyvsp;
+ }
+ }
+ }
+ else
+ {
+ if (yychar == 0) goto yyabort;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ yychar = (-1);
+ goto yyloop;
+ }
+yyreduce:
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+ YYPREFIX, yystate, yyn, yyrule[yyn]);
+#endif
+ yym = yylen[yyn];
+ yyval = yyvsp[1-yym];
+ switch (yyn)
+ {
+case 5:
+#line 166 "parser.y"
+{
+ 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(yyvsp[0].sval);
+ }
+break;
+case 6:
+#line 175 "parser.y"
+{
+ color_table->pairs = pair_list;
+ cur_pair = 0;
+ form_bind_tuple(color_table->tablename, FT_COLTAB, color_table);
+ }
+break;
+case 9:
+#line 187 "parser.y"
+{
+ pair = malloc(sizeof (struct pair_node));
+ if (!pair) {
+ fprintf(stderr, "Couldn't allocate memory for a color pair\n");
+ exit(1);
+ }
+ pair->foreground = cpstr(yyvsp[0].sval);
+ }
+break;
+case 10:
+#line 196 "parser.y"
+{
+ pair->background = cpstr(yyvsp[0].sval);
+ if (!cur_pair) {
+ pair_list = pair;
+ cur_pair = pair;
+ } else {
+ cur_pair->next = pair;
+ cur_pair = pair;
+ }
+ }
+break;
+case 11:
+#line 209 "parser.y"
+{ yyval.sval = "COLOR_BLACK"; }
+break;
+case 12:
+#line 211 "parser.y"
+{ yyval.sval = "COLOR_RED"; }
+break;
+case 13:
+#line 213 "parser.y"
+{ yyval.sval = "COLOR_GREEN"; }
+break;
+case 14:
+#line 215 "parser.y"
+{ yyval.sval = "COLOR_YELLOW"; }
+break;
+case 15:
+#line 217 "parser.y"
+{ yyval.sval = "COLOR_BLUE"; }
+break;
+case 16:
+#line 219 "parser.y"
+{ yyval.sval = "COLOR_MAGENTA"; }
+break;
+case 17:
+#line 221 "parser.y"
+{ yyval.sval = "COLOR_CYAN"; }
+break;
+case 18:
+#line 223 "parser.y"
+{ yyval.sval = "COLOR_WHITE"; }
+break;
+case 19:
+#line 227 "parser.y"
+{ formname = cpstr(yyvsp[0].sval); }
+break;
+case 20:
+#line 229 "parser.y"
+{
+ form = malloc(sizeof (struct Form));
+ if (!form) {
+ fprintf(stderr,"Failed to allocate memory for form\n");
+ exit(1);
+ }
+ form->y = y;
+ form->x = x;
+ }
+break;
+case 21:
+#line 239 "parser.y"
+{
+ form->startfield = startname;
+ form->colortable = colortable;
+ form->height = height;
+ form->width = width;
+ form->attr = formattr;
+ form->fieldlist = field_inst_list;
+ field_inst_list = 0;
+ form_bind_tuple(formname, FT_FORM, form);
+ }
+break;
+case 23:
+#line 255 "parser.y"
+{ startname = 0;
+ printf("Warning: No start field specified for form %s\n", formname);
+ }
+break;
+case 24:
+#line 259 "parser.y"
+{ startname = cpstr(yyvsp[0].sval); }
+break;
+case 25:
+#line 263 "parser.y"
+{ colortable = 0; }
+break;
+case 26:
+#line 265 "parser.y"
+{ colortable = cpstr(yyvsp[0].sval); }
+break;
+case 27:
+#line 269 "parser.y"
+{ formattr = 0; }
+break;
+case 28:
+#line 271 "parser.y"
+{ formattr = yyvsp[0].ival; }
+break;
+case 31:
+#line 279 "parser.y"
+{ fieldname = cpstr(yyvsp[0].sval); }
+break;
+case 32:
+#line 281 "parser.y"
+{
+ 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;
+ }
+break;
+case 33:
+#line 295 "parser.y"
+{
+ field->fup = up;
+ field->fdown = down;
+ field->fleft = left;
+ field->fright = right;
+ field->fnext = next;
+ if (!field_inst_list)
+ field_inst_list = field;
+ up = 0;
+ down = 0;
+ left = 0;
+ right = 0;
+ next = 0;
+ if (!cur_field)
+ cur_field = field;
+ else {
+ cur_field->next = field;
+ cur_field = field;
+ }
+ form_bind_tuple(fieldname, FT_FIELD_INST, field);
+ }
+break;
+case 34:
+#line 319 "parser.y"
+{ defname = cpstr(yyvsp[0].sval); }
+break;
+case 35:
+#line 321 "parser.y"
+{ define_field(defname); }
+break;
+case 36:
+#line 325 "parser.y"
+{ defname = 0; }
+break;
+case 37:
+#line 327 "parser.y"
+{ defname = cpstr(yyvsp[0].sval); }
+break;
+case 39:
+#line 330 "parser.y"
+{ defname = fieldname; define_field(defname); }
+break;
+case 43:
+#line 341 "parser.y"
+{ up = cpstr(yyvsp[0].sval); }
+break;
+case 44:
+#line 343 "parser.y"
+{ down = cpstr(yyvsp[0].sval); }
+break;
+case 45:
+#line 345 "parser.y"
+{ left = cpstr(yyvsp[0].sval); }
+break;
+case 46:
+#line 347 "parser.y"
+{ right = cpstr(yyvsp[0].sval); }
+break;
+case 47:
+#line 349 "parser.y"
+{ next = cpstr(yyvsp[0].sval); }
+break;
+case 52:
+#line 359 "parser.y"
+{ type = FF_TEXT; text = cpstr(yyvsp[0].sval); }
+break;
+case 53:
+#line 363 "parser.y"
+{ type = FF_INPUT; }
+break;
+case 54:
+#line 367 "parser.y"
+{ lbl_flag = 1; label = cpstr(yyvsp[-1].sval); }
+break;
+case 55:
+#line 369 "parser.y"
+{ lbl_flag = 0; label = cpstr(yyvsp[-1].sval); }
+break;
+case 57:
+#line 374 "parser.y"
+{ limit = yyvsp[0].ival; }
+break;
+case 58:
+#line 377 "parser.y"
+{ type = FF_MENU; selected = yyvsp[-3].ival; }
+break;
+case 61:
+#line 385 "parser.y"
+{
+ menu = malloc(sizeof(struct MenuList));
+ if (!menu) {
+ err(1, "Couldn't allocate memory for menu option\n");
+ }
+ menu->option = cpstr(yyvsp[0].sval);
+ if (!cur_menu) {
+ menu_list = menu;
+ cur_menu = menu;
+ } else {
+ cur_menu->next = menu;
+ cur_menu = menu;
+ }
+ }
+break;
+case 62:
+#line 402 "parser.y"
+{ type = FF_ACTION; text = cpstr(yyvsp[-3].sval); function = cpstr(yyvsp[0].sval); }
+break;
+case 63:
+#line 406 "parser.y"
+{ height = 0; }
+break;
+case 64:
+#line 408 "parser.y"
+{ height = yyvsp[0].ival; }
+break;
+case 65:
+#line 412 "parser.y"
+{ width = 0; }
+break;
+case 66:
+#line 414 "parser.y"
+{ width = yyvsp[0].ival; }
+break;
+case 67:
+#line 418 "parser.y"
+{ attr = 0; }
+break;
+case 68:
+#line 420 "parser.y"
+{ attr = yyvsp[0].ival; }
+break;
+case 69:
+#line 424 "parser.y"
+{ selattr = 0; }
+break;
+case 70:
+#line 426 "parser.y"
+{ selattr = yyvsp[0].ival; }
+break;
+case 71:
+#line 430 "parser.y"
+{ y = yyvsp[-2].ival; x = yyvsp[0].ival; }
+break;
+#line 967 "y.tab.c"
+ }
+ yyssp -= yym;
+ yystate = *yyssp;
+ yyvsp -= yym;
+ yym = yylhs[yyn];
+ if (yystate == 0 && yym == 0)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
+#endif
+ yystate = YYFINAL;
+ *++yyssp = YYFINAL;
+ *++yyvsp = yyval;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, YYFINAL, yychar, yys);
+ }
+#endif
+ }
+ if (yychar == 0) goto yyaccept;
+ goto yyloop;
+ }
+ if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+ yystate = yytable[yyn];
+ else
+ yystate = yydgoto[yym];
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *yyssp, yystate);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate;
+ *++yyvsp = yyval;
+ goto yyloop;
+yyoverflow:
+ yyerror("yacc stack overflow");
+yyabort:
+ return (1);
+yyaccept:
+ return (0);
+}
diff --git a/lib/libforms/parser.y b/lib/libforms/parser.y
new file mode 100644
index 000000000000..93e60085553c
--- /dev/null
+++ b/lib/libforms/parser.y
@@ -0,0 +1,567 @@
+%{
+/*-
+ * 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 <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;
+
+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(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->y = y;
+ form->x = x;
+ }
+ LBRACE formspec RBRACE
+ {
+ form->startfield = startname;
+ form->colortable = colortable;
+ form->height = height;
+ form->width = width;
+ form->attr = formattr;
+ form->fieldlist = field_inst_list;
+ field_inst_list = 0;
+ form_bind_tuple(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;
+ if (!field_inst_list)
+ field_inst_list = field;
+ up = 0;
+ down = 0;
+ left = 0;
+ right = 0;
+ next = 0;
+ if (!cur_field)
+ cur_field = field;
+ else {
+ cur_field->next = field;
+ cur_field = field;
+ }
+ form_bind_tuple(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);
+}
+
+/* Calculate a default height for a field */
+
+void
+calc_field_height(struct Field *field, char *string)
+{
+
+ int len;
+
+ len = strlen(string);
+
+ if (!field->width) {
+ /*
+ * This is a failsafe, this routine shouldn't be called
+ * with a width of 0, the width should be determined
+ * first.
+ */
+ field->height = 1;
+ return;
+ }
+
+ if (len < field->width) {
+ field->height = 1;
+ return;
+ } else
+ field->height = len / field->width;
+
+ if ((field->height*field->width) < len)
+ field->height++;
+
+ return;
+}
+
+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(defname, FT_FIELD_DEF, field);
+ width=0;
+ height = 0;
+ attr=0;
+ selattr=0;
+ limit=0;
+}
diff --git a/lib/libforms/y.tab.h b/lib/libforms/y.tab.h
new file mode 100644
index 000000000000..f3d9afa281dc
--- /dev/null
+++ b/lib/libforms/y.tab.h
@@ -0,0 +1,46 @@
+#define FORM 257
+#define COLORTABLE 258
+#define COLOR 259
+#define BLACK 260
+#define RED 261
+#define GREEN 262
+#define YELLOW 263
+#define BLUE 264
+#define MAGENTA 265
+#define CYAN 266
+#define WHITE 267
+#define PAIR 268
+#define NAME 269
+#define STRING 270
+#define AT 271
+#define AS 272
+#define HEIGHT 273
+#define EQUALS 274
+#define NUMBER 275
+#define WIDTH 276
+#define STARTFIELD 277
+#define COMMA 278
+#define LBRACE 279
+#define RBRACE 280
+#define TEXT 281
+#define ATTR 282
+#define SELATTR 283
+#define DEFAULT 284
+#define LABEL 285
+#define LIMIT 286
+#define SELECTED 287
+#define OPTIONS 288
+#define ACTION 289
+#define FUNC 290
+#define LINK 291
+#define UP 292
+#define DOWN 293
+#define LEFT 294
+#define RIGHT 295
+#define NEXT 296
+#define DEF 297
+typedef union {
+ int ival;
+ char *sval;
+} YYSTYPE;
+extern YYSTYPE yylval;