#include <stdio.h> #include "tintin.h" #include <ctype.h> int stacks[100][3]; extern struct listnode *common_myvars; #if IRIX #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; { /* char left[BUFFER_SIZE], right[BUFFER_SIZE], arg2[BUFFER_SIZE], */ char left[BUFFER_SIZE], right[BUFFER_SIZE], temp[BUFFER_SIZE], result[BUFFER_SIZE]; struct listnode *my_vars, *ln; 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); } void if_command(line, ses) char *line; struct session *ses; { /* char left[BUFFER_SIZE], right[BUFFER_SIZE], arg2[BUFFER_SIZE], */ char left[BUFFER_SIZE], right[BUFFER_SIZE], temp[BUFFER_SIZE]; /* int i; */ line=get_arg_in_braces(line, left, 0); line=get_arg_in_braces(line, right, 1); substitute_vars(right,temp); substitute_myvars(temp,right,ses); substitute_vars(left,temp); substitute_myvars(temp,left,ses); if (eval_expression(left)) { parse_input(right, ses); } } int eval_expression(arg) char *arg; { /* int i, begin, end, flag, prev, ptr; */ int i, begin, end, flag, prev; char temp[BUFFER_SIZE]; i=conv_to_ints(arg); if (i) { 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 return 0; } int conv_to_ints(arg) char *arg; { int i, flag; char *ptr, *tptr; i=0; ptr=arg; while (*ptr) { if (*ptr==' ') ; 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; } } } }