예제 #1
0
/******** HOOK ********/
char *
mesg_parse(int descr, dbref player, dbref what, dbref perms,
    const char *inbuf, char *outbuf, int maxchars, int mesgtyp)
{
	char wbuf[BUFFER_LEN];
	char buf[BUFFER_LEN];
	char buf2[BUFFER_LEN];
	char dbuf[BUFFER_LEN];
	char ebuf[BUFFER_LEN];
	char cmdbuf[MAX_MFUN_NAME_LEN + 1];
	const char *ptr;
	char *dptr;
	int p, q, s;
	int i;
	char *argv[10] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
	int argc = 0;
	int showtextflag = 0;
	int literalflag = 0;

	mesg_rec_cnt++;
	if (mesg_rec_cnt > 26) {
		char *zptr = get_mvar("how");
		snprintf(dbuf, sizeof(dbuf), "%s Recursion limit exceeded.", zptr);
		notify_nolisten(player, dbuf, 1);
		mesg_rec_cnt--;
		outbuf[0] = '\0';
		return NULL;
	}
	if (Typeof(player) == TYPE_GARBAGE) {
		mesg_rec_cnt--;
		outbuf[0] = '\0';
		return NULL;
	}
	if (Typeof(what) == TYPE_GARBAGE) {
		notify_nolisten(player, "MPI Error: Garbage trigger.", 1);
		mesg_rec_cnt--;
		outbuf[0] = '\0';
		return NULL;
	}
	strcpyn(wbuf, sizeof(wbuf), inbuf);
	for (p = q = 0; wbuf[p] && (p < maxchars - 1) && q < (maxchars - 1); p++) {
		if (wbuf[p] == '\\') {
			p++;
			showtextflag = 1;
			if (wbuf[p] == 'r') {
				outbuf[q++] = '\r';
			} else if (wbuf[p] == '[') {
				outbuf[q++] = ESCAPE_CHAR;
			} else {
				outbuf[q++] = wbuf[p];
			}
		} else if (wbuf[p] == MFUN_LITCHAR) {
			literalflag = (!literalflag);
		} else if (!literalflag && wbuf[p] == MFUN_LEADCHAR) {
			if (wbuf[p + 1] == MFUN_LEADCHAR) {
				showtextflag = 1;
				outbuf[q++] = wbuf[p++];
				ptr = "";
			} else {
				ptr = wbuf + (++p);
				s = 0;
				while (wbuf[p] && wbuf[p] != MFUN_LEADCHAR &&
					   !isspace(wbuf[p]) && wbuf[p] != MFUN_ARGSTART &&
					   wbuf[p] != MFUN_ARGEND && s < MAX_MFUN_NAME_LEN) {
					p++;
					s++;
				}
				if (s < MAX_MFUN_NAME_LEN &&
					(wbuf[p] == MFUN_ARGSTART || wbuf[p] == MFUN_ARGEND)) {
					int varflag;

					strncpy(cmdbuf, ptr, s);
					cmdbuf[s] = '\0';

					varflag = 0;
					if (*cmdbuf == '&') {
						s = find_mfn("sublist");
						varflag = 1;
					} else if (*cmdbuf) {
						s = find_mfn(cmdbuf);
					} else {
						s = 0;
					}
					if (s) {
						s--;
						if (++mesg_instr_cnt > tp_mpi_max_commands) {
							char *zptr = get_mvar("how");

							snprintf(dbuf, sizeof(dbuf), "%s %c%s%c: Instruction limit exceeded.",
									zptr, MFUN_LEADCHAR,
									(varflag ? cmdbuf : mfun_list[s].name), MFUN_ARGEND);
							notify_nolisten(player, dbuf, 1);
							mesg_rec_cnt--;
							outbuf[0] = '\0';
							return NULL;
						}
						for (i = 0; i < argc; i++) {
							free(argv[i]);
							argv[i] = NULL;
						}
						if (wbuf[p] == MFUN_ARGEND) {
							argc = 0;
						} else {
							argc = mfun_list[s].maxargs;
							if (argc < 0) {
								argc = mesg_args((wbuf + p + 1), (sizeof(wbuf) - p - 1),
												 &argv[(varflag ? 1 : 0)],
												 MFUN_LEADCHAR, MFUN_ARGSEP,
												 MFUN_ARGEND, MFUN_LITCHAR,
												 (-argc) + (varflag ? 1 : 0));
							} else {
								argc = mesg_args((wbuf + p + 1), (sizeof(wbuf) - p - 1),
												 &argv[(varflag ? 1 : 0)],
												 MFUN_LEADCHAR, MFUN_ARGSEP,
												 MFUN_ARGEND, MFUN_LITCHAR, (varflag ? 8 : 9));
							}
							if (argc == -1) {
								char *zptr = get_mvar("how");

								snprintf(ebuf, sizeof(ebuf), "%s %c%s%c: End brace not found.",
										zptr, MFUN_LEADCHAR, cmdbuf, MFUN_ARGEND);
								notify_nolisten(player, ebuf, 1);
								for (i = 0; i < argc; i++) {
									free(argv[i + (varflag? 1 : 0)]);
								}
								mesg_rec_cnt--;
								outbuf[0] = '\0';
								return NULL;
							}
						}
						if (varflag) {
							char *zptr;

							zptr = get_mvar(cmdbuf + 1);
							if (!zptr) {
								zptr = get_mvar("how");
								snprintf(ebuf, sizeof(ebuf), "%s %c%s%c: Unrecognized variable.",
										zptr, MFUN_LEADCHAR, cmdbuf, MFUN_ARGEND);
								notify_nolisten(player, ebuf, 1);
								for (i = 0; i < argc; i++) {
									if (argv[i + (varflag? 1 : 0)]) {
										free(argv[i + (varflag? 1 : 0)]);
									}
								}
								mesg_rec_cnt--;
								outbuf[0] = '\0';
								return NULL;
							}
							if (argv[0]) {
								free(argv[0]);
								argv[0] = NULL;
							}
							argv[0] = string_dup(zptr);
							argc++;
						}
						if (mesgtyp & MPI_ISDEBUG) {
							char *zptr = get_mvar("how");

							snprintf(dbuf, sizeof(dbuf), "%s %*s%c%s%c", zptr,
									(mesg_rec_cnt * 2 - 4), "", MFUN_LEADCHAR,
									(varflag ? cmdbuf : mfun_list[s].name), MFUN_ARGSTART);
							for (i = (varflag ? 1 : 0); i < argc; i++) {
								if (i) {
									const char tbuf[] = { MFUN_ARGSEP, '\0' };
									strcatn(dbuf, sizeof(dbuf), tbuf);
								}
								cr2slash(ebuf, sizeof(ebuf)/8, argv[i]);
								strcatn(dbuf, sizeof(dbuf), "`");
								strcatn(dbuf, sizeof(dbuf), ebuf);
								if (strlen(ebuf) >= (sizeof(ebuf)/8)-2) {
									strcatn(dbuf, sizeof(dbuf), "...");
								}
								strcatn(dbuf, sizeof(dbuf), "`");
							}
							{
								const char tbuf[] = { MFUN_ARGEND, '\0' };
								strcatn(dbuf, sizeof(dbuf), tbuf);
							}
							notify_nolisten(player, dbuf, 1);
						}
						if (mfun_list[s].stripp) {
							for (i = (varflag ? 1 : 0); i < argc; i++) {
								stripspaces(buf, sizeof(buf), argv[i]);
								/*
								 * stripspaces() can only shorten a string.
								 * The argv[i] buffer will therefore always
								 * be large enough.
								 */
								strcpyn(argv[i], strlen(buf)+1, buf);
							}
						}
						if (mfun_list[s].parsep) {
							for (i = (varflag ? 1 : 0); i < argc; i++) {
								ptr = MesgParse(argv[i], buf, sizeof(buf));
								if (!ptr) {
									char *zptr = get_mvar("how");

									snprintf(dbuf, sizeof(dbuf), "%s %c%s%c (arg %d)", zptr,
											MFUN_LEADCHAR,
											(varflag ? cmdbuf : mfun_list[s].name),
											MFUN_ARGEND, i + 1);
									notify_nolisten(player, dbuf, 1);
									for (i = 0; i < argc; i++) {
										free(argv[i]);
									}
									mesg_rec_cnt--;
									outbuf[0] = '\0';
									return NULL;
								}
								argv[i] = (char*)realloc(argv[i], strlen(buf) + 1);
								strcpyn(argv[i], strlen(buf)+1, buf);
							}
						}
						if (mesgtyp & MPI_ISDEBUG) {
							char *zptr = get_mvar("how");

							snprintf(dbuf, sizeof(dbuf), "%.512s %*s%c%.512s%c", zptr,
									(mesg_rec_cnt * 2 - 4), "", MFUN_LEADCHAR,
									(varflag ? cmdbuf : mfun_list[s].name), MFUN_ARGSTART);
							for (i = (varflag ? 1 : 0); i < argc; i++) {
								if (i) {
									const char tbuf[] = { MFUN_ARGSEP, '\0' };
									strcatn(dbuf, sizeof(dbuf), tbuf);
								}
								cr2slash(ebuf, sizeof(ebuf)/8, argv[i]);
								strcatn(dbuf, sizeof(dbuf), "`");
								strcatn(dbuf, sizeof(dbuf), ebuf);
								if (strlen(ebuf) >= (sizeof(ebuf)/8)-2) {
									strcatn(dbuf, sizeof(dbuf), "...");
								}
								strcatn(dbuf, sizeof(dbuf), "`");
							}
							{
								const char tbuf[] = { MFUN_ARGEND, '\0' };
								strcatn(dbuf, sizeof(dbuf), tbuf);
							}
						}
						if (argc < mfun_list[s].minargs) {
							char *zptr = get_mvar("how");

							snprintf(ebuf, sizeof(ebuf), "%s %c%s%c: Too few arguments",
									zptr, MFUN_LEADCHAR,
									(varflag ? cmdbuf : mfun_list[s].name), MFUN_ARGEND);
							notify_nolisten(player, ebuf, 1);
							for (i = 0; i < argc; i++) {
								free(argv[i]);
							}
							mesg_rec_cnt--;
							outbuf[0] = '\0';
							return NULL;
						} else if (mfun_list[s].maxargs > 0 && argc > mfun_list[s].maxargs) {
							char *zptr = get_mvar("how");

							snprintf(ebuf, sizeof(ebuf), "%s %c%s%c: Too many arguments",
									zptr, MFUN_LEADCHAR,
									(varflag ? cmdbuf : mfun_list[s].name), MFUN_ARGEND);
							notify_nolisten(player, ebuf, 1);
							for (i = 0; i < argc; i++) {
								free(argv[i]);
							}
							mesg_rec_cnt--;
							outbuf[0] = '\0';
							return NULL;
						} else {
							ptr = mfun_list[s].mfn(descr, player, what, perms,
							    argc, argv, buf, sizeof(buf), mesgtyp);
							if (!ptr) {
								outbuf[q] = '\0';
								for (i = 0; i < argc; i++) {
									free(argv[i]);
								}
								mesg_rec_cnt--;
								outbuf[0] = '\0';
								return NULL;
							}
							if (mfun_list[s].postp) {
								dptr = MesgParse(ptr, buf, sizeof(buf));
								if (!dptr) {
									char *zptr = get_mvar("how");

									snprintf(ebuf, sizeof(ebuf), "%s %c%s%c (returned string)",
											zptr, MFUN_LEADCHAR,
											(varflag ? cmdbuf : mfun_list[s].name),
											MFUN_ARGEND);
									notify_nolisten(player, ebuf, 1);
									for (i = 0; i < argc; i++) {
										free(argv[i]);
									}
									mesg_rec_cnt--;
									outbuf[0] = '\0';
									return NULL;
								}
								ptr = dptr;
							}
						}
						if (mesgtyp & MPI_ISDEBUG) {
							strcatn(dbuf, sizeof(dbuf), " = `");
							cr2slash(ebuf, sizeof(ebuf)/8, ptr);
							strcatn(dbuf, sizeof(dbuf), ebuf);
							if (strlen(ebuf) >= (sizeof(ebuf)/8)-2) {
								strcatn(dbuf, sizeof(dbuf), "...");
							}
							strcatn(dbuf, sizeof(dbuf), "`");
							notify_nolisten(player, dbuf, 1);
						}
					} else if (msg_is_macro(player, what, perms, cmdbuf, mesgtyp)) {
						for (i = 0; i < argc; i++) {
							free(argv[i]);
							argv[i] = NULL;
						}
						if (wbuf[p] == MFUN_ARGEND) {
							argc = 0;
							p++;
						} else {
							p++;
							argc = mesg_args(wbuf + p, (sizeof(wbuf) - p), argv, MFUN_LEADCHAR,
											 MFUN_ARGSEP, MFUN_ARGEND, MFUN_LITCHAR, 9);
							if (argc == -1) {
								char *zptr = get_mvar("how");

								snprintf(ebuf, sizeof(ebuf), "%s %c%s%c: End brace not found.",
										zptr, MFUN_LEADCHAR, cmdbuf, MFUN_ARGEND);
								notify_nolisten(player, ebuf, 1);
								for (i = 0; i < argc; i++) {
									free(argv[i]);
								}
								mesg_rec_cnt--;
								outbuf[0] = '\0';
								return NULL;
							}
						}
						msg_unparse_macro(player, what, perms, cmdbuf, argc,
										  argv, (wbuf + p), (BUFFER_LEN - p),
										  mesgtyp);
						p--;
						ptr = NULL;
					} else {
						/* unknown function */
						char *zptr = get_mvar("how");

						snprintf(ebuf, sizeof(ebuf), "%s %c%s%c: Unrecognized function.",
								zptr, MFUN_LEADCHAR, cmdbuf, MFUN_ARGEND);
						notify_nolisten(player, ebuf, 1);
						for (i = 0; i < argc; i++) {
							free(argv[i]);
						}
						mesg_rec_cnt--;
						outbuf[0] = '\0';
						return NULL;
					}
				} else {
					showtextflag = 1;
					ptr--;
					i = s + 1;
					while (ptr && *ptr && i-- && q < (maxchars - 1)) {
						outbuf[q++] = *(ptr++);
					}
					outbuf[q] = '\0';
					p = (int) (ptr - wbuf) - 1;
					ptr = "";	/* unknown substitution type */
				}
				while (ptr && *ptr && q < (maxchars - 1)) {
					outbuf[q++] = *(ptr++);
				}
			}
		} else {
			outbuf[q++] = wbuf[p];
			showtextflag = 1;
		}
	}
	outbuf[q] = '\0';
	if ((mesgtyp & MPI_ISDEBUG) && showtextflag) {
		char *zptr = get_mvar("how");

		snprintf(dbuf, sizeof(dbuf), "%s %*s`%.512s`",
		        zptr, (mesg_rec_cnt * 2 - 4), "",
				cr2slash(buf2, sizeof(buf2), outbuf));
		notify_nolisten(player, dbuf, 1);
	}
	for (i = 0; i < argc; i++) {
		free(argv[i]);
	}
	mesg_rec_cnt--;
	outbuf[maxchars - 1] = '\0';
	return (outbuf);
}
예제 #2
0
/******** HOOK ********/
char   *
mesg_parse(dbref player, dbref what, dbref perms, const char *inbuf, char *outbuf, int maxchars, int mesgtyp)
{
    char    wbuf[BUFFER_LEN];
    char    buf[BUFFER_LEN];
    char    buf2[BUFFER_LEN];
    char    dbuf[BUFFER_LEN];
    char    ebuf[BUFFER_LEN];
    char    cmdbuf[MAX_MFUN_NAME_LEN + 1];
    const char *ptr;
    char    *dptr;
    int     p, q, s;
    int     i;
    char    argv[9][BUFFER_LEN];
    int     argc;
    int showtextflag = 0;
    int literalflag = 0;

    mesg_rec_cnt++;
    if (mesg_rec_cnt > 26) {
        mesg_rec_cnt--;
        strncpy(outbuf, inbuf, maxchars);
        outbuf[maxchars - 1] = '\0';
        return outbuf;
    }
    if (Typeof(player) == TYPE_GARBAGE) {
	return NULL;
    }
    if (Typeof(what) == TYPE_GARBAGE) {
	notify_nolisten(player, "MPI Error: Garbage trigger.", 1);
	return NULL;
    }
    strcpy(wbuf, inbuf);
    for (p = q = 0; wbuf[p] && (p < maxchars - 1) && q < (maxchars - 1); p++) {
        if (wbuf[p] == '\\') {
            p++;
            showtextflag = 1;
            if (wbuf[p] == 'r') {
                outbuf[q++] = '\r';
            } else {
                outbuf[q++] = wbuf[p];
            }
        } else if (wbuf[p] == MFUN_LITCHAR) {
            literalflag = (!literalflag);
        } else if (!literalflag && wbuf[p] == MFUN_LEADCHAR) {
            if (wbuf[p + 1] == MFUN_LEADCHAR) {
                showtextflag = 1;
                outbuf[q++] = wbuf[p++];
		ptr = "";
            } else {
                ptr = wbuf + (++p);
                s = 0;
                while (wbuf[p] && wbuf[p] != MFUN_LEADCHAR &&
                        !isspace(wbuf[p]) && wbuf[p] != MFUN_ARGSTART &&
                        wbuf[p] != MFUN_ARGEND && s < MAX_MFUN_NAME_LEN) {
                    p++; s++;
                }
                if (s < MAX_MFUN_NAME_LEN &&
                        (wbuf[p] == MFUN_ARGSTART || wbuf[p] == MFUN_ARGEND)) {
                    int varflag;

                    strncpy(cmdbuf,ptr,s);
                    cmdbuf[s] = '\0';

		    varflag = 0;
                    if (*cmdbuf == '&') {
			s = find_mfn("sublist");
			varflag = 1;
                    } else if (*cmdbuf) {
			s = find_mfn(cmdbuf);
                    } else {
                        s = 0;
                    }
                    if (s) {
			s--;
			if (++mesg_instr_cnt > tp_mpi_max_commands) {
			    char *zptr = get_mvar("how");
			    sprintf(dbuf, "%s %c%s%c: Instruction limit exceeded.",
				    zptr, MFUN_LEADCHAR,
				    (varflag? cmdbuf : mfun_list[s].name),
				    MFUN_ARGEND);
			    notify_nolisten(player, dbuf, 1);
			    return NULL;
			}
                        if (wbuf[p] == MFUN_ARGEND) {
                            argc = 0;
                        } else {
			    argc = mfun_list[s].maxargs;
			    if (argc < 0) {
				argc = mesg_args((wbuf+p+1),
				        &argv[(varflag? 1 : 0)],
					MFUN_LEADCHAR, MFUN_ARGSEP,
					MFUN_ARGEND, MFUN_LITCHAR,
					(-argc) + (varflag? 1 : 0));
			    } else {
				argc = mesg_args((wbuf+p+1),
				        &argv[(varflag? 1 : 0)],
					MFUN_LEADCHAR, MFUN_ARGSEP,
					MFUN_ARGEND, MFUN_LITCHAR,
					(varflag? 8 : 9));
			    }
			    if (argc == -1) {
				char *zptr = get_mvar("how");
				sprintf(ebuf, "%s %c%s%c: End brace not found.",
					zptr, MFUN_LEADCHAR, cmdbuf,
					MFUN_ARGEND);
				notify_nolisten(player, ebuf, 1);
				return NULL;
			    }
                        }
                        if (varflag) {
			    char *zptr;

			    argc++;
			    zptr = get_mvar(cmdbuf + 1);
			    if (!zptr) {
				zptr = get_mvar("how");
				sprintf(ebuf, "%s %c%s%c: Unrecognized variable.",
					zptr, MFUN_LEADCHAR, cmdbuf, MFUN_ARGEND);
				notify_nolisten(player, ebuf, 1);
				return NULL;
			    }
			    strcpy(argv[0], zptr);
                        }
                        if (mesgtyp & MPI_ISDEBUG) {
                            char *zptr = get_mvar("how");
                            sprintf(dbuf, "%s %*s%c%s%c", zptr,
                                    (mesg_rec_cnt*2-4), "", MFUN_LEADCHAR,
                                    (varflag? cmdbuf : mfun_list[s].name),
                                    MFUN_ARGSTART);
                            for (i = (varflag? 1 : 0); i < argc; i++) {
                                if (i) {
                                    sprintf(dbuf, "%.512s%c ", dbuf,
                                            MFUN_ARGSEP);
                                }
                                cr2slash(ebuf, argv[i]);
                                if (strlen(ebuf) > 512) {
                                    sprintf(dbuf, "%.512s\"%.512s...\"",
                                            dbuf, ebuf);
                                } else {
                                    sprintf(dbuf, "%.512s\"%s\"", dbuf, ebuf);
                                }
                            }
                            sprintf(dbuf, "%.512s%c", dbuf, MFUN_ARGEND);
                            notify_nolisten(player, dbuf, 1);
                        }
                        if (mfun_list[s].stripp) {
                            for (i = (varflag? 1 : 0); i < argc; i++) {
                                strcpy(argv[i], stripspaces(buf, argv[i]));
                            }
                        }
                        if (mfun_list[s].parsep) {
                            for (i = (varflag? 1 : 0); i < argc; i++) {
                                ptr = MesgParse(argv[i], argv[i]);
                                if (!ptr) {
                                    char *zptr = get_mvar("how");
                                    sprintf(dbuf, "%s %c%s%c (arg %d)", zptr,
                                            MFUN_LEADCHAR,
                                            (varflag?cmdbuf:mfun_list[s].name),
                                            MFUN_ARGEND, i+1);
                                    notify_nolisten(player, dbuf, 1);
                                    return NULL;
                                }
                            }
                        }
                        if (mesgtyp & MPI_ISDEBUG) {
                            char *zptr = get_mvar("how");
                            sprintf(dbuf, "%.512s %*s%c%.512s%c", zptr,
                                    (mesg_rec_cnt*2-4), "", MFUN_LEADCHAR,
                                    (varflag? cmdbuf : mfun_list[s].name),
                                    MFUN_ARGSTART);
                            for (i = (varflag? 1 : 0); i < argc; i++) {
                                if (i) {
                                    sprintf(dbuf, "%.512s%c ", dbuf,
                                            MFUN_ARGSEP);
                                }
                                cr2slash(ebuf, argv[i]);
                                if (strlen(ebuf) > 128) {
                                    sprintf(dbuf, "%.512s\"%.128s...\"",
                                            dbuf, ebuf);
                                } else {
                                    sprintf(dbuf, "%.512s\"%s\"", dbuf, ebuf);
                                }
                            }
                            sprintf(dbuf, "%s%c", dbuf, MFUN_ARGEND);
                        }
                        if (argc < mfun_list[s].minargs) {
                            char *zptr = get_mvar("how");
                            sprintf(ebuf, "%s %c%s%c: Too few arguments",
                                    zptr, MFUN_LEADCHAR,
                                    (varflag? cmdbuf : mfun_list[s].name),
                                    MFUN_ARGEND);
                            notify_nolisten(player, ebuf, 1);
                            return NULL;
                        } else if (mfun_list[s].maxargs > 0 &&
				    argc > mfun_list[s].maxargs) {
                            char *zptr = get_mvar("how");
                            sprintf(ebuf, "%s %c%s%c: Too many arguments",
                                    zptr, MFUN_LEADCHAR,
                                    (varflag? cmdbuf : mfun_list[s].name),
                                    MFUN_ARGEND);
                            notify_nolisten(player, ebuf, 1);
                            return NULL;
                        } else {
                            ptr = mfun_list[s].mfn(player, what, perms, argc,
                                                   argv, buf, mesgtyp);
			    if (!ptr) {
				outbuf[q] = '\0';
				return NULL;
			    }
                            if (mfun_list[s].postp) {
                                dptr = MesgParse(ptr, buf);
                                if (!dptr) {
                                    char *zptr = get_mvar("how");
                                    sprintf(ebuf, "%s %c%s%c (returned string)",
                                            zptr, MFUN_LEADCHAR,
                                            (varflag?cmdbuf:mfun_list[s].name),
                                            MFUN_ARGEND);
                                    notify_nolisten(player, ebuf, 1);
                                    return NULL;
                                }
				ptr = dptr;
                            }
                        }
                        if (mesgtyp & MPI_ISDEBUG) {
                            sprintf(dbuf, "%.512s = \"%.512s\"", dbuf,
                                    cr2slash(ebuf, ptr));
                            notify_nolisten(player, dbuf, 1);
                        }
                    } else if (msg_is_macro(player, what, perms, cmdbuf)) {
                        if (wbuf[p] == MFUN_ARGEND) {
                            argc = 0;
			    p++;
                        } else {
			    p++;
                            argc = mesg_args(wbuf+p, argv, MFUN_LEADCHAR,
				 MFUN_ARGSEP, MFUN_ARGEND, MFUN_LITCHAR, 9);
			    if (argc == -1) {
				char *zptr = get_mvar("how");
				sprintf(ebuf, "%s %c%s%c: End brace not found.",
					zptr, MFUN_LEADCHAR, cmdbuf,
					MFUN_ARGEND);
				notify_nolisten(player, ebuf, 1);
				return NULL;
			    }
                        }
                        msg_unparse_macro(player, what, perms, cmdbuf, argc,
					    argv, (wbuf+p), (BUFFER_LEN - p));
			p--;
                        ptr = NULL;
                    } else {
			/* unknown function */
			char *zptr = get_mvar("how");
			sprintf(ebuf, "%s %c%s%c: Unrecognized function.",
				zptr, MFUN_LEADCHAR, cmdbuf, MFUN_ARGEND);
			notify_nolisten(player, ebuf, 1);
			return NULL;
                    }
                } else {
                    showtextflag = 1;
                    p = (int) (ptr - wbuf);
                    if (q < (maxchars - 1))
                        outbuf[q++] = MFUN_LEADCHAR;
                    ptr = "";   /* unknown substitution type */
                }
                while (ptr && *ptr && q < (maxchars -1))
                    outbuf[q++] = *(ptr++);
            }
        } else {
            outbuf[q++] = wbuf[p];
            showtextflag = 1;
        }
    }
    outbuf[q] = '\0';
    if ((mesgtyp & MPI_ISDEBUG) && showtextflag) {
        char *zptr = get_mvar("how");
        sprintf(dbuf, "%s %*s\"%.512s\"", zptr, (mesg_rec_cnt*2-4), "",
                cr2slash(buf2, outbuf));
        notify_nolisten(player, dbuf, 1);
    }
    mesg_rec_cnt--;
    return (outbuf);
}