summaryrefslogtreecommitdiff
path: root/lib/libforms/forms.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libforms/forms.c')
-rw-r--r--lib/libforms/forms.c147
1 files changed, 97 insertions, 50 deletions
diff --git a/lib/libforms/forms.c b/lib/libforms/forms.c
index a51c95e28932..a7207beede89 100644
--- a/lib/libforms/forms.c
+++ b/lib/libforms/forms.c
@@ -32,6 +32,7 @@
*
*/
+#include <hash.h>
#include <stdio.h>
#include <stdlib.h>
#include <forms.h>
@@ -42,8 +43,7 @@
extern FILE *yyin;
-struct Tuple *fbind_first;
-struct Tuple *fbind_last;
+hash_table *global_bindings;
unsigned int f_keymap[] = {
KEY_UP, /* F_UP */
@@ -65,6 +65,11 @@ form_load(const char *filename)
{
FILE *fd;
+ global_bindings = hash_create(0);
+
+ if (!global_bindings)
+ return (FS_ERROR);
+
if (!(fd = fopen(filename, "r"))) {
warn("Couldn't open forms file %s", filename);
return (FS_ERROR);
@@ -78,17 +83,40 @@ form_load(const char *filename)
return (FS_ERROR);
}
+ hash_stats(global_bindings, 1);
+
return (FS_OK);
}
+int
+find_editable(char *key, void *data, void *arg)
+{
+ struct Tuple *tuple = (struct Tuple *)data;
+ struct Field *field;
+
+ if (tuple->type != FT_FIELD_INST)
+ return (1);
+
+ field = (struct Field *)tuple->addr;
+
+ if ((field->type == FF_INPUT) ||
+ (field->type == FF_MENU) ||
+ (field->type == FF_ACTION)) {
+ arg = field;
+ return (0);
+ } else
+ return (1);
+}
+
struct Form *
-form_start(const char *formname)
+form_start(char *formname)
{
struct Tuple *tuple;
struct Form *form;
- struct Field *field;
+ struct Field *field = 0;
+ struct Field *start = 0;
- tuple = form_get_tuple(formname, FT_FORM);
+ tuple = form_get_tuple(global_bindings, formname, FT_FORM);
if (!tuple) {
warnx("No such form");
@@ -109,22 +137,24 @@ form_start(const char *formname)
return (0);
}
- tuple = form_get_tuple(form->startfield, FT_FIELD_INST);
+ /* Initialise the field instances */
+
+ hash_traverse(form->bindings, init_field, field);
+
+ tuple = form_get_tuple(form->bindings, form->startfield, FT_FIELD_INST);
if (!tuple) {
warnx("No start field specified");
- /* XXX should search for better default start */
- form->current_field = form->fieldlist;
+ /* Search for an editable field */
+ hash_traverse(form->bindings, &find_editable, start);
+ form->current_field = start;
} else
form->current_field = (struct Field *)tuple->addr;
- form->prev_field = form->current_field;
-
- /* Initialise the field instances */
+ if (!form->current_field)
+ errx(1, "No suitable start field found, aborting");
- for (field = form->fieldlist; field; field = field->next) {
- init_field(field);
- }
+ form->prev_field = form->current_field;
form->status = FS_RUNNING;
@@ -132,7 +162,7 @@ form_start(const char *formname)
}
int
-form_bind_tuple(char *name, TupleType type, void *addr)
+form_bind_tuple(hash_table *htable, char *name, TupleType type, void *addr)
{
struct Tuple *tuple;
@@ -147,54 +177,71 @@ form_bind_tuple(char *name, TupleType type, void *addr)
tuple->addr = addr;
tuple->next = 0;
-
- if (!fbind_first) {
- fbind_first = tuple;
- fbind_last = tuple;
- } else {
+ if (!htable)
+ return (FS_ERROR);
+ else {
/* Check there isn't already a tuple of this type with this name */
- if (form_get_tuple(name, type)) {
+ if (form_get_tuple(htable, name, type)) {
warn("Duplicate tuple name, %s, skipping", name);
return (FS_ERROR);
- }
- fbind_last->next = tuple;
- fbind_last = tuple;
+ } else
+ hash_search(htable, tuple->name, tuple, NULL);
}
return (0);
}
-struct Tuple *
-form_get_tuple(const char *name, TupleType type)
+int
+tuple_match_any(char *key, struct Tuple *tuple, TupleType *type)
{
- return (form_next_tuple(name, type, fbind_first));
+ if (tuple->type != *type) {
+ type = 0;
+ return (1);
+ } else {
+ type = (TupleType *)tuple;
+ return (0);
+ }
}
struct Tuple *
-form_next_tuple(const char *name, TupleType type, struct Tuple *tuple)
+form_get_tuple(hash_table *htable, char *key, TupleType type)
{
- for (; tuple; tuple = tuple->next) {
- if (type != FT_ANY)
- if (tuple->type != type)
- continue;
- if (name)
- if (strcmp(name, tuple->name))
- continue;
- return (tuple);
+ 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(htable, key, NULL, NULL));
+ else {
+ hash_traverse(htable, &tuple_match_any, arg);
+ return (arg);
}
+}
+
+int
+show_field(char *key, void *data, void *arg)
+{
+ struct Tuple *tuple = (struct Tuple *)data;
+ struct Field *field = (struct Field *)tuple->addr;
+
+ display_field(arg, field);
+
+ return (1);
- return (0);
}
int
-form_show(const char *formname)
+form_show(char *formname)
{
struct Tuple *tuple;
struct Form *form;
- struct Field *field;
int x, y;
- tuple = form_get_tuple(formname, FT_FORM);
+ tuple = form_get_tuple(global_bindings, formname, FT_FORM);
if (!tuple)
return (FS_NOBIND);
@@ -206,9 +253,7 @@ form_show(const char *formname)
for (x=0; x < form->width; x++)
mvwaddch(form->window, y, x, ' ');
- for (field = form->fieldlist; field; field = field->next) {
- display_field(form->window, field);
- }
+ hash_traverse(form->bindings, show_field, form->window);
return (FS_OK);
}
@@ -223,35 +268,35 @@ do_key_bind(struct Form *form, unsigned int ch)
if (ch == FK_UP) {
if (field->fup) {
- tuple = form_get_tuple(field->fup, FT_FIELD_INST);
+ tuple = form_get_tuple(form->bindings, field->fup, FT_FIELD_INST);
if (!tuple)
print_status("Field to move up to does not exist");
} else
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);
+ tuple = form_get_tuple(form->bindings, field->fdown, FT_FIELD_INST);
if (!tuple)
print_status("Field to move down to does not exist");
} else
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);
+ tuple = form_get_tuple(form->bindings, field->fleft, FT_FIELD_INST);
if (!tuple)
print_status("Field to move left to does not exist");
} else
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);
+ tuple = form_get_tuple(form->bindings, field->fright, FT_FIELD_INST);
if (!tuple)
print_status("Field to move right to does not exist");
} else
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);
+ tuple = form_get_tuple(form->bindings, field->fnext, FT_FIELD_INST);
if (!tuple)
print_status("Field to move to next does not exist");
} else
@@ -270,12 +315,13 @@ do_key_bind(struct Form *form, unsigned int ch)
}
}
+#ifdef DEBUG_NOT_YET
void
-debug_dump_bindings()
+debug_dump_bindings(hash_table *htable)
{
struct Tuple *binds;
- binds = form_get_tuple(0, FT_ANY);
+ binds = form_get_tuple(htable, 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);
@@ -292,3 +338,4 @@ void debug_dump_form(struct Form *form)
printf("%s, %x, next = %x\n", field->defname, (int)field, (int)field->next);
}
}
+#endif