/* Autoconf patching by David Hedbor, neotron@lysator.liu.se */ #include "tintin.h" #include <ctype.h> int stacks[100][3]; extern struct listnode *common_myvars; #ifdef HAVE_UNISTD_H #include <stdlib.h> #include <unistd.h> #endif extern char *get_arg_in_braces(); extern struct listnode *searchnode_list(); void math_command(line, ses) char *line; struct session *ses; { struct listnode *my_vars, *ln; char left[BUFFER_SIZE], right[BUFFER_SIZE]; char temp[BUFFER_SIZE], result[BUFFER_SIZE]; int i; my_vars = (ses) ? ses->myvars : common_myvars; line = get_arg_in_braces(line, left, 0); line = get_arg_in_braces(line, right, 1); substitute_vars(right, result); substitute_myvars(result, right, ses); i = eval_expression(right); sprintf(temp, "%d", i); if ((ln = searchnode_list(my_vars, left)) != NULL) deletenode_list(my_vars, ln); insertnode_list(my_vars, left, temp, "0", ALPHA); } void if_command(line, ses) char *line; struct session *ses; { char left[BUFFER_SIZE], right[BUFFER_SIZE], temp[BUFFER_SIZE]; char elsebuf[BUFFER_SIZE]; /* int i; */ line = get_arg_in_braces(line, left, 0); line = get_arg_in_braces(line, right, 1); /* MOVED by if-else addition substitute_vars(right,temp); substitute_myvars(temp,right,ses); */ substitute_vars(left, temp); substitute_myvars(temp, left, ses); if (eval_expression(left)) { /* MOVED to here */ substitute_vars(right, temp); substitute_myvars(temp, right, ses); parse_input(right, ses); } else { /* ADDITION for if-else addition */ line = (char *) get_arg_stop_spaces(line, elsebuf); if (*elsebuf && strcmp(elsebuf, "else") == 0) { line = get_arg_in_braces(line, elsebuf, 1); substitute_vars(elsebuf, temp); substitute_myvars(temp, elsebuf, ses); parse_input(elsebuf, ses); } } } int eval_expression(arg) char *arg; { int i, begin, end, flag, prev; char temp[BUFFER_SIZE]; i = conv_to_ints(arg); if (i == 1) { /* changed for if strings */ while (1) { i = 0; flag = 1; begin = -1; end = -1; prev = -1; while (stacks[i][0] && flag) { if (stacks[i][1] == 0) { begin = i; } else if (stacks[i][1] == 1) { end = i; flag = 0; } prev = i; i = stacks[i][0]; } if ((flag && (begin != -1)) || (!flag && (begin == -1))) { tintin_puts2("#Unmatched parentheses error.", (struct session *) NULL); return 0; } if (flag) { if (prev == -1) return (stacks[0][2]); begin = -1; end = i; } i = do_one_inside(begin, end); if (!i) { sprintf(temp, "#Invalid expression to evaluate in {%s}", arg); tintin_puts2(temp, (struct session *) NULL); return 0; } } } else if (i == 2) return 1; /* changed for #if strings */ else return 0; } int conv_to_ints(arg) char *arg; { int i, flag; char *ptr, *tptr; char left[256], right[256]; i = 0; ptr = arg; while (*ptr) { if (*ptr == ' ') ; /* START ADDITION for #if-strings */ else if (*ptr == '[') { ptr++; tptr = left; while ((*ptr) && (*ptr != ']') && (*ptr != '=')) { *tptr = (*ptr); ptr++; tptr++; } *tptr = '\0'; if (!*ptr) return -1; if (*ptr == ']') return -2; tptr = right; ptr++; while ((*ptr) && (*ptr != ']')) { *tptr = (*ptr); ptr++; tptr++; } *tptr = '\0'; if (!*ptr) return -1; if (strcmp(right, left) == 0) return 2; return 3; } /* END ADDITION for #if-strings */ else if (*ptr == '(') { stacks[i][1] = 0; } else if (*ptr == ')') { stacks[i][1] = 1; } else if (*ptr == '!') { if (*(ptr + 1) == '=') { stacks[i][1] = 12; ptr++; } else stacks[i][1] = 2; } else if (*ptr == '*') { stacks[i][1] = 3; } else if (*ptr == '/') { stacks[i][1] = 4; } else if (*ptr == '+') { stacks[i][1] = 5; } else if (*ptr == '-') { flag = -1; if (i > 0) flag = stacks[i - 1][1]; if (flag == 15) stacks[i][1] = 6; else { tptr = ptr; ptr++; while (isdigit(*ptr)) ptr++; sscanf(tptr, "%d", &stacks[i][2]); stacks[i][1] = 15; ptr--; } } else if (*ptr == '>') { if (*(ptr + 1) == '=') { stacks[i][1] = 8; ptr++; } else stacks[i][1] = 7; } else if (*ptr == '<') { if (*(ptr + 1) == '=') { ptr++; stacks[i][1] = 10; } else stacks[i][1] = 9; } else if (*ptr == '=') { stacks[i][1] = 11; if (*(ptr + 1) == '=') ptr++; } else if (*ptr == '&') { stacks[i][1] = 13; if (*(ptr + 1) == '&') ptr++; } else if (*ptr == '|') { stacks[i][1] = 14; if (*(ptr + 1) == '|') ptr++; } else if (isdigit(*ptr)) { stacks[i][1] = 15; tptr = ptr; while (isdigit(*ptr)) ptr++; sscanf(tptr, "%d", &stacks[i][2]); ptr--; } else if (*ptr == 'T') { stacks[i][1] = 15; stacks[i][2] = 1; } else if (*ptr == 'F') { stacks[i][1] = 15; stacks[i][2] = 0; } else { tintin_puts2("#Error. Invalid expression in #if or #math", (struct session *) NULL); return 0; } if (*ptr != ' ') { stacks[i][0] = i + 1; i++; } ptr++; } if (i > 0) stacks[i][0] = 0; return 1; } int do_one_inside(begin, end) int begin; int end; { /* int prev, ptr, highest, loc, ploc, next, nval, flag; */ int prev, ptr, highest, loc, ploc, next; while (1) { ptr = 0; if (begin > -1) ptr = stacks[begin][0]; highest = 16; loc = -1; ploc = -1; prev = -1; while (ptr < end) { if (stacks[ptr][1] < highest) { highest = stacks[ptr][1]; loc = ptr; ploc = prev; } prev = ptr; ptr = stacks[ptr][0]; } if (highest == 15) { if (begin > -1) { stacks[begin][1] = 15; stacks[begin][2] = stacks[loc][2]; stacks[begin][0] = stacks[end][0]; return 1; } else { stacks[0][0] = stacks[end][0]; stacks[0][1] = 15; stacks[0][2] = stacks[loc][2]; return 1; } } else if (highest == 2) { next = stacks[loc][0]; if (stacks[next][1] != 15 || stacks[next][0] == 0) { return 0; } stacks[loc][0] = stacks[next][0]; stacks[loc][1] = 15; stacks[loc][2] = !stacks[next][2]; } else { next = stacks[loc][0]; if (ploc == -1 || stacks[next][0] == 0 || stacks[next][1] != 15) return 0; if (stacks[ploc][1] != 15) return 0; switch (highest) { case 3: /* highest priority is * */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] *= stacks[next][2]; break; case 4: /* highest priority is / */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] /= stacks[next][2]; break; case 5: /* highest priority is + */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] += stacks[next][2]; break; case 6: /* highest priority is - */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] -= stacks[next][2]; break; case 7: /* highest priority is > */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] = (stacks[ploc][2] > stacks[next][2]); break; case 8: /* highest priority is >= */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] = (stacks[ploc][2] >= stacks[next][2]); break; case 9: /* highest priority is < */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] = (stacks[ploc][2] < stacks[next][2]); break; case 10: /* highest priority is <= */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] = (stacks[ploc][2] <= stacks[next][2]); break; case 11: /* highest priority is == */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] = (stacks[ploc][2] == stacks[next][2]); break; case 12: /* highest priority is != */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] = (stacks[ploc][2] != stacks[next][2]); break; case 13: /* highest priority is && */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] = (stacks[ploc][2] && stacks[next][2]); break; case 14: /* highest priority is || */ stacks[ploc][0] = stacks[next][0]; stacks[ploc][2] = (stacks[ploc][2] || stacks[next][2]); break; default: tintin_puts2("#Programming error *slap Bill*", (struct session *) NULL); return 0; } } } }