Beispiel #1
0
/*-------------------------------------------------------------------------*/
static vector_t *
intersect_ordered_arr (vector_t *a1, vector_t *a2)

/* Compute the intersection of the two ordered arrays <a1> and <a2>.
 *
 * The result is a new sorted(!) vector with all elements, which are present
 * in both input vectors.
 * This function is called by f_intersect_alists().
 */

{
    vector_t *a3;
    mp_int d, l, i1, i2, a1s, a2s;

    a1s = (mp_int)VEC_SIZE(a1);
    a2s = (mp_int)VEC_SIZE(a2);
    a3 = allocate_array( a1s < a2s ? a1s : a2s);
    for (i1=i2=l=0; i1 < a1s && i2 < a2s; ) {
        d = svalue_cmp(&a1->item[i1], &a2->item[i2]);
        if (d<0)
            i1++;
        else if (d>0)
            i2++;
        else {
            assign_svalue_no_free(&a3->item[l++], &a2->item[(i1++,i2++)] );
        }
    }
    return shrink_array(a3, l);
} /* intersect_ordered_arr() */
int
mgt_commit(islpci_private *priv)
{
	int rvalue;
	enum oid_num_t u;

	if (islpci_get_state(priv) < PRV_STATE_INIT)
		return 0;

	rvalue = mgt_commit_list(priv, commit_part1, VEC_SIZE(commit_part1));

	if (priv->iw_mode != IW_MODE_MONITOR)
		rvalue |= mgt_commit_list(priv, commit_part2, VEC_SIZE(commit_part2));

	u = OID_INL_MODE;
	rvalue |= mgt_commit_list(priv, &u, 1);
	rvalue |= mgt_update_addr(priv);

	if (rvalue) {
		/* some request have failed. The device might be in an
		   incoherent state. We should reset it ! */
		printk(KERN_DEBUG "%s: mgt_commit: failure\n", priv->ndev->name);
	}
	return rvalue;
}
Beispiel #3
0
void
count_simul_efun_extra_refs (struct pointer_table *ptable)

/* DEBUG support: count the extra refs for structures of this module.
 */

{
    if (simul_efun_vector)
    {
        simul_efun_vector->extra_ref++;
        if (NULL != register_pointer(ptable, simul_efun_vector) )
            count_extra_ref_in_vector(
              simul_efun_vector->item,
              VEC_SIZE(simul_efun_vector)
            );
    }

    if (simul_efun_program)
    {
        simul_efun_program->extra_ref++;
        if (NULL == register_pointer(ptable, simul_efun_program))
            return;
        simul_efun_program->extra_ref = 1;
        count_inherits(simul_efun_program);
    }
} /* count_simul_efun_extra_refs() */
Beispiel #4
0
int main(int argc, char** argv) {
    int64 nside=4096;
    double rad_radians=-1;
    int rad_in_file=0;
    process_args(argc, argv, &nside, &rad_radians, &rad_in_file);

    struct healpix* hpix = hpix_new(nside);

    VEC(int64) pixlist = VEC_NEW(int64);

    double ra=0, dec=0;
    while (2 == fscanf(stdin,"%lf %lf", &ra, &dec)) {
        if (rad_in_file) {
            if (1 != fscanf(stdin,"%lf", &rad_radians)) {
                fprintf(stderr,"failed to read radius\n");
                exit(EXIT_FAILURE);
            }
            rad_radians *= D2R/3600.;
        }

        hpix_disc_intersect_radec(hpix, ra, dec, rad_radians, pixlist);

        printf("%.16g %.16g %lu", ra, dec, VEC_SIZE(pixlist);
        VEC_FOREACH(pix_ptr, pixlist) {
            printf(" %ld", *pix_ptr);
        }
        printf("\n");
    }
Beispiel #5
0
/*-------------------------------------------------------------------------*/
void
count_simul_efun_refs (void)

/* GC support: count the references of all memory held by the module.
 */

{
    if (simul_efun_file_name)
        count_ref_from_string(simul_efun_file_name);

    if (simul_efunp)
    {
        int i;

        note_malloced_block_ref((char *)simul_efunp);
        for (i = num_simul_efun; --i >= 0; )
            count_ref_from_string(simul_efunp[i].name);
    }

    if (simul_efun_vector && !simul_efun_vector->ref++)
    {
        note_malloced_block_ref((char *)simul_efun_vector);
        count_ref_in_vector(
          simul_efun_vector->item,
          VEC_SIZE(simul_efun_vector)
        );
    }
    if (simul_efun_program)
        mark_program_ref(simul_efun_program);
} /* count_simul_efun_refs() */
Beispiel #6
0
int main(void) {
    char *strings[] = { "take", "a", "walk", "on", "the", "wild", "side",
                        "song", "composed", "by", "Lou", "Reed", "and", 
                        "Velvet", "undeground"};
    
    for (int i=0; i<VEC_SIZE(strings); i++)
        printf("hash of \'%11s\' is: %u\n", strings[i], hash(strings[i]));

    return(EXIT_SUCCESS);
}
Beispiel #7
0
/*-------------------------------------------------------------------------*/
void
check_wizlist_for_destr (void)

/* Check the 'extra' info in all wizinfo and remove destructed objects
 * and closures.
 */

{
    wiz_list_t *wl;

    for (wl = &default_wizlist_entry; wl; )
    {
        size_t num;
        svalue_t *item;

        if (wl->extra.type == T_POINTER)
        {
            num = VEC_SIZE(wl->extra.u.vec);
            item = &(wl->extra.u.vec->item[0]);
        }
        else
        {
            num = 1;
            item = &(wl->extra);
        }

        for ( ; num != 0 ; item++, num--)
        {
            switch(item->type)
            {
            case T_POINTER:
                check_for_destr(item->u.vec);
                break;
            case T_MAPPING:
                check_map_for_destr(item->u.map);
                break;
            case T_OBJECT:
            case T_CLOSURE:
                if (destructed_object_ref(item))
                    assign_svalue(item, &const0);
                break;
            default:
                NOOP;
                break;
            }
        }

        if (wl == &default_wizlist_entry)
            wl = all_wiz;
        else
            wl = wl->next;
    }
} /* check_wizlist_for_destr() */
Beispiel #8
0
void err_cb (const riff_chunkv_t * chunk_path_ptr, FILE * f, uint64_t position, riff_result_t err, void * cookie) {
    riff_chunk_t cur;
    char buf[5];
    int i;
    for(i=0;i<VEC_SIZE(*chunk_path_ptr);i++) {
        cur = VEC_GET(*chunk_path_ptr, i);
        fourcc_to_string(cur.fourcc, buf);
        printf("%s:", buf);
    }
    cur = VEC_TOP(*chunk_path_ptr);
    printf(" %" PRIu64 " - %" PRIu64 "\n", cur.pos_head, cur.pos_end);
}
Beispiel #9
0
riff_cbresult_t chunk_cb (const riff_chunkv_t * chunk_path_ptr, FILE * f, uint64_t position, void * cookie) {
    riff_chunk_t cur;
    char buf[5];
    int i;

    cur = VEC_TOP(*chunk_path_ptr);
    fourcc_to_string(cur.fourcc, buf);

    assert(cur.pos_content == position);

    for(i=0; i<VEC_SIZE(skipv); i++) {
        if(VEC_GET(skipv, i) == VEC_TOP(*chunk_path_ptr).fourcc) {
            printf("Skipping: %s\n", buf);
            return RIFF_SKIP_CHUNK;
        }
    }
    for(i=0; i<VEC_SIZE(stopv); i++) {
        if(VEC_GET(stopv, i) == VEC_TOP(*chunk_path_ptr).fourcc) {
            printf("Stoping: %s\n", buf);
            return RIFF_STOP;
        }
    }
    for(i=0; i<VEC_SIZE(readv); i++) {
        if(VEC_GET(readv, i) == VEC_TOP(*chunk_path_ptr).fourcc) {
            printf("Reading: %s\n", buf);
            for(; position < cur.pos_end; position++) {
                fgetc(f);
            }
            return RIFF_CHUNK_READ;
        }
    }
    for(i=0;i<VEC_SIZE(*chunk_path_ptr);i++) {
        cur = VEC_GET(*chunk_path_ptr, i);
        fourcc_to_string(cur.fourcc, buf);
        printf("%s:", buf);
    }
    cur = VEC_TOP(*chunk_path_ptr);
    printf(" %" PRIu64 " - %" PRIu64 "\n", cur.pos_head, cur.pos_end);
    return RIFF_CONTINUE; /* go print subchunks */
}
int
mgt_commit(islpci_private *priv)
{
	int rvalue;
	enum oid_num_t u;

	if (islpci_get_state(priv) < PRV_STATE_INIT)
		return 0;

	rvalue = mgt_commit_list(priv, commit_part1, VEC_SIZE(commit_part1));

	if (priv->iw_mode != IW_MODE_MONITOR)
		rvalue |= mgt_commit_list(priv, commit_part2, VEC_SIZE(commit_part2));

	u = OID_INL_MODE;
	rvalue |= mgt_commit_list(priv, &u, 1);
	rvalue |= mgt_update_addr(priv);

	if (rvalue) {
		printk(KERN_DEBUG "%s: mgt_commit: failure\n", priv->ndev->name);
	}
	return rvalue;
}
Beispiel #11
0
int main(void) {
    int arr[] = {10, 12, 24, 21, 34, 37, 41, 48, 54, 59, 61, 68, 72, 77, 80,
                 85, 88, 91, 92, 94, 98, 100, 101, 102, 120, 130, 130, 178};
    int value = 72;

    int result = binary_search(value, arr, VEC_SIZE(arr));

    if (result == -1)
        printf("Element %d is not present\n", value);
    else
        printf("Element '%d' has index: '%d'\n", value, result);

    return(EXIT_SUCCESS);
}
Beispiel #12
0
void
clear_simul_efun_refs (void)

/* GC support: clear the references of all memory held by the module.
 */

{
    if (simul_efun_vector && simul_efun_vector->ref)
    {
        simul_efun_vector->ref = 0;
        clear_ref_in_vector(
          simul_efun_vector->item,
          VEC_SIZE(simul_efun_vector)
        );
    }
    if (simul_efun_program)
        simul_efun_program->ref = 0;
} /* clear_simul_efun_refs() */
Beispiel #13
0
/*-------------------------------------------------------------------------*/
Bool
assert_simul_efun_object (void)

/* (Re)load the simul_efun object and extract all information we need.
 * Result is TRUE if either the simul_efun object could be loaded, or if
 * master::get_simul_efun() did not return a string/string vector to
 * name the simul efun object. The result is FALSE if master::get_simul_efun()
 * specified a simul efun object, which couldn't be found.
 *
 * In other words: after calling assert_simul_efun_object(), the caller
 * still has to check if simul_efun_object is NULL.
 *
 * At the time of call, simul_efun_object must be NULL.
 */

{
    svalue_t           *svp;
    object_t           *ob;
    program_t          *progp;
    CBool              *visible; /* Flag for every function: visible or not */
    string_t           *name;
    int                 i, j, num_fun;

    invalidate_simul_efuns(); /* Invalidate the simul_efun information */

    free_defines(); /* to prevent #defines hideing places for globals */

    /* Get the name(s) of the simul_efun  object. */
    svp = apply_master(STR_GET_SEFUN, 0);

    /* If a simul_efun_object appears during the GET_SEFUN call, it
     * might have been due to a recursive get_simul_efun() call which may
     * have gotten an old backup copy. This can lead to hard-to-debug
     * variable and function definition inconsistencies.
     */
    if (simul_efun_object)
    {
        printf("%s simul_efun object appeared while asking for it.\n", time_stamp());
        return MY_TRUE;
    }

    if (svp == NULL)
    {
        printf("%s No simul_efun\n", time_stamp());
        return MY_TRUE;
    }

    if (svp->type == T_POINTER)
    {
        simul_efun_vector = svp->u.vec;
        svp->type = T_NUMBER;
        if (VEC_SIZE(svp->u.vec))
            svp = svp->u.vec->item;
    }

    if (svp->type != T_STRING)
    {
        printf("%s No simul_efun\n", time_stamp());
        return MY_TRUE;
    }

    /* Make the (primary) simul_efun name */
    name = del_slash(svp->u.str);
    if (simul_efun_file_name)
        free_mstring(simul_efun_file_name);
    simul_efun_file_name = make_tabled(name);

    /* Get the object and load the program */
    ob = find_object(simul_efun_file_name);
    if (ob == NULL)
    {
        fprintf(stderr, "%s The simul_efun file %s was not loaded.\n"
               , time_stamp(), get_txt(simul_efun_file_name));
        fprintf(stderr, "%s The function get_simul_efun() in the master must load it.\n"
               , time_stamp());
        return MY_FALSE;
    }
    if (O_PROG_SWAPPED(ob) && load_ob_from_swap(ob) < 0)
    {
        fprintf(stderr, "%s Out of memory (unswap object '%s') ==> "
                        "No simul_efun\n", time_stamp(), get_txt(ob->name));
        return MY_TRUE;
    }
    reference_prog( (simul_efun_program = ob->prog), "get_simul_efun");

    num_fun = ob->prog->num_function_names;
    if (num_fun == 0)
        return MY_TRUE;
    if (!simul_efunp)
    {
        simul_efunp = xalloc(sizeof (function_t) * num_fun);
    }
    else
        num_fun = total_simul_efun;

    free_defines(); /* to prevent #defines hideing places for globals */

    /* locals and defines are freed now. There are still reserved words,
     * but it is impossible to define a function with the name being
     * a reserved word, thus, there will be no clashes with higher-priority
     * shared identifiers.
     */

    progp = ob->prog;
    visible = alloca((i = ob->prog->num_functions) * sizeof(*visible));
    memset(visible, 0, i);
    i = ob->prog->num_function_names;
    while (--i >= 0)
        visible[progp->function_names[i]] = MY_TRUE;
    /* The functions .num_function_names+1 .. .num_functions are not
     * visible by definition.
     */

    /* Loop over the functions in the simul_efun object and
     * copy the salient information.
     */
    for (i = 0; i < ob->prog->num_functions; i++)
    {
        int        ix;
        funflag_t  flags, flags2;
        bytecode_p funstart;
        mp_int     fun_ix_offs, var_ix_offs;
        program_t *inherit_progp;
        function_t*funheader;

        if (!visible[i])
            continue;

        ix = i;
        flags2 = flags = progp->functions[ix];
        flags &= ~FUNSTART_MASK;

        /* Pinpoint the function, resolving inheritance where
         * necessary.
         */
        fun_ix_offs = ix;
        var_ix_offs = 0;
        inherit_progp = progp;
        while (flags2 & NAME_INHERITED)
        {
            inherit_t *inheritp;

            inheritp = &inherit_progp->inherit[flags2 & INHERIT_MASK];
            ix -= inheritp->function_index_offset;
            var_ix_offs += inheritp->variable_index_offset;
            inherit_progp = inheritp->prog;
            flags2 = inherit_progp->functions[ix];
        }
        fun_ix_offs -= ix;

        funstart = inherit_progp->program + (flags2 & FUNSTART_MASK);
        funheader = inherit_progp->function_headers + FUNCTION_HEADER_INDEX(funstart);

        /* Don't stumble over undefined functions */
        if (is_undef_function(funstart))
        {
            flags |= NAME_UNDEFINED;
        }

        /* If the function is __INIT, pretend it's a private function */
        if ( !(flags & (TYPE_MOD_STATIC|TYPE_MOD_PRIVATE|NAME_UNDEFINED)) )
        {
            if (mstreq(funheader->name, STR_VARINIT))
                flags |= TYPE_MOD_PRIVATE;
        }

        /* If the function is indeed visible, get its information */
        if ( !(flags & (TYPE_MOD_STATIC|TYPE_MOD_PROTECTED|TYPE_MOD_PRIVATE|NAME_UNDEFINED)) )
        {
            string_t *function_name;
            ident_t *p;
            unsigned char num_arg;

            function_name = funheader->name;
            num_arg = funheader->num_arg;

            /* Find or make the identifier for the function */
            p = make_shared_identifier_mstr(function_name, I_TYPE_GLOBAL, 0);
            if (p->type == I_TYPE_UNKNOWN)
            {
                init_global_identifier(p, /* bVariable: */ MY_FALSE);
                p->next_all = all_simul_efuns;
                all_simul_efuns = p;
            }

            if (flags & TYPE_MOD_VARARGS)
                num_arg = SIMUL_EFUN_VARARGS;

            /* Find the proper index in simul_efunp[] */
            switch(0) { default: /* TRY... */

                /* Try to find a discarded sefun entry with matching
                 * name, number of arguments and XVARARGS flag to reuse.
                 */
                if (all_discarded_simul_efun >= 0)
                {
                    int last;

                    j = all_discarded_simul_efun;
                    while ( (j = simul_efunp[last = j].offset.next_sefun) >= 0)
                    {
                        if (num_arg != simul_efunp[j].num_arg
                         || 0 != ((simul_efunp[j].flags ^ flags) & TYPE_MOD_XVARARGS)
                           )
                            continue;
                        if (!mstreq(function_name, simul_efunp[j].name))
                            continue;

                        /* Found one: remove it from the 'discarded' list */
                        simul_efunp[last].offset.next_sefun =
                              simul_efunp[j].offset.next_sefun;
                        break;
                    }
                    if (j >= 0)
                        break; /* switch */
                }

                /* New simul_efun: make a new entry */
                (void)ref_mstring(function_name);
                j = num_simul_efun++;
                if (num_simul_efun > num_fun)
                {
                    num_fun = num_simul_efun + 12;
                    simul_efunp = rexalloc(simul_efunp
                                          , sizeof (function_t) * num_fun
                      );
                }
                simul_efunp[j].name    = function_name;
                simul_efunp[j].num_arg = num_arg;
            } /* switch() */

            /* j now indexes the simul_efunp[] entry to use */

            p->u.global.sim_efun = j;
            simul_efunp[j].flags      = funheader->flags;
            simul_efunp[j].type       = funheader->type;
            simul_efunp[j].num_locals = funheader->num_locals;

            /* If possible, make an entry in the simul_efun table */
            if ((size_t)j < SEFUN_TABLE_SIZE)
            {
                simul_efun_table[j].funstart = funstart;
                simul_efun_table[j].program = inherit_progp;
                simul_efun_table[j].function_index_offset = fun_ix_offs;
                simul_efun_table[j].variable_index_offset = var_ix_offs;
            }
        } /* if (function visible) */
    } /* for ( all functions) */

    total_simul_efun = num_fun;
    simul_efun_object = ob;

    return MY_TRUE;
} /* get_simul_efun_object() */
Beispiel #14
0
svalue_t *
f_psyc_parse (svalue_t *sp) {
    char *buffer = NULL;
    svalue_t *sv;
    vector_t *v, *list;
    mapping_t *map;
    char oper = 0;
    psycString name = {0,0}, value = {0,0}, elems[MAX_LIST_SIZE], elem;
    psycParseListState listState;
    int ret, retl, type = -1, error = 0;
    size_t size, i;
    ssize_t n;
    time_t timmy;

    if (!psyc_dispatch_callback)
      psyc_dispatch_callback = new_tabled("psyc_dispatch");

    if (!psyc_error_callback)
      psyc_error_callback = new_tabled("psyc_error");

    assert_shadow_sent(current_object);
    psyc_state_t *state = O_GET_PSYC_STATE(current_object);
    if (!state) {
	state = pxalloc(sizeof(psyc_state_t));
	if (!state) {
	    errorf("Out of memory for psyc state struct.\n");
	    return sp; // not reached
	}
	O_GET_PSYC_STATE(current_object) = state;
	memset(state, 0, sizeof(psyc_state_t));

	state->parser = pxalloc(sizeof(psycParseState));
	if (!state->parser) {
	    errorf("Out of memory for psyc parse state struct.\n");
	    return sp; // not reached
	}
	psyc_initParseState(state->parser);
    }
    v = state->packet;

    if (sp->type == T_POINTER) {
	errorf("\npsyc_parse got %ld int* bytes... not supported yet\n",
	       VEC_SIZE(sp->u.vec));
	return sp; // not reached
    } else if (sp->type == T_STRING) {
#ifdef DEBUG
	printf("\npsyc_parse got a %ld bytes long string...\n", mstrsize(sp->u.str));
#endif
	if (state->remaining) {
	    // there are remaining bytes from the previous call to psyc_parse,
	    // copy them together with the newly arrived data
	    buffer = pxalloc(state->remaining_len + mstrsize(sp->u.str));
	    if (!buffer) {
		errorf("Out of memory for psyc_parse buffer.\n");
		return sp; // not reached
	    }
	    memcpy(buffer, state->remaining, state->remaining_len);
	    memcpy(buffer + state->remaining_len, get_txt(sp->u.str),
		   mstrsize(sp->u.str));
	    psyc_setParseBuffer2(state->parser, buffer,
				 state->remaining_len + mstrsize(sp->u.str));
	    pfree(state->remaining);
	    state->remaining = NULL;
	    state->remaining_len = 0;
	} else {
	    psyc_setParseBuffer2(state->parser, get_txt(sp->u.str),
				 mstrsize(sp->u.str));
	}
    } else {
	errorf("\npsyc_parse got type %d, not supported\n", sp->type);
	return sp; // not reached
    }

    do {
	ret = psyc_parse(state->parser, &oper, &name, &value);
#ifdef DEBUG
	printf("#%2d %c%.*s = %.*s\n", ret, oper ? oper : ' ',
	       (int)name.length, name.ptr, (int)value.length, value.ptr);
#endif
	if (!state->packet) {
	    state->packet = allocate_array(4);
	    if (!state->packet) {
		errorf("Out of memory for psyc_parse array.\n");
		return sp; // not reached
	    }
	    v = state->packet;

	    map = allocate_mapping(0, 2);	// empty mapping
	    if (!map) {
		errorf("Out of memory for psyc_parse routing header.\n");
		return sp; // not reached
	    }
	    put_mapping(&v->item[PACKET_ROUTING], map);
	    map = allocate_mapping(0, 2);	// empty mapping
	    if (!map) {
		errorf("Out of memory for psyc_parse entity header.\n");
		return sp; // not reached
	    }
	    put_mapping(&v->item[PACKET_ENTITY], map);
	}

	switch (ret) {
	    case PSYC_PARSE_ENTITY_START: case PSYC_PARSE_BODY_START:
		// save oper, name & value in state at the start of
		// incomplete entity or body
		state->oper = oper;
		state->name = mstring_alloc_string(name.length);
		memcpy(get_txt(state->name), name.ptr, name.length);
		if (!state->name) {
		    errorf("Out of memory for name.\n");
		    return sp; // not reached
		}

		// allocate memory for the total length of the value
		state->value_len = 0;
		state->value = mstring_alloc_string(psyc_getParseValueLength(state->parser));
		if (!state->value) {
		    errorf("Out of memory for value.\n");
		    return sp; // not reached
		}

		// fall thru
	    case PSYC_PARSE_ENTITY_CONT:  case PSYC_PARSE_BODY_CONT:
	    case PSYC_PARSE_ENTITY_END:   case PSYC_PARSE_BODY_END:
		// append value to tmp buffer in state
		memcpy(get_txt(state->value) + state->value_len, value.ptr, value.length);
		state->value_len += value.length;
	}

	if (ret == PSYC_PARSE_ENTITY_END || ret == PSYC_PARSE_BODY_END) {
	    // incomplete entity or body parsing done,
	    // set oper/name/value to the ones saved in state
	    oper = state->oper;
	    name.ptr = get_txt(state->name);
	    name.length = mstrsize(state->name);
	    value.ptr = get_txt(state->value);
	    value.length = mstrsize(state->value);
	}

	switch (ret) {
	    case PSYC_PARSE_ROUTING:
		sv = pxalloc(sizeof(svalue_t));

		// new_n_tabled fetches a reference of a probably existing
		// shared string
		put_string(sv, new_n_tabled(name.ptr, name.length));
		sv = get_map_lvalue(v->item[PACKET_ROUTING].u.map, sv);
		put_number(&sv[1], oper);
		// strings are capable of containing 0 so we can do this
		// for binary data too. let's use a tabled string even
		// for values of routing variables as they repeat a lot
		put_string(sv, new_n_tabled(value.ptr, value.length));
		break;

	    case PSYC_PARSE_ENTITY_START:
	    case PSYC_PARSE_ENTITY_CONT:
		break;

	    case PSYC_PARSE_ENTITY_END:
	    case PSYC_PARSE_ENTITY:
		sv = pxalloc(sizeof(svalue_t));

		if (ret == PSYC_PARSE_ENTITY)
		    put_string(sv, new_n_tabled(name.ptr, name.length));
		else // PSYC_PARSE_ENTITY_END
		    put_string(sv, make_tabled(state->name));

		sv = get_map_lvalue(v->item[PACKET_ENTITY].u.map, sv);
		put_number(&sv[1], oper);

		type = psyc_getVarType(&name);

		switch (type) {
		    case PSYC_TYPE_DATE: // number + PSYC_EPOCH
			if (psyc_parseDate(&value, &timmy))
			    put_number(sv, timmy);
			else
			    error = PSYC_PARSE_ERROR_DATE;
			break;
		    case PSYC_TYPE_TIME: // number
			if (psyc_parseTime(&value, &timmy))
			    put_number(sv, timmy);
			else
			    error = PSYC_PARSE_ERROR_TIME;
			break;
		    case PSYC_TYPE_AMOUNT: // number
			if (psyc_parseNumber(&value, &n))
			    put_number(sv, n);
			else
			    error = PSYC_PARSE_ERROR_AMOUNT;
			break;
		    case PSYC_TYPE_DEGREE: // first digit
			if (value.length && value.ptr[0] >= '0' && value.ptr[0] <= '9')
			    put_number(sv, value.ptr[0] - '0');
			else
			    error = PSYC_PARSE_ERROR_DEGREE;
			break;
		    case PSYC_TYPE_FLAG: // 0 or 1
			if (value.length && value.ptr[0] >= '0' && value.ptr[0] <= '1')
			    put_number(sv, value.ptr[0] - '0');
			else
			    error = PSYC_PARSE_ERROR_FLAG;
			break;
		    case PSYC_TYPE_LIST: // array
			size = 0;
			if (value.length) {
			    psyc_initParseListState(&listState);
			    psyc_setParseListBuffer(&listState, value);
			    elem = (psycString){0, 0};
			    do {
				retl = psyc_parseList(&listState, &elem);
				switch (retl) {
				    case PSYC_PARSE_LIST_END:
					retl = 0;
				    case PSYC_PARSE_LIST_ELEM:
					if (size >= MAX_LIST_SIZE) {
					    error = PSYC_PARSE_ERROR_LIST_TOO_LARGE;
					    break;
					}
					elems[size++] = elem;
					break;
				    default:
					error = PSYC_PARSE_ERROR_LIST;
				}
			    } while (retl > 0 && !error);
			}
			if (error) break;

			list = allocate_array(size);
			for (i = 0; i < size; i++)
			    put_string(&list->item[i], new_n_tabled(elems[i].ptr,
			                                            elems[i].length));

			put_array(sv, list);
			break;
		    default: // string
			if (ret == PSYC_PARSE_ENTITY)
			    // is it good to put entity variable values into the
			    // shared string table? probably yes.. but it's a guess
			    //t_string(sv, new_n_mstring(value.ptr, value.length));
			    put_string(sv, new_n_tabled(value.ptr, value.length));
			else // PSYC_PARSE_ENTITY_END
			    put_string(sv, state->value);
		}
		break;

	    case PSYC_PARSE_BODY_START:
	    case PSYC_PARSE_BODY_CONT:
		break;

	    case PSYC_PARSE_BODY_END:
		put_string(&v->item[PACKET_METHOD], make_tabled(state->name));
		put_string(&v->item[PACKET_BODY], state->value);
		break;

	    case PSYC_PARSE_BODY:
		// new_n_tabled gets the shared string for the method
		put_string(&v->item[PACKET_METHOD],
			   new_n_tabled(name.ptr, name.length));

		// allocate an untabled string for the packet body
		put_string(&v->item[PACKET_BODY],
			   new_n_mstring(value.ptr, value.length));
		break;

	    case PSYC_PARSE_COMPLETE:
		put_array(inter_sp, v);
		sapply(psyc_dispatch_callback, current_object, 1);
		state->packet = NULL;
		break;

	    case PSYC_PARSE_INSUFFICIENT:
		// insufficient data, save remaining bytes
		state->remaining_len = psyc_getParseRemainingLength(state->parser);
		if (state->remaining_len) {
		    state->remaining = pxalloc(state->remaining_len);
		    memcpy(state->remaining,
			   psyc_getParseRemainingBuffer(state->parser),
			   state->remaining_len);
		} else
		    state->remaining = NULL;

		ret = 0;
		break;

	    default:
		error = ret;
	}

	switch (ret) {
	    case PSYC_PARSE_BODY_END:
	    case PSYC_PARSE_ENTITY_END:
		// reset tmp buffers in state when incomplete
		// entity or body parsing is finished
		state->oper = 0;
		state->name = NULL;
		state->value = NULL;
	}
    } while (ret && !error);

    if (buffer)
	pfree(buffer);

    free_svalue(sp);
    put_number(sp, error);
    return sp;
} /* f_psyc_parse */
Beispiel #15
0
/*-------------------------------------------------------------------------*/
static svalue_t *
insert_alist (svalue_t *key, svalue_t * /* TODO: bool */ key_data, vector_t *list)

/* Implementation of efun insert_alist()
 *
 * The function can be used in two ways:
 *
 * 1. Insert/replace a (new) <key>:<keydata> tuple into the alist <list>.
 *    <key> and <key_data> have to point to an array of svalues. The first
 *    element is the key value, the following values the associated
 *    data values. The function will read as many elements from the
 *    array as necessary to fill the alist <list>.
 *    Result is a fresh copy of the modified alist.
 *
 * 2. Lookup a <key> in the alist <list> and return its index. If the key
 *    is not found, return  the position at which it would be inserted.
 *    <key_data> must be NULL, <key> points to the svalue to be looked
 *    up, and <list> points to an alist with at least the key vector.
 *
 * If <list> is no alist, the result can be wrong (case 2.) or not
 * an alist either (case 1.).
 *
 * If the <key> is a string, it is made shared.
 *
 * TODO: Make the hidden flag 'key_data' a real flag.
 */

{
    static svalue_t stmp; /* Result value */
    mp_int i,j,ix;
    mp_int keynum, list_size;  /* Number of keys, number of alist vectors */
    int new_member;            /* Flag if a new tuple is given */

    /* If key is a string, make it shared */
    if (key->type == T_STRING && !mstr_tabled(key->u.str))
    {
        key->u.str = make_tabled(key->u.str);
    }

    keynum = (mp_int)VEC_SIZE(list->item[0].u.vec);

    /* Locate the key */
    ix = lookup_key(key, list->item[0].u.vec);

    /* If its just a lookup: return the result.
     */
    if (key_data == NULL) {
         put_number(&stmp, ix < 0 ? -ix-1 : ix);
         return &stmp;
    }

    /* Prepare the result alist vector */
    put_array(&stmp, allocate_array(list_size = (mp_int)VEC_SIZE(list)));

    new_member = ix < 0;
    if (new_member)
        ix = -ix-1;

    /* Loop over all key/data vectors in <list>, insert/replace the
     * new value and put the new vector into <stmp>.
     */
    for (i = 0; i < list_size; i++) {
        vector_t *vtmp;

        if (new_member) {

            svalue_t *pstmp = list->item[i].u.vec->item;

            vtmp = allocate_array(keynum+1);
            for (j=0; j < ix; j++) {
               assign_svalue_no_free(&vtmp->item[j], pstmp++);
            }
            assign_svalue_no_free(&vtmp->item[ix], i ? &key_data[i] : key );
            for (j = ix+1; j <= keynum; j++) {
               assign_svalue_no_free(&vtmp->item[j], pstmp++);
            }

        } else {

            vtmp = slice_array(list->item[i].u.vec, 0, keynum-1);
            if (i)
                assign_svalue(&vtmp->item[ix], &key_data[i]);
                /* No need to assign the key value: it's already there. */

        }

        stmp.u.vec->item[i].type=T_POINTER;
        stmp.u.vec->item[i].u.vec=vtmp;
    }

    /* Done */
    return &stmp;
} /* insert_alist() */
Beispiel #16
0
svalue_t *
f_psyc_render(svalue_t *sp) {
    uint8_t i;
    vector_t *v;
    string_t *out;
    char *meth, *body;
    size_t mlen, blen;
    mapping_t *map;

    psycPacket packet;
    psycHeader headers[2];

    // unless (sp->type == T_POINTER) return sp;
    v = sp->u.vec;
    if (VEC_SIZE(v) == PACKET_BODY + 1) {
	for (i = PACKET_ROUTING; i <= PACKET_ENTITY; i++) {
	    headers[i].lines = 0;
	    if (v->item[i].type == T_MAPPING) {
		map = v->item[i].u.map;
		if (!MAP_SIZE(map)) continue;

		headers[i].modifiers = malloc(sizeof(psycModifier) * MAP_SIZE(v->item[i].u.map));
		if (!headers[i].modifiers) {
		    errorf("Out of memory in psyc_render for modifier table.\n");
		    return sp; // not reached
		}

		walk_mapping(map, &fill_header_from_mapping,
		             &(psyc_modifier_t) {
		                 &headers[i], map->num_values,
		                 i == PACKET_ROUTING ?
		                     PSYC_MODIFIER_ROUTING :
		                     PSYC_MODIFIER_CHECK_LENGTH
		             });
	    }
	    // else ... ignoring possibly invalid args
	}
    } else {
	errorf("Wrong number of elements (%" PRIdMPINT ") "
	       "in array argument to psyc_render()\n", VEC_SIZE(v));
	return sp; // not reached
    }

    if (v->item[PACKET_METHOD].type == T_STRING) {
	meth = get_txt(v->item[PACKET_METHOD].u.str);
	mlen = mstrsize(v->item[PACKET_METHOD].u.str);
    } else {
	meth = NULL;
	mlen = 0;
    }

    if (v->item[PACKET_BODY].type == T_STRING) {
	body = get_txt(v->item[PACKET_BODY].u.str);
	blen = mstrsize(v->item[PACKET_BODY].u.str);
    } else {
	body = NULL;
	blen = 0;
    }

    packet = psyc_newPacket2(headers[PACKET_ROUTING].modifiers,
                             headers[PACKET_ROUTING].lines,
                             headers[PACKET_ENTITY].modifiers,
                             headers[PACKET_ENTITY].lines,
                             meth, mlen, body, blen,
                             PSYC_PACKET_CHECK_LENGTH);

#ifdef DEBUG
    printf("rendering... packet.length = %ld\n", packet.length);
#endif
    // alloc_mstring creates an *untabled* string suitable for tmp data 
    memsafe(out = alloc_mstring(packet.length), packet.length, "f_psyc_render");
    psyc_render(&packet, get_txt(out), packet.length);

    free_svalue(sp);
    put_string(sp, out);
    // stack should take care of freeing the string after use
    return sp;

} /* f_psyc_render */
Beispiel #17
0
/*-------------------------------------------------------------------------*/
svalue_t *
v_insert_alist (svalue_t *sp, int num_arg)

/* EFUN insert_alist()
 *
 *   mixed* insert_alist (mixed key, mixed data..., mixed * alist)
 *   int    insert_alist (mixed key, mixed * keys)
 *
 * 1. Form: Alist Insertion
 *
 *   The <key> and all following <data> values are inserted
 *   into the <alist>. If an entry for <key> already exists
 *   in the list, just the data values are replaced. The number
 *   of <data> values must match the number of data arrays
 *   in the alist, naturally.
 *
 *   Result is the updated <alist>.
 *
 * 2. Form: Key Insertion
 *
 *   Insert the <key> into the (ordered) array of <keys>, so that
 *   subsequent assoc()s can perform quick lookups. Result is the
 *   index at which <key> was inserted (or already found).
 *
 *   CAVEAT: when working with string keys, the index might no longer
 *     be valid after the next call to insert_alist().
 */
/* When the key list of an alist contains destructed objects
   it is better not to free them till the next reordering by
   order_alist to retain the alist property.
 */

{
    int i;
    vector_t *list;
    long listsize;
    size_t keynum;
    svalue_t *key,*key_data,*ret;
    static LOCAL_VEC1(insert_alist_vec, T_NUMBER);
      /* Mock-alist for the insert_alist() key-insertion form.
       */

    if (sp->type != T_POINTER)
        vefun_arg_error(num_arg, T_POINTER, sp->type, sp);

    /* Make up an alist if only a key-insertion is required */
    if ( !(listsize = (long)VEC_SIZE(sp->u.vec))
     ||  sp->u.vec->item[0].type != T_POINTER )
    {
        list = &insert_alist_vec.v;
        *list->item = *sp;
        listsize = 1;
    }
    else
        list = sp->u.vec;

    /* Check the validity of the alist */
    keynum = VEC_SIZE(list->item[0].u.vec);
    for (i = 1; i < listsize; i++)
    {
        if (list->item[i].type != T_POINTER
         || (size_t)VEC_SIZE(list->item[i].u.vec) != keynum)
        {
            errorf("Type or size mismatch of the data arrays.\n");
            /* NOTREACHED */
            return sp;
        }
    }

    /* Get and test the data to insert */
    if (num_arg == 2)
    {
        if (sp[-1].type != T_POINTER)
        {
            key_data = NULL;
            key = sp-1;
        }
        else
        {
            if (VEC_SIZE(sp[-1].u.vec) != listsize)
            {
                errorf("Size mismatch of the data arrays: "
                      "vec size %ld, list size %ld.\n"
                     , (long)VEC_SIZE(sp[-1].u.vec), (long)listsize
                     );
                /* NOTREACHED */
                return sp;
            }
            key_data = key = sp[-1].u.vec->item;
        }
    }
    else
    {
        if (num_arg - 1 != listsize)
        {
            errorf("Not enough data given: %ld arguments, %ld listsize.\n"
                 , (long)num_arg - 1, (long)listsize);
            /* NOTREACHED */
            return sp;
        }
        key_data = key = sp-num_arg+1;
    }

    /* Do the insertion */
    ret = insert_alist(key,key_data,list);
    sp = pop_n_elems(num_arg, sp);
    sp++;
    *sp = *ret;

    return sp;
} /* v_insert_alist() */
Beispiel #18
0
/*
 * os_badblocks_get -- returns 0 and bad blocks in the 'bbs' array
 *                     (that has to be pre-allocated)
 *                     or -1 in case of an error
 */
int
os_badblocks_get(const char *file, struct badblocks *bbs)
{
	LOG(3, "file %s badblocks %p", file, bbs);

	ASSERTne(bbs, NULL);

	VEC(bbsvec, struct bad_block) bbv = VEC_INITIALIZER;
	struct extents *exts = NULL;
	long extents = 0;

	unsigned long long bb_beg;
	unsigned long long bb_end;
	unsigned long long bb_len;
	unsigned long long bb_off;
	unsigned long long ext_beg;
	unsigned long long ext_end;
	unsigned long long not_block_aligned;

	int bb_found = -1; /* -1 means an error */

	memset(bbs, 0, sizeof(*bbs));

	if (os_dimm_files_namespace_badblocks(file, bbs)) {
		LOG(1, "checking the file for bad blocks failed -- '%s'", file);
		goto error_free_all;
	}

	if (bbs->bb_cnt == 0) {
		bb_found = 0;
		goto exit_free_all;
	}

	exts = Zalloc(sizeof(struct extents));
	if (exts == NULL) {
		ERR("!Zalloc");
		goto error_free_all;
	}

	extents = os_extents_count(file, exts);
	if (extents < 0) {
		LOG(1, "counting file's extents failed -- '%s'", file);
		goto error_free_all;
	}

	if (extents == 0) {
		/* dax device has no extents */
		bb_found = (int)bbs->bb_cnt;

		for (unsigned b = 0; b < bbs->bb_cnt; b++) {
			LOG(4, "bad block found: offset: %llu, length: %u",
				bbs->bbv[b].offset,
				bbs->bbv[b].length);
		}

		goto exit_free_all;
	}

	exts->extents = Zalloc(exts->extents_count * sizeof(struct extent));
	if (exts->extents == NULL) {
		ERR("!Zalloc");
		goto error_free_all;
	}

	if (os_extents_get(file, exts)) {
		LOG(1, "getting file's extents failed -- '%s'", file);
		goto error_free_all;
	}

	bb_found = 0;

	for (unsigned b = 0; b < bbs->bb_cnt; b++) {

		bb_beg = bbs->bbv[b].offset;
		bb_end = bb_beg + bbs->bbv[b].length - 1;

		for (unsigned e = 0; e < exts->extents_count; e++) {

			ext_beg = exts->extents[e].offset_physical;
			ext_end = ext_beg + exts->extents[e].length - 1;

			/* check if the bad block overlaps with file's extent */
			if (bb_beg > ext_end || ext_beg > bb_end)
				continue;

			bb_found++;

			bb_beg = (bb_beg > ext_beg) ? bb_beg : ext_beg;
			bb_end = (bb_end < ext_end) ? bb_end : ext_end;
			bb_len = bb_end - bb_beg + 1;
			bb_off = bb_beg + exts->extents[e].offset_logical
					- exts->extents[e].offset_physical;

			LOG(10,
				"bad block found: physical offset: %llu, length: %llu",
				bb_beg, bb_len);

			/* check if offset is block-aligned */
			not_block_aligned = bb_off & (exts->blksize - 1);
			if (not_block_aligned) {
				bb_off -= not_block_aligned;
				bb_len += not_block_aligned;
			}

			/* check if length is block-aligned */
			bb_len = ALIGN_UP(bb_len, exts->blksize);

			LOG(4,
				"bad block found: logical offset: %llu, length: %llu",
				bb_off, bb_len);

			/*
			 * Form a new bad block structure with offset and length
			 * expressed in bytes and offset relative
			 * to the beginning of the file.
			 */
			struct bad_block bb;
			bb.offset = bb_off;
			bb.length = (unsigned)(bb_len);
			/* unknown healthy replica */
			bb.nhealthy = NO_HEALTHY_REPLICA;

			/* add the new bad block to the vector */
			if (VEC_PUSH_BACK(&bbv, bb)) {
				VEC_DELETE(&bbv);
				bb_found = -1;
				goto error_free_all;
			}
		}
	}

error_free_all:
	Free(bbs->bbv);
	bbs->bbv = NULL;
	bbs->bb_cnt = 0;

exit_free_all:
	if (exts) {
		Free(exts->extents);
		Free(exts);
	}

	if (extents > 0 && bb_found > 0) {
		bbs->bbv = VEC_ARR(&bbv);
		bbs->bb_cnt = (unsigned)VEC_SIZE(&bbv);

		LOG(10, "number of bad blocks detected: %u", bbs->bb_cnt);

		/* sanity check */
		ASSERTeq((unsigned)bb_found, bbs->bb_cnt);
	}

	return (bb_found >= 0) ? 0 : -1;
}
Beispiel #19
0
/*-------------------------------------------------------------------------*/
vector_t *
order_alist (svalue_t *inlists, int listnum, Bool reuse)

/* Order the alist <inlists> and return a new vector with it. The sorting
 * order is the internal order defined by alist_cmp().
 *
 * <inlists> is a vector of <listnum> vectors:
 *   <inlists> = ({ ({ keys }), ({ data1 }), ..., ({ data<listnum-1> }) })
 *
 * If <reuse> is true, the vectors of <inlists> are reused for the
 * vectors of the result when possible, and their entries in <inlists> are
 * set to T_INVALID.
 *
 * As a side effect, strings in the key vector are made shared, and
 * destructed objects in key and data vectors are replaced by svalue 0s.
 *
 * This function is also called by the compiler for constant expressions.
 */

{
    vector_t *outlist;   /* The result vector of vectors */
    vector_t *v;         /* Aux vector pointer */
    svalue_t *outlists;  /* Next element in outlist to fill in */
    ptrdiff_t * sorted;  /* The vector elements in sorted order */
    svalue_t *inpnt;     /* Pointer to the value to copy into the result */
    mp_int keynum;       /* Number of keys */
    int i, j;

    keynum = (mp_int)VEC_SIZE(inlists[0].u.vec);

    /* Get the sorting order */

    sorted = get_array_order(inlists[0].u.vec);

    /* Generate the result vectors from the sorting order.
     */

    outlist = allocate_array(listnum);
    outlists = outlist->item;

    /* Copy the elements from all inlist vectors into the outlist
     * vectors.
     *
     * At the beginning of every loop v points to the vector to
     * use as the next 'out' vector. It may be a re-used 'in' vector
     * from the previous run.
     */
    v = allocate_array(keynum);
    for (i = listnum; --i >= 0; ) {

        svalue_t *outpnt; /* Next result value element to fill in */

        /* Set the new array v as the next 'out' vector, and init outpnt
         * and offs.
         */
        put_array(outlists + i, v);
        outpnt = v->item;

        v = inlists[i].u.vec; /* Next vector to fill if reusable */

        /* Copy the elements.
         * For a reusable 'in' vector, a simple memory copy is sufficient.
         * For a new vector, a full assignment is due to keep the refcounters
         * happy.
         */
        if (reuse && inlists[i].u.vec->ref == 1) {

            if (i) /* not the last iteration */
                inlists[i].type = T_INVALID;

            for (j = keynum; --j >= 0; ) {
                inpnt = inlists[i].u.vec->item + sorted[j];
                if (destructed_object_ref(inpnt))
                {
                    free_svalue(inpnt);
                    put_number(outpnt, 0);
                    outpnt++;
                } else {
                    *outpnt++ = *inpnt;
                }
                inpnt->type = T_INVALID;
            }

        } else {

            if (i) /* Not the last iteration: get new out-vector */
                v = allocate_array(keynum);

            for (j = keynum; --j >= 0; ) {
                inpnt = inlists[i].u.vec->item + sorted[j];
                if (destructed_object_ref(inpnt))
                {
                    put_number(outpnt, 0);
                    outpnt++;
                } else {
                    assign_svalue_no_free(outpnt++, inpnt);
                }
            }
        } /* if (reuse) */
    } /* for (listnum) */

    xfree(sorted);

    return outlist;
} /* order_alist() */
Beispiel #20
0
void
fill_header_from_mapping (svalue_t *key, svalue_t *val, void *extra) {
    psyc_modifier_t *m = extra;
    char oper = 0;
    char *name, *value;
    size_t namelen, valuelen, i;
    uint8_t type;
    svalue_t vsp, *lval;

    psycList list;
    psycString *elems = NULL;

    if (key->type != T_STRING) {
	errorf("fill_header_from_mapping: key type %d not supported\n", key->type);
	return; // not reached
    }

    name = get_txt(key->u.str);
    namelen = mstrsize(key->u.str);
    type = psyc_getVarType2(name, namelen);

    if (m->num_values > 1)
	oper = val[1].u.number;
    if (!oper)
	oper = C_GLYPH_OPERATOR_SET;

    switch (val->type) {
	case T_STRING:
	    value = get_txt(val->u.str);
	    valuelen = mstrsize(val->u.str);
	    break;

	case T_NUMBER:
	case T_OBJECT:
	    vsp.type = val->type;
	    switch (val->type) {
		case T_NUMBER:
		    if (type == PSYC_TYPE_DATE)
			vsp.u.number = val->u.number - PSYC_EPOCH;
		    else
			vsp.u.number = val->u.number;
		    break;
		case T_OBJECT:
		    vsp.u.ob = val->u.ob;
		    break;
	    }

	    f_to_string(&vsp);	// generates an mstring
	    value = get_txt(vsp.u.str);
	    valuelen = mstrsize(vsp.u.str);
	    break;

	case T_POINTER:
	    if (VEC_SIZE(val->u.vec)) {
		elems = pxalloc(sizeof(psycString) * VEC_SIZE(val->u.vec));
		if (!elems) {
		    errorf("Out of memory in fill_header_from_mapping for elems\n");
		    return; // not reached
		}

		for (i = 0; i < VEC_SIZE(val->u.vec); i++) {
		    lval = &(val->u.vec->item[i]);
		    switch (lval->type) {
			case T_STRING:
			    elems[i] = (psycString){mstrsize(lval->u.str), get_txt(lval->u.str)};
			    break;
			case T_NUMBER:
			case T_OBJECT:
			    vsp.type = lval->type;
			    switch (lval->type) {
				case T_NUMBER:
				    vsp.u.number = lval->u.number;
				    break;
				case T_OBJECT:
				    vsp.u.ob = lval->u.ob;
				    break;
			    }

			    f_to_string(&vsp);
			    elems[i] = (psycString){mstrsize(vsp.u.str), get_txt(vsp.u.str)};
			    break;
			default:
			    errorf("fill_header_from_mapping: list value type %d not supported\n", lval->type);
			    return; // not reached
		    }
		}
	    }

	    list = psyc_newList(elems, VEC_SIZE(val->u.vec), PSYC_LIST_CHECK_LENGTH);
	    valuelen = list.length;
	    value = pxalloc(valuelen);
	    if (!value) {
		errorf("Out of memory in fill_header_from_mapping for list value\n");
		return; // not reached
	    }

	    psyc_renderList(&list, value, valuelen);
	    break;

	default:
	    errorf("fill_header_from_mapping: value type %d not supported\n", val->type);
	    return; // not reached
    }

    m->header->modifiers[m->header->lines++] =
	psyc_newModifier2(oper, name, namelen, value, valuelen, m->flag);
}
Beispiel #21
0
/*-------------------------------------------------------------------------*/
svalue_t *
v_order_alist (svalue_t *sp, int num_arg)

/* EFUN order_alist()
 *
 *   mixed *order_alist(mixed *keys, mixed *|void data, ...)
 *
 * Creates an alist.
 *
 * Either takes an array containing keys, and others containing
 * the associated data, where all arrays are to be of the same
 * length, or takes a single array that contains as first member
 * the array of keys and has an arbitrary number of other members
 * containing data, each of wich has to be of the same length as
 * the key array. Returns an array holding the sorted key array
 * and the data arrays; the same permutation that is applied to
 * the key array is applied to all data arrays.
 */

{
    int i;
    svalue_t *args;
    vector_t *list;
    long listsize;
    Bool reuse;
    size_t keynum;

    args = sp-num_arg+1;

    /* Get the key array to order */
    if (num_arg == 1
      && ((list = args->u.vec), (listsize = (long)VEC_SIZE(list)))
      && list->item[0].type == T_POINTER)
    {
        args     = list->item;
        reuse = (list->ref == 1);
    }
    else
    {
        listsize = num_arg;
        reuse = MY_TRUE;
    }
    keynum = VEC_SIZE(args[0].u.vec);

    /* Get the data arrays to order */
    for (i = 0; i < listsize; i++)
    {
        if (args[i].type != T_POINTER
         || (size_t)VEC_SIZE(args[i].u.vec) != keynum)
        {
            errorf("bad data array %d in call to order_alist\n",i);
        }
    }

    /* Create the alist */
    list = order_alist(args, listsize, reuse);
    sp = pop_n_elems(num_arg, sp);
    sp++;
    put_array(sp, list);

    return sp;
} /* v_order_alist() */
Beispiel #22
0
/*-------------------------------------------------------------------------*/
svalue_t *
v_assoc (svalue_t *sp, int num_arg)

/* EFUN assoc()
 *
 *     int   assoc (mixed key, mixed *keys)
 *     mixed assoc (mixed key, mixed *alist [, mixed fail] )
 *     mixed assoc (mixed key, mixed *keys, mixed *data [, mixed fail])
 *
 * Search for <key> in the <alist> resp. in the <keys>.
 *
 * When the key list of an alist contains destructed objects
 * it is better not to free them till the next reordering by
 * order_alist to retain the alist property.
 */

{
    svalue_t *args;
    vector_t *keys,*data;
    svalue_t *fail_val;
    int ix;

    args = sp -num_arg +1;

    /* Analyse the arguments */
    if ( !VEC_SIZE(args[1].u.vec)
     ||  args[1].u.vec->item[0].type != T_POINTER )
    {
        keys = args[1].u.vec;
        if (num_arg == 2)
        {
            data = NULL;
        }
        else
        {
            if (args[2].type != T_POINTER
             || VEC_SIZE(args[2].u.vec) != VEC_SIZE(keys))
            {
                errorf("Number of values in key and data arrays differ.\n");
                /* NOTREACHED */
                return sp;
            }
            data = args[2].u.vec;
        }
        if (num_arg == 4)
        {
            fail_val = &args[3];
        }
        else
        {
            fail_val = &const0;
        }
    }
    else
    {
        keys = args[1].u.vec->item[0].u.vec;
        if (VEC_SIZE(args[1].u.vec) > 1)
        {
            if (args[1].u.vec->item[1].type != T_POINTER
             || VEC_SIZE(args[1].u.vec->item[1].u.vec) != VEC_SIZE(keys))
            {
                errorf("Number of values in key and data arrays differ.\n");
                /* NOTREACHED */
                return sp;
            }
            data = args[1].u.vec->item[1].u.vec;
        }
        else
        {
            data = NULL;
        }

        if (num_arg == 3) fail_val = &args[2];
        else if (num_arg == 2) fail_val = &const0;
        else
        {
            errorf("too many args to efun assoc\n");
            /* NOTREACHED */
            return sp;
        }
    }

    /* Call lookup_key() and push the result */
    ix = lookup_key(&args[0],keys);
    if (data == NULL)
    {
        sp = pop_n_elems(num_arg, sp);
        push_number(sp, ix < 0 ? -1 : ix);
    }
    else
    {
        assign_svalue(args
                     , ix < 0
                       ? fail_val
                       : (destructed_object_ref(&data->item[ix])
                         ? &const0
                         : &data->item[ix])
                     );
        sp = pop_n_elems(num_arg-1, sp);
    }

    return sp;
} /* v_assoc() */
Beispiel #23
0
/*-------------------------------------------------------------------------*/
svalue_t *
f_wizlist_info (svalue_t *sp)

/* EFUN wizlist_info()
 *
 *    mixed *wizlist_info()
 *
 * Returns an array with the interesting entries of the wizlist.
 * Raises a privilege_violation (wizlist_info, this_object(), 0).
 *
 * The result is an array with one entry for every wizard (uid).
 * Every entry is an array itself:
 *
 *   string w[WL_NAME]        = Name of the wizard.
 *   int    w[WL_COMMANDS]    = Weighted number of commands execute by objects
 *                              of this wizard.
 *   int    w[WL_COST] and  w[WL_GIGACOST] = Weighted sum of eval_costs.
 *   int    w[WL_TOTAL_COST] and  w[WL_TOTAL_GIGACOST] = Total sum of
 *                              eval_costs.
 *   int    w[WL_HEART_BEATS] = Weighted count of heart_beats.
 *   int    w[WL_CALL_OUT]    = Reserved for call_out() (unused yet).
 *   int    w[WL_ARRAY_TOTAL] = Total size of arrays in elements.
 *   int    w[WL_MAPPING_TOTAL] = Total size of mappings in elements.
#ifdef USE_STRUCTS
 *   int    w[WL_STRUCT_TOTAL] = Total size of mappings in elements.
#endif
 *   mixed  w[WL_EXTRA]       = Extra wizlist-info if set.
 */

{
    vector_t *all, *entry;
    svalue_t *wsvp, *svp;
    wiz_list_t *w;

    if (!privilege_violation(STR_WIZLIST_INFO, &const0, sp))
    {
        all = allocate_array(0);
    }
    else
    {
        all = allocate_array(number_of_wiz);
        wsvp = all->item;
        for (w = all_wiz; w; w = w->next)
        {
            entry = allocate_array(WL_SIZE);
            put_array(wsvp, entry);
            wsvp++;
            svp = entry->item;
            put_ref_string(&(svp[WL_NAME]), w->name);
            put_number(&(svp[WL_COMMANDS]), w->score);
            put_number(&(svp[WL_COST]), w->cost);
            put_number(&(svp[WL_GIGACOST]), w->gigacost);
            put_number(&(svp[WL_TOTAL_COST]), w->total_cost);
            put_number(&(svp[WL_TOTAL_GIGACOST]), w->total_gigacost);
            put_number(&(svp[WL_HEART_BEATS]), w->heart_beats);
            put_number(&(svp[WL_CALL_OUT]), 0); /* TODO: Implement me */
            put_number(&(svp[WL_ARRAY_TOTAL]), w->size_array);
            put_number(&(svp[WL_MAPPING_TOTAL]), w->mapping_total);
#ifdef USE_STRUCTS
            put_number(&(svp[WL_STRUCT_TOTAL]), w->struct_total);
#else
            put_number(&(svp[WL_STRUCT_TOTAL]), 0);
#endif /* USE_STRUCTS */
            if (w->extra.type == T_POINTER)
            {
                vector_t *v = w->extra.u.vec;
                put_array(&(svp[WL_EXTRA]), slice_array(v, 0, VEC_SIZE(v) - 1));
            }
            else
                assign_svalue_no_free(&(svp[WL_EXTRA]), &w->extra);
        } /* end for */
    } /* end if */

    push_array(sp, all);
    return sp;
} /* f_wizlist_info() */
Beispiel #24
0
/*-------------------------------------------------------------------------*/
static size_t
svalue_size (svalue_t *v, mp_int * pTotal)

/* Compute the memory usage of *<v> (modified to reflect data sharing),
 * calling svalue_size() recursively if necessary, and return it.
 * The size of *v itself is not included.
 * *<pUnshared> and *<pShared> are set to the total unshared and shared
 * datasize.
 */

{
    mp_int i, composite, total, overhead;

    assert_stack_gap();

    *pTotal = 0;

    total = overhead = composite = 0;

    switch(v->type)
    {
    case T_OBJECT:
    case T_NUMBER:
    case T_FLOAT:
        return 0;

    case T_STRING:
    case T_SYMBOL:
        // If ref==0 the string is probably shared a lot, but we can't estimate
        // the correct number, so we return 0 as memory consumption for the
        // string.
        if (v->u.str->info.ref)
        {
            *pTotal = mstr_mem_size(v->u.str);
            return *pTotal / v->u.str->info.ref;
        }
        else
            return 0;

    case T_MAPPING:
    {
        struct svalue_size_locals locals;

        if (NULL == register_pointer(ptable, v->u.map) ) return 0;

        if (v->u.map->ref)
        {
            overhead = (mp_uint)mapping_overhead(v->u.map);
            locals.total = 0;
            locals.composite = 0;
            locals.num_values = v->u.map->num_values;
            walk_mapping(v->u.map, svalue_size_map_filter, &locals);

            *pTotal = locals.total + overhead;
            return (overhead + locals.composite) / v->u.map->ref;
        }
        else
            return 0;
    }

    case T_POINTER:
    case T_QUOTED_ARRAY:
    {
        if (v->u.vec == &null_vector) return 0;
        if (NULL == register_pointer(ptable, v->u.vec) ) return 0;
        if (v->u.vec->ref)
        {
            overhead = sizeof *v->u.vec - sizeof v->u.vec->item +
                       sizeof(svalue_t) * v->u.vec->size + sizeof(char *);
            for (i=0; i < (mp_int)VEC_SIZE(v->u.vec); i++) {
                composite += svalue_size(&v->u.vec->item[i], &total);
                *pTotal += total;
            }
            *pTotal += overhead;

            return (overhead + composite) / v->u.vec->ref;
        }
        else
            return 0;
    }
    case T_STRUCT:
    {
        struct_t *st = v->u.strct;
        if (NULL == register_pointer(ptable, st) ) return 0;
        if (st->ref)
        {
            overhead = sizeof *st - sizeof st->member
                       + sizeof(svalue_t) * struct_size(st);
            for (i=0; i < (mp_int)struct_size(st); i++) {
                composite += svalue_size(&st->member[i], &total);
                *pTotal += total;
            }
            *pTotal += overhead;

            return (overhead + composite) / st->ref;
        }
        else
            return 0;
    }

    case T_CLOSURE:
    {
        int num_values;
        svalue_t *svp;
        lambda_t *l;

        if (!CLOSURE_MALLOCED(v->x.closure_type)) return 0;
        if (!CLOSURE_REFERENCES_CODE(v->x.closure_type))
        {
            if (v->x.closure_type == CLOSURE_LFUN)
                composite = SIZEOF_LAMBDA(v->u.lambda->function.lfun.context_size);
            else /* CLOSURE_IDENTIFIER || CLOSURE_PRELIMINARY */
                composite = sizeof *v->u.lambda;

            composite += sizeof(char *);
            *pTotal = composite;
            return composite / v->u.lambda->ref;
        }
        /* CLOSURE_LAMBDA */
        composite = overhead = 0;
        l = v->u.lambda;
        if (v->x.closure_type == CLOSURE_BOUND_LAMBDA)
        {
            total = sizeof *l - sizeof l->function + sizeof l->function.lambda;
            *pTotal += total;
            composite += total / l->ref;
            l = l->function.lambda;
        }
        num_values = l->function.code.num_values;
        svp = (svalue_t *)l - num_values;
        if (NULL == register_pointer(ptable, svp)) return 0;
        overhead = sizeof(svalue_t) * num_values + sizeof (char *);
        {
            bytecode_p p = l->function.code.program;
            do {
                switch(GET_CODE(p++)) {
                case F_RETURN:
                case F_RETURN0:
                    break;
                default:
                    continue;
                }
                break;
            } while (1);
            overhead +=   (p - (bytecode_p)l + (sizeof(bytecode_p) - 1))
                          & ~(sizeof(bytecode_p) - 1);
        }

        while (--num_values >= 0)
        {
            composite += svalue_size(svp++, &total);
            *pTotal += total;
        }

        *pTotal += overhead;
        if (l->ref)
            return (overhead + composite) / l->ref;
        else
            return 0;
    }

    default:
        fatal("Illegal type: %d\n", v->type);
    }

    /*NOTREACHED*/
    return 0;
}