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 parse_menu_description (Init *init)
 Parse menu description file and create Menu.
unsigned int get_command_type (char *t)
 Get command type from command string.

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 251 of file parse_menu_desc.c.

251 {
252 char *s, *p;
253
254 s = p = t;
255 while (*s != ' ' && *s != '\0') {
256 if (*s == '/')
257 p = s + 1;
258 s++;
259 }
260 *s = '\0';
261 if (!strcmp(p, "ckeys"))
262 return (CT_CKEYS);
263 else if (!strcmp(p, "exec"))
264 return (CT_EXEC);
265 else if (!strcmp(p, "help"))
266 return (CT_HELP);
267 else if (!strcmp(p, "about"))
268 return (CT_ABOUT);
269 else if (!strcmp(p, "menu"))
270 return (CT_MENU);
271 else if (!strcmp(p, "form"))
272 return (CT_FORM);
273 else if (!strcmp(p, "pick"))
274 return (CT_PICK);
275 else if (!strcmp(p, "return"))
276 return (CT_RETURN);
277 else if (!strcmp(p, "view"))
278 return (CT_VIEW);
279 else if (!strcmp(p, "?"))
280 return (CT_HELP);
281 else if (!strcmp(p, "write_config"))
282 return (CT_WRITE_CONFIG);
283 return (CT_UNDEFINED);
284}
@ CT_PICK
Definition menu.h:37
@ CT_FORM
Definition menu.h:33
@ CT_UNDEFINED
Definition menu.h:43
@ CT_MENU
Definition menu.h:36
@ CT_RETURN
Definition menu.h:40
@ CT_HELP
Definition menu.h:31
@ CT_WRITE_CONFIG
Definition menu.h:42
@ CT_EXEC
Definition menu.h:30
@ CT_VIEW
Definition menu.h:38
@ CT_ABOUT
Definition menu.h:32
@ CT_CKEYS
Definition menu.h:39

References CT_ABOUT, CT_CKEYS, 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

':' Text line, parse and add to menu

< 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 int Pos;
36 unsigned char ltr;
37 unsigned char fltr[127];
38 int directive;
39 int l;
40 char *s, *d, *e;
41 int actions = 0;
42 int choices = 0;
43 int in_fp_line = 0;
44 menu = init->menu;
45 fp = fopen(menu->mapp_spec, "r");
46 if (fp == nullptr) {
47 strnz__cpy(tmp_buf, "file not found", MAXLEN);
48 abend(-1, tmp_buf);
49 exit(-1);
50 }
51 while ((fgets(in_buf, MAXLEN, fp)) != nullptr) {
52 if (in_buf[0] == '\0')
53 continue;
54 in_fp_line++;
55 chrep(in_buf, '\r', '\0');
56 chrep(in_buf, '\n', '\0');
57 chrep(in_buf, '\t', ' ');
58 in_buf_p = in_buf;
59 directive = *in_buf_p;
60 in_buf_p++;
61 strnz__cpy(tmp_buf, in_buf_p, MAXLEN);
62 trim(tmp_buf);
63 l = strlen(tmp_buf);
64 if (!l)
65 continue;
66 if (directive == '#')
67 continue;
68 switch (directive) {
70 case '!':
71 if (!menu->line_idx)
72 break;
73 if (menu->line[menu->line_idx - 1]->type != MT_TEXT)
74 break;
75 menu->line_idx--;
76 l = strlen(tmp_buf);
77 if (l + 1 > MAXLEN)
78 break;
79 menu->line[menu->line_idx]->command_str =
80 calloc(MAXLEN + 1, sizeof(char));
81 if (!menu->line[menu->line_idx]->command_str) {
82 sprintf(tmp_str,
83 "0-malloc(%d bytes) failed M-L[%d]->command_str",
84 MAXLEN + 1, menu->line_idx);
85 abend(-1, tmp_str);
86 }
87 strnz__cpy(menu->line[menu->line_idx]->command_str, tmp_buf,
88 MAXLEN - 1);
89 menu->line[menu->line_idx]->command_type =
90 get_command_type(tmp_buf);
91 s = menu->line[menu->line_idx]->raw_text;
92 if (*s == '-' || *s == '_') {
93 s++;
94 ltr = *s++;
95 } else
96 ltr = *s;
97 l = 0;
98 while (*s++ != '\0')
99 l++;
100 if (l + 1 > MAXLEN)
101 l = MAXLEN - 1;
102 menu->line[menu->line_idx]->choice_text =
103 calloc(MAXLEN + 1, sizeof(char));
104 if (!menu->line[menu->line_idx]->choice_text) {
105 sprintf(tmp_str,
106 "1-malloc(%d bytes) failed M-L[%d]->choice_text",
107 MAXLEN + 1, menu->line_idx);
108 abend(-1, tmp_str);
109 }
110 d = menu->line[menu->line_idx]->choice_text;
111 e = d + l;
112 s = menu->line[menu->line_idx]->raw_text;
113 if (*s == '-' || *s == '_')
114 s += 2;
115 while (*s != '\0' && d < e)
116 *d++ = *s++;
117 *d = (char)'\0';
118 if (l > menu->choice_max_len)
119 menu->choice_max_len = l;
120 if (menu->line[menu->line_idx]->command_type == CT_RETURN)
121 menu->line[menu->line_idx]->choice_letter = 'Q';
122 else
123 menu->line[menu->line_idx]->choice_letter = ltr;
124 menu->line[menu->line_idx]->type = MT_CHOICE;
125 menu->line_idx++;
126 actions++;
127 break;
129 case ':':
130 if (choices > actions) {
131 ssnprintf(em0, MAXLEN - 1,
132 "More choices than actions at line %d of",
133 in_fp_line);
134 strnz__cpy(em1, menu->mapp_spec, MAXLEN - 1);
135 strnz__cpy(em2, in_buf, MAXLEN - 1);
136 display_error(em0, em1, em2, nullptr);
137 abend(-1, "unrecoverable error");
138 }
139 chrep(tmp_buf, '\t', ' ');
140 l = strlen(tmp_buf);
141 if (l > menu->text_max_len)
142 menu->text_max_len = l;
143 if (!menu->title[0]) {
144 if (l + 5 > MAXLEN)
145 l = MAXLEN - 5;
146 strnz__cpy(menu->title, tmp_buf, l);
147 l += 4;
148 if (l > menu->text_max_len)
149 menu->text_max_len = l;
150 } else {
151 menu->line[menu->line_idx] = calloc(1, sizeof(Line));
152 if (menu->line[menu->line_idx] == (Line *)0) {
153 sprintf(tmp_str,
154 "2-malloc(%ld bytes) failed menu->line[%d]",
155 sizeof(Line), menu->line_idx);
156 abend(-1, tmp_str);
157 }
158 menu->line[menu->line_idx]->type = MT_TEXT;
159 menu->line[menu->line_idx]->raw_text = strdup(tmp_buf);
160 menu->line[menu->line_idx]->choice_text = nullptr;
161 menu->line[menu->line_idx]->choice_letter = '\0';
162 menu->line[menu->line_idx]->letter_pos = 0;
163 menu->line[menu->line_idx]->command_type = '\0';
164 menu->line[menu->line_idx]->command_str = nullptr;
165 menu->line_idx++;
166 choices++;
167 }
168 break;
169 case '?':
170 break;
171 case ' ':
172 case '\0':
173 case '\n':
174 break;
175 default:
176 ssnprintf(em0, MAXLEN - 1, "Invalid directive '%c' at line %d of",
177 directive, in_fp_line);
178 strnz__cpy(em1, menu->mapp_spec, MAXLEN - 1);
179 strnz__cpy(em2, in_buf, MAXLEN - 1);
180 display_error(em0, em1, em2, nullptr);
181 }
182 }
183 fclose(fp);
184 menu->item_count = menu->line_idx;
185 for (ltr = '0'; ltr < 'z'; ltr++)
186 fltr[ltr] = FALSE;
187 fltr['Q'] = TRUE;
188 for (menu->line_idx = 0; menu->line_idx < menu->item_count;
189 menu->line_idx++) {
190 ltr = menu->line[menu->line_idx]->choice_letter;
191 if (ltr < '0' || ltr > 'z')
192 ltr = '0';
193 if (!fltr[ltr] ||
194 (menu->line[menu->line_idx]->command_type == CT_RETURN &&
195 ltr == 'Q')) {
196 fltr[ltr] = TRUE;
197 s = menu->line[menu->line_idx]->choice_text;
198 Pos = 0;
199 while (*s != '\0') {
200 if (*s == ltr)
201 break;
202 s++;
203 Pos++;
204 }
205 } else {
206 Pos = 0;
207 while (ltr != '\0') {
208 Pos++;
209 ltr = toupper(menu->line[menu->line_idx]->choice_text[Pos]);
210 if (ltr >= '0' && ltr <= 'Z')
211 if (!fltr[ltr])
212 break;
213 }
214 if (ltr == '\0') {
215 for (ltr = '0'; ltr < 'Z'; ltr++)
216 if (!fltr[ltr])
217 break;
218 if (ltr > 'z') {
219 Perror("Ran out of letters");
220 return 0;
221 }
222 }
223 fltr[ltr] = TRUE;
224 menu->line[menu->line_idx]->choice_letter = ltr;
225 }
226 menu->line[menu->line_idx]->letter_pos = Pos;
227 }
228 menu->lines = menu->item_count;
229 if (menu->text_max_len > (menu->choice_max_len + 6))
230 menu->cols = menu->text_max_len;
231 else
232 menu->cols = menu->choice_max_len + 6;
233 if (menu->cols >= MAXLEN)
234 Perror("line too long");
235 for (menu->line_idx = 0; menu->line_idx < menu->item_count;
236 menu->line_idx++) {
237 strnz__cpy(tmp_buf, " x - ", MAXLEN - 1);
238 tmp_buf[1] = menu->line[menu->line_idx]->choice_letter;
239 strnz__cat(tmp_buf, menu->line[menu->line_idx]->choice_text,
240 MAXLEN - 1);
241 strnz__cpy(menu->line[menu->line_idx]->choice_text, tmp_buf,
242 MAXLEN - 1);
243 }
244 return 0;
245}
Init * init
Definition common.h:186
@ MT_TEXT
Definition menu.h:22
@ MT_CHOICE
Definition menu.h:22
Menu * menu
Definition mem.c:45
#define TRUE
Definition iloan.c:19
#define FALSE
Definition iloan.c:18
#define MAXLEN
Definition curskeys.c:15
char em1[MAXLEN]
Definition dwin.c:133
char em0[MAXLEN]
Definition dwin.c:132
char em2[MAXLEN]
Definition dwin.c:134
int Perror(char *)
Display a simple error message window or print to stderr.
Definition dwin.c:1110
int display_error(char *em0, char *em1, char *em2, char *em3)
Display an error message window or print to stderr.
Definition dwin.c:1054
void abend(int, char *)
Abnormal program termination.
Definition dwin.c:1331
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
Definition futil.c:269
size_t trim(char *)
Trims leading and trailing spaces from string s in place.
Definition futil.c:118
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
Definition futil.c:147
size_t strnz__cat(char *, const char *, size_t)
safer alternative to strncat
Definition futil.c:298
bool chrep(char *, char, char)
Replaces all occurrences of old_chr in s with new_chr in place.
Definition futil.c:486
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:48

References abend(), Line::choice_letter, Menu::choice_max_len, Line::choice_text, chrep(), Menu::cols, Line::command_str, Line::command_type, CT_RETURN, 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_cmd_processor(), and menu_engine().

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