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