示例#1
0
文件: data.c 项目: Miraculix/dgd
/*
 * NAME:	del_lhs()
 * DESCRIPTION:	delete the left-hand side in an assignment
 */
static void del_lhs(dataspace *data, value *lhs)
{
    string *str;
    array *arr;

    switch (lhs->type) {
    case T_STRING:
	str = lhs->u.string;
	if (str->primary != (strref *) NULL && str->primary->data == data) {
	    /* in this object */
	    if (--(str->primary->ref) == 0) {
		str->primary->str = (string *) NULL;
		str->primary = (strref *) NULL;
		str_del(str);
		data->plane->schange++;	/* last reference removed */
	    }
	    data->plane->flags |= MOD_STRINGREF;
	} else {
	    /* not in this object: deref imported string */
	    data->plane->schange--;
	}
	break;

    case T_ARRAY:
    case T_MAPPING:
    case T_LWOBJECT:
	arr = lhs->u.array;
	if (arr->primary->data == data) {
	    /* in this object */
	    if (arr->primary->arr != (array *) NULL) {
		/* swapped in */
		data->plane->flags |= MOD_ARRAYREF;
		if ((--(arr->primary->ref) & ~ARR_MOD) == 0) {
		    d_get_elts(arr);
		    arr->primary->arr = (array *) NULL;
		    arr->primary = &arr->primary->plane->alocal;
		    arr_del(arr);
		    data->plane->achange++;
		}
	    } else {
		/* deref new array */
		data->plane->achange--;
	    }
	} else {
	    /* not in this object: deref imported array */
	    data->plane->imports--;
	    data->plane->achange--;
	}
	break;
    }
}
示例#2
0
/*
 * NAME:	path->include()
 * DESCRIPTION:	resolve an include path
 */
char *path_include(char *buf, char *from, char *file, string ***strs, int *nstr)
{
    frame *f;
    int i;
    value *v;
    string **str;

    *strs = NULL;
    *nstr = 0;
    if (c_autodriver()) {
	return path_from(buf, from, file);
    }

    f = cframe;
    PUSH_STRVAL(f, str_new(from, strlen(from)));
    PUSH_STRVAL(f, str_new(file, (long) strlen(file)));
    if (!call_driver_object(f, "include_file", 2)) {
	f->sp++;
	return path_from(buf, from, file);
    }

    if (f->sp->type == T_STRING) {
	/* simple path */
	path_resolve(buf, f->sp->u.string->text);
	str_del((f->sp++)->u.string);
	return buf;
    } else if (f->sp->type == T_ARRAY) {
	/*
	 * Array of strings.  Check that the array does indeed contain only
	 * strings, then return it.
	 */
	i = f->sp->u.array->size;
	if (i != 0) {   
	    v = d_get_elts(f->sp->u.array);
	    while ((v++)->type == T_STRING) {
		if (--i == 0) {
		    *nstr = i = f->sp->u.array->size;
		    str = ALLOC(string*, i);
		    do {
			str_ref(*str++ = (--v)->u.string);
		    } while (--i != 0);
		    *strs = str;
		    arr_del((f->sp++)->u.array);
 
		    /* return the untranslated path, as well */
		    return path_from(buf, from, file);
		}
	    }
示例#3
0
文件: data.c 项目: Miraculix/dgd
/*
 * NAME:	data->list_callouts()
 * DESCRIPTION:	list all call_outs in an object
 */
array *d_list_callouts(dataspace *host, dataspace *data)
{
    uindex n, count, size;
    dcallout *co;
    value *v, *v2, *elts;
    array *list, *a;
    uindex max_args;
    xfloat flt;

    if (data->ncallouts == 0) {
	return arr_new(host, 0L);
    }
    if (data->callouts == (dcallout *) NULL) {
	d_get_callouts(data);
    }

    /* get the number of callouts in this object */
    count = data->ncallouts;
    for (n = data->fcallouts; n != 0; n = data->callouts[n - 1].co_next) {
	--count;
    }
    if (count > conf_array_size()) {
	return (array *) NULL;
    }

    list = arr_new(host, (long) count);
    elts = list->elts;
    max_args = conf_array_size() - 3;

    for (co = data->callouts; count > 0; co++) {
	if (co->val[0].type == T_STRING) {
	    size = co->nargs;
	    if (size > max_args) {
		/* unlikely, but possible */
		size = max_args;
	    }
	    a = arr_new(host, size + 3L);
	    v = a->elts;

	    /* handle */
	    PUT_INTVAL(v, co - data->callouts + 1);
	    v++;
	    /* function */
	    PUT_STRVAL(v, co->val[0].u.string);
	    v++;
	    /* time */
	    if (co->mtime == 0xffff) {
		PUT_INTVAL(v, co->time);
	    } else {
		flt.low = co->time;
		flt.high = co->mtime;
		PUT_FLTVAL(v, flt);
	    }
	    v++;

	    /* copy arguments */
	    switch (size) {
	    case 3:
		*v++ = co->val[3];
	    case 2:
		*v++ = co->val[2];
	    case 1:
		*v++ = co->val[1];
	    case 0:
		break;

	    default:
		n = size - 2;
		for (v2 = d_get_elts(co->val[3].u.array) + n; n > 0; --n) {
		    *v++ = *--v2;
		}
		*v++ = co->val[2];
		*v++ = co->val[1];
		break;
	    }
	    while (size > 0) {
		i_ref_value(--v);
		--size;
	    }
	    d_ref_imports(a);

	    /* put in list */
	    PUT_ARRVAL(elts, a);
	    elts++;
	    --count;
	}
    }
    co_list(list);

    return list;
}
示例#4
0
文件: data.c 项目: Miraculix/dgd
/*
 * NAME:	data->get_call_out()
 * DESCRIPTION:	get a callout
 */
string *d_get_call_out(dataspace *data, unsigned int handle, frame *f, 
	int *nargs)
{
    string *str;
    dcallout *co;
    value *v, *o;
    uindex n;

    if (data->callouts == (dcallout *) NULL) {
	d_get_callouts(data);
    }

    co = &data->callouts[handle - 1];
    v = co->val;
    del_lhs(data, &v[0]);
    str = v[0].u.string;

    i_grow_stack(f, (*nargs = co->nargs) + 1);
    *--f->sp = v[0];

    switch (co->nargs) {
    case 3:
	del_lhs(data, &v[3]);
	*--f->sp = v[3];
    case 2:
	del_lhs(data, &v[2]);
	*--f->sp = v[2];
    case 1:
	del_lhs(data, &v[1]);
	*--f->sp = v[1];
    case 0:
	break;

    default:
	n = co->nargs - 2;
	f->sp -= n;
	memcpy(f->sp, d_get_elts(v[3].u.array), n * sizeof(value));
	del_lhs(data, &v[3]);
	FREE(v[3].u.array->elts);
	v[3].u.array->elts = (value *) NULL;
	arr_del(v[3].u.array);
	del_lhs(data, &v[2]);
	*--f->sp = v[2];
	del_lhs(data, &v[1]);
	*--f->sp = v[1];
	break;
    }

    /* wipe out destructed objects */
    for (n = co->nargs, v = f->sp; n > 0; --n, v++) {
	switch (v->type) {
	case T_OBJECT:
	    if (DESTRUCTED(v)) {
		*v = nil_value;
	    }
	    break;

	case T_LWOBJECT:
	    o = d_get_elts(v->u.array);
	    if (o->type == T_OBJECT && DESTRUCTED(o)) {
		arr_del(v->u.array);
		*v = nil_value;
	    }
	    break;
	}
    }

    co->val[0] = nil_value;
    n = data->fcallouts;
    if (n != 0) {
	data->callouts[n - 1].co_prev = handle;
    }
    co->co_next = n;
    data->fcallouts = handle;

    data->plane->flags |= MOD_CALLOUT;
    return str;
}