/*-
* Copyright (c) 2001 Jordan DeLong
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "menu.h"
/* handler for command entries */
static void handler_command(menu_t *menu, param_t *param, int type) {
param_t *dat;
char *tmp1, *tmp2;
/*
* command entries are formed like so:
* param "command" "text" { param "dat" "value"; }
* text is the visible text, value is the program to launch.
*/
if (param->subparams.count != 1) {
PWARN("invalid subparam structure for 'command', 1 subparam named dat expected");
return;
}
dat = param->subparams.params[0];
if (strcmp(dat->name, "dat") != 0) {
PWARN("subparam for 'command' must be called dat");
return;
}
if ((tmp1 = strdup(param->value)) == NULL
|| (tmp2 = strdup(dat->value)) == NULL) {
PWARN("out of memory in parseparams, command");
if (tmp1) free(tmp1);
return;
}
if (menu_addent(menu, POS_LAST, type, tmp1, (void *) tmp2) == NULL) {
free(tmp1);
free(tmp2);
}
}
/* handler for restart entries */
static void handler_restart(menu_t *menu, param_t *param, int type) {
param_t *dat = NULL;
char *tmp1, *tmp2 = NULL;
/*
* these are like command entires, except the
* dat subparam is optional
*/
if (param->subparams.count == 1) {
dat = param->subparams.params[0];
if (strcmp(dat->name, "dat") != 0) {
PWARN("subparam for 'restart' must be called dat");
return;
}
} else if (param->subparams.count > 1) {
PWARN("invalid subparam structure for 'restart'");
return;
}
if ((tmp1 = strdup(param->value)) == NULL
|| dat ? (tmp2 = strdup(dat->value)) == NULL : 0) {
PWARN("out of memory in parseparams, restart");
if (tmp1) free(tmp1);
return;
}
if (menu_addent(menu, POS_LAST, type, tmp1, (void *) tmp2) == NULL) {
free(tmp1);
free(tmp2);
}
}
/* handler for submenus */
static void handler_submenu(menu_t *menu, param_t *param, int type) {
menu_t *submenu;
char *tmp;
/*
* submenus are formed like so:
* param "submenu" "text" { ...more param stuff here... }
* so we just recurse on this function and take it's menu and add it
*/
if ((submenu = menu_create()) == NULL) {
PWARN("couldn't get memory for submenu %s", param->value);
return;
}
/* parse the subparams of the submenu */
parseparams(submenu, param);
if ((tmp = strdup(param->value)) == NULL)
goto free1;
if (menu_addent(menu, POS_LAST, type, tmp, (void *) submenu) == NULL)
goto free2;
return;
free2:
free(tmp);
free1:
menu_delete(submenu);
return;
}
/* handler for exit */
static void handler_exit(menu_t *menu, param_t *param, int type) {
char *tmp;
if ((tmp = strdup(param->value)) == NULL) {
PWARN("out of memory in parseparams, exit/abort");
return;
}
if (menu_addent(menu, POS_LAST, type, tmp, NULL) == NULL)
free(tmp);
}
/* table of menu types and handler functions */
static struct paramhndlr {
char *text;
int type;
void (*handler)(menu_t *menu, param_t *param, int type);
} handlers[] = {
{"command", ET_COMMAND, handler_command},
{"restart", ET_RESTART, handler_restart},
{"submenu", ET_SUBMENU, handler_submenu},
{"exit", ET_EXIT, handler_exit},
{"abort", ET_ABORT, handler_exit}
};
/* parse a menu tree, this can be recursed */
void parseparams(menu_t *menu, param_t *topparam) {
param_t *param;
int i, n;
/* go through every subparam and handle it */
SUBPARAMS_FOREACH(i, param, &topparam->subparams) {
for (n = 0; n < sizeof(handlers) / sizeof(struct paramhndlr); n++) {
if (strcmp(handlers[n].text, param->name) == 0) {
handlers[n].handler(menu, param, handlers[n].type);
goto found;
}
}
PWARN("ignoring unknown parameter type %s, under %s", param->name, topparam->name);
found:
continue;
}
}
syntax highlighted by Code2HTML, v. 0.9.1