/* Copyright (c) 2002 * Marko Boomstra (m.boomstra@chello.nl). 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. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 #include #include #include #include #include #include #include "mudix.h" typedef enum { OP_NONE, OP_EQUAL, /* == */ OP_INEQUAL, /* != */ OP_GREATER, /* > */ OP_GREATER_EQUAL, /* >= */ OP_LESSER, /* < */ OP_LESSER_EQUAL /* <= */ } OPERATOR_TYPE; void show_vars(void) { static int current; VAR *var; char *str; int line, i, width, height, centre, wsize; width = LEN_COL-4; height = 20; wsize = height-2; centre = ((width-2)/2)-1; wresize(wMsg, height, width); werase(wMsg); move_panel(pMsg, 1, 2); if (panel_hidden(pMsg) == PANEL_HIDDEN) current = 0; for (line=1, i=0, var = settings->vars_list; var; var = var->next) { if (!var->name || !var->value) continue; i+=2; if (i < (current*wsize)+2) continue; mvwprintw(wMsg, line++, 1, "Name : %s", var->name); mvwprintw(wMsg, line++, 1, "Value: %s", var->value); if (line >= wsize && var->next) { current++; break; } if (!var->next) /* last one */ current = 0; } draw_border(wMsg); str = "Variables"; mvwprintw(wMsg, 0, centre-strlen(str)/2, str); show_panel(pMsg); return; } VAR *new_var(bool last) { VAR *var; if (!(var = (VAR *)malloc(sizeof(VAR)))) return NULL; if (last && settings->vars_list) { VAR *iVar; for (iVar = settings->vars_list; iVar; iVar = iVar->next) { if (!iVar->next) break; } iVar->next = var; var->next = NULL; } else { var->next = settings->vars_list; settings->vars_list = var; } var->name = NULL; var->value = NULL; return var; } void free_var(VAR *var) { VAR *iVar; if (!var) return; for (iVar = settings->vars_list; iVar; iVar = iVar->next) { if (iVar->next == var) { iVar->next = var->next; break; } } if (var == settings->vars_list) settings->vars_list = var->next; if (var->name) free(var->name); if (var->value) free(var->value); free(var); return; } VAR *var_lookup(char *var) { VAR *iVar; for (iVar = settings->vars_list; iVar; iVar = iVar->next) { if (!iVar->name || !iVar->value) continue; if (!strcmp(var, iVar->name)) break; } return iVar; } static bool is_numeric(char *str, double *value) { char *begin = str; /* parse till end of string */ while (*str != '\0') { /* character in the string is not a digit! no numeric string */ if (!isdigit(*str)) { return FALSE; } str++; } *value = strtod(begin, NULL); return TRUE; } static OPERATOR_TYPE get_operator(char *expr) { OPERATOR_TYPE retval = OP_NONE; switch (*expr) { case '!': /* != */ if (*(expr+1) == '=') { retval = OP_INEQUAL; } break; case '=': /* == */ if (*(expr+1) == '=') { retval = OP_EQUAL; } break; case '>': /* >=, > */ if (*(expr+1) == '=') { retval = OP_GREATER_EQUAL; } else { retval = OP_GREATER; } break; case '<': /* <=, < */ if (*(expr+1) == '=') { retval = OP_LESSER_EQUAL; } else { retval = OP_LESSER; } break; default: break; } return retval; } static bool check_expression(char *expr) { static char arg1[MAX_STRING]; static char arg2[MAX_STRING]; VAR *var; char *pExpr = expr; char *pArg1, *pArg2; OPERATOR_TYPE opr; bool retval, fNumeric = FALSE; double lval, rval; /* get the first argument */ pArg1 = arg1; while (*pExpr) { if (*pExpr == '!' || *pExpr == '=' || *pExpr == '>' || *pExpr == '<') { break; } *pArg1++ = *pExpr++; } *pArg1 = '\0'; /* retrieve the operator type */ opr = get_operator(pExpr); if (opr == OP_NONE) { return FALSE; } else if (opr == OP_LESSER || opr == OP_GREATER) { pExpr++; } else { pExpr += 2; } /* copy the 2nd argument into arg2 */ strcpy(arg2, pExpr); /* look up if this references a variable */ var = var_lookup(arg1); if (var) { /* set the argument pointer to point to the variable value :) */ pArg1 = var->value; } else { /* set to the original argument */ pArg1 = arg1; } /* look up if this references a variable */ var = var_lookup(arg2); if (var) { /* set the argument pointer to point to the variable value :) */ pArg2 = var->value; } else { /* set to the original argument */ pArg2 = arg2; } /* check if arguments are numeric */ if (is_numeric(pArg1, &lval) && is_numeric(pArg2, &rval)) { fNumeric = TRUE; } /* now check the operand type and the values */ switch (opr) { case OP_GREATER: retval = fNumeric? (lval > rval): (strcmp(pArg1, pArg2) > 0); break; case OP_GREATER_EQUAL: retval = fNumeric? (lval >= rval): (strcmp(pArg1, pArg2) >= 0); break; case OP_LESSER: retval = fNumeric? (lval < rval): (strcmp(pArg1, pArg2) < 0); break; case OP_LESSER_EQUAL: retval = fNumeric? (lval <= rval): (strcmp(pArg1, pArg2) <= 0); break; case OP_INEQUAL: retval = fNumeric? (lval != rval): (strcmp(pArg1, pArg2) != 0); break; case OP_EQUAL: retval = fNumeric? (lval == rval): (strcmp(pArg1, pArg2) == 0); break; default: retval = FALSE; break; } return retval; } bool process_if(char *buffer) { char str[MAX_STRING]; /* grab the expression */ buffer = get_arg(buffer, str); /* and check it */ if (check_expression(str)) { /* grab first argument after expression and process it */ get_arg(buffer, str); process_input(str, NULL, TRUE); return TRUE; } else { /* skip to 2nd argument */ buffer = get_arg(buffer, str); get_arg(buffer, str); if (str[0]) { /* process the 'else' command */ process_input(str, NULL, TRUE); } return FALSE; } }