Example #1
0
int
array_setrange(stk_array **harr, array_iter *start, stk_array *inarr)
{
    stk_array *arr;
    array_iter idx;

    if (!harr || !*harr) {
        return -1;
    }
    arr = *harr;
    if (!inarr || !inarr->items) {
        return arr->items;
    }
    switch (arr->type) {
        case ARRAY_PACKED:{
            if (!start) {
                return -1;
            }
            if (start->type != PROG_INTEGER) {
                return -1;
            }
            if (start->data.number < 0 || start->data.number > arr->items) {
                return -1;
            }
            if (arr->links > 1 && !arr->pinned) {
                arr->links--;
                arr = *harr = array_decouple(arr);
            }
            if (array_first(inarr, &idx)) {
                do {
                    array_setitem(&arr, start, array_getitem(inarr, &idx));
                    start->data.number++;
                } while (array_next(inarr, &idx));
            }
            return arr->items;
            break;
        }

        case ARRAY_DICTIONARY:{
            if (arr->links > 1 && !arr->pinned) {
                arr->links--;
                arr = *harr = array_decouple(arr);
            }
            if (array_first(inarr, &idx)) {
                do {
                    array_setitem(&arr, &idx, array_getitem(inarr, &idx));
                } while (array_next(inarr, &idx));
            }
            return arr->items;
            break;
        }

        default:
            break;
    }
    return -1;
}
Example #2
0
stk_array *
array_promote(stk_array *arr)
{
    stk_array *new2;
    int i;
    array_iter idx;

    if (!arr) {
        return NULL;
    }
    if (arr->type != ARRAY_PACKED) {
        return NULL;
    }

    new2 = new_array_dictionary();

    idx.type = PROG_INTEGER;
    for (i = 0; i < arr->items; i++) {
        idx.data.number = i;
        array_setitem(&new2, &idx, array_getitem(arr, &idx));
    }
    array_free(arr);

    return new2;
}
Example #3
0
/*\
|*| array_mash
|*| Takes the lists of values from the first array and
|*| uses each value as a key in the second array.  For
|*| each key, the passed "change_by" value is applied to
|*| any existing value.  If the value does not exist, it
|*| is set.
|*| This will be the core of the different/union/intersection
|*| code.
|*| Of course, this is going to absolutely blow chunks when
|*| passed an array with value types that can't be used as
|*| key values in an array.  Blast.  That may be infeasible
|*| regardless, though.
\*/
void
array_mash(stk_array *arr_in, stk_array **mash, int value)
{

    int still_values = 0;
    array_iter current_key;
    array_iter *current_keyval;
    array_iter *current_value;
    array_data temp_value;

    if (NULL == arr_in || NULL == mash || NULL == *mash)
        return;

    still_values = array_first(arr_in, &current_key);
    while (still_values) {
        current_keyval = array_getitem(arr_in, &current_key);
        current_value = array_getitem(*mash, current_keyval);
        if (NULL != current_value) {
            if (PROG_INTEGER == current_value->type) {
                copyinst(current_value, &temp_value);
                temp_value.data.number += value;
                array_setitem(mash, current_keyval, &temp_value);
            }
        } else {
            temp_value.type = PROG_INTEGER;
            temp_value.data.number = value;
            array_insertitem(mash, current_keyval, &temp_value);
        }
        still_values = array_next(arr_in, &current_key);
    }
}
Example #4
0
stk_array *
get_pids(dbref ref)
{
	struct inst temp1, temp2;
	stk_array  *nw;
	int count = 0;

	timequeue ptr = tqhead;
	nw = new_array_packed(0);
	while (ptr) {
		if (((ptr->typ != TQ_MPI_TYP) ? (ptr->called_prog == ref) : (ptr->trig == ref)) ||
			(ptr->uid == ref) || (ref < 0) ) {
			temp2.type = PROG_INTEGER;
			temp2.data.number = ptr->eventnum;
			temp1.type = PROG_INTEGER;
			temp1.data.number = count++;
			array_setitem(&nw, &temp1, &temp2);
			CLEAR(&temp1);
			CLEAR(&temp2);
		}
		ptr = ptr->next;
	}
	nw = get_mufevent_pids(nw, ref);
	return nw;
}
Example #5
0
int
array_appenditem(stk_array **harr, array_data *item)
{
    struct inst key;

    if (!harr || !*harr)
        return -1;
    if ((*harr)->type != ARRAY_PACKED)
        return -1;
    key.type = PROG_INTEGER;
    key.data.number = array_count(*harr);

    return array_setitem(harr, &key, item);
}
Example #6
0
int
array_set_strkey(stk_array **harr, const char *key, struct inst *val)
{
    struct inst name;
    int result;

    name.type = PROG_STRING;
    name.data.string = alloc_prog_string(key);

    result = array_setitem(harr, &name, val);

    CLEAR(&name);

    return result;
}
Example #7
0
int
array_set_intkey(stk_array **harr, int key, struct inst *val)
{
    struct inst name;
    int result;

    name.type = PROG_INTEGER;
    name.data.number = key;

    result = array_setitem(harr, &name, val);

    CLEAR(&name);

    return result;

}
Example #8
0
stk_array *
array_decouple(stk_array *arr)
{
    stk_array *new2;

    if (!arr) {
        return NULL;
    }

    new2 = new_array();
    new2->pinned = arr->pinned;
    new2->type = arr->type;
    switch (arr->type) {
        case ARRAY_PACKED:{
            int i;

            new2->items = arr->items;
            new2->data.packed =
                (array_data *) malloc(sizeof(array_data) * arr->items);
            for (i = arr->items; i-- > 0;) {
                copyinst(&arr->data.packed[i], &new2->data.packed[i]);
            }
            return new2;
            break;
        }

        case ARRAY_DICTIONARY:{
            array_iter idx;
            array_data *val;

            if (array_first(arr, &idx)) {
                do {
                    val = array_getitem(arr, &idx);
                    array_setitem(&new2, &idx, val);
                } while (array_next(arr, &idx));
            }
            return new2;
            break;
        }

        default:
            break;
    }
    return NULL;
}
Example #9
0
void
prim_array_regmatchval(PRIM_PROTOTYPE)
{
    struct inst *in;
    stk_array *arr;
    stk_array *nw;
    muf_re* re;
    char* text;
    int flags;
    int matchcnt = 0;
    const char* errstr = NULL;

    CHECKOP(3);
    oper3 = POP();              /* int  pcreflags */
    oper2 = POP();              /* str  pattern */
    oper1 = POP();              /* arr  Array */
    if (oper1->type != PROG_ARRAY)
        abort_interp("Argument not an array. (1)");
    if (oper2->type != PROG_STRING)
        abort_interp("Argument not a string pattern. (2)");
    if (oper3->type != PROG_INTEGER)
        abort_interp("Non-integer argument (3)");

    flags = PCRE_NO_AUTO_CAPTURE;

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

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

    nw = new_array_dictionary();
    arr = oper1->data.array;

    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);
    }

    if (array_first(arr, &temp1)) {
        do {
            in = array_getitem(arr, &temp1);
            if (in->type == PROG_STRING) {
                text    = (char *)DoNullInd(in->data.string);
                if ((matchcnt = regmatch_exec(re, text)) < 0) {
                    if (matchcnt != PCRE_ERROR_NOMATCH)
                        abort_interp(muf_re_error(matchcnt));
                } else {
                    array_setitem(&nw, &temp1, in);
                }
            } else if (in->type == PROG_OBJECT) {
                text    = (char *) NAME(in->data.objref);
                if ((matchcnt = regmatch_exec(re, text)) < 0) {
                    if (matchcnt != PCRE_ERROR_NOMATCH)
                        abort_interp(muf_re_error(matchcnt));
                } else {
                    array_setitem(&nw, &temp1, in);
                }
            }
        } while (array_next(arr, &temp1));
    }


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

    PushArrayRaw(nw);
}
Example #10
0
void
prim_array_regsub(PRIM_PROTOTYPE)
{
    struct inst *in;
    stk_array *arr;
    stk_array *nw;
    int         matches[MATCH_ARR_SIZE];
    int         flags       = 0;
    char*       write_ptr   = buf;
    int         write_left  = BUFFER_LEN - 1;
    muf_re*     re;
    char*       text;
    char*       textstart;
    const char* errstr;
    int         matchcnt, len;

    CHECKOP(4);

    oper4 = POP(); /* int:Flags */
    oper3 = POP(); /* str:Replace */
    oper2 = POP(); /* str:Pattern */
    oper1 = POP(); /* str:Text */

    if (oper1->type != PROG_ARRAY)
        abort_interp("Argument not an array of strings. (1)");
    if (!array_is_homogenous(oper1->data.array, PROG_STRING))
        abort_interp("Argument not an array of strings. (1)");
    if (oper2->type != PROG_STRING)
        abort_interp("Non-string argument (2)");
    if (oper3->type != PROG_STRING)
        abort_interp("Non-string argument (3)");
    if (oper4->type != PROG_INTEGER)
        abort_interp("Non-integer argument (4)");
    if (!oper2->data.string)
        abort_interp("Empty string argument (2)");

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

    if ((re = muf_re_get(oper2->data.string, flags, &errstr)) == NULL)
        abort_interp(errstr);



    nw = new_array_dictionary();
    arr = oper1->data.array;

    if (!re->extra
        && ((oper4->data.number & MUF_RE_ALL ) || array_count(arr) > 2)) {
        /* Study the pattern if the user requested recursive substitution, or
         * if the input array contains at least three items. */
        re->extra = pcre_study(re->re, 0, &errstr);
        if (errstr)
            abort_interp(errstr);
    }

    if (array_first(arr, &temp1)) {
        do {
            write_ptr = buf;
            write_left = BUFFER_LEN - 1;

            in = array_getitem(arr, &temp1);
            textstart = text = (char *)DoNullInd(in->data.string);
            len = strlen(textstart);

            while((*text != '\0') && (write_left > 0))
            {
                if ((matchcnt = pcre_exec(re->re, re->extra, textstart, len,
                                          text-textstart, 0, matches,
                                          MATCH_ARR_SIZE)) < 0)
                {
                    if (matchcnt != PCRE_ERROR_NOMATCH)
                    {
                        abort_interp(muf_re_error(matchcnt));
                    }

                    while((write_left > 0) && (*text != '\0'))
                    {
                        *write_ptr++ = *text++;
                        write_left--;
                    }

                    break;
                }
                else
                {
                    int         allstart    = matches[0];
                    int         allend      = matches[1];
                    int         substart    = -1;
                    int         subend      = -1;
                    char*       read_ptr    = (char *)DoNullInd(oper3->data.string);
                    int         count;

                    for(count = allstart-(text-textstart);
                                (write_left > 0) && (*text != '\0') && (count > 0);
                                count--)
                    {
                        *write_ptr++ = *text++;
                        write_left--;
                    }

                    while((write_left > 0) && (*read_ptr != '\0'))
                    {
                        if (*read_ptr == '\\')
                        {
                            if (!isdigit(*(++read_ptr)))
                            {
                                *write_ptr++ = *read_ptr++;
                                write_left--;
                            }
                            else
                            {
                                int idx = (*read_ptr++) - '0';

                                if ((idx < 0) || (idx >= matchcnt))
                                {
                                    abort_interp("Invalid \\subexp in substitution string. (3)");
                                }

                                substart = matches[idx*2];
                                subend = matches[idx*2+1];

                                if ((substart >= 0) && (subend >= 0) && (substart < len))
                                {
                                    char* ptr = &textstart[substart];

                                    count = subend - substart;

                                    if (count > write_left)
                                    {
                                        abort_interp("Operation would result in overflow");
                                    }

                                    for(; (write_left > 0) && (count > 0) && (*ptr != '\0'); count--)
                                    {
                                        *write_ptr++ = *ptr++;
                                        write_left--;
                                    }
                                }
                            }
                        }
                        else
                        {
                            *write_ptr++ = *read_ptr++;
                            write_left--;
                        }
                    }

                    for(count = allend - allstart; (*text != '\0') && (count > 0); count--)
                        text++;

                    if (allstart == allend && *text) {
                        *write_ptr++ = *text++;
                        write_left--;
                    }
                }

                if ((oper4->data.number & MUF_RE_ALL) == 0)
                {
                    while((write_left > 0) && (*text != '\0'))
                    {
                        *write_ptr++ = *text++;
                        write_left--;
                    }

                    break;
                }
            }

            if (*text != '\0')
                abort_interp("Operation would result in overflow");

            *write_ptr = '\0';

            temp2.type = PROG_STRING;
            temp2.data.string = alloc_prog_string(buf);

            array_setitem(&nw, &temp1, &temp2);
            CLEAR(&temp2);
        } while (array_next(arr, &temp1));
    }

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

    PushArrayRaw(nw);
}
Example #11
0
void
prim_regexp(PRIM_PROTOTYPE)
{
    stk_array*  nu_val  = 0;
    stk_array*  nu_idx  = 0;
    int         matches[MATCH_ARR_SIZE];
    muf_re*     re;
    char*       text;
    int         flags   = 0;
    int         len, i;
    int         matchcnt = 0;
    const char* errstr;

    CHECKOP(3);

    oper3 = POP(); /* int:Flags */
    oper2 = POP(); /* str:Pattern */
    oper1 = POP(); /* str:Text */

    if (oper1->type != PROG_STRING)
        abort_interp("Non-string argument (1)");
    if (oper2->type != PROG_STRING)
        abort_interp("Non-string argument (2)");
    if (oper3->type != PROG_INTEGER)
        abort_interp("Non-integer argument (3)");
    if (!oper2->data.string)
        abort_interp("Empty string argument (2)");

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

    if ((re = muf_re_get(oper2->data.string, flags, &errstr)) == NULL)
        abort_interp(errstr);

    text    = (char *)DoNullInd(oper1->data.string);
    len     = strlen(text);

    if ((matchcnt = pcre_exec(re->re, re->extra, text, len, 0, 0, matches, MATCH_ARR_SIZE)) < 0)
    {
        if (matchcnt != PCRE_ERROR_NOMATCH)
        {
            abort_interp(muf_re_error(matchcnt));
        }

        if (((nu_val = new_array_packed(0)) == NULL) ||
            ((nu_idx = new_array_packed(0)) == NULL))
        {
            if (nu_val != NULL)
                array_free(nu_val);

            if (nu_idx != NULL)
                array_free(nu_idx);

            abort_interp("Out of memory");
        }
    }
    else
    {
        if (((nu_val = new_array_packed(matchcnt)) == NULL) ||
            ((nu_idx = new_array_packed(matchcnt)) == NULL))
        {
            if (nu_val != NULL)
                array_free(nu_val);

            if (nu_idx != NULL)
                array_free(nu_idx);

            abort_interp("Out of memory");
        }

        for(i = 0; i < matchcnt; i++)
        {
            int substart = matches[i*2];
            int subend = matches[i*2+1];
            struct inst idx, val;
            stk_array*  nu;

            if ((substart >= 0) && (subend >= 0) && (substart < len))
                snprintf(buf, BUFFER_LEN, "%.*s", (int)(subend - substart), &text[substart]);
            else
                buf[0] = '\0';

            idx.type        = PROG_INTEGER;
            idx.data.number = i;
            val.type        = PROG_STRING;
            val.data.string = alloc_prog_string(buf);

            array_setitem(&nu_val, &idx, &val);

            CLEAR(&idx);
            CLEAR(&val);

            if ((nu = new_array_packed(2)) == NULL)
            {
                array_free(nu_val);
                array_free(nu_idx);

                abort_interp("Out of memory");
            }

            idx.type        = PROG_INTEGER;
            idx.data.number = 0;
            val.type        = PROG_INTEGER;
            val.data.number = substart + 1;

            array_setitem(&nu, &idx, &val);

            CLEAR(&idx);
            CLEAR(&val);

            idx.type        = PROG_INTEGER;
            idx.data.number = 1;
            val.type        = PROG_INTEGER;
            val.data.number = subend - substart;

            array_setitem(&nu, &idx, &val);

            CLEAR(&idx);
            CLEAR(&val);

            idx.type        = PROG_INTEGER;
            idx.data.number = i;
            val.type        = PROG_ARRAY;
            val.data.array  = nu;

            array_setitem(&nu_idx, &idx, &val);

            CLEAR(&idx);
            CLEAR(&val);
        }
    }

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

    PushArrayRaw(nu_val);
    PushArrayRaw(nu_idx);
}
Example #12
0
int
array_insertrange(stk_array **harr, array_iter *start, stk_array *inarr)
{
    stk_array *arr;
    array_data *itm;
    array_iter idx;
    array_iter didx;

    if (!harr || !*harr) {
        return -1;
    }
    arr = *harr;
    if (!inarr || !inarr->items) {
        return arr->items;
    }
    switch (arr->type) {
        case ARRAY_PACKED:{
            if (!start) {
                return -1;
            }
            if (start->type != PROG_INTEGER) {
                return -1;
            }
            if (start->data.number < 0 || start->data.number > arr->items) {
                return -1;
            }
            if (arr->links > 1 && !arr->pinned) {
                arr->links--;
                arr = *harr = array_decouple(arr);
            }
            arr->data.packed = (array_data *)
                realloc(arr->data.packed,
                        sizeof(array_data) * (arr->items + inarr->items));
            copyinst(start, &idx);
            copyinst(start, &didx);
            idx.data.number = arr->items - 1;
            didx.data.number = arr->items + inarr->items - 1;
            while (idx.data.number >= start->data.number) {
                itm = array_getitem(arr, &idx);
                copyinst(itm, &arr->data.packed[didx.data.number]);
                CLEAR(itm);
                idx.data.number--;
                didx.data.number--;
            }
            if (array_first(inarr, &idx)) {
                do {
                    itm = array_getitem(inarr, &idx);
                    copyinst(itm, &arr->data.packed[start->data.number]);
                    start->data.number++;
                } while (array_next(inarr, &idx));
            }
            arr->items += inarr->items;
            return arr->items;
            break;
        }

        case ARRAY_DICTIONARY:{
            if (arr->links > 1 && !arr->pinned) {
                arr->links--;
                arr = *harr = array_decouple(arr);
            }
            if (array_first(inarr, &idx)) {
                do {
                    array_setitem(&arr, &idx, array_getitem(inarr, &idx));
                } while (array_next(inarr, &idx));
            }
            return arr->items;
            break;
        }

        default:
            break;
    }
    return -1;
}
Example #13
0
stk_array *
array_getrange(stk_array *arr, array_iter *start, array_iter *end)
{
    stk_array *new2;
    array_data *tmp;
    int sidx, eidx;

    if (!arr) {
        return NULL;
    }
    switch (arr->type) {
        case ARRAY_PACKED:{
            array_iter idx;
            array_iter didx;

            if (start->type != PROG_INTEGER) {
                return NULL;
            }
            if (end->type != PROG_INTEGER) {
                return NULL;
            }
            sidx = start->data.number;
            eidx = end->data.number;
            if (sidx < 0) {
                sidx = 0;
            } else if (sidx > arr->items) {
                return NULL;
            }
            if (eidx >= arr->items) {
                eidx = arr->items - 1;
            } else if (eidx < 0) {
                return NULL;
            }
            if (sidx > eidx) {
                return NULL;
            }
            idx.type = PROG_INTEGER;
            idx.data.number = sidx;
            didx.type = PROG_INTEGER;
            didx.data.number = 0;
            new2 = new_array_packed(eidx - sidx + 1);
            while (idx.data.number <= eidx) {
                tmp = array_getitem(arr, &idx);
                if (!tmp)
                    break;
                array_setitem(&new2, &didx, tmp);
                didx.data.number++;
                idx.data.number++;
            }
            return new2;
            break;
        }

        case ARRAY_DICTIONARY:{
            stk_array *new2;
            array_tree *s;
            array_tree *e;

            new2 = new_array_dictionary();
            s = array_tree_find(arr->data.dict, start);
            if (!s) {
                s = array_tree_next_node(arr->data.dict, start);
                if (!s) {
                    return new2;
                }
            }
            e = array_tree_find(arr->data.dict, end);
            if (!e) {
                e = array_tree_prev_node(arr->data.dict, end);
                if (!e) {
                    return new2;
                }
            }
            if (array_tree_compare(&s->key, &e->key, 0, 0, 0) > 0) {
                return new2;
            }
            while (s) {
                array_setitem(&new2, &s->key, &s->data);
                if (s == e)
                    break;
                s = array_tree_next_node(arr->data.dict, &s->key);
            }
            return new2;
            break;
        }

        default:
            break;
    }
    return NULL;
}
Example #14
0
stk_array *
get_pidinfo(int pid)
{
	struct inst temp1, temp2;
	stk_array  *nw;
	time_t      rtime = time(NULL);
	time_t      etime = 0;
	double      pcnt  = 0.0;

	timequeue ptr = tqhead;
	nw = new_array_dictionary();
	while (ptr) {
		if (ptr->eventnum == pid) {
			if (ptr->typ != TQ_MUF_TYP || ptr->subtyp != TQ_MUF_TIMER) {
				break;
			}
		}
		ptr = ptr->next;
	}
	if (ptr && (ptr->eventnum == pid) &&
			(ptr->typ != TQ_MUF_TYP || ptr->subtyp != TQ_MUF_TIMER)) {
		if (ptr->fr) {
			etime = rtime - ptr->fr->started;
			if (etime > 0) {
				pcnt = ptr->fr->totaltime.tv_sec;
				pcnt += ptr->fr->totaltime.tv_usec / 1000000;
				pcnt = pcnt * 100 / etime;
				if (pcnt > 100.0) {
					pcnt = 100.0;
				}
			} else {
				pcnt = 0.0;
			}
		}
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("PID");
		temp2.type = PROG_INTEGER;
		temp2.data.number = ptr->eventnum;
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("CALLED_PROG");
		temp2.type = PROG_OBJECT;
		temp2.data.objref = ptr->called_prog;
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("TRIG");
		temp2.type = PROG_OBJECT;
		temp2.data.objref = ptr->trig;
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("PLAYER");
		temp2.type = PROG_OBJECT;
		temp2.data.objref = ptr->uid;
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("CALLED_DATA");
		temp2.type = PROG_STRING;
		temp2.data.string = alloc_prog_string(ptr->called_data);
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("INSTCNT");
		temp2.type = PROG_INTEGER;
		temp2.data.number = ptr->fr ? ptr->fr->instcnt : 0;
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("DESCR");
		temp2.type = PROG_INTEGER;
		temp2.data.number = ptr->descr;
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("CPU");
		temp2.type = PROG_FLOAT;
		temp2.data.fnumber = pcnt;
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("NEXTRUN");
		temp2.type = PROG_INTEGER;
		temp2.data.number = (int) ptr->when;
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("STARTED");
		temp2.type = PROG_INTEGER;
		temp2.data.number = (int) (ptr->fr ? ptr->fr->started : 0);
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("TYPE");
		temp2.type = PROG_STRING;
		temp2.data.string = 	(ptr->typ == TQ_MUF_TYP) ? alloc_prog_string("MUF") :
						(ptr->typ == TQ_MPI_TYP) ? alloc_prog_string("MPI") : alloc_prog_string("UNK") ;
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
		temp1.type = PROG_STRING;
		temp1.data.string = alloc_prog_string("SUBTYPE");
		temp2.type = PROG_STRING;
		if (ptr->typ == TQ_MUF_TYP) {
			temp2.data.string = (ptr->subtyp == TQ_MUF_READ) ? alloc_prog_string("READ") :
							(ptr->subtyp == TQ_MUF_TREAD) ? alloc_prog_string("TREAD") :
							(ptr->subtyp == TQ_MUF_QUEUE) ? alloc_prog_string("QUEUE") :
							(ptr->subtyp == TQ_MUF_LISTEN) ? alloc_prog_string("LISTEN") :
							(ptr->subtyp == TQ_MUF_TIMER) ? alloc_prog_string("TIMER") :
							(ptr->subtyp == TQ_MUF_DELAY) ? alloc_prog_string("DELAY") :
							alloc_prog_string("");
		} else if (ptr->typ == TQ_MPI_TYP) {
			int subtyp = (ptr->subtyp & TQ_MPI_SUBMASK);
			temp2.data.string = (subtyp == TQ_MPI_QUEUE) ? alloc_prog_string("QUEUE") :
							(subtyp == TQ_MPI_DELAY) ? alloc_prog_string("DELAY") :
							alloc_prog_string("");
		} else {
			temp2.data.string = alloc_prog_string("");
		}
		array_setitem(&nw, &temp1, &temp2);
		CLEAR(&temp1);
		CLEAR(&temp2);
	} else {
		nw = get_mufevent_pidinfo(nw, pid);
	}
	return nw;
}
Example #15
0
void
prim_regexp(PRIM_PROTOTYPE)
{
    stk_array *nu_val = 0;
    stk_array *nu_idx = 0;
    regmatch_t *matches = 0;
    muf_re *re;
    char *text;
    int flags = 0;
    int nosubs, err, len, i;

    CHECKOP(3);

    oper3 = POP();              /* int:Flags */
    oper2 = POP();              /* str:Pattern */
    oper1 = POP();              /* str:Text */

    if (oper1->type != PROG_STRING)
        abort_interp("Non-string argument (1)");
    if (oper2->type != PROG_STRING)
        abort_interp("Non-string argument (2)");
    if (oper3->type != PROG_INTEGER)
        abort_interp("Non-integer argument (3)");
    if (!oper2->data.string)
        abort_interp("Empty string argument (2)");

    if (oper3->data.number & MUF_RE_ICASE)
        flags |= REG_ICASE;

    if ((re = muf_re_get(oper2->data.string, flags, &err)) == NULL)
        abort_interp(muf_re_error(err));

    text = DoNullInd(oper1->data.string);
    len = strlen(text);
    nosubs = re->re.re_nsub + 1;

    if ((matches = (regmatch_t *) malloc(sizeof(regmatch_t) * nosubs)) == NULL)
        abort_interp("Out of memory");

    if ((err = regexec(&re->re, text, nosubs, matches, 0)) != 0) {
        if (err != REG_NOMATCH) {
            free(matches);
            abort_interp(muf_re_error(err));
        }

        if (((nu_val = new_array_packed(0)) == NULL) ||
            ((nu_idx = new_array_packed(0)) == NULL)) {
            free(matches);

            if (nu_val != NULL)
                array_free(nu_val);

            if (nu_idx != NULL)
                array_free(nu_idx);

            abort_interp("Out of memory");
        }
    } else {
        if (((nu_val = new_array_packed(nosubs)) == NULL) ||
            ((nu_idx = new_array_packed(nosubs)) == NULL)) {
            free(matches);

            if (nu_val != NULL)
                array_free(nu_val);

            if (nu_idx != NULL)
                array_free(nu_idx);

            abort_interp("Out of memory");
        }

        for (i = 0; i < nosubs; i++) {
            regmatch_t *cm = &matches[i];
            struct inst idx, val;
            stk_array *nu;

            if ((cm->rm_so >= 0) && (cm->rm_eo >= 0) && (cm->rm_so < len))
                snprintf(buf, BUFFER_LEN, "%.*s", cm->rm_eo - cm->rm_so,
                         &text[cm->rm_so]);
            else
                buf[0] = '\0';

            idx.type = PROG_INTEGER;
            idx.data.number = i;
            val.type = PROG_STRING;
            val.data.string = alloc_prog_string(buf);

            array_setitem(&nu_val, &idx, &val);

            CLEAR(&idx);
            CLEAR(&val);

            if ((nu = new_array_packed(2)) == NULL) {
                free(matches);

                array_free(nu_val);
                array_free(nu_idx);

                abort_interp("Out of memory");
            }

            idx.type = PROG_INTEGER;
            idx.data.number = 0;
            val.type = PROG_INTEGER;
            val.data.number = cm->rm_so + 1;

            array_setitem(&nu, &idx, &val);

            CLEAR(&idx);
            CLEAR(&val);

            idx.type = PROG_INTEGER;
            idx.data.number = 1;
            val.type = PROG_INTEGER;
            val.data.number = cm->rm_eo - cm->rm_so;

            array_setitem(&nu, &idx, &val);

            CLEAR(&idx);
            CLEAR(&val);

            idx.type = PROG_INTEGER;
            idx.data.number = i;
            val.type = PROG_ARRAY;
            val.data.array = nu;

            array_setitem(&nu_idx, &idx, &val);

            CLEAR(&idx);
            CLEAR(&val);
        }
    }

    free(matches);

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

    PushArrayRaw(nu_val);
    PushArrayRaw(nu_idx);
}
Example #16
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);
}