mirror of
https://github.com/opnsense/src.git
synced 2026-06-10 17:22:46 -04:00
Completely rewrite libforms so everything is done at runtime rather
than at compile time. Should have same functionality as old libforms but with new mechanism. Lots of new features that use the new mechanism are still to be added.
This commit is contained in:
parent
1214e6da66
commit
be7d950dc8
17 changed files with 4882 additions and 502 deletions
|
|
@ -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 || \
|
||||
|
|
|
|||
12
lib/libforms/Makefile.orig
Normal file
12
lib/libforms/Makefile.orig
Normal file
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
if (res == F_DONE) {
|
||||
while (form->status == FS_RUNNING) {
|
||||
do_field(form);
|
||||
wrefresh(form->window);
|
||||
}
|
||||
|
||||
wclear(form->window);
|
||||
wrefresh(form->window);
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
520
lib/libforms/fields.c
Normal file
520
lib/libforms/fields.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
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);
|
||||
}
|
||||
if (!(fd = fopen(filename, "r"))) {
|
||||
warn("Couldn't open forms file %s", filename);
|
||||
return (FS_ERROR);
|
||||
}
|
||||
cbreak();
|
||||
noecho();
|
||||
|
||||
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;
|
||||
|
||||
tuple = form_get_tuple(formname, FT_FORM);
|
||||
|
||||
if (!tuple) {
|
||||
warnx("No such form");
|
||||
return (0);
|
||||
}
|
||||
|
||||
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);
|
||||
warnx("Couldn't open window, closing form");
|
||||
return (0);
|
||||
}
|
||||
form->no_fields = 0;
|
||||
|
||||
keypad(form->window, TRUE);
|
||||
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;
|
||||
|
||||
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->prev_field = form->current_field;
|
||||
|
||||
/* Initialise the field instances */
|
||||
|
||||
for (field = form->fieldlist; field; field = field->next) {
|
||||
init_field(field);
|
||||
}
|
||||
form->current_field = form->start_field;
|
||||
show_form(form);
|
||||
return (OK);
|
||||
}
|
||||
|
||||
void
|
||||
endfrm(struct form *form)
|
||||
{
|
||||
form->status = FS_RUNNING;
|
||||
|
||||
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];
|
||||
}
|
||||
return (form);
|
||||
}
|
||||
|
||||
int
|
||||
update_form(struct form *form)
|
||||
form_bind_tuple(char *name, TupleType type, void *addr)
|
||||
{
|
||||
show_form(form);
|
||||
struct Tuple *tuple;
|
||||
|
||||
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);
|
||||
tuple = malloc(sizeof (struct Tuple));
|
||||
if (!tuple) {
|
||||
warn("Couldn't allocate memory for new tuple");
|
||||
return (FS_ERROR);
|
||||
}
|
||||
wattrset(form->window, 0);
|
||||
|
||||
return (done);
|
||||
tuple->name = name;
|
||||
tuple->type = type;
|
||||
tuple->addr = addr;
|
||||
tuple->next = 0;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
show_form(struct form *form)
|
||||
struct Tuple *
|
||||
form_get_tuple(const char *name, TupleType type)
|
||||
{
|
||||
int i;
|
||||
int y, x;
|
||||
return (form_next_tuple(name, type, fbind_first));
|
||||
}
|
||||
|
||||
struct Tuple *
|
||||
form_next_tuple(const char *name, TupleType type, struct Tuple *tuple)
|
||||
{
|
||||
for (; tuple; tuple = tuple->next) {
|
||||
if (type != FT_ANY)
|
||||
if (tuple->type != type)
|
||||
continue;
|
||||
if (name)
|
||||
if (strcmp(name, tuple->name))
|
||||
continue;
|
||||
return (tuple);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
form_show(const char *formname)
|
||||
{
|
||||
struct Tuple *tuple;
|
||||
struct Form *form;
|
||||
struct Field *field;
|
||||
int x, y;
|
||||
|
||||
tuple = form_get_tuple(formname, FT_FORM);
|
||||
if (!tuple)
|
||||
return (FS_NOBIND);
|
||||
|
||||
form = tuple->addr;
|
||||
|
||||
/* Clear form */
|
||||
wattrset(form->window, form->attr);
|
||||
for (y = 0; y < form->height; y++)
|
||||
for (x = 0; x < form->width; x++)
|
||||
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;
|
||||
}
|
||||
for (field = form->fieldlist; field; field = field->next) {
|
||||
display_field(form->window, field);
|
||||
}
|
||||
wattrset(form->window, 0);
|
||||
wrefresh(form->window);
|
||||
|
||||
return (FS_OK);
|
||||
}
|
||||
|
||||
static void
|
||||
disp_text(struct form *form, int index)
|
||||
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[index];
|
||||
/* XXX -- check for keymappings here --- not yet done */
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
debug_dump_bindings()
|
||||
{
|
||||
done = F_DONE;
|
||||
struct Tuple *binds;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cancel_form(void)
|
||||
void debug_dump_form(struct Form *form)
|
||||
{
|
||||
done = F_CANCEL;
|
||||
struct Field *field;
|
||||
|
||||
field = form->fieldlist;
|
||||
|
||||
for ( ; field; field = field->next) {
|
||||
printf("%s, %x, next = %x\n", field->defname, (int)field, (int)field->next);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
502
lib/libforms/forms.c.orig
Normal file
502
lib/libforms/forms.c.orig
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
126
lib/libforms/forms.h.orig
Normal file
126
lib/libforms/forms.h.orig
Normal file
|
|
@ -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 *);
|
||||
|
|
@ -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
|
||||
|
|
|
|||
38
lib/libforms/internal.h.orig
Normal file
38
lib/libforms/internal.h.orig
Normal file
|
|
@ -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);
|
||||
1606
lib/libforms/lex.c
Normal file
1606
lib/libforms/lex.c
Normal file
File diff suppressed because it is too large
Load diff
58
lib/libforms/menu.c
Normal file
58
lib/libforms/menu.c
Normal file
|
|
@ -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);
|
||||
}
|
||||
1022
lib/libforms/parser.c
Normal file
1022
lib/libforms/parser.c
Normal file
File diff suppressed because it is too large
Load diff
567
lib/libforms/parser.y
Normal file
567
lib/libforms/parser.y
Normal file
|
|
@ -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;
|
||||
}
|
||||
46
lib/libforms/y.tab.h
Normal file
46
lib/libforms/y.tab.h
Normal file
|
|
@ -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;
|
||||
Loading…
Reference in a new issue