예제 #1
0
파일: array.c 프로젝트: DruSatori/AEMud
struct vector *
set_manipulate_array(struct vector *arr1, struct vector *arr2, int op)
{
    struct mapping *m;
    struct vector *r;
    struct svalue tmp, *v;
    char *flags;
    int cnt, res;
    
    if (arr1->size < 1 || arr2->size < 1)
    {
	switch (op)
	{
	case SETARR_SUBTRACT:
	    INCREF(arr1->ref);
	    return arr1;

        case SETARR_INTERSECT:
	    return allocate_array(0);
	}
    }

    m = make_mapping(arr2, 0);
    tmp.type = T_NUMBER;
    tmp.u.number = 1;
    assign_svalue_no_free(get_map_lvalue(m, &arr2->item[0], 1), &tmp);

    res = 0;

    flags = alloca((size_t)arr1->size + 1); 
    for (cnt = 0; cnt < arr1->size; cnt++) 
    {
	flags[cnt] = 0;
	v = get_map_lvalue(m, &(arr1->item[cnt]), 0);
	if (op == SETARR_INTERSECT && v != &const0)
	{
	    flags[cnt] = 1; 
	    res++; 
	}
	else if (op == SETARR_SUBTRACT && v == &const0)
	{
	    flags[cnt] = 1; 
	    res++; 
	}
    }
    r = allocate_array(res);
    if (res) 
    {
	for (cnt = res = 0; cnt < arr1->size; cnt++) 
	{
	    if (flags[cnt]) 
		assign_svalue_no_free(&r->item[res++], &arr1->item[cnt]);
	}
    }
    free_mapping(m);
    return r;
}
예제 #2
0
파일: array.c 프로젝트: DruSatori/AEMud
INLINE struct vector *
union_array(struct vector *arr1, struct vector *arr2)
{
    int i, size;
    struct mapping *mp;
    struct vector *arr3;
    char *set;

    if (arr1->size == 0)
    {
	INCREF(arr2->ref);
	return arr2;
    }

    if (arr2->size == 0)
    {
	INCREF(arr1->ref);
	return arr1;
    }

    mp = allocate_map(arr1->size);

    for (i = 0; i < arr1->size; i++)
	assign_svalue(get_map_lvalue(mp, &arr1->item[i], 1), &const1);

    set = alloca((size_t)arr2->size);

    for (i = size = 0; i < arr2->size; i++)
    {
	if (get_map_lvalue(mp, &arr2->item[i], 0) == &const0)
	    set[i] = 1, size++;
	else
	    set[i] = 0;
    }

    free_mapping(mp);

    arr3 = allocate_array(arr1->size + size);

    for (i = 0; i < arr1->size; i++)
	assign_svalue_no_free(&arr3->item[i], &arr1->item[i]);

    size = arr1->size;

    for (i = 0; i < arr2->size; i++)
	if (set[i])
	    assign_svalue_no_free(&arr3->item[size++], &arr2->item[i]);

    return arr3;
}
예제 #3
0
파일: pkg-odbc.c 프로젝트: Fuchur/ldmud
static mapping_t * 
fetch_into_mapping( hDBC * handle )
{
   int       i;

   mapping_t  * map;   
   svalue_t  * key,
             * value;

   STORE_DOUBLE_USED;

   map = allocate_mapping( handle->colcnt, 1 );
   MEM_CHECK( map );
         
   for( i = 0; i < handle->colcnt; ++i ) {
      if ( !handle->columns[ i ] ) continue;

      //printf( " fetch_into_mapping[%2d] ", i );
      
      key = pxalloc( sizeof( svalue_t ) ); 
      MEM_CHECK( key );
         
      put_malloced_string( key, string_copy( handle->columns[ i ]->name ) );
         
      value = get_map_lvalue( map, key );
      MEM_CHECK( value );

      switch( handle->columns[ i ]->type ){
         case T_FLOAT:
            //printf( "float=%f\n",  handle->columns[ i ]->data.double_v );
            STORE_DOUBLE( value, *handle->columns[ i ]->data.double_v );

            value->type = T_FLOAT;
            break; 

         case T_NUMBER:
            //printf( "number=%d\n",  *handle->columns[ i ]->data.number_v );
            put_number( value, *handle->columns[ i ]->data.number_v );
            break;

         case T_STRING: 
         default      :
            //printf( "string=%s\n",  handle->columns[ i ]->data.string_v );
            put_malloced_string( value, string_copy(  handle->columns[ i ]->data.string_v ) );
            break;
      }
   }

   return( map );
}
예제 #4
0
struct svalue *
json_to_mapping(json_object *ob)
{
    static struct svalue ret;
    ret.type = T_MAPPING;
    ret.u.map = allocate_map(10);

    json_object_object_foreach(ob, name, val) {
        struct svalue key = {};
        key.type = T_STRING;
        key.string_type = STRING_MSTRING;
        key.u.string = make_mstring(name);

        assign_svalue_no_free(get_map_lvalue(ret.u.map, &key, 1), 
            json_to_value(val)); 
    }

    return &ret;
}
예제 #5
0
static struct mapping *
restore_mapping(char **str)
{
    struct mapping *m;

    m = allocate_map(0);
    for(;;)
    {
	if (**str == ']')
	{
	    if (*++*str == ')')
	    {
		++*str;
		return m;
	    }
	    else
		break;
	}
	else
	{
	    struct svalue arg, *val;
	    arg = const0;
	    if (!restore_one(&arg, str))
		break;
      	    if (*(*str)++ != ':')
	    {
		free_svalue(&arg);
		break;
	    }
	    val = get_map_lvalue(m, &arg, 1);
	    free_svalue(&arg);

	    if (!restore_one(val, str) ||
		*(*str)++ != ',')
		break;
	}
    }
    free_mapping(m);
    return 0;
}
예제 #6
0
/*
 * Save an object to a mapping.
 */
struct mapping *
m_save_object(struct object *ob)
{
    int i, j;
    struct mapping *ret;
    struct svalue s = const0;
    
    if (ob->flags & O_DESTRUCTED)
	return allocate_map(0);	/* XXX is this right /LA */

    ret = allocate_map((short)(ob->prog->num_variables +
			       ob->prog->inherit[ob->prog->num_inherited - 1].
			       variable_index_offset));
    
    for (j = 0; j < (int)ob->prog->num_inherited; j++)
    {
	struct program *prog = ob->prog->inherit[j].prog;
	if (ob->prog->inherit[j].type & TYPE_MOD_SECOND ||
	    prog->num_variables == 0)
	    continue;
	for (i = 0; i < (int)prog->num_variables; i++)
	{
	    struct svalue *v =
		&ob->variables[i + ob->prog->inherit[j].
			       variable_index_offset];
	    
	    if (prog->variable_names[i].type & TYPE_MOD_STATIC)
		continue;
	    free_svalue(&s);
	    s.type = T_STRING;
	    s.string_type = STRING_MSTRING;
	    s.u.string = make_mstring(prog->variable_names[i].name);
	    assign_svalue(get_map_lvalue(ret, &s, 1), v);
	}
    }
    
    free_svalue(&s);
    return ret;
}
예제 #7
0
void 
restore_map(struct object *ob, struct mapping *map, char *file)
{
    char *name, *buff, *space;
    size_t len;
    FILE *f;
    struct object *save = current_object;
    struct stat st;

    if (current_object != ob)
	fatal("Bad argument to restore_map()\n");
    if (ob->flags & O_DESTRUCTED)
	return;

    file = check_valid_path(file, ob, "restore_map", 0);
    if (file == 0)
	error("Illegal use of restore_map()\n");

    len = strlen(file);
    name = alloca(len + 2 + 1);
    (void)strcpy(name, file);
    if (name[len-2] == '.' && name[len-1] == 'c')
	name[len-1] = 'o';
    else
	(void)strcat(name, ".o");
    f = fopen(name, "r");
    if (s_flag)
	num_fileread++;
    if (!f || fstat(fileno(f), &st) == -1) {
	if (f) 
	    (void)fclose(f);
	return;
    }
    if (st.st_size == 0) {
	(void)fclose(f);
	return;
    }
    buff = xalloc((size_t)st.st_size + 1);
    
    for (;;) {
	struct svalue v;

	v.type = T_STRING;
	v.string_type = STRING_MSTRING;

	if (fgets(buff, (int)st.st_size + 1, f) == 0)
	    break;
	/* Remember that we have a newline at end of buff ! */
	space = strchr(buff, ' ');
	if (space == 0) {
	    (void)fclose(f);
	    free(buff);
	    error("Illegal format when restoring %s.\n", file);
	}
	*space++ = '\0';
	v.u.string = make_mstring(buff);
	
	if (!restore_one(get_map_lvalue(map,&v,1), &space)) {
	    (void)fclose(f);
	    free(buff);
	    free_svalue(&v);
	    error("Illegal format when restoring %s.\n", file);
	}
	free_svalue(&v);
    }
    current_object = save;
    free(buff);
    (void)fclose(f);
}
예제 #8
0
파일: pkg-odbc.c 프로젝트: Fuchur/ldmud
/*************************************************************************
 * f_sql_odbc_datasources( void )
 *
 * returns a mapping of all defined datasources.
 * ([ name : description ])
 *************************************************************************/
svalue_t *
f_sql_odbc_datasources( svalue_t * argv, int argc )
{
#if ODBC_DEBUG & DEBUG_FUNC
   printf( "call f_sql_odbc_datasources( )\n" );
#endif
   SQLRETURN   ret;
   
   char        * err;
   
   char        dsName[ 256 ],
               dsDescription[ 256 ];
   SQLSMALLINT dsNameLen,
               dsDescriptionLen;
   
   mapping_t   * map;
   svalue_t    * key;
   svalue_t    * value;

   argv++;

   err = init_odbc_environment();
   if ( err ) {
      errorf( err );
      return( NULL );
   }
   
   map = allocate_mapping( 0, 1 );
   MEM_CHECK( map );
   
   do {
      ret = SQLDataSources( hODBCEnv->hODBCEnv, SQL_FETCH_NEXT, dsName, 256, &dsNameLen,
                                                                dsDescription, 256, &dsDescriptionLen );
      if ( SQL_SUCCEEDED( ret ) ) {
         key = pxalloc( sizeof( svalue_t ) );
         put_malloced_string( key, string_copy( dsName ) );

         value = get_map_lvalue( map, key ); 
         MEM_CHECK( value );

         put_malloced_string( value, string_copy( dsDescription ) );
      }
      
   } while( SQL_SUCCEEDED( ret ) );

   if ( ret != SQL_NO_DATA ) {
      char * err;
      err = extract_diagnostics_info( SQL_HANDLE_ENV, hODBCEnv->hODBCEnv );

      free_mapping( map );

      errorf( (err?err:"Failed to fetch datasource information.\n") );
      return( NULL );
   }

   put_mapping( argv, map );
   
#if ODBC_DEBUG & DEBUG_FUNC
   printf( "ret f_sql_odbc_datasources( )\n" );
#endif
   return( argv );
}
예제 #9
0
파일: pkg-psyc.c 프로젝트: jomat/ldmud
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 */