/*- * 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; } }