These things should work nicely... I've taken a couple of the functions out of my mobprog.c and supplied them here. In the mprog_process_if there might be one or two function calls that are undefined in your particular versions. But it should work. Helver > char* find_endif (char* com_list, struct char_data* mob) > { > > int if_scope = 1; > > char* cmnd = '\0'; > char* morebuf = '\0'; > > char buf [MAX_INPUT_LENGTH]; > > while (if_scope > 0) > { > cmnd = com_list; > > while (*com_list != '\n' && *com_list != '\r' && *com_list != '\0') com_list++; com_list++; > > while (isspace(*cmnd)) cmnd++; > > if (*cmnd == '\0') > { > bug ("Mob: %d missing else or endif in find_endif", mob_index[mob->nr].virtual); > return '\0'; > } > > morebuf = one_argument (cmnd, buf); > > if (!str_cmp (buf, "if")) if_scope++; > if (!str_cmp (buf, "endif")) if_scope--; > > } /* while */ > > return com_list; > > } /* find_endif */ > > /* Used in mprog_process_if to determine the proper 'else' of the if-block so that > * other subsequent commands are not skipped in the event of and error or > * breaks in nested if statements. This will inprove the logical flow of > * mob_prog processing to what it should be. > */ > > char* find_else (char* com_list, struct char_data *mob) > { > int if_scope = 1; > > char* cmnd = '\0'; > char* morebuf = '\0'; > > char buf [MAX_INPUT_LENGTH]; > > while (if_scope > 0) > { > cmnd = com_list; > > while (*com_list != '\n' && *com_list != '\r' && *com_list != '\0') com_list++; com_list++; > > while (isspace(*cmnd)) cmnd++; > > if (*cmnd == '\0') > { > bug ("Mob: %d missing else or endif in find_else", mob_index[mob->nr].virtual); > return '\0'; > } > > morebuf = one_argument (cmnd, buf); > > if (!str_cmp (buf, "if")) if_scope++; > if (!str_cmp (buf, "endif")) if_scope--; > if ((!str_cmp (buf, "else")) && (if_scope == 1)) > { > return cmnd; > } > > } /* while */ > > return cmnd; > > } /* find_else */ > > > /* Used to get sequential lines of a multi line string (separated by "\n\r") > * Thus its like one_argument(), but a trifle different. It is destructive > * to the multi line string argument, and thus clist must not be shared. > */ > > char *mprog_next_command(char *clist) > { > > char *pointer = clist; > > /* a little error checking here, if we are sent a null pointer > * dereferencing it would cause a seg fault and crash the mud > * this is defined as 'bad'. for a complete description of 'bad' > * check your local dictionary :) > */ > if (!clist) return NULL; > > if (*pointer == '\r') > pointer++; > if (*pointer == '\n') > pointer++; > > while (*pointer != '\n' && *pointer != '\0' && *pointer != '\r') > pointer++; > if (*pointer == '\n') { > *pointer = '\0'; > pointer++; } > if (*pointer == '\r') { > *pointer = '\0'; > pointer++; } > > return (pointer); > > } > > /* Quite a long and arduous function, this guy handles the control > * flow part of MOBprograms. Basicially once the driver sees an > * 'if' attention shifts to here. While many syntax errors are > * caught, some will still get through due to the handling of break > * and errors in the same fashion. The desire to break out of the > * recursion without catastrophe in the event of a mis-parse was > * believed to be high. Thus, if an error is found, it is bugged and > * the parser acts as though a break were issued and just bails out > * at that point. I havent tested all the possibilites, so I'm speaking > * in theory, but it is 'guaranteed' to work on syntactically correct > * MOBprograms, so if the mud crashes here, check the mob carefully! > */ > > char null[1]; > > char *mprog_process_if(char *ifchck, char *com_list, struct char_data *mob, > struct char_data *actor, struct obj_data *obj, void *vo, > struct char_data *rndm) > { > > char buf[ MAX_INPUT_LENGTH ]; > char buf2[ MAX_INPUT_LENGTH ]; > char *morebuf = '\0'; > char *cmnd = '\0'; > int loopdone = FALSE; > int flag = FALSE; > int legal; > > char *end_list = '\0'; > char *else_list = '\0'; > > *null = '\0'; > > /* find the end of the list if-block for returning instead of > * completely dropping out the mob-prog > */ > > end_list = find_endif (com_list, mob); > > /* skip all of the if-block to the proper 'else' segment > * if there is no 'else' segment, this function will skip > * to the proper 'endif' -- it's amazingly cool :) brr > */ > > else_list = find_else (com_list, mob); > > > /* check for trueness of the ifcheck */ > if ((legal = mprog_do_ifchck(ifchck, mob, actor, obj, vo, rndm))) flag = TRUE; > > while(loopdone == FALSE) /*scan over any existing or statements */ > { > cmnd = com_list; > com_list = mprog_next_command(com_list); > while (*cmnd == ' ') > cmnd++; > if (*cmnd == '\0') > { > bug ("Mob: %d no commands after IF/OR", mob_index[mob->nr].virtual); > return null; > } > morebuf = one_argument(cmnd,buf); > if (!str_cmp(buf, "or")) > { > if ((legal = mprog_do_ifchck(morebuf,mob,actor,obj,vo,rndm))) flag = TRUE; > } > else > loopdone = TRUE; > } > > if (flag) > for (; ;) /*ifcheck was true, do commands but ignore else to endif*/ > { > if (!str_cmp(buf, "if")) > { > com_list = mprog_process_if(morebuf,com_list,mob,actor,obj,vo,rndm); > while (*cmnd==' ') > cmnd++; > if (*com_list == '\0') > return null; > cmnd = com_list; > com_list = mprog_next_command(com_list); > morebuf = one_argument(cmnd,buf); > continue; > } > if ( (!str_cmp(buf, "break")) > || (!str_cmp(buf, "endif")) > || (!str_cmp(buf, "else")) > ) > return end_list; > > strcpy (buf2, cmnd); > strcat (buf2, com_list); > mprog_process_cmnd(buf2, mob, actor, obj, vo, rndm); > if (!(*buf2)) com_list[0] = '\0'; > cmnd = com_list; > com_list = mprog_next_command(com_list); > while (*cmnd == ' ') > cmnd++; > if (*cmnd == '\0') > { > bug ("Mob: %d missing else or endif", mob_index[mob->nr].virtual); > return null; > } > morebuf = one_argument(cmnd, buf); > } > else /*false ifcheck, find else and do existing commands or quit at endif*/ > { > com_list = else_list; > cmnd = com_list; > com_list = mprog_next_command(com_list); > > morebuf = one_argument(cmnd, buf); > > /* found either an else or an endif.. act accordingly */ > if (!str_cmp(buf, "endif")) { > return com_list; > } > cmnd = com_list; > com_list = mprog_next_command(com_list); > if (cmnd == NULL) { > bug ("Mob: %d null command list", mob_index[mob->nr].virtual); > return null; > } > while (*cmnd == ' ') > cmnd++; > if (*cmnd == '\0') > { > bug ("Mob: %d missing endif", mob_index[mob->nr].virtual); > return null; > } > morebuf = one_argument(cmnd, buf); > > for (; ;) /*process the post-else commands until an endif is found.*/ > { > if (!str_cmp(buf, "if")) > { > com_list = mprog_process_if(morebuf, com_list, mob, actor, > obj, vo, rndm); > while (*cmnd == ' ') > cmnd++; > if (*com_list == '\0') > return null; > cmnd = com_list; > com_list = mprog_next_command(com_list); > morebuf = one_argument(cmnd,buf); > continue; > } > if (!str_cmp(buf, "else")) > { > bug ("Mob: %d found else in an else section", > mob_index[mob->nr].virtual); > return end_list; > } > if ( (!str_cmp(buf, "break")) > || (!str_cmp(buf, "endif")) > ) > return end_list; > > strcpy (buf2, cmnd); > strcat (buf2, com_list); > mprog_process_cmnd(buf2, mob, actor, obj, vo, rndm); > if (!(*buf2)) com_list[0] = '\0'; > cmnd = com_list; > com_list = mprog_next_command(com_list); > while (*cmnd == ' ') > cmnd++; > if (*cmnd == '\0') > { > bug ("Mob:%d missing endif in else section", > mob_index[mob->nr].virtual); > return null; > } > morebuf = one_argument(cmnd, buf); > } > } > } > +-----------------------------------------------------------+ | Ensure that you have read the CircleMUD Mailing List FAQ: | | http://cspo.queensu.ca/~fletcher/Circle/list_faq.html | +-----------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/07/00 PST