diff --git a/WINGs/Makefile.am b/WINGs/Makefile.am index 831325f0..1d764f0f 100644 --- a/WINGs/Makefile.am +++ b/WINGs/Makefile.am @@ -72,6 +72,7 @@ libWUtil_la_SOURCES = \ hashtable.c \ memory.c \ menuparser.c \ + menuparser.h \ misc.c \ notification.c \ proplist.c \ diff --git a/WINGs/WINGs/WUtil.h b/WINGs/WINGs/WUtil.h index e7f4fc00..802b9e49 100644 --- a/WINGs/WINGs/WUtil.h +++ b/WINGs/WINGs/WUtil.h @@ -869,9 +869,18 @@ extern char *WMUserDefaultsDidChangeNotification; /* ---[ WINGs/menuparser.c ]---------------------------------------------- */ -char *getLine(void * file, const char *file_name); +typedef struct w_menu_parser *WMenuParser; + + +WMenuParser WMenuParserCreate(const char *file_name, void *file); + +const char *WMenuParserGetFilename(WMenuParser parser); + +char *getLine(WMenuParser parser); void separateline(char *line, char **title, char **command, char **parameter, char **shortcut); +void WMenuParserDelete(WMenuParser parser); + /*-------------------------------------------------------------------------*/ diff --git a/WINGs/menuparser.c b/WINGs/menuparser.c index dcd0d362..b3a3349c 100644 --- a/WINGs/menuparser.c +++ b/WINGs/menuparser.c @@ -25,10 +25,44 @@ #include -#define MAXLINE 1024 +#include "menuparser.h" + +static WMenuParser menu_parser_create_new(const char *file_name, void *file); -char *getLine(void * file, const char *file_name) +/***** Constructor and Destructor for the Menu Parser object *****/ +WMenuParser WMenuParserCreate(const char *file_name, void *file) +{ + WMenuParser parser; + + parser = menu_parser_create_new(file_name, file); + return parser; +} + +void WMenuParserDelete(WMenuParser parser) +{ + wfree(parser); +} + +static WMenuParser menu_parser_create_new(const char *file_name, void *file) +{ + WMenuParser parser; + + parser = wmalloc(sizeof(*parser)); + parser->file_name = file_name; + parser->file_handle = file; + parser->rd = parser->line_buffer; + + return parser; +} + +/***** To report helpfull messages to user *****/ +const char *WMenuParserGetFilename(WMenuParser parser) +{ + return parser->file_name; +} + +char *getLine(WMenuParser parser) { char linebuf[MAXLINE]; char *line = NULL, *result = NULL; @@ -37,7 +71,7 @@ char *getLine(void * file, const char *file_name) again: done = 0; - while (!done && fgets(linebuf, sizeof(linebuf), file) != NULL) { + while (!done && fgets(linebuf, sizeof(linebuf), parser->file_handle) != NULL) { line = wtrimspace(linebuf); len = strlen(line); @@ -57,7 +91,7 @@ again: wfree(line); } } - if (!done || ferror(file)) { + if (!done || ferror(parser->file_handle)) { wfree(result); result = NULL; } else if (result != NULL && (result[0] == 0 || result[0] == '#' || @@ -67,7 +101,7 @@ again: goto again; } else if (result != NULL && strlen(result) >= MAXLINE) { wwarning(_("%s:maximal line size exceeded in menu config: %s"), - file_name, line); + parser->file_name, line); wfree(result); result = NULL; goto again; diff --git a/WINGs/menuparser.h b/WINGs/menuparser.h new file mode 100644 index 00000000..752e1053 --- /dev/null +++ b/WINGs/menuparser.h @@ -0,0 +1,40 @@ +/* menuparser.h + * + * Copyright (c) 2012 Christophe Curis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _MENUPARSER_H_INCLUDED +#define _MENUPARSER_H_INCLUDED + +/* + * This file is not part of WINGs public API + * + * It defines internal things for the Menu Parser, the public API is + * located in WINGs/WUtil.h as usual + */ + +#define MAXLINE 1024 + +struct w_menu_parser { + const char *file_name; + FILE *file_handle; + int line_number; + char *rd; + char line_buffer[MAXLINE]; +}; + +#endif /* _MENUPARSER_H_INCLUDED */ diff --git a/src/rootmenu.c b/src/rootmenu.c index c0e7ddef..11868927 100644 --- a/src/rootmenu.c +++ b/src/rootmenu.c @@ -410,7 +410,7 @@ static void removeShortcutsForMenu(WMenu * menu) menu->menu->screen_ptr->flags.root_menu_changed_shortcuts = 1; } -static Bool addShortcut(char *file, char *shortcutDefinition, WMenu * menu, WMenuEntry * entry) +static Bool addShortcut(const char *file, char *shortcutDefinition, WMenu * menu, WMenuEntry * entry) { Shortcut *ptr; KeySym ksym; @@ -759,7 +759,7 @@ static WMenuEntry *addWindowsMenu(WScreen * scr, WMenu * menu, char *title) } static WMenuEntry *addMenuEntry(WMenu * menu, char *title, char *shortcut, char *command, - char *params, char *file_name) + char *params, const char *file_name) { WScreen *scr; WMenuEntry *entry = NULL; @@ -891,16 +891,16 @@ static void freeline(char *title, char *command, char *parameter, char *shortcut wfree(shortcut); } -static WMenu *parseCascade(WScreen * scr, WMenu * menu, FILE * file, char *file_name) +static WMenu *parseCascade(WScreen * scr, WMenu * menu, WMenuParser parser) { char *line; char *command, *params, *shortcut, *title; - while ((line = getLine(file, file_name)) != NULL) { + while ((line = getLine(parser)) != NULL) { separateline(line, &title, &command, ¶ms, &shortcut); if (command == NULL || !command[0]) { - wwarning(_("%s:missing command in menu config: %s"), file_name, line); + wwarning(_("%s:missing command in menu config: %s"), WMenuParserGetFilename(parser), line); freeline(title, command, params, shortcut); wfree(line); goto error; @@ -913,7 +913,7 @@ static WMenu *parseCascade(WScreen * scr, WMenu * menu, FILE * file, char *file_ cascade = wMenuCreate(scr, M_(title), False); cascade->on_destroy = removeShortcutsForMenu; - if (!parseCascade(scr, cascade, file, file_name)) { + if (!parseCascade(scr, cascade, parser)) { wMenuDestroy(cascade, True); } else { wMenuEntrySetCascade(menu, wMenuAddCallback(menu, M_(title), NULL, NULL), cascade); @@ -925,13 +925,13 @@ static WMenu *parseCascade(WScreen * scr, WMenu * menu, FILE * file, char *file_ return menu; } else { /* normal items */ - addMenuEntry(menu, M_(title), shortcut, command, params, file_name); + addMenuEntry(menu, M_(title), shortcut, command, params, WMenuParserGetFilename(parser)); } freeline(title, command, params, shortcut); wfree(line); } - wwarning(_("%s:syntax error in menu file:END declaration missing"), file_name); + wwarning(_("%s:syntax error in menu file:END declaration missing"), WMenuParserGetFilename(parser)); error: return NULL; @@ -941,6 +941,7 @@ static WMenu *readMenuFile(WScreen * scr, char *file_name) { WMenu *menu = NULL; FILE *file = NULL; + WMenuParser parser; char *line; char *command, *params, *shortcut, *title; char cmd[MAXLINE]; @@ -974,8 +975,9 @@ static WMenu *readMenuFile(WScreen * scr, char *file_name) return NULL; } } + parser = WMenuParserCreate(file_name, file); - while ((line = getLine(file, file_name)) != NULL) { + while ((line = getLine(parser)) != NULL) { separateline(line, &title, &command, ¶ms, &shortcut); if (command == NULL || !command[0]) { @@ -987,7 +989,7 @@ static WMenu *readMenuFile(WScreen * scr, char *file_name) if (strcasecmp(command, "MENU") == 0) { menu = wMenuCreate(scr, M_(title), True); menu->on_destroy = removeShortcutsForMenu; - if (!parseCascade(scr, menu, file, file_name)) { + if (!parseCascade(scr, menu, parser)) { wMenuDestroy(menu, True); menu = NULL; } @@ -1004,6 +1006,7 @@ static WMenu *readMenuFile(WScreen * scr, char *file_name) wfree(line); } + WMenuParserDelete(parser); #ifdef USECPP if (cpp) { if (pclose(file) == -1) { @@ -1025,6 +1028,7 @@ static WMenu *readMenuPipe(WScreen * scr, char **file_name) { WMenu *menu = NULL; FILE *file = NULL; + WMenuParser parser; char *command, *params, *shortcut, *title; char *line; char *filename; @@ -1068,8 +1072,9 @@ static WMenu *readMenuPipe(WScreen * scr, char **file_name) return NULL; } } + parser = WMenuParserCreate(flat_file, file); - while ((line = getLine(file, filename)) != NULL) { + while ((line = getLine(parser)) != NULL) { separateline(line, &title, &command, ¶ms, &shortcut); if (command == NULL || !command[0]) { @@ -1081,7 +1086,7 @@ static WMenu *readMenuPipe(WScreen * scr, char **file_name) if (strcasecmp(command, "MENU") == 0) { menu = wMenuCreate(scr, M_(title), True); menu->on_destroy = removeShortcutsForMenu; - if (!parseCascade(scr, menu, file, filename)) { + if (!parseCascade(scr, menu, parser)) { wMenuDestroy(menu, True); menu = NULL; } @@ -1099,6 +1104,7 @@ static WMenu *readMenuPipe(WScreen * scr, char **file_name) wfree(line); } + WMenuParserDelete(parser); pclose(file); return menu;