C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
Menu Parser

Functions for parsing menu description files and creating Menu structures. More...

Functions

unsigned int get_command_type (char *t)
 Get command type from command string.
unsigned int parse_menu_description (Init *init)
 Parse menu description file and create Menu.

Detailed Description

Functions for parsing menu description files and creating Menu structures.

Function Documentation

◆ get_command_type()

unsigned int get_command_type ( char * t)

Get command type from command string.

Parameters
tCommand string
Returns
Command type as an unsigned int

Definition at line 228 of file parse_menu_desc.c.

228 {
229 char *s, *p;
230
231 s = p = t;
232 while (*s != ' ' && *s != '\0') {
233 if (*s == '/')
234 p = s + 1;
235 s++;
236 }
237 *s = '\0';
238 if (!strcmp(p, "ckeys"))
239 return (CT_CKEYS);
240 else if (!strcmp(p, "dmon"))
241 return (CT_DMON);
242 else if (!strcmp(p, "exec"))
243 return (CT_EXEC);
244 else if (!strcmp(p, "help"))
245 return (CT_HELP);
246 else if (!strcmp(p, "about"))
247 return (CT_ABOUT);
248 else if (!strcmp(p, "menu"))
249 return (CT_MENU);
250 else if (!strcmp(p, "form"))
251 return (CT_FORM);
252 else if (!strcmp(p, "pick"))
253 return (CT_PICK);
254 else if (!strcmp(p, "return"))
255 return (CT_RETURN);
256 else if (!strcmp(p, "view"))
257 return (CT_VIEW);
258 else if (!strcmp(p, "?"))
259 return (CT_HELP);
260 else if (!strcmp(p, "write_config"))
261 return (CT_WRITE_CONFIG);
262 return (CT_UNDEFINED);
263}
@ CT_PICK
Definition menu.h:46
@ CT_FORM
Definition menu.h:42
@ CT_UNDEFINED
Definition menu.h:52
@ CT_MENU
Definition menu.h:45
@ CT_RETURN
Definition menu.h:49
@ CT_HELP
Definition menu.h:40
@ CT_WRITE_CONFIG
Definition menu.h:51
@ CT_EXEC
Definition menu.h:39
@ CT_VIEW
Definition menu.h:47
@ CT_ABOUT
Definition menu.h:41
@ CT_DMON
Definition menu.h:38
@ CT_CKEYS
Definition menu.h:48

References CT_ABOUT, CT_CKEYS, CT_DMON, CT_EXEC, CT_FORM, CT_HELP, CT_MENU, CT_PICK, CT_RETURN, CT_UNDEFINED, CT_VIEW, and CT_WRITE_CONFIG.

Referenced by parse_menu_description().

Here is the caller graph for this function:

◆ parse_menu_description()

unsigned int parse_menu_description ( Init * init)

Parse menu description file and create Menu.

Parameters
initPointer to Init structure containing menu information
Returns
0 on success, non-zero on failure

'!' Command

':' Choice

< in_buf -> Title

' ' Empty line, ignore

Definition at line 29 of file parse_menu_desc.c.

29 {
30 FILE *fp;
31 char tmp_str[MAXLEN];
32 char tmp_buf[MAXLEN];
33 char in_buf[MAXLEN];
34 char *in_buf_p;
35 unsigned char ltr;
36 bool fltr[127];
37 int directive;
38 int l;
39 char *s;
40 int commands = 0;
41 int choices = 0;
42 int in_fp_line = 0;
43 menu = init->menu;
44 fp = fopen(menu->mapp_spec, "r");
45 if (fp == nullptr) {
46 strnz__cpy(tmp_buf, "file not found", MAXLEN);
47 abend(-1, tmp_buf);
48 exit(-1);
49 }
50 while ((fgets(in_buf, MAXLEN, fp)) != nullptr) {
51 if (in_buf[0] == '\0')
52 continue;
53 in_fp_line++;
54 // Replace carriage returns, newlines, and tabs in in_buf with null
55 // terminators and spaces
56 chrep(in_buf, '\r', '\0');
57 chrep(in_buf, '\n', '\0');
58 chrep(in_buf, '\t', ' ');
59 in_buf_p = in_buf;
60 directive = *in_buf_p;
61 in_buf_p++;
62
63 strnz__cpy(tmp_buf, in_buf_p, MAXLEN);
64 trim(tmp_buf);
65 l = strlen(tmp_buf);
66 if (l == 0)
67 continue;
68 if (directive == '#')
69 continue;
70 for (ltr = 0; ltr < 32; ltr++)
71 fltr[ltr] = true;
72 for (ltr = 32; ltr < 127; ltr++)
73 fltr[ltr] = false;
74 fltr['q'] = true;
75 switch (directive) {
77 case '!':
78 if (!menu->line_idx)
79 break;
80 if (menu->line[menu->line_idx - 1]->type != MT_TEXT)
81 break;
82
83 // Convert tmp_buf to command_str and determine command_type
84 menu->line_idx--;
85 menu->line[menu->line_idx]->command_str = strdup(tmp_buf);
86 menu->line[menu->line_idx]->command_type =
87 get_command_type(tmp_buf);
88 s = menu->line[menu->line_idx]->raw_text;
89 l = min(strlen(s), (size_t)(MAXLEN - 1));
90 if (l > menu->choice_max_len)
91 menu->choice_max_len = l;
92 // if the choice text starts with '-' or '_',
93 // reserve the next character as the choice_letter
94 // and remove the choice_letter designator from the choice text
95 if (*s == '-' || *s == '_') {
96 s++;
97 ltr = *s;
98 if (ltr > 31 && ltr < 127) {
99 if (!fltr[ltr]) {
100 fltr[ltr] = true;
101 menu->line[menu->line_idx]->choice_letter = *s;
102 }
103 }
104 s++;
105 }
106 strnz__cpy(tmp_buf, " x - ", MAXLEN - 1);
107 strnz__cat(tmp_buf, s, MAXLEN - 1);
108 menu->line[menu->line_idx]->choice_text = strdup(tmp_buf);
109 menu->line[menu->line_idx]->type = MT_CHOICE;
110 menu->line_idx++;
111 commands++;
112 break;
114 case ':':
115 if (choices > commands) {
116 ssnprintf(em0, MAXLEN - 1,
117 "More choices than commands at line %d of",
118 in_fp_line);
119 strnz__cpy(em1, menu->mapp_spec, MAXLEN - 1);
120 strnz__cpy(em2, in_buf, MAXLEN - 1);
121 display_error(em0, em1, em2, nullptr);
122 abend(-1, "unrecoverable error");
123 }
124 l = strlen(tmp_buf);
125 menu->text_max_len = max(menu->text_max_len, l);
126 if (!menu->title[0]) {
127 // if menu title is not set, use this line as the title,
128 l = min(l, (MAXLEN - 5));
129 strnz__cpy(menu->title, tmp_buf, l);
130 l += 4;
131 menu->text_max_len = max(menu->text_max_len, l);
132 } else {
133 // otherwise add it as a text line
134 menu->line[menu->line_idx] = calloc(1, sizeof(Line));
135 if (menu->line[menu->line_idx] == (Line *)0) {
136 sprintf(tmp_str,
137 "2-malloc(%ld bytes) failed menu->line[%d]",
138 sizeof(Line), menu->line_idx);
139 abend(-1, tmp_str);
140 }
141 menu->line[menu->line_idx]->type = MT_TEXT;
142 menu->line[menu->line_idx]->raw_text = strdup(tmp_buf);
143 menu->line_idx++;
144 choices++;
145 }
146 break;
147 case '?':
148 break;
149 case ' ':
150 case '\0':
151 case '\n':
152 break;
153 default:
154 ssnprintf(em0, MAXLEN - 1, "Invalid directive '%c' at line %d of",
155 directive, in_fp_line);
156 strnz__cpy(em1, menu->mapp_spec, MAXLEN - 1);
157 strnz__cpy(em2, in_buf, MAXLEN - 1);
158 display_error(em0, em1, em2, nullptr);
159 }
160 }
161 fclose(fp);
162 menu->item_count = menu->line_idx;
163 for (menu->line_idx = 0; menu->line_idx < menu->item_count;
164 menu->line_idx++) {
165 menu->line[menu->line_idx]->letter_pos = 1;
166 // Try to get a choice_letter
167 // skip past " x - "
168 if (menu->line[menu->line_idx]->choice_letter != '\0') {
169 ltr = menu->line[menu->line_idx]->choice_letter;
170 s = menu->line[menu->line_idx]->choice_text + 5;
171 while (*s != '\0') {
172 if (*s == ltr) {
173 menu->line[menu->line_idx]->letter_pos =
174 s - menu->line[menu->line_idx]->choice_text;
175 break;
176 }
177 s++;
178 }
179 fltr[ltr] = true;
180 } else {
181 s = menu->line[menu->line_idx]->choice_text + 5;
182 // Search string for first character that is not a space and not
183 // already used as a choice_letter
184 while (*s != '\0') {
185 if (*s != ' ')
186 if (!fltr[(int)(uintptr_t)*s]) {
187 ltr = *s;
188 fltr[ltr] = true;
189 break;
190 }
191 s++;
192 }
193 if (*s != '\0') {
194 menu->line[menu->line_idx]->letter_pos =
195 s - menu->line[menu->line_idx]->choice_text;
196 ltr = *s;
197 } else {
198 // If no letter found in choice text, find the first unused
199 // letter in the ASCII range 32-126
200 for (ltr = '0'; ltr < 127; ltr++)
201 if (fltr[ltr] == false) {
202 fltr[ltr] = true;
203 break;
204 }
205 if (ltr > 126) {
206 Perror("Ran out of letters");
207 return 0;
208 }
209 }
210 }
211 menu->line[menu->line_idx]->choice_letter = ltr;
212 menu->line[menu->line_idx]->choice_text[1] = ltr;
213 }
214 menu->lines = menu->item_count;
215 if (menu->text_max_len > (menu->choice_max_len + 6))
216 menu->cols = menu->text_max_len;
217 else
218 menu->cols = menu->choice_max_len + 6;
219 if (menu->cols >= MAXLEN)
220 Perror("line too long");
221 return 0;
222}
Init * init
Definition init.c:74
#define min(x, y)
min macro evaluates two expressions, returning least result
Definition cm.h:56
#define max(a, b)
max macro evaluates two expressions, returning greatest result.
Definition cm.h:49
Menu * menu
Definition mem.c:45
@ MT_TEXT
Definition menu.h:23
@ MT_CHOICE
Definition menu.h:24
#define MAXLEN
Definition curskeys.c:15
char em1[MAXLEN]
Definition dwin.c:142
char em0[MAXLEN]
Definition dwin.c:141
char em2[MAXLEN]
Definition dwin.c:143
int Perror(char *)
Display a simple error message window or print to stderr.
Definition dwin.c:1162
int display_error(char *em0, char *em1, char *em2, char *em3)
Display an error message window or print to stderr.
Definition dwin.c:1102
void abend(int, char *)
Abnormal program termination.
Definition dwin.c:1588
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
Definition futil.c:435
size_t trim(char *)
Trims leading and trailing spaces from string s in place.
Definition futil.c:282
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
Definition futil.c:311
size_t strnz__cat(char *, const char *, size_t)
safer alternative to strncat
Definition futil.c:464
bool chrep(char *, char, char)
Replaces all occurrences of old_chr in s with new_chr in place.
Definition futil.c:652
unsigned int get_command_type(char *)
Get command type from command string.
The Line strutures are attached to the Menu main structure.
Definition menu.h:57

References abend(), Line::choice_letter, Menu::choice_max_len, Line::choice_text, chrep(), Menu::cols, Line::command_str, Line::command_type, display_error(), em0, em1, em2, get_command_type(), Menu::item_count, Line::letter_pos, Menu::line, Menu::line_idx, Menu::lines, Menu::mapp_spec, Init::menu, menu, MT_CHOICE, MT_TEXT, Perror(), Line::raw_text, ssnprintf(), strnz__cat(), strnz__cpy(), Menu::text_max_len, Menu::title, trim(), and Line::type.

Referenced by menu_engine().

Here is the call graph for this function:
Here is the caller graph for this function: