1 /******************************************************************************
2 
3   #####    ##    #####   #       ######          #    #
4     #     #  #   #    #  #       #               #    #
5     #    #    #  #####   #       #####           ######
6     #    ######  #    #  #       #        ###    #    #
7     #    #    #  #    #  #       #        ###    #    #
8     #    #    #  #####   ######  ######   ###    #    #
9 
10 ******************************************************************************/
11 /* This file is part of MAPMAKER 3.0b, Copyright 1987-1992, Whitehead Institute
12    for Biomedical Research. All rights reserved. See READ.ME for license. */
13 
14 /* Tables are a generally useful structure, allowing one to make a list of
15    strings, where each is assigned either a numeric or alphanumeric key.
16    Tables can be made to either expand themselves as needed, or to bash old
17    entries. Numbered tables are kept sorted, and named tables may be sorted. */
18 
19 typedef struct named_entry {
20     char *string;
21     union { int num; char *name; } id;
22     struct named_entry *next; /* make a linked list */
23 } TABLE_ENTRY;
24 
25 typedef struct {
26     struct named_entry *list, *unused;
27     bool named_entries;
28     int string_length, expands_by;
29     int next_entry_num; /* used if !named_entries */
30 } TABLE;
31 
32 TABLE *allocate_table();
33 /* args: int initial_num_entries, string_length, expands_by, index_by_name; */
34 #define EXPANDS_BY(num_entries) (num_entries)
35 #define CANT_EXPAND 0
36 #define INDEX_BY_NUMBER FALSE
37 #define INDEX_BY_NAME   TRUE
38 
39 void free_table();       /* args: TABLE *list; */
40 
41 void put_named_entry();    /* args: char *name, *string; TABLE *p; */
42 void put_numbered_entry(); /* args: char *string; TABLE *p; int *num; */
43 /* string is saved in table under the index name or num. Names must be
44 single tokens both despace()ed and filter()ed. Numbered strings are
45 assigned numbers sequentially, with numbers starting at 0, indicated by
46 *num. This routine does not check for duplicate names or some other
47 bad things. If the table is out of space for new entries, either more
48 space is added, or the oldest entry is bashed, depending on the setting
49 of expands_by when the list was allocated. */
50 
51 bool get_named_entry();    /* args: char *name; char **string, **full_name;
52 			            TABLE *p; flag *fail;*/
53 bool delete_named_entry(); /* args: char *name; TABLE *p; flag *fail; */
54 /* The string with the specified name is looked up the table using matches()
55 to find an unambiguous match for the (possibly abbreviated) name. If no
56 such string can be found, FALSE is returned and *fail is set to one of the
57 constants below. Otherwise, delete_named_entry() deletes the string from the
58 table, while get_named_entry() side-effects *string and *full_name
59 accordingly. */
60 #define NAME_DOESNT_MATCH 1
61 #define NAME_IS_AMBIGUOUS 2
62 
63 bool get_numbered_entry();    /* args: int num; char **string; TABLE *p; */
64 bool delete_numbered_entry(); /* args: int num; TABLE *p; UNIMPLEMENTED! */
65 /* The string with the specified number is looked up the table. If no
66 such string can be found, FALSE is returned. Otherwise,
67 delete_numbered_entry() deletes the string from the table, while
68 get_numbered_entry() side-effects *string to point to it. */
69 
70 bool table_full();          /* args: TABLE *p; */
71   /* TRUE iff the list is full AND it can't be expanded. */
72 bool table_empty();         /* args: TABLE *p; */
73 int  count_table_entries(); /* args: TABLE *p; */
74 #define next_entry_number(table) ((table)->next_entry_num)
75 
76 bool valid_name(); /* args: char *name; */
77 
78 /* iterator macros:
79 
80    for_all_numbered_entries()  args: TABLE *p; char *string; int num;
81    for_all_named_entries()     args: TABLE *p; char *string, *name;
82 
83 Iterate over all entries in the table, setting num to the number or
84 name to the name, and string to the string (note that these are NOT
85 pointers to the side-effected variables, as is necessary in C
86 functions). The loop always goes in a FIFO (first-in, first-out)
87 fashion. Do not put one for_all...() loop inside another! */
88 
89 #define for_named_entries(Table,Str,Name) 				\
90  for (Te=Table->list, Name=Te->id.name, Str=Te->string; 		\
91       Te!=NULL; 							\
92       Te=Te->next, Name=Te->id.name, Str=Te->string)
93 
94 #define for_numbered_entries(Table,Str,Num) 				\
95  for (Te=Table->list, Num=Te->id.num, Str=Te->string; 			\
96       Te!=NULL; 							\
97       Te=Te->next, Num=Te->id.num, Str=Te->string)
98 
99 extern TABLE_ENTRY *Te;
100 
101 void save_table(), load_table();
102 
103 extern TABLE *cmd_history;
104 
105 #define NAME_TAG_CHARS    "*"
106 #define NUMBER_TAG_CHARS  "#"
107 
108 #define NAME_FIRST_CHARS \
109 	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
110 #define NAME_CHARS \
111  	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._"
112