const char *
safegetprop_strict(dbref player, dbref what, dbref perms, const char *inbuf)
{
    const char *ptr;
    char  bbuf[BUFFER_LEN];
    static char  vl[32];

    if (!inbuf) {
        notify_nolisten(player, "PropFetch: Propname required.", 1);
        return NULL;
    }
    while (*inbuf == PROPDIR_DELIMITER)
        inbuf++;
    if (!*inbuf) {
        notify_nolisten(player, "PropFetch: Propname required.", 1);
        return NULL;
    }
    strcpy(bbuf, inbuf);
    ptr = get_property_class(what, bbuf);
    if (!ptr) {
        int i;

	i = get_property_value(what, bbuf);
	if (!i) {
	    dbref dd;

	    dd = get_property_dbref(what, bbuf);
	    if (dd == NOTHING) {
		*vl = '\0';
		ptr = vl;
		return ptr;
	    } else {
		sprintf(vl, "#%d", dd);
		ptr = vl;
	    }
	} else {
	    sprintf(vl, "%d", i);
	    ptr = vl;
	}
    }

#ifdef COMPRESS
    ptr = uncompress(ptr);
#endif

    if (!Wizperms(perms)) {
        if (Prop_Hidden(bbuf)) {
            notify_nolisten(player, "PropFetch: Permission denied.", 1);
            return NULL;
        }
//        if (Prop_Private(bbuf) && OWNER(perms) != OWNER(what)) {
        if (Prop_Private(bbuf) && !controls_nowizperm(OWNER(perms), what)) {
            notify_nolisten(player, "PropFetch: Permission denied.", 1);
            return NULL;
        }
    }
    return ptr;
}
Exemple #2
0
char *
do_parse_prop(int descr, dbref player, dbref what, const char *propname, const char *abuf, char *outbuf, int outbuflen, int mesgtyp)
{
	const char* propval = get_property_class(what, propname);
	if (!propval)
		return NULL;
	if (Prop_Blessed(what, propname))
		mesgtyp |= MPI_ISBLESSED;
	return do_parse_mesg(descr, player, what, propval, abuf, outbuf, outbuflen, mesgtyp);
}
Exemple #3
0
/* return old gender values for pronoun substitution code */
int
genderof(int descr, dbref player)
{
    const char *sexstr = NULL;
    sexstr = get_property_class(player, tp_sex_prop);
    while (sexstr && isspace(*sexstr)) sexstr++;

    if (!sexstr || !*sexstr)
        return GENDER_UNASSIGNED;
    if (string_compare(sexstr, "male") == 0)
        return GENDER_MALE;
    if (string_compare(sexstr, "female") == 0)
        return GENDER_FEMALE;
    if (string_compare(sexstr, "neuter") == 0)
        return GENDER_NEUTER;
    return GENDER_UNASSIGNED;
}
Exemple #4
0
void 
check_properties(const char *dir, dbref obj)
{
    int     val;
    char   *buf, *prop;
    PropPtr pptr;
    PropPtr pref;
    char    name[BUFFER_LEN];

    pref = first_prop(obj, dir, &pptr, name);
    while (pref > 0) {
	buf = (char *) malloc(strlen(dir) + strlen(name) + 2);
	(void) strcat(strcpy(buf, dir), name);
	if (prop = (char *) get_property_class(obj, buf))
	    printf("%s%c%s\n", buf + 1, PROP_DELIMITER, uncompress(prop));
	else if (val = get_property_value(obj, buf))
	    printf("%s%c^%d\n", buf + 1, PROP_DELIMITER, val);
	if (is_propdir(obj, buf))
	    check_properties((char *) strcat(buf, "/"), obj);
	free(buf);
	pref = next_prop(pptr, pref, name);
    }
}
Exemple #5
0
void
prim_array_regfilter_prop(PRIM_PROTOTYPE)
{
    char buf[BUFFER_LEN];
    struct inst *in;
    stk_array *arr;
    stk_array *nu;
    char* prop;
    const char* ptr;
    muf_re* re;
    int flags;
    int matchcnt = 0;
    const char* errstr = NULL;

    CHECKOP(4);
    oper4 = POP();    /* int     pcreflags */
    oper3 = POP();    /* str     pattern */
    oper2 = POP();    /* str     propname */
    oper1 = POP();    /* refarr  Array */

    if (oper1->type != PROG_ARRAY)
        abort_interp("Argument not an array. (1)");
    if (!array_is_homogenous(oper1->data.array, PROG_OBJECT))
        abort_interp("Argument not an array of dbrefs. (1)");
    if (oper2->type != PROG_STRING || !oper2->data.string)
        abort_interp("Argument not a non-null string. (2)");
    if (oper3->type != PROG_STRING)
        abort_interp("Argument not a string pattern. (3)");
    if (oper4->type != PROG_INTEGER)
        abort_interp("Non-integer argument (4)");


    ptr = oper2->data.string->data;
    while ((ptr = index(ptr, PROPDIR_DELIMITER)))
        if (!(*(++ptr)))
            abort_interp("Cannot access a propdir directly.");
    nu = new_array_packed(0);
    arr = oper1->data.array;

    flags = PCRE_NO_AUTO_CAPTURE;

    if (oper4->data.number & MUF_RE_ICASE)
        flags |= PCRE_CASELESS;
    if (oper4->data.number & MUF_RE_EXTENDED)
        flags |= PCRE_EXTENDED;

    re = regmatch_re_get(oper3->data.string, flags, &errstr);
    if (errstr)
        abort_interp(errstr)

    if (re && !re->extra && array_count(arr) > 2) {
        /* This pattern is getting used 3 or more times, let's study it. A null
         * return is okay, that just means there's nothing to optimize. */
        re->extra = pcre_study(re->re, 0, &errstr);
        if (errstr)
            abort_interp(errstr);
    }

    prop = (char *) DoNullInd(oper2->data.string);
    if (array_first(arr, &temp1)) {
        do {
            in = array_getitem(arr, &temp1);
            if (valid_object(in)) {
                ref = in->data.objref;
                CHECKREMOTE(ref);
                if (prop_read_perms(ProgUID, ref, prop, mlev)) {
                    ptr = get_property_class(ref, prop);
                    if (ptr)
                        strcpy(buf, ptr);
                    else
                        strcpy(buf, "");
                    if ((matchcnt = regmatch_exec(re, buf)) < 0) {
                        if (matchcnt != PCRE_ERROR_NOMATCH)
                            abort_interp(muf_re_error(matchcnt));
                    } else {
                        array_appenditem(&nu, in);
                    }
                }
            }
        } while (array_next(arr, &temp1));
    }


    CLEAR(oper4);
    CLEAR(oper3);
    CLEAR(oper2);
    CLEAR(oper1);
    PushArrayRaw(nu);
}
Exemple #6
0
const char *
safegetprop_strict(dbref player, dbref what, dbref perms, const char *inbuf, int mesgtyp, int* blessed)
{
	const char *ptr;
	char bbuf[BUFFER_LEN];
	static char vl[32];

	*blessed = 0;

	if (!inbuf) {
		notify_nolisten(player, "PropFetch: Propname required.", 1);
		return NULL;
	}
	while (*inbuf == PROPDIR_DELIMITER)
		inbuf++;
	if (!*inbuf) {
		notify_nolisten(player, "PropFetch: Propname required.", 1);
		return NULL;
	}
	strcpyn(bbuf, sizeof(bbuf), inbuf);

	if (Prop_System(bbuf))
	{
		notify_nolisten(player, "PropFetch: Permission denied.", 1);
		return NULL;
	}

	if (!(mesgtyp & MPI_ISBLESSED)) {
		if (Prop_Hidden(bbuf)) {
			notify_nolisten(player, "PropFetch: Permission denied.", 1);
			return NULL;
		}
		if (Prop_Private(bbuf) && OWNER(perms) != OWNER(what)) {
			notify_nolisten(player, "PropFetch: Permission denied.", 1);
			return NULL;
		}
	}

	ptr = get_property_class(what, bbuf);
	if (!ptr) {
		int i;

		i = get_property_value(what, bbuf);
		if (!i) {
			dbref dd;

			dd = get_property_dbref(what, bbuf);
			if (dd == NOTHING) {
				*vl = '\0';
				ptr = vl;
				return ptr;
			} else {
				snprintf(vl, sizeof(vl), "#%d", dd);
				ptr = vl;
			}
		} else {
			snprintf(vl, sizeof(vl), "%d", i);
			ptr = vl;
		}
	}

	if (ptr) {
		if (Prop_Blessed(what, bbuf)) {
			*blessed = 1;
		}
	}
	return ptr;
}
Exemple #7
0
void
listenqueue(int descr, dbref player, dbref where, dbref trigger, dbref what, dbref xclude,
			const char *propname, const char *toparg, int mlev, int mt, int mpi_p)
{
	const char *tmpchar;
	const char *pname, *sep, *ptr;
	dbref the_prog = NOTHING;
	char buf[BUFFER_LEN];
	char exbuf[BUFFER_LEN];
	char *ptr2;

	if (!(FLAGS(what) & LISTENER) && !(FLAGS(OWNER(what)) & ZOMBIE))
		return;

	the_prog = NOTHING;
	tmpchar = NULL;

	/* queue up program referred to by the given property */
	if (((the_prog = get_property_dbref(what, propname)) != NOTHING) ||
		(tmpchar = get_property_class(what, propname))) {

		if (tmpchar) {
			sep = tmpchar;
			while (*sep) {
				if (*sep == '\\') {
					sep++;
				} else if (*sep == '=') {
					break;
				}
				if (*sep)
					sep++;
			}
			if (*sep == '=') {
				for (ptr = tmpchar, ptr2 = buf; ptr < sep; *ptr2++ = *ptr++) ;
				*ptr2 = '\0';
				strcpyn(exbuf, sizeof(exbuf), toparg);
				if (!equalstr(buf, exbuf)) {
					tmpchar = NULL;
				} else {
					tmpchar = ++sep;
				}
			}
		}

		if ((tmpchar && *tmpchar) || the_prog != NOTHING) {
			if (tmpchar) {
				if (*tmpchar == '&') {
					the_prog = AMBIGUOUS;
				} else if (*tmpchar == NUMBER_TOKEN && number(tmpchar + 1)) {
					the_prog = (dbref) atoi(++tmpchar);
				} else if (*tmpchar == REGISTERED_TOKEN) {
					the_prog = find_registered_obj(what, tmpchar);
				} else if (number(tmpchar)) {
					the_prog = (dbref) atoi(tmpchar);
				} else {
					the_prog = NOTHING;
				}
			} else {
				if (the_prog == AMBIGUOUS)
					the_prog = NOTHING;
			}
			if (the_prog != AMBIGUOUS) {
				if (the_prog < 0 || the_prog >= db_top) {
					the_prog = NOTHING;
				} else if (Typeof(the_prog) != TYPE_PROGRAM) {
					the_prog = NOTHING;
				} else if (OWNER(the_prog) != OWNER(player) && !(FLAGS(the_prog) & LINK_OK)) {
					the_prog = NOTHING;
				} else if (MLevel(the_prog) < mlev) {
					the_prog = NOTHING;
				} else if (MLevel(OWNER(the_prog)) < mlev) {
					the_prog = NOTHING;
				} else if (the_prog == xclude) {
					the_prog = NOTHING;
				}
			}
			if (the_prog == AMBIGUOUS) {
				if (mpi_p) {
					add_mpi_event(1, descr, player, where, trigger, tmpchar + 1,
								  (mt ? "Listen" : "Olisten"), toparg, 1, (mt == 0),
								  Prop_Blessed(what, propname));
				}
			} else if (the_prog != NOTHING) {
				add_muf_queue_event(descr, player, where, trigger, the_prog, toparg,
									"(_Listen)", 1);
			}
		}
	}
	strcpyn(buf, sizeof(buf), propname);
	if (is_propdir(what, buf)) {
		strcatn(buf, sizeof(buf), "/");
		while ((pname = next_prop_name(what, exbuf, sizeof(exbuf), buf))) {
			*buf = '\0';
			strcatn(buf, sizeof(buf), pname);
			listenqueue(descr, player, where, trigger, what, xclude, buf,
						toparg, mlev, mt, mpi_p);
		}
	}
}
Exemple #8
0
void
propqueue(int descr, dbref player, dbref where, dbref trigger, dbref what, dbref xclude,
		  const char *propname, const char *toparg, int mlev, int mt)
{
	const char *tmpchar;
	const char *pname;
	dbref the_prog;
	char buf[BUFFER_LEN];
	char exbuf[BUFFER_LEN];

	the_prog = NOTHING;
	tmpchar = NULL;

	/* queue up program referred to by the given property */
	if (((the_prog = get_property_dbref(what, propname)) != NOTHING) ||
		(tmpchar = get_property_class(what, propname))) {

		if ((tmpchar && *tmpchar) || the_prog != NOTHING) {
			if (tmpchar) {
				if (*tmpchar == '&') {
					the_prog = AMBIGUOUS;
				} else if (*tmpchar == NUMBER_TOKEN && number(tmpchar + 1)) {
					the_prog = (dbref) atoi(++tmpchar);
				} else if (*tmpchar == REGISTERED_TOKEN) {
					the_prog = find_registered_obj(what, tmpchar);
				} else if (number(tmpchar)) {
					the_prog = (dbref) atoi(tmpchar);
				} else {
					the_prog = NOTHING;
				}
			} else {
				if (the_prog == AMBIGUOUS)
					the_prog = NOTHING;
			}
			if (the_prog != AMBIGUOUS) {
				if (the_prog < 0 || the_prog >= db_top) {
					the_prog = NOTHING;
				} else if (Typeof(the_prog) != TYPE_PROGRAM) {
					the_prog = NOTHING;
				} else if ((OWNER(the_prog) != OWNER(player)) && !(FLAGS(the_prog) & LINK_OK)) {
					the_prog = NOTHING;
				} else if (MLevel(the_prog) < mlev) {
					the_prog = NOTHING;
				} else if (MLevel(OWNER(the_prog)) < mlev) {
					the_prog = NOTHING;
				} else if (the_prog == xclude) {
					the_prog = NOTHING;
				}
			}
			if (propq_level < 8) {
				propq_level++;
				if (the_prog == AMBIGUOUS) {
					char cbuf[BUFFER_LEN];
					int ival;

					strcpyn(match_args, sizeof(match_args), "");
					strcpyn(match_cmdname, sizeof(match_cmdname), toparg);
					ival = (mt == 0) ? MPI_ISPUBLIC : MPI_ISPRIVATE;
					if (Prop_Blessed(what, propname))
						ival |= MPI_ISBLESSED;
					do_parse_mesg(descr, player, what, tmpchar + 1, "(MPIqueue)", cbuf, sizeof(cbuf), ival);
					if (*cbuf) {
						if (mt) {
							notify_filtered(player, player, cbuf, 1);
						} else {
							char bbuf[BUFFER_LEN];
							dbref plyr;

							snprintf(bbuf, sizeof(bbuf), ">> %.4000s",
									pronoun_substitute(descr, player, cbuf));
							plyr = DBFETCH(where)->contents;
							while (plyr != NOTHING) {
								if (Typeof(plyr) == TYPE_PLAYER && plyr != player)
									notify_filtered(player, plyr, bbuf, 0);
								plyr = DBFETCH(plyr)->next;
							}
						}
					}
				} else if (the_prog != NOTHING) {
					struct frame *tmpfr;

					strcpyn(match_args, sizeof(match_args), toparg ? toparg : "");
					strcpyn(match_cmdname, sizeof(match_cmdname), "Queued event.");
					tmpfr = interp(descr, player, where, the_prog, trigger,
								   BACKGROUND, STD_HARDUID, 0);
					if (tmpfr) {
						interp_loop(player, the_prog, tmpfr, 0);
					}
				}
				propq_level--;
			} else {
				notify_nolisten(player, "Propqueue stopped to prevent infinite loop.", 1);
			}
		}
	}
	strcpyn(buf, sizeof(buf), propname);
	if (is_propdir(what, buf)) {
		strcatn(buf, sizeof(buf), "/");
		while ((pname = next_prop_name(what, exbuf, sizeof(exbuf), buf))) {
			strcpyn(buf, sizeof(buf), pname);
			propqueue(descr, player, where, trigger, what, xclude, buf, toparg, mlev, mt);
		}
	}
}
Exemple #9
0
void
prim_parseprop(PRIM_PROTOTYPE)
{
	const char *temp;
	char *ptr;
	struct inst *oper1 = NULL; /* prevents re-entrancy issues! */
	struct inst *oper2 = NULL; /* prevents re-entrancy issues! */
	struct inst *oper3 = NULL; /* prevents re-entrancy issues! */
	struct inst *oper4 = NULL; /* prevents re-entrancy issues! */

	char buf[BUFFER_LEN];
	char type[BUFFER_LEN];

	CHECKOP(4);
	oper4 = POP();				/* int */
	oper2 = POP();				/* arg str */
	oper1 = POP();				/* propname str */
	oper3 = POP();				/* object dbref */
	if (mlev < 3)
		abort_interp("Mucker level 3 or greater required.");
	if (oper3->type != PROG_OBJECT)
		abort_interp("Non-object argument. (1)");
	if (!valid_object(oper3))
		abort_interp("Invalid object. (1)");
	if (oper2->type != PROG_STRING)
		abort_interp("String expected. (3)");
	if (oper1->type != PROG_STRING)
		abort_interp("String expected. (2)");
	if (!oper1->data.string)
		abort_interp("Empty string argument (2)");
	if (oper4->type != PROG_INTEGER)
		abort_interp("Integer expected. (4)");
	if (oper4->data.number < 0 || oper4->data.number > 1)
		abort_interp("Integer of 0 or 1 expected. (4)");
	CHECKREMOTE(oper3->data.objref);
	{
		int len = oper1->data.string->length;

		if (!prop_read_perms(ProgUID, oper3->data.objref, oper1->data.string->data, mlev))
			abort_interp("Permission denied.");

		if (mlev < 3 && !permissions(player, oper3->data.objref) &&
			prop_write_perms(ProgUID, oper3->data.objref, oper1->data.string->data, mlev))
			abort_interp("Permission denied.");

		strcpyn(type, sizeof(type), oper1->data.string->data);
		while (len-- > 0 && type[len] == PROPDIR_DELIMITER) {
			type[len] = '\0';
		}

		temp = get_property_class(oper3->data.objref, type);
#ifdef LOG_PROPS
		log2file("props.log", "#%d (%d) GETPROPSTR: o=%d n=\"%s\" s=\"%s\"",
				 program, pc->line, oper3->data.objref, type, temp);
#endif

	}
	ptr = (oper2->data.string) ? oper2->data.string->data : "";
	if (temp) {
		result = 0;
		if (oper4->data.number)
			result |= MPI_ISPRIVATE;
		if (Prop_Blessed(oper3->data.objref, type))
			result |= MPI_ISBLESSED;
		ptr = do_parse_mesg(fr->descr, player, oper3->data.objref, temp, ptr, buf, sizeof(buf), result);
		CLEAR(oper1);
		CLEAR(oper2);
		CLEAR(oper3);
		CLEAR(oper4);
		PushString(ptr);
	} else {
		CLEAR(oper1);
		CLEAR(oper2);
		CLEAR(oper3);
		CLEAR(oper4);
		PushNullStr;
	}
}
Exemple #10
0
void
prim_parsepropex(PRIM_PROTOTYPE)
{
	struct inst*	oper1 = NULL; /* prevents reentrancy issues! */
	struct inst*	oper2 = NULL; /* prevents reentrancy issues! */
	struct inst*	oper3 = NULL; /* prevents reentrancy issues! */
	struct inst*	oper4 = NULL; /* prevents reentrancy issues! */
	stk_array*		vars;
	const char*		mpi;
	char*			str = 0;
	array_iter		idx;
	extern int		varc; /* from msgparse.c */
	int				mvarcnt = 0;
	char*			buffers = NULL;
	int				novars;
	int				hashow = 0;
	int				i;
	int             len;
	char			tname[BUFFER_LEN];
	char			buf[BUFFER_LEN];

	CHECKOP(4);

	oper4 = POP(); /* int:Private */
	oper3 = POP(); /* dict:Vars */
	oper2 = POP(); /* str:Prop */
	oper1 = POP(); /* ref:Object */

	if (mlev < 3)
		abort_interp("Mucker level 3 or greater required.");

	if (oper1->type != PROG_OBJECT)
		abort_interp("Non-object argument. (1)");
	if (oper2->type != PROG_STRING)
		abort_interp("Non-string argument. (2)");
	if (oper3->type != PROG_ARRAY)
		abort_interp("Non-array argument. (3)");
	if (oper3->data.array && (oper3->data.array->type != ARRAY_DICTIONARY))
		abort_interp("Dictionary array expected. (3)");
	if (oper4->type != PROG_INTEGER)
		abort_interp("Non-integer argument. (4)");

	if (!valid_object(oper1))
		abort_interp("Invalid object. (1)");
	if (!oper2->data.string)
		abort_interp("Empty string argument. (2)");
	if ((oper4->data.number != 0) && (oper4->data.number != 1))
		abort_interp("Integer of 0 or 1 expected. (4)");

	CHECKREMOTE(oper1->data.objref);

	if (!prop_read_perms(ProgUID, oper1->data.objref, oper2->data.string->data, mlev))
		abort_interp("Permission denied.");

	len = oper2->data.string->length;
	strcpyn(tname, sizeof(tname), oper2->data.string->data);
	while (len-- > 0 && tname[len] == PROPDIR_DELIMITER) {
		tname[len] = '\0';
	}

	mpi		= get_property_class(oper1->data.objref, tname);
	vars	= oper3->data.array;
	novars	= array_count(vars);

	if (check_mvar_overflow(novars))
		abort_interp("Out of MPI variables. (3)");

	if (array_first(vars, &idx))
	{
		do
		{
			array_data*	val = array_getitem(vars, &idx);

			if (idx.type != PROG_STRING)
			{
				CLEAR(&idx);
				abort_interp("Only string keys supported. (3)");
			}

			if (idx.data.string == NULL)
			{
				CLEAR(&idx);
				abort_interp("Empty string keys not supported. (3)");
			}

			if (strlen(idx.data.string->data) > MAX_MFUN_NAME_LEN)
			{
				CLEAR(&idx);
				abort_interp("Key too long to be an MPI variable. (3)");
			}

			switch(val->type)
			{
				case PROG_INTEGER:
				case PROG_FLOAT:
				case PROG_OBJECT:
				case PROG_STRING:
				case PROG_LOCK:
				break;

				default:
					CLEAR(&idx);
					abort_interp("Only integer, float, dbref, string and lock values supported. (3)");
				break;
			}

			if (string_compare(idx.data.string->data, "how") == 0)
				hashow = 1;
		}
		while(array_next(vars, &idx));
	}

	if (mpi && *mpi)
	{
		if (novars > 0)
		{
			mvarcnt = varc;

			if ((buffers = (char*)malloc(novars * BUFFER_LEN)) == NULL)
				abort_interp("Out of memory.");

			if (array_first(vars, &idx))
			{
				i = 0;

				do
				{
					char*		var_buf = buffers + (i++ * BUFFER_LEN);
					array_data*	val;

					val = array_getitem(vars, &idx);

					switch(val->type)
					{
						case PROG_INTEGER:
							snprintf(var_buf, BUFFER_LEN, "%i", val->data.number);
						break;

						case PROG_FLOAT:
							snprintf(var_buf, BUFFER_LEN, "%g", val->data.fnumber);
						break;

						case PROG_OBJECT:
							snprintf(var_buf, BUFFER_LEN, "#%i", val->data.objref);
						break;

						case PROG_STRING:
							strncpy(var_buf, DoNullInd(val->data.string), BUFFER_LEN);
						break;

						case PROG_LOCK:
							strncpy(var_buf, unparse_boolexp(ProgUID, val->data.lock, 1), BUFFER_LEN);
						break;

						default:
							var_buf[0] = '\0';
						break;
					}

					var_buf[BUFFER_LEN - 1] = '\0';

					new_mvar(idx.data.string->data, var_buf);
				}
				while(array_next(vars, &idx));
			}
		}

		result = 0;

		if (oper4->data.number)
			result |= MPI_ISPRIVATE;

		if (Prop_Blessed(oper1->data.objref, oper2->data.string->data))
			result |= MPI_ISBLESSED;

		if (hashow)
			result |= MPI_NOHOW;

		str = do_parse_mesg(fr->descr, player, oper1->data.objref, mpi, "(parsepropex)", buf, sizeof(buf), result);

		if (novars > 0)
		{
			if (array_first(vars, &idx))
			{
				i = 0;

				do
				{
					char*		var_buf = buffers + (i++ * BUFFER_LEN);
					struct inst	temp;

					temp.type			= PROG_STRING;
					temp.data.string	= alloc_prog_string(var_buf);

					array_setitem(&vars, &idx, &temp);

					CLEAR(&temp);
				}
				while(array_next(vars, &idx));
			}

			free(buffers);

			varc = mvarcnt;
		}
	}

	oper3->data.array = NULL;

	CLEAR(oper1);
	CLEAR(oper2);
	CLEAR(oper3);
	CLEAR(oper4);

	PushArrayRaw(vars);
	PushString(str);
}