/[LeafOK_CVS]/lbbs/src/menu.c
ViewVC logotype

Annotation of /lbbs/src/menu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.21 - (hide annotations)
Mon Apr 28 03:31:00 2025 UTC (10 months, 2 weeks ago) by sysadm
Branch: MAIN
Changes since 1.20: +397 -413 lines
Content type: text/x-csrc
Update

1 sysadm 1.1 /***************************************************************************
2 sysadm 1.21 menu.c - description
3     -------------------
4     begin : Wed Mar 16 2004
5     copyright : (C) 2005 by Leaflet
6     email : leaflet@leafok.com
7 sysadm 1.1 ***************************************************************************/
8    
9     /***************************************************************************
10     * *
11     * This program is free software; you can redistribute it and/or modify *
12     * it under the terms of the GNU General Public License as published by *
13     * the Free Software Foundation; either version 2 of the License, or *
14     * (at your option) any later version. *
15     * *
16     ***************************************************************************/
17    
18 sysadm 1.3 #include "bbs.h"
19 sysadm 1.17 #include "bbs_cmd.h"
20 sysadm 1.1 #include "menu.h"
21     #include "io.h"
22 sysadm 1.2 #include "common.h"
23 sysadm 1.1 #include <stdio.h>
24     #include <ctype.h>
25 sysadm 1.2 #include <regex.h>
26 sysadm 1.6 #include <stdlib.h>
27 sysadm 1.1
28 sysadm 1.2 MENU_SET bbs_menu;
29 sysadm 1.1
30 sysadm 1.21 int load_menu(MENU_SET *p_menu_set, const char *conf_file)
31 sysadm 1.1 {
32 sysadm 1.21 FILE *fin, *fout;
33     int i = 0, j;
34     char buffer[256], screen_filename[256], temp[256];
35     regmatch_t pmatch[10];
36    
37     if ((fin = fopen(conf_file, "r")) == NULL)
38     {
39     log_error("Open %s failed", conf_file);
40     return -1;
41     }
42    
43     strcpy(p_menu_set->conf_file, conf_file);
44    
45     while (fgets(buffer, 255, fin))
46 sysadm 1.3 {
47 sysadm 1.21 switch (buffer[0])
48     {
49     case '#':
50     break;
51     case '%':
52     if (ireg("^%S_([A-Za-z0-9_]+)", buffer, 2, pmatch) == 0)
53     {
54     strncpy(temp, buffer + pmatch[1].rm_so,
55     pmatch[1].rm_eo - pmatch[1].rm_so);
56     temp[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
57     sprintf(screen_filename, "%sMENU_SCR_%s", app_temp_dir, temp);
58    
59     if ((fout = fopen(screen_filename, "w")) == NULL)
60     {
61     log_error("Open %s failed", screen_filename);
62     return -2;
63     }
64    
65     while (fgets(buffer, 255, fin))
66     {
67     if (buffer[0] != '%')
68     fputs(buffer, fout);
69     else
70     break;
71     }
72    
73     fclose(fout);
74     break;
75     }
76    
77     if (ireg("^%menu ([A-Za-z0-9_]+)", buffer, 2, pmatch) == 0)
78     {
79     p_menu_set->p_menu[i] = malloc(sizeof(MENU));
80     p_menu_set->p_menu[i]->title.show = 0;
81     p_menu_set->p_menu[i]->screen.show = 0;
82    
83     strncpy(p_menu_set->p_menu[i]->name,
84     buffer + pmatch[1].rm_so,
85     pmatch[1].rm_eo - pmatch[1].rm_so);
86     p_menu_set->p_menu[i]->name[pmatch[1].rm_eo - pmatch[1].rm_so] =
87     '\0';
88    
89     j = 0;
90    
91     while (fgets(buffer, 255, fin))
92     {
93     if (buffer[0] == '#')
94     {
95     continue;
96     }
97     if (buffer[0] == '%')
98     {
99     p_menu_set->p_menu[i]->item_count = j;
100     p_menu_set->p_menu[i]->item_cur_pos = 0;
101     i++;
102     break;
103     }
104     if (ireg("^!([A-Za-z0-9_.]+)[[:space:]]*([0-9]+),"
105     "[[:space:]]*([0-9]+),[[:space:]]*([0-9]+),"
106     "[[:space:]]*([0-9]+),[[:space:]]*\"([^\"]+)\","
107     "[[:space:]]*\"([^\"]+)\"",
108     buffer, 8, pmatch) == 0)
109     {
110     p_menu_set->p_menu[i]->items[j] =
111     malloc(sizeof(MENU_ITEM));
112     p_menu_set->p_menu[i]->items[j]->submenu = 1;
113     strncpy(p_menu_set->p_menu[i]->items[j]->action,
114     buffer + pmatch[1].rm_so,
115     pmatch[1].rm_eo - pmatch[1].rm_so);
116     p_menu_set->p_menu[i]->items[j]->action[pmatch[1].rm_eo -
117     pmatch[1].rm_so] = '\0';
118     strncpy(temp, buffer + pmatch[2].rm_so,
119     pmatch[2].rm_eo - pmatch[2].rm_so);
120     temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
121     p_menu_set->p_menu[i]->items[j]->row = atoi(temp);
122     strncpy(temp,
123     buffer + pmatch[3].rm_so,
124     pmatch[3].rm_eo - pmatch[3].rm_so);
125     temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
126     p_menu_set->p_menu[i]->items[j]->col = atoi(temp);
127     strncpy(temp,
128     buffer + pmatch[4].rm_so,
129     pmatch[4].rm_eo - pmatch[4].rm_so);
130     temp[pmatch[4].rm_eo - pmatch[4].rm_so] = '\0';
131     p_menu_set->p_menu[i]->items[j]->priv = atoi(temp);
132     strncpy(temp,
133     buffer + pmatch[5].rm_so,
134     pmatch[5].rm_eo - pmatch[5].rm_so);
135     temp[pmatch[5].rm_eo - pmatch[5].rm_so] = '\0';
136     p_menu_set->p_menu[i]->items[j]->level = atoi(temp);
137     strncpy(p_menu_set->p_menu[i]->items[j]->name,
138     buffer + pmatch[6].rm_so,
139     pmatch[6].rm_eo - pmatch[6].rm_so);
140     p_menu_set->p_menu[i]->items[j]->name[pmatch[6].rm_eo -
141     pmatch[6].rm_so] =
142     '\0';
143     strncpy(p_menu_set->p_menu[i]->items[j]->text,
144     buffer + pmatch[7].rm_so,
145     pmatch[7].rm_eo - pmatch[7].rm_so);
146     p_menu_set->p_menu[i]->items[j]->text[pmatch[7].rm_eo -
147     pmatch[7].rm_so] =
148     '\0';
149     j++;
150     continue;
151     }
152     if (ireg("^@([A-Za-z0-9_]+)[[:space:]]*([0-9]+),"
153     "[[:space:]]*([0-9]+),[[:space:]]*([0-9]+),"
154     "[[:space:]]*([0-9]+),[[:space:]]*\"([^\"]+)\","
155     "[[:space:]]*\"([^\"]+)\"",
156     buffer, 8, pmatch) == 0)
157     {
158     p_menu_set->p_menu[i]->items[j] =
159     malloc(sizeof(MENU_ITEM));
160     p_menu_set->p_menu[i]->items[j]->submenu = 0;
161     strncpy(p_menu_set->p_menu[i]->items[j]->action,
162     buffer + pmatch[1].rm_so,
163     pmatch[1].rm_eo - pmatch[1].rm_so);
164     p_menu_set->p_menu[i]->items[j]->action[pmatch[1].rm_eo -
165     pmatch[1].rm_so] = '\0';
166     strncpy(temp, buffer + pmatch[2].rm_so,
167     pmatch[2].rm_eo - pmatch[2].rm_so);
168     temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
169     p_menu_set->p_menu[i]->items[j]->row = atoi(temp);
170     strncpy(temp,
171     buffer + pmatch[3].rm_so,
172     pmatch[3].rm_eo - pmatch[3].rm_so);
173     temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
174     p_menu_set->p_menu[i]->items[j]->col = atoi(temp);
175     strncpy(temp,
176     buffer + pmatch[4].rm_so,
177     pmatch[4].rm_eo - pmatch[4].rm_so);
178     temp[pmatch[4].rm_eo - pmatch[4].rm_so] = '\0';
179     p_menu_set->p_menu[i]->items[j]->priv = atoi(temp);
180     strncpy(temp,
181     buffer + pmatch[5].rm_so,
182     pmatch[5].rm_eo - pmatch[5].rm_so);
183     temp[pmatch[5].rm_eo - pmatch[5].rm_so] = '\0';
184     p_menu_set->p_menu[i]->items[j]->level = atoi(temp);
185     strncpy(p_menu_set->p_menu[i]->items[j]->name,
186     buffer + pmatch[6].rm_so,
187     pmatch[6].rm_eo - pmatch[6].rm_so);
188     p_menu_set->p_menu[i]->items[j]->name[pmatch[6].rm_eo -
189     pmatch[6].rm_so] =
190     '\0';
191     strncpy(p_menu_set->p_menu[i]->items[j]->text,
192     buffer + pmatch[7].rm_so,
193     pmatch[7].rm_eo - pmatch[7].rm_so);
194     p_menu_set->p_menu[i]->items[j]->text[pmatch[7].rm_eo -
195     pmatch[7].rm_so] =
196     '\0';
197     j++;
198     continue;
199     }
200     if (ireg("^title[[:space:]]*([0-9]+),"
201     "[[:space:]]*([0-9]+),[[:space:]]*\"([^\"]+)\"",
202     buffer, 4, pmatch) == 0)
203     {
204     p_menu_set->p_menu[i]->title.show = 1;
205     strncpy(temp,
206     buffer + pmatch[1].rm_so,
207     pmatch[1].rm_eo - pmatch[1].rm_so);
208     temp[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
209     p_menu_set->p_menu[i]->title.row = atoi(temp);
210     strncpy(temp,
211     buffer + pmatch[2].rm_so,
212     pmatch[2].rm_eo - pmatch[2].rm_so);
213     temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
214     p_menu_set->p_menu[i]->title.col = atoi(temp);
215     strncpy(p_menu_set->p_menu[i]->title.text,
216     buffer + pmatch[3].rm_so,
217     pmatch[3].rm_eo - pmatch[3].rm_so);
218     p_menu_set->p_menu[i]->title.text[pmatch[3].rm_eo -
219     pmatch[3].rm_so] =
220     '\0';
221     continue;
222     }
223     if (ireg("^screen[[:space:]]*([0-9]+),"
224     "[[:space:]]*([0-9]+),[[:space:]]*S_([A-Za-z0-9_]+)",
225     buffer, 4, pmatch) == 0)
226     {
227     p_menu_set->p_menu[i]->screen.show = 1;
228     strncpy(temp,
229     buffer + pmatch[1].rm_so,
230     pmatch[1].rm_eo - pmatch[1].rm_so);
231     temp[pmatch[1].rm_eo - pmatch[1].rm_so] = '\0';
232     p_menu_set->p_menu[i]->screen.row = atoi(temp);
233     strncpy(temp,
234     buffer + pmatch[2].rm_so,
235     pmatch[2].rm_eo - pmatch[2].rm_so);
236     temp[pmatch[2].rm_eo - pmatch[2].rm_so] = '\0';
237     p_menu_set->p_menu[i]->screen.col = atoi(temp);
238     strncpy(temp,
239     buffer + pmatch[3].rm_so,
240     pmatch[3].rm_eo - pmatch[3].rm_so);
241     temp[pmatch[3].rm_eo - pmatch[3].rm_so] = '\0';
242     sprintf(p_menu_set->p_menu[i]->screen.filename,
243     "%sMENU_SCR_%s", app_temp_dir, temp);
244     continue;
245     }
246     }
247     }
248     break;
249 sysadm 1.10 }
250 sysadm 1.3 }
251 sysadm 1.21 fclose(fin);
252 sysadm 1.3
253 sysadm 1.21 p_menu_set->menu_count = i;
254     p_menu_set->menu_select_depth = 0;
255     p_menu_set->p_menu_select[p_menu_set->menu_select_depth] = (i == 0 ? NULL : p_menu_set->p_menu[0]);
256 sysadm 1.2
257 sysadm 1.21 return 0;
258 sysadm 1.1 }
259    
260 sysadm 1.10 MENU *
261 sysadm 1.21 get_menu(MENU_SET *p_menu_set, const char *menu_name)
262 sysadm 1.3 {
263 sysadm 1.21 int i;
264 sysadm 1.5
265 sysadm 1.21 for (i = 0; i < p_menu_set->menu_count; i++)
266 sysadm 1.10 {
267 sysadm 1.21 if (strcmp(p_menu_set->p_menu[i]->name, menu_name) == 0)
268     {
269     return p_menu_set->p_menu[i];
270     }
271 sysadm 1.10 }
272 sysadm 1.5
273 sysadm 1.21 return NULL;
274 sysadm 1.3 }
275    
276 sysadm 1.18 static void
277 sysadm 1.21 display_menu_cursor(MENU *p_menu, int show)
278 sysadm 1.1 {
279 sysadm 1.21 moveto((p_menu->items[p_menu->item_cur_pos])->r_row,
280     (p_menu->items[p_menu->item_cur_pos])->r_col - 2);
281     prints(show ? ">" : " ");
282     iflush();
283 sysadm 1.1 }
284    
285 sysadm 1.21 int display_menu(MENU *p_menu)
286 sysadm 1.1 {
287 sysadm 1.21 int i, row, col, menu_selectable = 0;
288 sysadm 1.3
289 sysadm 1.21 if (p_menu == NULL)
290     return -1;
291 sysadm 1.5
292 sysadm 1.21 if (p_menu->title.show)
293     show_top(p_menu->title.text);
294 sysadm 1.3
295 sysadm 1.21 if (p_menu->screen.show)
296 sysadm 1.10 {
297 sysadm 1.21 moveto(p_menu->screen.row, p_menu->screen.col);
298     if (display_file(p_menu->screen.filename) != 0)
299     log_error("Display menu screen <%s> failed!\n",
300     p_menu->screen.filename);
301 sysadm 1.10 }
302 sysadm 1.21
303     row = p_menu->items[0]->row;
304     col = p_menu->items[0]->col;
305    
306     for (i = 0; i < p_menu->item_count; i++)
307 sysadm 1.10 {
308 sysadm 1.21 if (checkpriv(&BBS_priv, 0, p_menu->items[i]->priv) == 0 || checklevel(&BBS_priv, p_menu->items[i]->level) == 0)
309     {
310     p_menu->items[i]->display = 0;
311     }
312     else
313     {
314     p_menu->items[i]->display = 1;
315 sysadm 1.10
316 sysadm 1.21 menu_selectable = 1;
317 sysadm 1.3
318 sysadm 1.21 if (p_menu->items[i]->row != 0)
319     row = p_menu->items[i]->row;
320     else
321     row++;
322     p_menu->items[i]->r_row = row;
323     if (p_menu->items[i]->col != 0)
324     col = p_menu->items[i]->col;
325     p_menu->items[i]->r_col = col;
326     moveto(row, col);
327     prints(p_menu->items[i]->text);
328     iflush();
329     }
330 sysadm 1.10 }
331    
332 sysadm 1.21 if (!menu_selectable)
333     return -1;
334 sysadm 1.3
335 sysadm 1.21 display_menu_cursor(p_menu, 1);
336 sysadm 1.1
337 sysadm 1.21 return 0;
338 sysadm 1.1 }
339    
340 sysadm 1.21 int display_current_menu(MENU_SET *p_menu_set)
341 sysadm 1.12 {
342 sysadm 1.21 MENU *p_menu;
343 sysadm 1.12
344 sysadm 1.21 p_menu = p_menu_set->p_menu_select[p_menu_set->menu_select_depth];
345 sysadm 1.12
346 sysadm 1.21 return display_menu(p_menu);
347 sysadm 1.12 }
348    
349 sysadm 1.21 int menu_control(MENU_SET *p_menu_set, int key)
350 sysadm 1.1 {
351 sysadm 1.21 int i;
352     MENU *p_menu;
353 sysadm 1.3
354 sysadm 1.21 if (p_menu_set->menu_count == 0)
355     return 0;
356 sysadm 1.3
357 sysadm 1.21 p_menu = p_menu_set->p_menu_select[p_menu_set->menu_select_depth];
358 sysadm 1.3
359 sysadm 1.21 switch (key)
360 sysadm 1.10 {
361 sysadm 1.21 case CR:
362     case KEY_RIGHT:
363     if (p_menu->items[p_menu->item_cur_pos]->submenu)
364     {
365     if (strcmp(p_menu->items[p_menu->item_cur_pos]->action, "..") == 0)
366     return menu_control(p_menu_set, KEY_LEFT);
367     p_menu_set->menu_select_depth++;
368     p_menu =
369     p_menu_set->p_menu_select[p_menu_set->menu_select_depth] =
370     get_menu(p_menu_set,
371     p_menu->items[p_menu->item_cur_pos]->action);
372     if (display_menu(p_menu) != 0)
373     return menu_control(p_menu_set, KEY_LEFT);
374     break;
375     }
376     else
377     {
378     return (exec_cmd(p_menu->items[p_menu->item_cur_pos]->action,
379     p_menu->items[p_menu->item_cur_pos]->name));
380     }
381     case KEY_LEFT:
382     if (p_menu_set->menu_select_depth > 0)
383     {
384     p_menu_set->menu_select_depth--;
385     if (display_current_menu(p_menu_set) != 0)
386     return menu_control(p_menu_set, KEY_LEFT);
387     break;
388     }
389     else
390     {
391     display_menu_cursor(p_menu, 0);
392     p_menu->item_cur_pos = p_menu->item_count - 1;
393     while (!p_menu->items[p_menu->item_cur_pos]->display || p_menu->items[p_menu->item_cur_pos]->priv != 0 || p_menu->items[p_menu->item_cur_pos]->level != 0)
394     p_menu->item_cur_pos--;
395     display_menu_cursor(p_menu, 1);
396     break;
397     }
398     case KEY_UP:
399     display_menu_cursor(p_menu, 0);
400     do
401     {
402     p_menu->item_cur_pos--;
403     if (p_menu->item_cur_pos < 0)
404     p_menu->item_cur_pos = p_menu->item_count - 1;
405     } while (!p_menu->items[p_menu->item_cur_pos]->display);
406     display_menu_cursor(p_menu, 1);
407     break;
408     case KEY_DOWN:
409     display_menu_cursor(p_menu, 0);
410     do
411     {
412     p_menu->item_cur_pos++;
413     if (p_menu->item_cur_pos >= p_menu->item_count)
414     p_menu->item_cur_pos = 0;
415     } while (!p_menu->items[p_menu->item_cur_pos]->display);
416     display_menu_cursor(p_menu, 1);
417     break;
418     default:
419     for (i = 0; i < p_menu->item_count; i++)
420     {
421     if (key == p_menu->items[i]->name[0] &&
422     p_menu->items[i]->display)
423     {
424     display_menu_cursor(p_menu, 0);
425     p_menu->item_cur_pos = i;
426     display_menu_cursor(p_menu, 1);
427     return 0;
428     }
429     }
430     if (isalpha(key))
431     {
432     for (i = 0; i < p_menu->item_count; i++)
433     {
434     if (toupper(key) == toupper(p_menu->items[i]->name[0]) &&
435     p_menu->items[i]->display)
436     {
437     display_menu_cursor(p_menu, 0);
438     p_menu->item_cur_pos = i;
439     display_menu_cursor(p_menu, 1);
440     return 0;
441     }
442     }
443 sysadm 1.16 }
444 sysadm 1.3 }
445 sysadm 1.1
446 sysadm 1.21 return 0;
447 sysadm 1.1 }
448 sysadm 1.15
449 sysadm 1.21 void unload_menu(MENU_SET *p_menu_set)
450 sysadm 1.15 {
451 sysadm 1.21 MENU *p_menu;
452     MENU_ITEM *p_menuitem;
453     int i, j;
454    
455     for (i = 0; i < p_menu_set->menu_count; i++)
456 sysadm 1.16 {
457 sysadm 1.21 p_menu = p_menu_set->p_menu[i];
458     for (j = 0; j < p_menu->item_count; j++)
459     {
460     free(p_menu->items[j]);
461     }
462     remove(p_menu->screen.filename);
463     free(p_menu);
464 sysadm 1.16 }
465    
466 sysadm 1.21 p_menu_set->menu_count = 0;
467     p_menu_set->menu_select_depth = 0;
468 sysadm 1.15 }
469 sysadm 1.18
470 sysadm 1.21 int reload_menu(MENU_SET *p_menu_set)
471 sysadm 1.18 {
472 sysadm 1.21 int result;
473     char conf_file[256];
474    
475     strcpy(conf_file, p_menu_set->conf_file);
476     unload_menu(p_menu_set);
477     result = load_menu(p_menu_set, conf_file);
478 sysadm 1.18
479 sysadm 1.21 return result;
480 sysadm 1.18 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1