mirror of
https://github.com/gryf/wmaker.git
synced 2026-01-09 15:24:12 +01:00
The default function used so far provides informations not so useful to user, like wmaker's source file, line number and function; it also cannot provide the line number from the parsed file because cpp messes this information. With this dedicated function we try to provide useful things which are being tracked by the parser internally, like valid line number and the name of the file being read (which can be convenient in the case of #include, for which we may also be able to provide the inclusion tree!)
179 lines
4.3 KiB
C
179 lines
4.3 KiB
C
/*
|
|
* Window Maker window manager
|
|
*
|
|
* Copyright (c) 1997-2003 Alfredo K. Kojima
|
|
*
|
|
* 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.
|
|
*/
|
|
#include "wconfig.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
|
|
#include <WINGs/WUtil.h>
|
|
|
|
#include "menuparser.h"
|
|
|
|
static WMenuParser menu_parser_create_new(const char *file_name, void *file);
|
|
static void separateline(char *line, char **title, char **command, char **parameter, char **shortcut);
|
|
|
|
|
|
/***** 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;
|
|
}
|
|
|
|
void WMenuParserError(WMenuParser parser, const char *msg, ...)
|
|
{
|
|
char buf[MAXLINE];
|
|
va_list args;
|
|
|
|
va_start(args, msg);
|
|
vsnprintf(buf, sizeof(buf), msg, args);
|
|
va_end(args);
|
|
__wmessage("WMenuParser", parser->file_name, parser->line_number, WMESSAGE_TYPE_WARNING, buf);
|
|
}
|
|
|
|
/***** Read one line from file and split content *****/
|
|
Bool WMenuParserGetLine(WMenuParser top_parser, char **title, char **command, char **parameter, char **shortcut)
|
|
{
|
|
WMenuParser cur_parser;
|
|
char *line = NULL, *result = NULL;
|
|
size_t len;
|
|
int done;
|
|
|
|
*title = NULL;
|
|
*command = NULL;
|
|
*parameter = NULL;
|
|
*shortcut = NULL;
|
|
|
|
cur_parser = top_parser;
|
|
|
|
again:
|
|
done = 0;
|
|
while (!done && fgets(cur_parser->line_buffer, sizeof(cur_parser->line_buffer), cur_parser->file_handle) != NULL) {
|
|
line = wtrimspace(cur_parser->line_buffer);
|
|
len = strlen(line);
|
|
cur_parser->line_number++;
|
|
|
|
/* allow line wrapping */
|
|
if (len > 0 && line[len - 1] == '\\') {
|
|
line[len - 1] = '\0';
|
|
} else {
|
|
done = 1;
|
|
}
|
|
|
|
if (result == NULL) {
|
|
result = line;
|
|
} else {
|
|
if (strlen(result) < MAXLINE) {
|
|
result = wstrappend(result, line);
|
|
}
|
|
wfree(line);
|
|
}
|
|
}
|
|
if (!done || ferror(cur_parser->file_handle)) {
|
|
wfree(result);
|
|
result = NULL;
|
|
} else if (result != NULL && (result[0] == 0 || result[0] == '#' ||
|
|
(result[0] == '/' && result[1] == '/'))) {
|
|
wfree(result);
|
|
result = NULL;
|
|
goto again;
|
|
} else if (result != NULL && strlen(result) >= MAXLINE) {
|
|
WMenuParserError(cur_parser, _("maximal line size exceeded in menu config") );
|
|
wfree(result);
|
|
result = NULL;
|
|
goto again;
|
|
}
|
|
|
|
if (result == NULL)
|
|
return False;
|
|
|
|
separateline(line, title, command, parameter, shortcut);
|
|
wfree(line);
|
|
return True;
|
|
}
|
|
|
|
static void separateline(char *line, char **title, char **command, char **parameter, char **shortcut)
|
|
{
|
|
char *suffix, *next = line;
|
|
|
|
/* get the title */
|
|
*title = wtokennext(line, &next);
|
|
if (next == NULL)
|
|
return;
|
|
line = next;
|
|
|
|
/* get the command or shortcut keyword */
|
|
*command = wtokennext(line, &next);
|
|
if (next == NULL)
|
|
return;
|
|
line = next;
|
|
|
|
if (*command != NULL && strcmp(*command, "SHORTCUT") == 0) {
|
|
/* get the shortcut */
|
|
*shortcut = wtokennext(line, &next);
|
|
if (next == NULL)
|
|
return;
|
|
line = next;
|
|
|
|
/* get the command */
|
|
*command = wtokennext(line, &next);
|
|
if (next == NULL)
|
|
return;
|
|
line = next;
|
|
}
|
|
|
|
/* get the parameters */
|
|
suffix = wtrimspace(line);
|
|
|
|
/* should we keep this weird old behavior? */
|
|
if (suffix[0] == '"') {
|
|
*parameter = wtokennext(suffix, &next);
|
|
wfree(suffix);
|
|
} else {
|
|
*parameter = suffix;
|
|
}
|
|
}
|