Remove libforms, it was never used.

This commit is contained in:
Jordan K. Hubbard 1996-06-19 21:19:37 +00:00
parent eeb1baccd6
commit 40582d7142
13 changed files with 0 additions and 2903 deletions

View File

@ -1,17 +0,0 @@
LIB = forms
SHLIB_MAJOR= 3
SHLIB_MINOR= 0
SRCS = debug.c bindings.c parser.y lex.l forms.c objects.c ncurses.c
CFLAGS += -I. -I${.CURDIR} -DHASH_STATS #-g -DDEBUG -Wall -ansi -pedantic -Dlint
LDFLAGS += -ll
CLEANFILES+= lex.c parser.c y.tab.h
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>

View File

@ -1,131 +0,0 @@
/*
* 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 <err.h>
#include <forms.h>
#include <strhash.h>
#include <stdlib.h>
#include "internal.h"
int
bind_tuple(hash_table *htable, char *name,
TupleType type, void(*fn)(void*))
{
struct Tuple *tuple;
/* First check to see if we've been bound in already */
if (hash_search(htable, tuple->name, NULL, NULL)) {
warn("Duplicate tuple name, %s, skipping", name);
return (ST_ERROR);
}
tuple = malloc(sizeof (struct Tuple));
if (!tuple) {
warn("Couldn't allocate memory for new tuple");
return (ST_ERROR);
}
tuple->name = name;
tuple->type = type;
tuple->addr = fn;
/* Insert it */
hash_search(htable, tuple->name, tuple, NULL);
#ifdef DEBUG
debug_dump_table(htable);
#endif
return (0);
}
int
tuple_match_any(char *key, void *data, void *arg)
{
TUPLE *tuple = (TUPLE *)data;
TupleType *type = (TupleType *)arg;
if (tuple->type != *type) {
arg = 0;
return (1);
} else {
arg = data;
return (0);
}
}
/*
* Search a single hash table for a tuple.
*/
TUPLE *
get_tuple(hash_table *table, char *key, TupleType type)
{
void *arg = &type;
/*
* If a key is specified then search for that key,
* otherwise, search the whole table for the first
* tuple of the required type.
*/
if (key)
return(hash_search(table, key, NULL, NULL));
else {
hash_traverse(table, &tuple_match_any, arg);
return (arg);
}
}
/*
* Search all tables currently in scope.
*/
TUPLE *
tuple_search(OBJECT *obj, char *key, TupleType type)
{
TUPLE *tuple;
while (obj) {
tuple = get_tuple(obj->bind, key, type);
if (tuple)
return (tuple);
else
obj = obj->parent;
}
return (get_tuple(root_table, key, type));
}

View File

@ -1,21 +0,0 @@
#ifdef DEBUG
#include <forms.h>
int
debug_dump_bindings(char *key, void *data, void *arg)
{
TUPLE *tuple = (TUPLE *)data;
printf("%s, %d, %x\n", tuple->name, tuple->type, (int)tuple->addr);
return (1);
}
void
debug_dump_table(hash_table *htable)
{
printf("Dumping table at address %x\n", htable);
hash_traverse(htable, debug_dump_bindings, NULL);
printf("------------------------------\n");
}
#endif

View File

@ -1,17 +0,0 @@
PROG = example
NOMAN = yet
SRCS = example.c
CFLAGS = -static #-g
.if exists(${.CURDIR}/../obj)
FORMDIR=${.CURDIR}/../obj
.else
FORMDIR=${.CURDIR}/..
.endif
LDADD = -L${FORMDIR} -lforms -lncurses -lmytinfo -ll
DPADD = ${LIBFORMS} ${LIBNCURSES}
.include <bsd.prog.mk>

View File

@ -1,60 +0,0 @@
/*
* 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 <stdio.h>
#include <strhash.h>
#include <ncurses.h>
#include "../forms.h"
void UserRoutine(OBJECT *);
main()
{
struct Tuple *tuple;
struct Form *form1, *form2;
int res;
if (load_objects("example.frm") == ST_ERROR)
exit(0);
bind_tuple(root_table, "User_Routine", TT_FUNC, &UserRoutine);
start_object("adduser");
}
void
UserRoutine(OBJECT *obj)
{
/* Just draw a box and return */
exit (1);
}

View File

@ -1,162 +0,0 @@
# An example form file for an adduser command
!Forms Version name
Display screen1 {
Height 1000
Width 1000
Type Ncurses {
# libdialog compatible color pairs
ColorPairs {
01 Cyan Blue
02 Black Black
03 Black White
04 Yellow White
05 White White
06 White Blue
07 Black White
08 White Blue
09 Red White
10 Yellow Blue
11 Black White
12 Black White
13 Black White
14 Black White
15 Yellow White
16 White White
17 Yellow White
18 Black White
19 White White
20 Black White
21 White Blue
22 Yellow White
23 Yellow Blue
24 Red White
25 Red Blue
26 Black White
27 White White
28 Green White
29 Green White
}
}
#
# The AttrTable assosciates attribute strings with numeric id's.
# It's up to the device dependant code to decide how to interprate an
# attribute id. For ncurses the id is treated as a color pair number.
# For other devices they'd likely be an index to some device specific
# structure declared above.
#
AttrTable {
screen 01
shadow 02
dialog 03
title 04
border 05
button_active 06
button_inactive 07
button_key_active 08
button_key_inactive 09
button_label_active 10
button_label_inactive 11
inputbox 12
inputbox_border 13
searchbox 14
searchbox_title 15
searchbox_border 16
position_indicator 17
menubox 18
menubox_border 19
item 20
item_selected 21
tag 22
tag_selected 23
tag_key 24
tag_key_selected 25
check 26
check_selected 27
uarrow 28
darrow 29
}
}
template {
Width 15
Text "This is defined as a template and duplicated here"
}
Window adduser on screen1 at 0,0 {
Attributes "\screen"
window at 1,1 {
Height 22
Width 75
Attributes "\dialog"
Active username
box {
Attributes "\dialog"
Highlight "\border"
CallFunc draw_box
shadow {
Attributes "\shadow"
CallFunc draw_shadow
}
}
Title at 0,9 { Text " This is a title " }
username at 5,20 {
Height 1
Width 30
Attributes "\screen"
Highlight "\tag_selected"
Next shells
Input "nobody"
exp at 3,3 {
Attributes "\dialog"
Text "The is an input object:"
}
prompt at 5,3 {
Text "Username: "
}
}
shells at 9,20 {
Attributes "\dialog"
Highlight "\tag_selected"
Next button
Options {
"sh"
"csh"
"tcsh"
"bash"
}
exp at 7,3 {
Attributes "\dialog"
Text "This is a horizontal menu:"
}
prompt at 9,3 { Text "Select a shell: "}
}
button at 14,9 {
Height 3
Width 7
Attributes "\tag_key_selected"
Highlight "\tag_selected"
Active button
button_box at 14,9 {
CallFunc draw_box
}
button at 15, 10 {
Up username Down username
Action User_Routine
Label "QUIT"
}
}
}
}

View File

@ -1,267 +0,0 @@
/*
* Copyright (c) 1995
* Paul Richards. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* verbatim and that no modifications are made prior to this
* point in the file.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Paul Richards.
* 4. The name Paul Richards may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY PAUL RICHARDS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PAUL RICHARDS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <strhash.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ncurses.h>
#include <forms.h>
#include <err.h>
#include "internal.h"
extern FILE *yyin;
hash_table *root_table, *cbind;
OBJECT *cur_obj;
int done;
/* Default attribute commands */
struct attr_cmnd attr_cmnds[] = {
{"box", ATTR_BOX },
{"center", ATTR_CENTER },
{"right", ATTR_RIGHT }
};
/* Internal bindings */
struct intbind {
char *key;
void *addr;
};
struct intbind internal_bindings[] = {
{"draw_box", &draw_box},
{"draw_shadow", &draw_shadow}
};
/* Bind the internal function addresses */
void
bind_internals(hash_table *table)
{
int i;
for (i=0; i < (sizeof internal_bindings)/(sizeof (struct intbind)); i++)
if (bind_tuple(table, internal_bindings[i].key,
TT_FUNC, internal_bindings[i].addr) == ST_ERROR)
errx(-1, "Failed to bind internal tuples");
}
/*
* Find the default device and open a display on it.
*/
DISPLAY *
default_open(DISPLAY *display)
{
/* XXX -- not implemented, just calls ncurses */
return (ncurses_open(display));
}
int
load_objects(const char *filename)
{
FILE *fd;
root_table = hash_create(0);
if (!root_table)
errx(-1, "Failed to allocate root bindings table");
cbind = root_table;
bind_internals(root_table);
if (!(fd = fopen(filename, "r"))) {
warn("Couldn't open file %s", filename);
return (ST_ERROR);
}
yyin = fd;
yyparse();
if (fclose(fd)) {
warn("Couldn't close file %s", filename);
return (ST_ERROR);
}
return (ST_OK);
}
int
start_object(char *objname)
{
TUPLE *tuple;
OBJECT *object;
tuple = get_tuple(root_table, objname, TT_OBJ_INST);
if (!tuple)
return (ST_NOBIND);
object = (OBJECT *)tuple->addr;
cur_obj = object;
set_display(object->display);
cur_obj->status |= O_VISIBLE;
while (!done) {
hash_traverse(root_table, &display_tuples, root_table);
hash_traverse(root_table, &refresh_displays, root_table);
process_object(cur_obj);
}
return (ST_DONE);
}
int
call_function(char *func, OBJECT *obj)
{
TUPLE *tuple;
tuple = tuple_search(obj, func, TT_FUNC);
if (!tuple)
return (0);
(*tuple->addr)(obj);
return (1);
}
set_display(DISPLAY *display)
{
switch (display->type) {
case DT_NCURSES:
ncurses_set_display(display);
break;
default:
break;
}
}
void
display_object(OBJECT *obj)
{
switch(obj->display->type) {
case DT_NCURSES:
ncurses_display_object(obj);
break;
default:
break;
}
}
void
process_object(OBJECT *obj)
{
TUPLE *tuple;
/* Call user routine, if there is one. */
if (obj->UserProcFunc)
if (call_function(obj->UserProcFunc, obj))
return;
/* Find the first non-compound object or a default override */
while (obj->type == OT_COMPOUND) {
tuple = tuple_search(obj, obj->object.compound->defobj, TT_OBJ_INST);
obj = (OBJECT *)tuple->addr;
}
cur_obj = obj;
switch(obj->display->type) {
case DT_NCURSES:
ncurses_process_object(obj);
break;
default:
break;
}
}
int
refresh_displays(char *key, void *data, void *arg)
{
TUPLE *tuple = (TUPLE *)data;
DISPLAY *display;
if (tuple->type == TT_DISPLAY)
display = (DISPLAY *)tuple->addr;
switch (display->type) {
case DT_NCURSES:
ncurses_refresh_display(display);
break;
default:
break;
}
return (1);
}
int
display_tuples(char *key, void *data, void *arg)
{
TUPLE *tuple = (TUPLE *)data;
OBJECT *obj;
void (* fn)();
switch(tuple->type) {
case TT_OBJ_INST:
obj = (OBJECT *)tuple->addr;
/* Call user routine, if there is one. */
if (obj->UserDrawFunc) {
if (!call_function(obj->UserDrawFunc, obj))
display_object(obj);
} else
display_object(obj);
/* Display sub-objects */
if (obj->bind)
hash_traverse(obj->bind, &display_tuples, 0);
break;
default:
break;
}
return (1);
}
AttrType
parse_default_attributes(char *string)
{
int i;
for (i=0; i < (sizeof attr_cmnds) / (sizeof (struct attr_cmnd)); i++)
if (!strcmp(string, attr_cmnds[i].attr_name))
return (attr_cmnds[i].attr_type);
return (ATTR_UNKNOWN);
}

View File

@ -1,189 +0,0 @@
/*-
* 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.
*
*/
#ifndef _FORMS_H_
#define _FORMS_H_
#include <ncurses.h>
#include <strhash.h>
#define F_DEFATTR 0
#define F_SELATTR A_REVERSE
/* Status values */
#define ST_ERROR -1
#define ST_OK 0
#define ST_DONE 1
#define ST_CANCEL 2
#define ST_NOBIND 3
#define ST_RUNNING 4
typedef enum {
TT_ANY,
TT_OBJ_INST,
TT_OBJ_DEF,
TT_FUNC,
TT_DISPLAY,
TT_ATTR
} TupleType;
typedef enum {
DT_ANY,
DT_NCURSES,
DT_X,
DT_VGA
} DisplayType;
typedef enum {
OT_ACTION,
OT_COMPOUND,
OT_FUNCTION,
OT_INPUT,
OT_MENU,
OT_SHADOW,
OT_TEXT
} ObjectType;
#define FUNCP void(*)(void *)
typedef struct Tuple {
char *name;
int type;
void (*addr)(void *);
} TUPLE;
typedef struct NcursesDevice {
char *ttyname;
char *input;
char *output;
SCREEN *screen;
} NCURSDEV;
typedef struct NcursesWindow {
WINDOW *win;
} NCURSES_WINDOW;
typedef struct Display {
DisplayType type;
int height;
int width;
int virt_height;
int virt_width;
union {
NCURSDEV *ncurses;
} device;
hash_table *bind;
} DISPLAY;
typedef struct ActionObject {
char *text;
char *action;
} ACTION_OBJECT;
typedef struct CompoundObject {
char *defobj;
} COMPOUND_OBJECT;
typedef struct FunctionObject {
char *fn;
} FUNCTION_OBJECT;
typedef struct InputObject {
int lbl_flag;
char *label;
char *input;
int limit;
} INPUT_OBJECT;
typedef struct MenuObject {
int selected;
int no_options;
char **options;
} MENU_OBJECT;
typedef struct TextObject {
char *text;
} TEXT_OBJECT;
typedef union {
NCURSES_WINDOW *ncurses;
} WIN;
typedef union {
ACTION_OBJECT *action;
COMPOUND_OBJECT *compound;
FUNCTION_OBJECT *function;
INPUT_OBJECT *input;
MENU_OBJECT *menu;
TEXT_OBJECT *text;
} OBJ_TYPE;
typedef struct Object {
ObjectType type;
int status;
struct Object *parent;
int y;
int x;
int height;
int width;
char *attributes;
char *highlight;
char *lnext;
char *lup;
char *ldown;
char *lleft;
char *lright;
char *UserDrawFunc;
char *UserProcFunc;
char *OnEntry;
char *OnExit;
OBJ_TYPE object;
hash_table *bind;
struct Display *display;
WIN window;
} OBJECT;
/* Externally visible variables */
extern hash_table *root_table;
/* Function declarations */
__inline struct Tuple *get_tuple(hash_table *, char *, TupleType);
TUPLE *tuple_search(OBJECT *, char *, TupleType);
int bind_tuple(hash_table *, char *, TupleType, void(*fn)());
int add_menu_option(MENU_OBJECT *, char *);
void draw_box(OBJECT *);
void draw_shadow(OBJECT *);
#endif /* _FORMS_H_ */

View File

@ -1,91 +0,0 @@
/*
* 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.
*
*/
/* Object status values */
#define O_VISIBLE 0x0001
#define O_ACTIVE 0x0002
/* Standard attribute commands */
typedef enum {
ATTR_BOX,
ATTR_CENTER,
ATTR_RIGHT,
ATTR_SHADOW,
ATTR_UNKNOWN
} AttrType;
struct attr_cmnd {
char *attr_name;
AttrType attr_type;
};
/* Ncurses color pairs */
typedef struct color_pair {
int no;
int fg;
int bg;
} COLPAIR;
extern struct attr_cmnd attr_cmnds[];
extern hash_table *root_table, *cbind;
extern DISPLAY *cdisp;
extern int lineno;
/* Private function declarations */
int display_tuples(char *, void *, void *);
int refresh_displays(char *, void *, void *);
int copy_object_tree(char *, void *, void *);
void process_tuple(OBJECT *);
void process_object(OBJECT *);
void process_input_object(OBJECT *);
void process_menu_object(OBJECT *);
void process_text_object(OBJECT *);
DISPLAY *default_open(DISPLAY *);
DISPLAY *ncurses_open(DISPLAY *);
int ncurses_print_string(OBJECT *, char *);
void ncurses_print_status(char *);
int ncurses_bind_key(OBJECT *, unsigned int);
void ncurses_display_action(OBJECT *);
void ncurses_display_compound(OBJECT *);
void ncurses_display_function(OBJECT *);
void ncurses_display_input(OBJECT *);
void ncurses_display_menu(OBJECT *);
void ncurses_display_text(OBJECT *);
void ncurses_process_action(OBJECT *);
void ncurses_process_input(OBJECT *);
void ncurses_process_menu(OBJECT *);
void ncurses_process_text(OBJECT *);

View File

@ -1,122 +0,0 @@
%{
/*-
* 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 <unistd.h>
#include "y.tab.h"
extern int lineno;
extern int charno;
extern int off;
%}
NUM [0-9]+
%%
!Forms { return FORMS; }
Action { return ACTION; }
Active { return ACTIVE; }
as { return AS; }
at { return AT; }
Attributes { return ATTR; }
AttrTable { return ATTRTABLE; }
CallFunc { return CALLFUNC; }
ColorPairs { return COLORPAIRS; }
Default { return DEFAULT; }
Display { return A_DISPLAY; }
Down { return DOWN; }
Forms { return FORMS; }
Function { return FUNCTION; }
Height { return HEIGHT; }
Highlight { return HIGHLIGHT; }
Input { return INPUT; }
InputFile { return INPUTFILE; }
Label { return LABEL; }
Left { return LEFT; }
Limit { return LIMIT; }
Menu { return MENU; }
Ncurses { return NCURSES; }
Next { return NEXT; }
Object { return AN_OBJECT; }
on { return ON; }
OnEntry { return ONENTRY; }
OnExit { return ONEXIT; }
Options { return OPTIONS; }
OutputFile { return OUTPUTFILE; }
Right { return RIGHT; }
Selected { return SELECTED; }
Text { return TEXT; }
Ttyname { return TTYNAME; }
Type { return TYPE; }
Up { return UP; }
Use { return USE; }
UserDrawFunc { return USERDRAWFUNC; }
UserProcFunc { return USERPROCFUNC; }
Version { return VERSION; }
Width { return WIDTH; }
Window { return WINDOW; }
Black { return BLACK; }
Red { return RED; }
Green { return GREEN; }
Yellow { return YELLOW; }
Blue { return BLUE; }
Magenta { return MAGENTA; }
Cyan { return CYAN; }
White { return WHITE; }
, { return COMMA; }
\{ { return LBRACE; }
\} { return RBRACE; }
; { return SEMICOLON; }
{NUM}+ { yylval.ival = atoi(yytext); return NUMBER; }
[A-Za-z_][A-Za-z0-9_.]* { yylval.sval = strdup(yytext);
free(yytext);
return NAME;
}
\"[^"]+\" {
yytext[strlen(yytext)-1] = '\0';
yylval.sval = strdup(yytext + 1);
free(yytext);
return STRING;
}
\n { lineno++; }
#.* { /* Ignored (comment) */; }
[ \t\f]* { /* Ignored (white space) */; }

View File

@ -1,707 +0,0 @@
/*
* 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.
*
*/
/*
* Low level ncurses support routines.
*/
#include <forms.h>
#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ttyent.h>
#include "internal.h"
/* ncurses key mappings */
/* XXX -- need to look at implementing key mapping properly */
#define K_UPL KEY_UP
#define K_DOWNL KEY_DOWN
#define K_RIGHTL 9
#define K_LEFTL 8
#define K_NEXTL 10
#define K_LEFT KEY_LEFT
#define K_RIGHT KEY_RIGHT
#define K_HOME KEY_HOME
#define K_END KEY_END
#define K_BS 263
#define K_DEL 330
#define K_ACCEPT K_NEXTL
/* Function declarations */
DISPLAY *ncurses_open(DISPLAY *);
void ncurses_moveto(OBJECT *);
int ncurses_print_srtring(OBJECT *, char *);
extern OBJECT *cur_obj;
DISPLAY *
ncurses_open(DISPLAY *display)
{
struct ttyent *tty;
NCURSDEV *device = display->device.ncurses;
FILE *in, *out;
if (device) {
tty = getttynam(device->ttyname);
if (!tty)
return (0);
in = fopen(device->input, "r");
out = fopen(device->output, "w+");
if ((!in) || (!out))
return (0);
device->screen = newterm(tty->ty_type, in, out);
} else {
display->device.ncurses = malloc(sizeof (NCURSDEV));
device = display->device.ncurses;
if (!device)
return (0);
device->screen = newterm(getenv("TERM"), stdout, stdin);
}
if (!device->screen)
return (0);
start_color();
cbreak();
noecho();
/* If we got here by default, set device type to ncurses */
if (display->type == DT_ANY)
display->type = DT_NCURSES;
display->height = LINES;
display->width = COLS;
return (display);
}
ncurses_set_display(DISPLAY *display)
{
set_term(display->device.ncurses->screen);
}
ncurses_open_window(OBJECT *object)
{
object->window.ncurses->win =
newwin(object->height, object->width, object->y, object->x);
if (!object->window.ncurses->win)
errx(-1, "Couldn't open window (%d)", lineno);
if (keypad(object->window.ncurses->win, TRUE) == ERR)
errx(-1, "Keypad call failed (%d)", lineno);
}
void
ncurses_refresh_display(DISPLAY *display)
{
doupdate();
}
/*
* Parse an attribute string. For ncurses we look up the display
* specific bindings table for the attribute strings. For ncurses
* the attribute entry is a simple integer which is passed to wattron.
*/
int
ncurses_parse_attrs(OBJECT *object, char *string)
{
hash_table *htable;
TUPLE *tuple;
int inc = 1;
char *attribute = 0;
AttrType attr_type;
int len, y, x;
int skip = 0;
if ((!string) || (*string != '\\'))
return (0);
do {
if (*(string + inc) == '\\')
return (skip);
while ((!isspace(*(string + inc)))
&& (*(string+inc) != '\\')
&& (*(string + inc) != '\0'))
inc++;
attribute = malloc(inc);
if (!attribute)
errx(-1, "Failed to allocate memory for attribute when parsing string");
strncpy(attribute, string+1, inc-1);
attribute[inc-1] = 0;
#ifdef no
/* Skip trailing space after the attribute string */
while (isspace(*(string + inc)))
inc++;
#endif
attr_type = parse_default_attributes(attribute);
free(attribute);
switch (attr_type) {
case ATTR_CENTER:
len = calc_string_width(string+inc);
getyx(object->window.ncurses->win, y, x);
wmove(object->window.ncurses->win, y,
(object->width - x - len)/2);
break;
case ATTR_RIGHT:
len = calc_string_width(string+inc);
getyx(object->window.ncurses->win, y, x);
wmove(object->window.ncurses->win, y, COLS-len);
break;
case ATTR_UNKNOWN:
default:
/*
* If no bindings table is found just skip over the attribute
* string. i.e. ignore the attribute but keep printing the text.
*/
if (object->display && object->display->bind) {
tuple = get_tuple(object->display->bind, attribute, TT_ATTR);
if (tuple)
wattron(object->window.ncurses->win, COLOR_PAIR((int)*(tuple->addr)));
}
break;
}
skip += inc;
string += inc;
inc = 0;
} while (*(string + inc++) == '\\');
return (skip);
}
int
ncurses_print_string(OBJECT *object, char *string)
{
int len, skip;
int y = object->y;
int x;
int height = object->height;
/* If it's a null string, clear the area using spaces. */
if (!string)
len = -1;
else
len = strlen(string);
wmove(object->window.ncurses->win, y, x);
while (height--) {
x = object->x;
if (wmove(object->window.ncurses->win, y++, x) == ERR)
return (ERR);
while (x++ < (object->x + object->width)) {
if (len-- > 0) {
/* Print input objects without processing \'s */
if ((*string == '\\') && (object->type != OT_INPUT)) {
skip = ncurses_parse_attrs(object, string);
len -= skip;
string += skip;
}
if (waddch(object->window.ncurses->win, *string++) == ERR)
return (ERR);
} else if (waddch(object->window.ncurses->win, ' ') == ERR)
return (ERR);
}
}
return (OK);
}
void
ncurses_display_object(OBJECT *object)
{
ncurses_set_attributes(object, 0);
switch (object->type) {
case OT_ACTION:
ncurses_display_action(object);
break;
case OT_COMPOUND:
ncurses_display_compound(object);
break;
case OT_FUNCTION:
ncurses_display_function(object);
break;
case OT_INPUT:
ncurses_display_input(object);
break;
case OT_MENU:
ncurses_display_menu(object);
break;
case OT_TEXT:
ncurses_display_text(object);
break;
default:
break;
}
}
void
ncurses_process_object(OBJECT *object)
{
ncurses_set_attributes(object, 1);
switch (object->type) {
case OT_ACTION:
ncurses_process_action(object);
break;
case OT_FUNCTION:
break;
case OT_INPUT:
ncurses_process_input(object);
break;
case OT_MENU:
ncurses_process_menu(object);
break;
case OT_TEXT:
break;
default:
break;
}
}
void
ncurses_draw_box(OBJECT *object)
{
int y, x;
chtype box, border;
ncurses_parse_attrs(object, object->highlight);
wattron(object->window.ncurses->win, A_BOLD);
mvwaddch(object->window.ncurses->win, object->y, object->x,
ACS_ULCORNER);
mvwaddch(object->window.ncurses->win,
object->y + object->height - 1,
object->x,
ACS_LLCORNER);
for (y=object->y + 1; y < (object->y + object->height) - 1; y++) {
mvwaddch(object->window.ncurses->win, y, object->x,
ACS_VLINE);
}
for (x=object->x + 1; x < (object->x + object->width) - 1; x++) {
mvwaddch(object->window.ncurses->win, object->y, x,
ACS_HLINE);
}
ncurses_parse_attrs(object, object->attributes);
wattroff(object->window.ncurses->win, A_BOLD);
mvwaddch(object->window.ncurses->win, object->y,
object->x + object->width-1,
ACS_URCORNER);
mvwaddch(object->window.ncurses->win,
object->y + object->height-1,
object->x + object->width-1,
ACS_LRCORNER);
for (y=object->y + 1; y < (object->y + object->height) - 1; y++) {
mvwaddch(object->window.ncurses->win, y, object->x + object->width - 1,
ACS_VLINE);
}
for (x=object->x + 1; x < (object->x + object->width) - 1; x++) {
mvwaddch(object->window.ncurses->win, object->y + object->height - 1, x,
ACS_HLINE);
}
wnoutrefresh(object->window.ncurses->win);
}
void
ncurses_draw_shadow(OBJECT *object)
{
int i;
for (i=object->y + 1; i < (object->y + object->height); i++) {
wattron(object->window.ncurses->win, A_INVIS);
mvwaddch(object->window.ncurses->win, i, object->x + object->width, ' ');
waddch(object->window.ncurses->win,
mvwinch(object->window.ncurses->win,
i, object->x + object->width) & A_CHARTEXT);
waddch(object->window.ncurses->win,
mvwinch(object->window.ncurses->win,
i, object->x + object->width+1) & A_CHARTEXT);
}
for (i=object->x + 1; i < (object->x + object->width + 2); i++) {
wattrset(object->window.ncurses->win, A_INVIS);
wmove(object->window.ncurses->win, object->y+object->height, i);
waddstr(object->window.ncurses->win, " ");
wattrset(object->window.ncurses->win, COLOR_PAIR(2)|A_BOLD);
waddch(object->window.ncurses->win,
mvwinch(object->window.ncurses->win,
object->y+object->height, i) & A_CHARTEXT);
}
wnoutrefresh(object->window.ncurses->win);
}
void
ncurses_display_compound(OBJECT *object)
{
int y, x;
for (y=object->y; y < (object->y + object->height); y++)
for (x=object->x; x < (object->x + object->width); x++)
waddch(object->window.ncurses->win,
mvwinch(object->window.ncurses->win, y, x) & A_CHARTEXT);
}
void
ncurses_display_action(OBJECT *object)
{
ncurses_print_string(object, object->object.action->text);
wnoutrefresh(object->window.ncurses->win);
}
void
ncurses_display_function(OBJECT *object)
{
TUPLE *tuple;
void (* fn)();
tuple = tuple_search(object, object->object.function->fn, TT_FUNC);
if (!tuple)
return;
fn = (FUNCP)tuple->addr;
if (fn)
(*fn)(object);
wnoutrefresh(object->window.ncurses->win);
}
void
ncurses_display_text(OBJECT *object)
{
ncurses_print_string(object, object->object.text->text);
wnoutrefresh(object->window.ncurses->win);
}
void
ncurses_display_input(OBJECT *object)
{
if (object->object.input->lbl_flag)
ncurses_print_string(object, object->object.input->label);
else
ncurses_print_string(object, object->object.input->input);
wnoutrefresh(object->window.ncurses->win);
}
void
ncurses_process_action(OBJECT *object)
{
TUPLE *tuple;
int ch;
ncurses_display_action(object);
wmove(object->window.ncurses->win, object->y, object->x);
for (;;) {
ch = wgetch(object->window.ncurses->win);
if (ch == K_ACCEPT) {
tuple = tuple_search(object,
object->object.action->action, TT_FUNC);
if (!tuple) {
ncurses_print_status("No function bound to action");
continue;
} else {
(*tuple->addr)(object);
return;
}
} else {
ch = ncurses_bind_key(object, ch);
if (ch == ST_ERROR) {
beep();
continue;
} else
return;
}
}
}
void
ncurses_process_input(OBJECT *object)
{
int len;
int disp_off=0, abspos=0, cursor = 0;
int ch;
#define DISPOFF ((len < object->width) ? 0 : len - object->width)
#define CURSPOS ((len < object->width) ? len : object->width)
ncurses_display_input(object);
len = strlen(object->object.input->input);
cursor = CURSPOS;
abspos = cursor;
for (;;) {
wmove(object->window.ncurses->win, object->y, object->x+cursor);
ch = wgetch(object->window.ncurses->win);
ch = ncurses_bind_key(object, ch);
/*
* If there was a valid motion command then we've
* moved to a new object 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 == ST_OK)
return;
else if (ch == ST_ERROR)
continue;
ncurses_print_status("");
if (object->object.input->lbl_flag) {
object->object.input->lbl_flag = 0;
}
if ((ch == K_HOME) || (ch == '')) {
disp_off = 0;
cursor = 0;
abspos = 0;
} else if ((ch == K_END) || (ch == '')) {
disp_off = DISPOFF;
abspos = len;
cursor = CURSPOS;
} else if (ch == K_DEL) {
if (!(len-abspos))
beep();
else {
bcopy(object->object.input->input+abspos+1,
object->object.input->input+abspos,
len - abspos);
--len;
}
} else if ((ch == K_LEFT) || (ch == K_BS) || (ch == '')) {
if (!abspos)
beep();
else {
if (ch == K_BS) {
bcopy(object->object.input->input+abspos,
object->object.input->input+abspos-1,
len-abspos+1);
--len;
}
--abspos;
--cursor;
if ((disp_off) && (cursor < 0)) {
--disp_off;
++cursor;
}
}
}else if (ch == '') {
bzero(object->object.input->input, len);
len = 0;
abspos = 0;
cursor = 0;
disp_off = 0;
} else if ((ch == K_RIGHT) || (ch == '')) {
if (abspos == len)
beep();
else {
++abspos;
if (++cursor >= object->width) {
++disp_off;
--cursor;
}
}
} else if ((isprint(ch)) && (len < object->object.input->limit)){
bcopy(object->object.input->input+abspos,
object->object.input->input+abspos+1, len-abspos+1);
object->object.input->input[abspos++] = ch;
len++;
if (++cursor > object->width) {
++disp_off;
--cursor;
}
} else
beep();
ncurses_print_string(object, object->object.input->input+disp_off);
}
}
void
ncurses_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
ncurses_bind_key(OBJECT *object, unsigned int ch)
{
struct Tuple *tuple=0;
/* XXX -- check for keymappings here --- not yet done */
if (ch == K_UPL) {
if (object->lup) {
tuple = tuple_search(object, object->lup, TT_OBJ_INST);
if (!tuple)
ncurses_print_status("Field to move up to does not exist");
} else
ncurses_print_status("Can't move up from this object");
} else if (ch == K_DOWNL) {
if (object->ldown) {
tuple = tuple_search(object, object->ldown, TT_OBJ_INST);
if (!tuple)
ncurses_print_status("Field to move down to does not exist");
} else
ncurses_print_status("Can't move down from this object");
} else if (ch == K_LEFTL) {
if (object->lleft) {
tuple = tuple_search(object, object->lleft, TT_OBJ_INST);
if (!tuple)
ncurses_print_status("Field to move left to does not exist");
} else
ncurses_print_status("Can't move left from this object");
} else if (ch == K_RIGHTL) {
if (object->lright) {
tuple = tuple_search(object, object->lright, TT_OBJ_INST);
if (!tuple)
ncurses_print_status("Field to move right to does not exist");
} else
ncurses_print_status("Can't move right from this object");
} else if (ch == K_NEXTL) {
if (object->lnext) {
tuple = tuple_search(object, object->lnext, TT_OBJ_INST);
if (!tuple)
ncurses_print_status("Field to move to next does not exist");
} else
ncurses_print_status("There is no next object from this object");
} else
/* No motion keys pressed */
return (ch);
if (tuple) {
cur_obj = (OBJECT *)tuple->addr;
return (ST_OK);
} else {
beep();
return (ST_ERROR);
}
}
void
ncurses_display_menu(OBJECT *object)
{
if (ncurses_print_string(object,
object->object.menu->options[object->object.menu->selected]) == ERR)
ncurses_print_status("Illegal scroll in print_string");
wnoutrefresh(object->window.ncurses->win);
}
void
ncurses_process_menu(OBJECT *object)
{
int ch;
for (;;) {
ncurses_display_menu(object);
wmove(object->window.ncurses->win, object->y, object->x);
ch = wgetch(object->window.ncurses->win);
switch (ch) {
case ' ':
ncurses_print_status("");
object->object.menu->selected++;
if (object->object.menu->selected >= object->object.menu->no_options)
object->object.menu->selected = 0;
ch = ST_OK;
break;
default:
ch = ncurses_bind_key(object, ch);
break;
}
if (ch == ST_OK)
return;
else if (ch == ST_ERROR) {
beep();
continue;
} else {
ncurses_print_status("Hit the space bar to toggle through options");
beep();
continue;
}
}
}
ncurses_set_attributes(OBJECT *object, int hl)
{
int y, x;
char *attr = 0;
if (hl && object->highlight)
attr = object->highlight;
else if (object->attributes)
attr = object->attributes;
if (attr) {
wattrset(object->window.ncurses->win, A_NORMAL);
ncurses_parse_attrs(object, attr);
}
}

View File

@ -1,391 +0,0 @@
/*-
* Copyright (c) 1995
* Paul Richards. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* verbatim and that no modifications are made prior to this
* point in the file.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Paul Richards.
* 4. The name Paul Richards may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY PAUL RICHARDS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PAUL RICHARDS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <strhash.h>
#include <ctype.h>
#include <err.h>
#include <ncurses.h>
#include <forms.h>
#include <string.h>
#include <stdlib.h>
#include "internal.h"
extern hash_table *global_bindings;
extern int lineno;
int done=0;
__inline void
inherit_parent(OBJECT *obj, OBJECT *parent)
{
obj->parent = parent;
obj->status = parent->status;
if (!obj->y)
obj->y = parent->y;
if (!obj->x)
obj->x = parent->x;
if (!obj->height)
obj->height = parent->height;
if (!obj->width)
obj->width = parent->width;
if (!obj->attributes && parent->attributes)
obj->attributes = strdup(parent->attributes);
if (!obj->highlight && parent->highlight)
obj->highlight = strdup(parent->highlight);
if (!obj->lnext && parent->lnext)
obj->lnext = strdup(parent->lnext);
if (!obj->lup && parent->lup)
obj->lup = strdup(parent->lup);
if (!obj->ldown && parent->ldown)
obj->ldown = strdup(parent->ldown);
if (!obj->lleft && parent->lleft)
obj->lleft = strdup(parent->lleft);
if (!obj->lright && parent->lright)
obj->lright = strdup(parent->lright);
obj->display = parent->display;
obj->window = parent->window;
}
/*
* Inherit any unspecified properties from the parent. Not
* all properties get passed down to children.
*/
int
inherit_props(char *key, void *data, void *arg)
{
TUPLE *tuple = (TUPLE *)data;
OBJECT *parent = (OBJECT *)arg;
OBJECT *obj = (OBJECT *)tuple->addr;
inherit_parent(obj, parent);
if (obj->bind)
hash_traverse(obj->bind, &inherit_props, obj);
return (1);
}
/*
* Propagate unspecified properties from the parent
* to any attached sub-objects.
*/
void
inherit_properties(OBJECT *obj, OBJECT *parent)
{
inherit_parent(obj, parent);
hash_traverse(obj->bind, &inherit_props, obj);
}
__inline void
clone_object(OBJECT *object, OBJECT *def)
{
int i;
/* XXX - Should really check if strdup's succeed */
object->type = def->type;
object->status = def->status;
object->parent = def->parent;
/*
* Only copy sizes for fixed size objects,
* otherwise inherit from parent. Always
* inherit x and y.
*/
if (def->type != OT_COMPOUND && def->type != OT_FUNCTION) {
object->height = def->height;
object->width = def->width;
}
if (def->attributes)
object->attributes = strdup(def->attributes);
if (def->highlight)
object->highlight = strdup(def->highlight);
if (def->lnext)
object->lnext = strdup(def->lnext);
if (def->lup)
object->lup = strdup(def->lup);
if (def->ldown)
object->ldown = strdup(def->ldown);
if (def->lleft)
object->lleft = strdup(def->lleft);
if (def->lright)
object->lright = strdup(def->lright);
if (def->UserDrawFunc)
object->UserDrawFunc = strdup(def->UserDrawFunc);
if (def->UserProcFunc)
object->UserProcFunc = strdup(def->UserProcFunc);
if (def->OnEntry)
object->OnEntry = strdup(def->OnEntry);
if (def->OnExit)
object->OnExit = strdup(def->OnExit);
object->display = def->display;
object->window = def->window;
switch (object->type) {
case OT_ACTION:
if (def->object.action) {
object->object.action = malloc(sizeof (ACTION_OBJECT));
if (!object->object.action)
errx(-1,
"Failed to allocate memory for copy of action object");
if (def->object.action->text)
object->object.action->text =
strdup(def->object.action->text);
if (def->object.action->action)
object->object.action->action =
strdup(def->object.action->action);
}
break;
case OT_COMPOUND:
if (def->object.compound) {
object->object.compound = malloc(sizeof (COMPOUND_OBJECT));
if (!object->object.compound)
errx(-1,
"Failed to allocate memory for copy of compound object");
if (def->object.compound->defobj)
object->object.compound->defobj =
strdup(def->object.compound->defobj);
}
break;
case OT_FUNCTION:
object->object.function = malloc(sizeof (FUNCTION_OBJECT));
if (!object->object.function)
errx(-1, "Failed to allocate memory for copy of function object");
object->object.function->fn = strdup(def->object.function->fn);
break;
case OT_INPUT:
object->object.input = malloc(sizeof (INPUT_OBJECT));
if (!object->object.input)
errx(-1, "Failed to allocate memory for copy of input object");
object->object.input->lbl_flag = def->object.input->lbl_flag;
object->object.input->label = strdup(def->object.input->label);
object->object.input->input = strdup(def->object.input->input);
object->object.input->limit = def->object.input->limit;
break;
case OT_MENU:
object->object.menu = malloc(sizeof (MENU_OBJECT));
if (!object->object.menu)
errx(-1, "Failed to allocate memory for copy of menu object");
object->object.menu->selected = def->object.menu->selected;
for (i=0; i < def->object.menu->no_options; i++) {
object->object.menu->no_options =
add_menu_option(object->object.menu,
def->object.menu->options[i]);
if (!object->object.menu->no_options)
errx(-1, "Failed to allocate memory for copy of menu option");
}
break;
case OT_TEXT:
object->object.text = malloc(sizeof (TEXT_OBJECT));
if (!object->object.text)
errx(-1, "Failed to allocate memory for copy of text object");
object->object.text->text = strdup(def->object.text->text);
break;
default:
break;
}
}
/*
* Recursively clone objects in the bindings table.
*/
int
copy_bound_objects(char *key, void *data, void *arg)
{
TUPLE *tuple = (TUPLE *)data;
OBJECT *object = (OBJECT *)arg;
OBJECT *clone, *src;
if (tuple->type != TT_OBJ_DEF && tuple->type != TT_OBJ_INST)
errx(-1, "Invalid tuple type in definition");
src = (OBJECT *)tuple->addr;
clone = malloc(sizeof (OBJECT));
if (!clone)
errx(-1, "Failed to allocate memory for clone object");
clone->bind = hash_create(0);
if (!clone->bind)
errx(-1, "Failed to create hash table for definition copy");
clone_object(clone, src);
bind_tuple(object->bind, key, tuple->type, (FUNCP)clone);
if (src->bind)
hash_traverse(src->bind, &copy_bound_objects, clone);
return (1);
}
int
use_defined_object(OBJECT *object, char *src)
{
TUPLE *tuple;
OBJECT *def;
tuple = tuple_search(object, src, TT_OBJ_DEF);
if (!tuple)
return (ST_NOBIND);
else
def = (OBJECT *)tuple->addr;
/* Clone root object */
clone_object(object, def);
/* Now recursively clone sub-objects */
hash_traverse(def->bind, &copy_bound_objects, object);
}
/*
* Calculate length of printable part of the string,
* stripping out the attribute modifiers.
*/
int
calc_string_width(char *string)
{
int len, width=0;
if (!string)
return (0);
len = strlen(string);
while (len) {
if (*string != '\\') {
width++;
len--;
string++;
continue;
} else {
string++;
len--;
if (*string == '\\') {
string++;
width++;
len--;
continue;
} else {
while (!isspace(*string)) {
string++;
len--;
}
while (isspace(*string)) {
string ++;
len--;
}
}
}
}
return (width);
}
/* Calculate a default height for a object */
void
calc_object_height(OBJECT *object, char *string)
{
int len;
len = calc_string_width(string);
if (!object->width) {
/*
* This is a failsafe, this routine shouldn't be called
* with a width of 0, the width should be determined
* first.
*/
object->height = 1;
return;
}
if (len < object->width) {
object->height = 1;
return;
} else
object->height = len / object->width;
if ((object->height*object->width) < len)
object->height++;
return;
}
int
add_menu_option(MENU_OBJECT *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);
}
/* Default object functions */
void
draw_box(OBJECT *object)
{
/* Gross hack for now */
ncurses_draw_box(object);
}
void
draw_shadow(OBJECT *object)
{
/* Gross hack for now */
ncurses_draw_shadow(object);
}

View File

@ -1,728 +0,0 @@
%{
/*-
* Copyright (c) 1995
* Paul Richards. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* verbatim and that no modifications are made prior to this
* point in the file.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Paul Richards.
* 4. The name Paul Richards may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY PAUL RICHARDS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PAUL RICHARDS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <strhash.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ncurses.h>
#include <forms.h>
#include <err.h>
#include "internal.h"
extern int yyleng;
int lineno = 1;
OBJECT *parent;
extern hash_table *cbind;
/* Some variables for holding temporary values as we parse objects */
OBJECT *object, *tmpobj;
DISPLAY *display;
int tmp, len;
char *tmpstr, *objname, *dispname, *useobj;
TUPLE *tmptuple;
TupleType t_type;
%}
%union {
int ival;
char *sval;
}
%token <ival> ACTION
%token <ival> ACTIVE
%token <ival> AS
%token <ival> AT
%token <ival> ATTR
%token <ival> ATTRTABLE
%token <ival> CALLFUNC
%token <ival> COLORPAIRS
%token <ival> DEFAULT
%token <ival> A_DISPLAY
%token <ival> DOWN
%token <ival> FORMS
%token <ival> FUNCTION
%token <ival> HANDLER
%token <ival> HEIGHT
%token <ival> INPUT
%token <ival> INPUTFILE
%token <ival> LABEL
%token <ival> LEFT
%token <ival> LIMIT
%token <ival> MENU
%token <ival> NCURSES
%token <ival> NEXT
%token <ival> AN_OBJECT
%token <ival> ON
%token <ival> ONENTRY
%token <ival> ONEXIT
%token <ival> OPTIONS
%token <ival> OUTPUTFILE
%token <ival> RIGHT
%token <ival> HIGHLIGHT
%token <ival> SELECTED
%token <ival> TEXT
%token <ival> TTYNAME
%token <ival> TYPE
%token <ival> UP
%token <ival> USE
%token <ival> USERDRAWFUNC
%token <ival> USERPROCFUNC
%token <ival> VERSION
%token <ival> WIDTH
%token <ival> WINDOW
%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> COMMA
%token <ival> SEMICOLON
%token <ival> LBRACE
%token <ival> RBRACE
%token <sval> NAME
%token <ival> NUMBER
%token <sval> STRING
%type <ival> color
%start forms
%%
forms: FORMS VERSION NAME spec
{
#ifdef DEBUG
printf("Forms language version %s\n", $3);
#endif
}
;
spec: /* empty */
| spec display
| spec window
| spec object
;
display: A_DISPLAY NAME
{
dispname = $2;
display = malloc(sizeof (DISPLAY));
if (!display)
errx(-1,
"Failed to allocate memory for display (%d)", lineno);
}
LBRACE HEIGHT NUMBER
{
display->virt_height = $6;
}
WIDTH NUMBER
{
display->virt_width = $9;
}
disp_type disp_attr_table RBRACE
{
if (!display)
errx(-1, "Failed to open display (%d)", lineno);
bind_tuple(root_table, dispname, TT_DISPLAY, (FUNCP)display);
dispname = 0;
}
;
disp_type: /* empty */
{
display->type = DT_ANY;
display->device = 0;
display = default_open(display);
}
| TYPE NCURSES device_ncurses
{ display->type = DT_NCURSES; }
;
device_ncurses: /* empty */
{
/* Use ncurses drivers but on a default tty */
display->device.ncurses = 0;
display = ncurses_open(display);
}
| LBRACE device_ncurses_tty
{
display = ncurses_open(display);
}
device_ncurses_colors RBRACE
;
device_ncurses_tty: /* empty */
{
/* Use ncurses drivers but on a default tty */
display->device.ncurses = 0;
}
| TTYNAME STRING INPUTFILE STRING OUTPUTFILE STRING
{
display->device.ncurses = (NCURSDEV *)malloc(sizeof (NCURSDEV));
if (!display->device.ncurses)
errx(-1, "Failed to allocate memory for ncurses device (%d)", lineno);
display->device.ncurses->ttyname = $2;
display->device.ncurses->input = $4;
display->device.ncurses->output = $6;
}
;
device_ncurses_colors: /* empty */
| COLORPAIRS LBRACE color_pairs RBRACE
;
color_pairs: /* empty */
| color_pairs color_pair
;
color_pair: NUMBER color color
{
if (display)
init_pair($1, $2, $3);
}
;
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; }
;
disp_attr_table: /* empty */
{ display->bind = 0; }
| ATTRTABLE
{
display->bind = hash_create(0);
if (!display->bind)
errx(-1, "Failed to allocate memory for display bindings (%d)", lineno);
}
LBRACE disp_attrs RBRACE
;
disp_attrs: /* empty */
| disp_attrs disp_attr
;
disp_attr: NAME NUMBER
{ bind_tuple(display->bind, $1, TT_ATTR, (FUNCP)$2); }
;
window: WINDOW NAME ON NAME AT NUMBER COMMA NUMBER LBRACE
{
objname = $2;
dispname = $4;
object = malloc(sizeof (OBJECT));
if (!object)
errx(-1, "Failed to allocate memory for window (%d)", lineno);
object->y = $6;
object->x = $8;
object->status = O_VISIBLE;
object->bind = hash_create(0);
if (!object->bind)
errx(-1, "Failed to allocate memory for window's bindings (%d)", lineno);
}
object_params
{
tmptuple = tuple_search(object, dispname, TT_DISPLAY);
if (!tmptuple)
errx(-1, "Couldn't find binding for display (%d)", lineno);
free(dispname);
object->display = (struct Display *)tmptuple->addr;
switch (object->display->type) {
case DT_NCURSES:
default:
object->window.ncurses = malloc(sizeof (NCURSES_WINDOW));
if (!object->window.ncurses)
errx(-1, "Failed to allocate memory for ncurses window, (%d)", lineno);
ncurses_open_window(object);
break;
}
object->parent = 0;
if (!object->height)
object->height = display->height;
if (!object->width)
object->width = display->width;
bind_tuple(root_table, objname, TT_OBJ_INST, (FUNCP)object);
parent = object;
cbind = parent->bind;
}
object RBRACE
{
parent = 0;
cbind = root_table;
}
;
objects: /* empty */
| objects object
;
object: NAME
{
objname = $1;
object = malloc(sizeof (OBJECT));
if (!object)
errx(-1, "Failed to allocate memory for object (%d)", lineno);
object->bind = hash_create(0);
if (!object->bind)
errx(-1, "Failed to allocate memory for ",
"object's bindings (%d)", lineno);
}
at LBRACE use_copy
{
if (useobj) {
/* Need to declare parent to see previous scope levels */
object->parent = parent;
if (use_defined_object(object, useobj) == ST_NOBIND)
errx(-1, "Object, %s, not found in scope (%d)",
useobj, lineno);
}
}
object_params
{
/*
* If this is a function object convert it from
* a definition to an instance (see 'at' below).
*/
if (object->type == OT_FUNCTION)
t_type = TT_OBJ_INST;
/*
* If this is an instance object and it doesn't
* have a parent then there's a syntax error since
* instances can only be specified inside windows.
*/
if (parent)
inherit_properties(object, parent);
else if (t_type != TT_OBJ_DEF)
errx(-1, "Object, %s, has no parent (%d)", objname, lineno);
/* Propagate defobj up through nested compounds */
if (t_type == TT_OBJ_INST &&
parent && parent->type == OT_COMPOUND &&
!parent->object.compound->defobj)
parent->object.compound->defobj =
strdup(objname);
/* Add object and go down to next object */
bind_tuple(cbind, objname, t_type, (FUNCP)object);
parent = object;
cbind = object->bind;
}
objects RBRACE
{
parent = object->parent;
if (parent)
cbind = parent->bind;
else
cbind = root_table;
object = parent;
}
;
at: /* empty */
{
/*
* If there's no 'at' part specified then this is
* either a definition rather than an instance of
* an object or it's a function. Set it to a definition,
* we deal with the function case above.
*/
t_type = TT_OBJ_DEF;
object->y = 0;
object->x = 0;
}
| AT NUMBER COMMA NUMBER
{
t_type = TT_OBJ_INST;
object->y = $2;
object->x = $4;
}
;
use_copy: /* empty */
{ useobj = 0; }
| USE NAME
{ useobj = $2; }
;
object_params: user_draw_func user_proc_func height width attributes highlight on_entry on_exit links object_type
;
object_type: /* empty */
{
/* If we haven't inherited a type assume it's a compound */
if (!object->type) {
object->type = OT_COMPOUND;
object->object.compound = malloc(sizeof (COMPOUND_OBJECT));
if (!object->object.compound)
errx(-1, "Failed to allocate memory for object, (%d)\n",
lineno);
object->object.compound->defobj = 0;
}
}
| object_action
| object_compound
| object_function
| object_input
| object_menu
| object_text
;
links: /* empty */
| links conns
;
conns: UP NAME
{
if (object->lup)
free(object->lup);
object->lup = $2;
}
| DOWN NAME
{
if (object->ldown)
free(object->ldown);
object->ldown = $2;
}
| LEFT NAME
{
if (object->lleft)
free(object->lleft);
object->lleft = $2;
}
| RIGHT NAME
{
if (object->lright)
free(object->lright);
object->lright = $2;
}
| NEXT NAME
{
if (object->lnext)
free(object->lnext);
object->lnext = $2;
}
;
/*
* Parse the action object type.
*/
object_action: ACTION NAME LABEL STRING
{
object->type = OT_ACTION;
object->object.action = malloc(sizeof (ACTION_OBJECT));
if (!object->object.action)
errx(-1, "Failed to allocate memory for object, (%d)\n", lineno);
object->object.action->action = $2;
object->object.action->text = $4;
if (!object->width)
object->width = calc_string_width(object->object.text->text);
if (!object->height)
calc_object_height(object, object->object.text->text);
}
;
/*
* Parse the compound object type.
*/
object_compound: ACTIVE NAME
{
object->type = OT_COMPOUND;
object->object.compound = malloc(sizeof (COMPOUND_OBJECT));
if (!object->object.compound)
errx(-1, "Failed to allocate memory for object, (%d)\n", lineno);
object->object.compound->defobj = $2;
}
;
/*
* Parse the function object type
*/
object_function: CALLFUNC NAME
{
object->type = OT_FUNCTION;
object->object.function = malloc(sizeof (FUNCTION_OBJECT));
if (!object->object.function)
errx(-1, "Failed to allocate memory for object (%d)", lineno);
object->object.function->fn = $2;
}
;
/*
* Parse the input object type
*/
object_input: INPUT
{
object->type = OT_INPUT;
object->object.input = malloc(sizeof (INPUT_OBJECT));
if (!object->object.input)
errx(-1, "Failed to allocate memory for object (%d)", lineno);
}
input_params limit
{
/* Force height to 1 regardless */
object->height = 1;
if (!object->width && !object->object.input->limit) {
if (!object->object.input->label)
errx(-1, "Unable to determine size of input object (%d)",
lineno);
object->width = calc_string_width(object->object.input->label);
object->object.input->limit = object->width;
} else if (!object->width)
object->width = object->object.input->limit;
else if (!object->object.input->limit)
object->object.input->limit = object->width;
if (object->object.input->limit < object->width)
object->width = object->object.input->limit;
object->object.input->input =
malloc(object->object.input->limit + 1);
if (!object->object.input->input)
errx(-1, "Failed to allocate memory for object (%d)", lineno);
/*
* If it's a label then clear the input string
* otherwise copy the default there.
*/
if (object->object.input->lbl_flag)
object->object.input->input[0] = '\0';
else if (object->object.input->label) {
tmp = strlen(object->object.input->label);
strncpy(object->object.input->input,
object->object.input->label,
tmp);
object->object.input->input[tmp] = 0;
}
}
;
input_params: /* empty */
{
object->object.input->lbl_flag = 0;
object->object.input->label = 0;
}
| STRING
{
object->object.input->lbl_flag = 0;
object->object.input->label = $1;
}
| DEFAULT STRING
{
object->object.input->lbl_flag = 0;
object->object.input->label = $2;
}
| LABEL STRING
{
object->object.input->lbl_flag = 1;
object->object.input->label = $2;
}
;
limit: /* empty */
{ object->object.input->limit = 0; }
| LIMIT NUMBER
{ object->object.input->limit = $2; }
;
/*
* Parse the menu object type
*/
object_menu: OPTIONS LBRACE
{
object->type = OT_MENU;
object->object.menu = malloc(sizeof (MENU_OBJECT));
if (!object->object.menu)
errx(-1, "Failed to allocate memory for object (%d)", lineno);
object->object.menu->no_options = 0;
object->object.menu->options = 0;
len = 0;
}
menuoptions
{
object->height = 1;
if (!object->width)
object->width = len;
}
RBRACE option_selected
;
menuoptions: menuoption
| menuoptions menuoption
;
menuoption: STRING
{
tmpstr = $1;
object->object.menu->no_options =
add_menu_option(object->object.menu, tmpstr);
if (!object->object.menu->no_options)
errx(-1, "Failed to allocate memory for option (%d)", lineno);
tmp = calc_string_width(tmpstr);
if (tmp > len)
len = tmp;
free(tmpstr);
}
;
option_selected: /* empty */
{ object->object.menu->selected = 0; }
| SELECTED NUMBER
{ object->object.menu->selected = $2; }
;
/*
* Parse the text object type
*/
object_text: TEXT STRING
{
object->type = OT_TEXT;
object->object.text = malloc(sizeof (TEXT_OBJECT));
if (!object->object.text)
errx(-1, "Failed to allocate memory for object (%d)", lineno);
object->object.text->text = $2;
if (!object->width)
object->width = calc_string_width(object->object.text->text);
if (!object->height)
calc_object_height(object, object->object.text->text);
}
;
user_draw_func: /* empty */
| USERDRAWFUNC NAME
{
if (object->UserDrawFunc)
free(object->UserDrawFunc);
object->UserDrawFunc = $2;
}
;
user_proc_func: /* empty */
| USERPROCFUNC NAME
{
if (object->UserProcFunc)
free(object->UserProcFunc);
object->UserProcFunc = $2;
}
;
height: /* empty */
| HEIGHT NUMBER
{ object->height = $2; }
;
width: /* empty */
| WIDTH NUMBER
{ object->width = $2; }
;
attributes: /* empty */
| ATTR STRING
{
if (object->attributes)
free(object->attributes);
object->attributes = $2;
}
;
highlight: /* empty */
| HIGHLIGHT STRING
{
if (object->highlight)
free(object->highlight);
object->highlight = $2;
}
;
on_entry: /* empty */
| ONENTRY NAME
{
if (object->OnEntry)
free(object->OnEntry);
object->OnEntry = $2;
}
;
on_exit: /* empty */
| ONEXIT NAME
{
if (object->OnExit)
free(object->OnExit);
object->OnExit = $2;
}
;
%%
void
yyerror (char *error)
{
errx(-1, "%s at line %d\n", error, lineno);
}