Exemple #1
0
/************************************************************************* 
 * f_sql_handles( void ) 
 *
 * returns an array containing the IDs of the currently opened connections
 *************************************************************************/
svalue_t *
f_sql_handles( svalue_t * argv, int argc )
{
#if ODBC_DEBUG & DEBUG_FUNC
   printf( "call f_sql_handles( )\n" );
#endif
   int  cnt, i;
   hDBC * tmp;

   vector_t    * vec;

   argv++;
   
   if ( !hODBCEnv )
      init_odbc_environment();
  
   if ( !hODBCEnv ) {
      put_number( argv, 0 );
      return( argv );
   }
   
   if ( !hODBCEnv->hDBCons ) {

      vec = allocate_array( 0 );
      MEM_CHECK( vec );

      put_array( argv, vec );
      return( argv );
   }

   tmp = hODBCEnv->hDBCons;
   cnt = 1;

   while( (tmp = tmp->next ) )
      cnt++;

   vec = allocate_array( cnt );
   MEM_CHECK( vec );

   tmp = hODBCEnv->hDBCons;
   for ( i = 0; i < cnt; ++i ) {
      put_number( vec->item + i, tmp->ID );
      tmp = tmp->next;
   }

   put_array( argv, vec );
#if ODBC_DEBUG & DEBUG_FUNC
   printf( "ret f_sql_handles( )\n" );
#endif
   return( argv );
}
Exemple #2
0
void Options::Flush() const {
	json::Object obj_out;

	for (auto const& ov : values) {
		switch (ov.second->GetType()) {
			case OptionValue::Type_String:
				put_option(obj_out, ov.first, ov.second->GetString());
				break;

			case OptionValue::Type_Int:
				put_option(obj_out, ov.first, ov.second->GetInt());
				break;

			case OptionValue::Type_Double:
				put_option(obj_out, ov.first, ov.second->GetDouble());
				break;

			case OptionValue::Type_Color:
				put_option(obj_out, ov.first, ov.second->GetColor().GetRgbFormatted());
				break;

			case OptionValue::Type_Bool:
				put_option(obj_out, ov.first, ov.second->GetBool());
				break;

			case OptionValue::Type_List_String:
				put_array(obj_out, ov.first, "string", ov.second->GetListString());
				break;

			case OptionValue::Type_List_Int:
				put_array(obj_out, ov.first, "int", ov.second->GetListInt());
				break;

			case OptionValue::Type_List_Double:
				put_array(obj_out, ov.first, "double", ov.second->GetListDouble());
				break;

			case OptionValue::Type_List_Color:
				put_array(obj_out, ov.first, "color", ov.second->GetListColor());
				break;

			case OptionValue::Type_List_Bool:
				put_array(obj_out, ov.first, "bool", ov.second->GetListBool());
				break;
		}
	}

	json::Writer::Write(obj_out, io::Save(config_file).Get());
}
Exemple #3
0
void f_db_fetch (void)
{
	db_t *db;
	array_t *ret;

	valid_database("fetch", &the_null_array);

	db = find_db_conn((sp-1)->u.number);
	if (!db) {
		error("Attempt to fetch from an invalid database handle\n");
	}

	if (db->type->fetch) {
		ret = db->type->fetch(&(db->c), sp->u.number);
	} else {
		ret = &the_null_array;
	}

	pop_stack();
	if (!ret) {
		if (db->type->error) {
			char *errormsg;

			errormsg = db->type->error(&(db->c));
			put_malloced_string(errormsg);
		} else {
			sp->u.number = 0;
		}
	} else {
		put_array(ret);
	}
}
Exemple #4
0
/*-------------------------------------------------------------------------*/
void
finalize_arraylist (svalue_t * list)

/* Turn the arraylist in <list> into a proper array.
 */
{
    arraylist_t * data = (arraylist_t *) list->u.lvalue;
    arraylist_element_t * element;
    vector_t * result;
    svalue_t * item;

    result = allocate_array(data->num);

    element = data->first;
    item = result->item;

    while (element)
    {
        arraylist_element_t * temp = element;

        *item = element->value;

        item++;
        element = element->next;
        xfree(temp);
    }

    xfree(data);
    put_array(list, result);
} /* finalize_arraylist() */
Exemple #5
0
/*************************************************************************
 * f_sql_column_names( int handle )                                      
 *
 * returns the returned column names of the last executed statement
 *************************************************************************/
svalue_t *
f_sql_column_names( svalue_t * argv, int argc )
{
#if ODBC_DEBUG & DEBUG_FUNC
   printf( "call f_sql_column_names( )\n" );
#endif
   int  id, cnt, i;
   hDBC * handle;

   vector_t    * vec;

   TYPE_TEST1( argv, T_NUMBER );
   id = argv->u.number;
   free_svalue( argv );

   if ( !(handle = get_db_connection_by_id( id )) ) {
      errorf( "Illegal handle for database.\n" );

      return( NULL );
   }

   if ( !handle->columns ) {

      vec = allocate_array( 0 );
      MEM_CHECK( vec );

      put_array( argv, vec );
      return( argv );
   }

   cnt = handle->colcnt;

   vec = allocate_array( cnt );
   MEM_CHECK( vec );

   for ( i = 0; i < cnt; ++i ) {
      if ( handle->columns[ i ] )
         put_malloced_string(vec->item + i, string_copy(  handle->columns[ i ]->name ) );
   }

   put_array( argv, vec );
#if ODBC_DEBUG & DEBUG_FUNC
   printf( "ret f_sql_column_names( )\n" );
#endif
   return( argv );
}
int put_game_state(FILE *fout)
{
    if (game_state)
    {
        /* Write the view and tilt state. */

        put_float(fout, &game_rx);
        put_float(fout, &game_rz);
        put_array(fout,  view_c, 3);
        put_array(fout,  view_p, 3);

        /* Write the game simulation state. */

        put_file_state(fout, &file);

        return 1;
    }
    return 0;
}
Exemple #7
0
/*-------------------------------------------------------------------------*/
svalue_t *
f_tls_query_connection_info (svalue_t *sp)

/* EFUN tls_query_connection_info()
 *
 *
 *       #include <sys/tls.h>
 *       int *tls_query_connection_info (object ob)
 *
 * If <ob> does not have a TLS connection, or if the TLS connection is
 * still being set up, the efun returns 0.
 *
 * If <ob> has a TLS connection, tls_query_connection_info() returns an array
 * that contains some parameters of <ob>'s connection:
 *
 *    int|string [TLS_CIPHER]: the cipher used
 *    int        [TLS_COMP]:   the compression used
 *    int        [TLS_KX]:     the key-exchange used
 *    int        [TLS_MAC]:    the digest algorithm used
 *    int|string [TLS_PROT]:   the protocol used
 *
 * To translate these numbers into strings, <tls.h> offers a number of macros:
 *
 *    TLS_xxx_TABLE: a literal array of strings describing the value in
 *        question.
 *    TLS_xxx_NAME(x): a macro translating the numeric result value into a
 *        string.
 *
 *    xxx: CIPHER, COMP, KX, MAC, PROT
 */

{
    interactive_t *ip;

    if (O_SET_INTERACTIVE(ip, sp->u.ob) && ip->tls_status == TLS_ACTIVE)
    {
        vector_t * rc;
	
        rc = tls_query_connection_info(ip);
        free_svalue(sp);
        put_array(sp, rc);
    }
    else
    {
        free_svalue(sp);
        put_number(sp, 0);
    }

    return sp;
} /* tls_query_connection_info() */
Exemple #8
0
void f_str_to_arr(){
  static struct translation *newt = 0;
  if(!newt){
    newt = get_translator("UTF-32");
    translate_easy(newt->outgoing, " ");
  }
  int len;
  int *trans = (int *)translate(newt->outgoing, sp->u.string, SVALUE_STRLEN(sp)+1, &len);
  len/=4;
  array_t *arr = allocate_array(len);
  while(len--)
    arr->item[len].u.number = trans[len];
  free_svalue(sp, "str_to_arr");
  put_array(arr);
}
Exemple #9
0
/*-------------------------------------------------------------------------*/
static vector_t *
single_struct_info (struct_type_t * st, Bool include_base)

/* Create the struct_info() result array for a single struct and return it.
 * If <include_base> is TRUE, all members defined in a possible base
 * struct are included as if they were top-level members.
 */

{
    vector_t * rc;
    size_t offset;
    size_t i;

    offset = 0;
    if (!include_base && st->base != NULL)
        offset = struct_t_size(st->base);
    rc = allocate_array(struct_t_size(st) - offset + SI_MAX);
    put_ref_string(&rc->item[SI_NAME], struct_t_name(st));
    put_ref_string(&rc->item[SI_PROG_NAME], struct_t_pname(st));
    put_number(&rc->item[SI_PROG_ID], st->prog_id);
    for (i = offset; i < struct_t_size(st); i++)
    {
        vector_t * member;
        struct_member_t * pMember;

        pMember = &st->member[i];

        member = allocate_array(SIM_MAX);
        put_array(&rc->item[SI_MEMBER+i-offset], member);
        put_ref_string(&member->item[SIM_NAME], pMember->name);
        put_number(&member->item[SIM_TYPE], 0); /* TODO: Convert pMember->type to int */

        if (pMember->type->t_class == TCLASS_STRUCT)
            put_ref_string(&member->item[SIM_EXTRA]
                          , pMember->type->t_struct.name->name
                          );
    }

    return rc;
} /* single_struct_info() */
Exemple #10
0
/*-------------------------------------------------------------------------*/
svalue_t *
f_tls_check_certificate(svalue_t *sp)

/* EFUN tls_check_certificate()
 *
 *   mixed *tls_check_certificate(object obj);
 *   mixed *tls_check_certificate(object obj, int extra);
 * 
 * tls_check_certificate() checks the certificate of the secured
 * connection bound to <obj> (default is the current object).  If
 * <obj> is not interactive, or if TLS is not available, an error
 * is thrown.
 * 
 * If <obj> doesn't have a secure connection up and running, an
 * error is thrown.
 * Otherwise, the result is an array with these values:
 * 
 *   int [0]      : Result code of SSL_get_verify_result (see man 1 verify
 *                  subsection DIAGNOSTICS for possible values)
 *   array [1]          : array with 3*n entries of extra x509 data.
 *                       structure is:
 *                       3*i    : numerical form of object name, e.g. "2.5.4.3"
 *                       3*i + 1: long or short name if available, e.g. "commonName"
 *                       3*i + 2: value
 *   array [2]          : if extra is set:
 *                       array with 3*n entries of x509 extension data
 *                       data structure is:
 *                       3*i    : numerical form of extension name
 *                       3*i + 1: long or short name of extension name if available
 *                       3*i + 2: array of strings with the data structure of [1]
 *
 * Note: a x509 certificate can have more than one object with the same name
 *
 * See associated documentation for code that generates more convient mapping
 * data structures
 */

{
    vector_t *v = NULL;
    interactive_t *ip;
    int more;

    /* more information requested */
    more = sp->u.number;
    free_svalue(sp--);

    if (!tls_available())
        errorf("tls_check_certificate(): TLS layer hasn't been initialized.\n");

    if (!O_SET_INTERACTIVE(ip, sp->u.ob))
        errorf("Bad arg 1 to tls_check_certificate(): "
              "object not interactive.\n");

    if (ip->tls_status != TLS_ACTIVE) 
        errorf("tls_check_certificate(): object doesn't have a secure connection.\n");

    if (more < 0 || more > 1)
        errorf("tls_check_certificate(): invalid flag passed as second argument.\n");

    v = tls_check_certificate(ip, (more == 1) ? MY_TRUE : MY_FALSE);

    free_svalue(sp);

    if (v != NULL)
        put_array(sp, v);
    else
        put_number(sp, 0);
    return sp;
} /* tls_check_certificate() */
Exemple #11
0
svalue_t *
f_sql_fetch( svalue_t * argv, int argc )
{
#if ODBC_DEBUG & DEBUG_FUNC
   printf( "call f_sql_fetch( )\n" );
#endif
   int       id, method = 0;
   hDBC      * handle;

   SQLRETURN ret;
   
   STORE_DOUBLE_USED;

   switch( argc ) {
      case 2 :
         TYPE_TEST2( argv, T_NUMBER );
         method = argv->u.number;
         free_svalue( argv );
         argv--;
      case 1 :
         TYPE_TEST1( argv, T_NUMBER );
         id = argv->u.number;
         free_svalue( argv );
         break;
      default:
         errorf( "Too many arguments to sql_fetch().\n" );
         return( NULL );
   }
   
   if ( !(handle = get_db_connection_by_id( id )) ) {
      errorf( "Illegal handle for database.\n" );

      return( NULL );
   }

   if ( !handle->hStmt ) {
      put_number( argv, 0 );
      return( argv );
   }

   //printf( "\nFetching ....\n" );
   ret = SQLFetch( handle->hStmt );
   if ( ret == SQL_NO_DATA ) {
      //printf( "NO_DATA\n" );

      put_number( argv, 0 );
      return( argv );
      
   } else if ( !SQL_SUCCEEDED( ret ) ) {
       put_number( argv, 0 );
       return( argv );
   }

   if ( !handle->columns ) {
      put_number( argv, 0 );
      return( argv );
   }
   
   if ( !method ) { //fetch as array
      put_array( argv, fetch_into_vector( handle ) );
   } else { //fetch as mapping 
      put_mapping( argv, fetch_into_mapping( handle ) );
   }
   
#if ODBC_DEBUG & DEBUG_FUNC
   printf( "ret f_sql_fetch( )\n" );
#endif
   return( argv );
}
Exemple #12
0
/*-------------------------------------------------------------------------*/
svalue_t *
f_struct_info (svalue_t *sp)

/* EFUN struct_info()
 *
 *    mixed * struct_info(struct s, int type)
 *
 * Return an array with information about the struct <s>. The
 * type of information returned is determined by <type>.
 */

{
    struct_type_t *st;
    int rtype;
    svalue_t result;

    /* Get the arguments from the stack */
    st = sp[-1].u.strct->type;
    rtype = sp[0].u.number;
  
    /* Get the basic result information */
    put_array(&result, single_struct_info(st, rtype != SINFO_NESTED));

    if (st->base != NULL)
    {
        /* Depending on the <rtype> argument, determine the how to handle
         * the base structs (if any).
         */
        switch(rtype)
        {
        case SINFO_FLAT:
            put_ref_string(&result.u.vec->item[SI_BASE], struct_t_name(st->base));
            break;

        case SINFO_NESTED:
          {
            svalue_t *rc;

            for ( rc = &result.u.vec->item[SI_BASE], st = st->base
                ; st != NULL
                ; st = st->base, rc = &rc->u.vec->item[SI_BASE]
                )
            {
                put_array(rc, single_struct_info(st, MY_FALSE));
            }
            break;
                
          }
        default:
            free_svalue(&result);
            errorf("Bad arg 2 to struct_info(): illegal value %"PRIdPINT"\n"
                 , sp->u.number);
            /* NOTREACHED */
            return sp;
        }
    }

    free_svalue(sp); sp--; /* type */
    free_svalue(sp); /* struct */

    /* Assign the result */
    transfer_svalue_no_free(sp, &result);

    return sp;
} /* f_struct_info() */
Exemple #13
0
CORBA_boolean 
porbit_put_sv (GIOPSendBuffer *buf, CORBA_TypeCode tc, SV *sv)
{
    switch (tc->kind) {
    case CORBA_tk_null:
    case CORBA_tk_void:
        return CORBA_TRUE;
    case CORBA_tk_short:
	return put_short (buf, sv);
    case CORBA_tk_long:
	return put_long (buf, sv);
    case CORBA_tk_ushort:
	return put_ushort (buf, sv);
    case CORBA_tk_ulong:
	return put_ulong (buf, sv);
    case CORBA_tk_float:
	return put_float (buf, sv);
    case CORBA_tk_double:
	return put_double (buf, sv);
    case CORBA_tk_char:
	return put_char (buf, sv);
    case CORBA_tk_boolean:
	return put_boolean (buf, sv);
    case CORBA_tk_octet:
	return put_octet (buf, sv);
    case CORBA_tk_enum:
	return put_enum (buf, tc, sv);
    case CORBA_tk_struct:
	return put_struct (buf, tc, sv);
    case CORBA_tk_sequence:
	return put_sequence (buf, tc, sv);
    case CORBA_tk_except:
	return put_except (buf, tc, sv);
    case CORBA_tk_objref:
	return put_objref (buf, tc, sv);
    case CORBA_tk_union:
	return put_union (buf, tc, sv);
    case CORBA_tk_alias:
	return put_alias (buf, tc, sv);
    case CORBA_tk_string:
	return put_string (buf, tc, sv);
    case CORBA_tk_array:
	return put_array (buf, tc, sv);
    case CORBA_tk_longlong:
	return put_longlong (buf, sv);
    case CORBA_tk_ulonglong:
	return put_ulonglong (buf, sv);
    case CORBA_tk_longdouble:
	return put_longdouble (buf, sv);
    case CORBA_tk_TypeCode:
	return put_typecode (buf, tc, sv);
    case CORBA_tk_any:
	return put_any (buf, tc, sv);
    case CORBA_tk_fixed:
	return put_fixed (buf, tc, sv);
    case CORBA_tk_wchar:
    case CORBA_tk_wstring:
    case CORBA_tk_Principal:
    default:
	warn ("Unsupported output typecode %d\n", tc->kind);
	return CORBA_FALSE;
    }
}
Exemple #14
0
/*-------------------------------------------------------------------------*/
svalue_t * 
v_sl_exec (svalue_t * sp, int num_arg) 

/* EFUN sl_exec()
 *
 *   mixed* sl_exec(string statement, ...)
 *
 * Executes the SQL statement <statement> for the current
 * SQLite database. The SQL statement may contain wildcards like
 * '?' and '?nnn', where 'nnn' is an integer. These wildcards
 * can be given as further parameters to sl_exec. With '?nnn'
 * the number of a specific parameter can be given, the first
 * parameter has number 1.
 * 
 * If the statement returns data, sl_exec returns an array
 * with each row (which is itself an array of columns) as 
 * an element.
 */

{
    svalue_t *argp;
    sqlite_dbs_t *db;
    sqlite3_stmt *stmt;
    const char* tail;
    int err, rows, cols, num;
    struct sl_exec_cleanup_s * rec_data;
    vector_t * result;

    argp = sp - num_arg + 1; /* First argument: the SQL query */
    
    db = find_db (current_object);
    if (!db)
        errorf("The current object doesn't have a database open.\n");
    
    err = sqlite3_prepare(db->db, get_txt(argp->u.str), mstrsize(argp->u.str),
        &stmt, &tail);
    if(err)
    {
        const char* msg = sqlite3_errmsg(db->db);
        if(stmt)
            sqlite3_finalize(stmt);
        errorf("sl_exec: %s\n", msg);
        /* NOTREACHED */
    }
    
    /* Now bind all parameters. */
    for(argp++, num=1; argp <= sp; argp++, num++)
    {
        switch(argp->type)
        {
        default:
            sqlite3_finalize(stmt);
            errorf("Bad argument %d to sl_exec(): type %s\n",
                num+1, typename(argp->type));
            break; /* NOTREACHED */

        case T_FLOAT:
            sqlite3_bind_double(stmt, num, READ_DOUBLE(argp));
            break;

        case T_NUMBER:
            if (sizeof(argp->u.number) > 4)
                sqlite3_bind_int64(stmt, num, argp->u.number);
            else
                sqlite3_bind_int(stmt, num, argp->u.number);
            break;
    
        case T_STRING:
            sqlite3_bind_text(stmt, num, get_txt(argp->u.str),
                mstrsize(argp->u.str), SQLITE_STATIC);
            break;
        }
    }
    
    rows = 0;
    cols = sqlite3_column_count(stmt);

    rec_data = xalloc(sizeof(*rec_data));
    if(!rec_data)
    {
        sqlite3_finalize(stmt);
        errorf("(sl_exec) Out of memory: (%lu bytes) for cleanup structure\n",
            (unsigned long) sizeof(*rec_data));
    }
    rec_data->rows = NULL;
    rec_data->stmt = stmt;
    
    sp = push_error_handler(sl_exec_cleanup, &(rec_data->head));
    
    while((err = sqlite3_step(stmt)) == SQLITE_ROW)
    {
        int col;
        sqlite_rows_t *this_row;

        rows++;
        this_row = pxalloc(sizeof(*this_row));
        if(!this_row)
            errorf("(sl_exec) Out of memory: (%lu bytes)\n",
                (unsigned long) sizeof(*this_row));

        this_row->last = rec_data->rows;
        rec_data->rows = this_row;
        this_row->row = NULL; /* Because allocate_array may throw an error. */

        this_row->row = allocate_array(cols);
        if(!this_row->row)
            errorf("(sl_exec) Out of memory: row vector\n");
    
        for(col = 0; col < cols; col++)
        {
            svalue_t * entry;
            STORE_DOUBLE_USED;

            entry = this_row->row->item + col;

            switch(sqlite3_column_type(stmt, col))
            {
            default:
                errorf( "sl_exec: Unknown type %d.\n"
                      , sqlite3_column_type(stmt, col));
                break;

            case SQLITE_BLOB:
                errorf("sl_exec: Blob columns are not supported.\n");
                break;

            case SQLITE_INTEGER:
                if (sizeof(entry->u.number) >= 8)
                    put_number(entry, sqlite3_column_int64(stmt, col));
                else
                    put_number(entry, sqlite3_column_int(stmt, col));
                break;

           case SQLITE_FLOAT:
                entry->type = T_FLOAT;
                STORE_DOUBLE(entry, sqlite3_column_double(stmt, col));
                break;

            case SQLITE_TEXT:
                put_c_n_string( entry
                              , (char *)sqlite3_column_text(stmt, col)
                              , sqlite3_column_bytes(stmt, col));
                break;

            case SQLITE_NULL:
                /* All elements from this_row->row are initialized to 0. */
                break;
            }
        }
    }

    sqlite3_finalize(stmt);
    rec_data->stmt = NULL;
    
    switch(err)
    {
    default:
        errorf("sl_exec: Unknown return code from sqlite3_step: %d.\n", err);
        break;

    case SQLITE_BUSY:
        errorf("sl_exec: Database is locked.\n");
        break;

    case SQLITE_ERROR:
        errorf("sl_exec: %s\n", sqlite3_errmsg(db->db));
        break;

    case SQLITE_MISUSE:
        errorf("sl_exec: sqlite3_step was called inappropriately.\n");
        break;

    case SQLITE_DONE:
        break;
    }

    if(rows)
    {
        sqlite_rows_t *this_row;

        result = allocate_array(rows);
        if(!result)
            errorf("(sl_exec) Out of memory: result vector\n");

        this_row = rec_data->rows;
        while(rows--)
        {
            put_array(result->item + rows, this_row->row);
            this_row->row = NULL;
            this_row = this_row->last;
        }
    }
    else
        result = NULL;

    // Pop arguments and our error handler.
    // Our error handler gets called and cleans the row stuff.
    sp = pop_n_elems(num_arg + 1, sp) + 1; 
 
    if(rows)
        put_array(sp,result);
    else
        put_number(sp, 0);

    return sp;
} /* v_sl_exec() */
Exemple #15
0
/*-------------------------------------------------------------------------*/
svalue_t *
f_get_error_file (svalue_t *sp)

/* EFUN get_error_file()
 *
 *   mixed * get_error_file(string name, int set_forget_flag)
 *
 * Return information about the last error which occured for
 * <name> (where <name> is a valid name from the wiz list).
 *
 * Result is an array of four elements: the filename of the
 * program where the error occured, the linenumber in the
 * program, the error message (runtime error messages usually
 * start with a '*'), and a numerical flag (the 'forget flag') if
 * the error information has been queried already.
 *
 * If there is no error stored for the given <name>, 0 is
 * returned.
 *
 * If <set_forget_flag> is non-zero, the 'forget' flag is set
 * for the error message after it has been returned.
 */

{
    string_t *name;
    int forget;
    wiz_list_t *wl;
    vector_t *vec;
    svalue_t *v;
#   define FORGET_FLAG 0x4000000 /* 0x80...0 would be the sign! */

    /* Get the function arguments */
    name = sp[-1].u.str;
    forget = sp->u.number;
    wl = find_wiz(name);
    sp--;
    free_string_svalue(sp);

    /* The error_message is used as a flag if there has been any error.
     */
    if (!wl || !wl->error_message)
    {
        put_number(sp, 0);
        return sp;
    }

    vec = allocate_array(4);
    v = vec->item;
    put_ref_string(v, wl->file_name);
    put_number(v+1, wl->line_number & ~0x40000000);
    put_ref_string(v+2, wl->error_message);
    put_number(v+3, (wl->line_number & 0x40000000) != 0);

    if (forget)
        wl->line_number |= 0x40000000;

    put_array(sp, vec);
    return sp;

#   undef FORGET_FLAG
} /* f_get_error_file() */
Exemple #16
0
/* FIXME: most of the #ifdefs here should be based on configure checks
   instead.  Same for rusage() */
void
f_localtime (void)
{
    struct tm *tm;
    array_t *vec;
    time_t lt;

#ifdef sequent
    struct timezone tz;
#endif

    lt = sp->u.number;
    tm = localtime(&lt);

    vec = allocate_empty_array(11);
    vec->item[LT_SEC].type = T_NUMBER;
    vec->item[LT_SEC].u.number = tm->tm_sec;
    vec->item[LT_MIN].type = T_NUMBER;
    vec->item[LT_MIN].u.number = tm->tm_min;
    vec->item[LT_HOUR].type = T_NUMBER;
    vec->item[LT_HOUR].u.number = tm->tm_hour;
    vec->item[LT_MDAY].type = T_NUMBER;
    vec->item[LT_MDAY].u.number = tm->tm_mday;
    vec->item[LT_MON].type = T_NUMBER;
    vec->item[LT_MON].u.number = tm->tm_mon;
    vec->item[LT_YEAR].type = T_NUMBER;
    vec->item[LT_YEAR].u.number = tm->tm_year + 1900;
    vec->item[LT_WDAY].type = T_NUMBER;
    vec->item[LT_WDAY].u.number = tm->tm_wday;
    vec->item[LT_YDAY].type = T_NUMBER;
    vec->item[LT_YDAY].u.number = tm->tm_yday;
    vec->item[LT_GMTOFF].type = T_NUMBER;
    vec->item[LT_ZONE].type = T_STRING;
    vec->item[LT_ZONE].subtype = STRING_MALLOC;
    vec->item[LT_ISDST].type = T_NUMBER;
#if defined(BSD42) || defined(apollo) || defined(_AUX_SOURCE) \
        || defined(OLD_ULTRIX)
    /* 4.2 BSD doesn't seem to provide any way to get these last three values */
    vec->item[LT_GMTOFF].u.number = 0;
    vec->item[LT_ZONE].type = T_NUMBER;
    vec->item[LT_ZONE].u.number = 0;
    vec->item[LT_ISDST].u.number = -1;
#else                           /* BSD42 */
    vec->item[LT_ISDST].u.number = tm->tm_isdst;
#if defined(sequent)
    vec->item[LT_GMTOFF].u.number = 0;
    gettimeofday(NULL, &tz);
    vec->item[LT_GMTOFF].u.number = tz.tz_minuteswest;
    vec->item[LT_ZONE].u.string =
        string_copy(timezone(tz.tz_minuteswest, tm->tm_isdst), "f_localtime");
#else                           /* sequent */
#if (defined(hpux) || defined(_SEQUENT_) || defined(_AIX) || defined(SunOS_5) \
        || defined(SVR4) || defined(sgi) || defined(linux) || defined(cray) \
        || defined(LATTICE) || defined(SCO))
    if (!tm->tm_isdst) {
        vec->item[LT_GMTOFF].u.number = timezone;
        vec->item[LT_ZONE].u.string = string_copy(tzname[0], "f_localtime");
    } else {
#if (defined(_AIX) || defined(hpux) || defined(linux) || defined(cray) \
        || defined(LATTICE))
        vec->item[LT_GMTOFF].u.number = timezone;
#else
        vec->item[LT_GMTOFF].u.number = altzone;
#endif
        vec->item[LT_ZONE].u.string = string_copy(tzname[1], "f_localtime");
    }
#else
#ifndef WIN32
    vec->item[LT_GMTOFF].u.number = tm->tm_gmtoff;
    vec->item[LT_ZONE].u.string = string_copy(tm->tm_zone, "f_localtime");
#else
    vec->item[LT_GMTOFF].u.number = _timezone;
    vec->item[LT_ZONE].u.string = string_copy(_tzname[_daylight?1:0],"f_localtime");
#endif
#endif
#endif                          /* sequent */
#endif                          /* BSD42 */
    put_array(vec);
}
Exemple #17
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 */
Exemple #18
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() */
Exemple #19
0
void HASH_put_array(hash_t *hash, const char *key, const dynvec_t dynvec){
  put_array(hash, key, 0, dynvec);
}
int main(int argc, char *argv[]) {
	char endServer[100];
    int fd,fdx, novofd,nbytes,j,fdmax;
    struct sockaddr_in addr, client_addr, serverdei;
    int client_addr_size;
    struct hostent *hostPtr;
    char buffer[BUF_SIZE];
    int clientes_fd[MAX];// array com o fds dos clientes
    if (argc != 4) {
    printf("cliente  <port> <nome servidor central> <Porto servidor central>\n");
    exit(-1);
  }
    fd_set master;  // descritor de arquivo mestre
    fd_set ler_fds;    //  descritor de arquivo para temporario
	FD_ZERO(&master);   //limpa os conjuntos mestre e temporário
    FD_ZERO(&ler_fds);
    int yes=1;
  
	
	bzero((void *) &addr, sizeof(addr));
    addr.sin_family      = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port        = htons((short) atoi(argv[1]));
    
	
    if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
	erro("na funcao socket");
	
	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (int)) == -1) {

            perror ("setsockopt");
            exit (1);
        }
	
    if ( bind(fd,(struct sockaddr*)&addr,sizeof(addr)) < 0)
	erro("na funcao bind");
    if( listen(fd, MAX) < 0) //servidor a escuta de max clientes
	erro("na funcao listen");
		FD_SET(fd, &master);

	clientes_fd[0]=fd;
	fdmax=fd;
	
	
	
  strcpy(endServer, argv[2]);
  
  if ((hostPtr = gethostbyname(endServer)) != 0) {
    bzero((void *) &addr, sizeof(addr));
	serverdei.sin_family = AF_INET;
	serverdei.sin_addr.s_addr = *((unsigned long*) hostPtr->h_addr_list[0]);
	serverdei.sin_port = htons((short) atoi(argv[3]));
	
	printf("entrei"); //sucesso
	
	if((fdx = socket(AF_INET,SOCK_STREAM,0)) == -1)
	erro("socket2");
	printf("%s",hostPtr->h_addr);
  if( connect(fdx,(struct sockaddr *)&serverdei,sizeof (serverdei))< 0) //liga ao servidor do dei
	erro("Connect2");
	
	FD_SET(fdx, &master);

	clientes_fd[put_array(clientes_fd)]=fdx;
	fdmax=fdx;
	
  }


	while(1){
			
            ler_fds = master; // copia os master para o temporario
            
            if (select (fdmax+1,  &ler_fds, NULL, NULL, NULL)== -1) {
                
                perror ("select");
                exit(1);
            }

            int i;// percorre as conexões existentes em busca de dados
            for ( i = 0; i <=fdmax; i++) {
        
                if  ( FD_ISSET ( i,  &ler_fds))  { 
                    
                    if ( i == clientes_fd[0]) {
                     
                        //trata novas conexões
                       client_addr_size = sizeof(client_addr);
                        
                        if (( novofd = accept(fd,(struct sockaddr *)&client_addr, &client_addr_size)) == -1)  {
                            perror ("accept");
                        } else {
                            FD_SET ( novofd , &master);//adiciona ao mestre
                            char print[150]="->";
							char t[5];
							
							strcat(print,"servidor : nova conexão de ");
							strcat(print, inet_ntoa(client_addr.sin_addr));
							strcat(print," no  socket ");
							sprintf(t, "%d", novofd);
							strcat(print, t);
							strcat(print, "\n");
							
							for (j = 0; j<MAX; j++)  {
                                
                                //envia a todos os clientes
                                if (FD_ISSET (j, &master)) {
                                    // exceto a nós e ao socket em escuta
                                  
                                    if (j != fd &&j != novofd) {
                                         if (write(j,print,strlen(print)) == -1) {
                                        perror ("write");
                                       
                            }}}}
                            print[0]='\0';
                            
                            if(fdmax<novofd){
								fdmax=novofd;
								novofd=0;
							}
							clientes_fd[put_array(clientes_fd)]=novofd;
							
                        
                    }} else {

                        // cuida dos dados do cliente
                      
                           if  ( (nbytes=(read (i, buffer, BUF_SIZE-1)))>= 0) {
                            
                            // recebeu erro ou a conexão foi fechada pelo cliente
                            if (nbytes == 0) {
								char printR[150]="->";
								char p[5];
								strcat(printR,"servidor : o Cliente foi desligado ");
								strcat(printR, inet_ntoa(client_addr.sin_addr));
								strcat(printR," no  socket ");
								sprintf(p, "%d", i);
								strcat(printR, p);
								strcat(printR, "\n");
							
								for (j = 0; j<MAX; j++)  {
                                
                                //envia a todos os clientes
									if (FD_ISSET (j, &master)) {
                                    // exceto a nós e ao socket em escuta
                                  
										if (j != fd &&j != novofd) {
											if (write(j,printR,strlen(printR)) == -1) {
											perror ("write");
                                       
                            }}}}
                            printR[0]='\0';
                                FD_CLR( i , &master); // remove do conjunto mestre
                                search(clientes_fd, i);
                            } else if(nbytes==-1) {
                                perror ("read"); 
                            }
                           
                        }
                        strcat(buffer, "\n");
                            // temos alguns dados do cliente
                            for (j = 0; j<MAX; j++)  {
                                
                                //envia a todos os clientes
                                if (FD_ISSET (j, &master)) {
                                    // exceto a nós e ao socket em escuta
                                  
                                    if (j != fd &&j!=i ) {
                                         if (write(j,buffer,nbytes) == -1) {
                                        perror ("write");
                                         }
                                    }
                                }
                            }
                        }
                    } 
                }
            }
       
    
  
  return 0;
}
Exemple #21
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() */
Exemple #22
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() */
Exemple #23
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() */
Exemple #24
0
void HASH_put_array_at(hash_t *hash, const char *key, int i, const dynvec_t val){
  put_array(hash, key, i, val);
  int new_size = i+1;
  if(new_size>hash->num_array_elements)
    hash->num_array_elements = new_size;
}
Exemple #25
0
/*-------------------------------------------------------------------------*/
wiz_list_t *
add_name (string_t * str)

/* Check if an entry for wizard <str> exists; add it, if it doesn't.
 * Return the pointer to the wiz_list entry.
 * Must not change refcount of <str>.
 */

{
    wiz_list_t *wl;
    wiz_list_t *prev, *this;

    wl = find_wiz(str);
    if (wl)
        return wl;

    number_of_wiz++;
    wl = xalloc(sizeof (wiz_list_t));

    str = make_tabled_from(str);

    wl->next           = NULL;
    wl->name           = str;
    wl->score          = 0;
    wl->cost           = 0;
    wl->gigacost       = 0;
    wl->total_cost     = 0;
    wl->total_gigacost = 0;
    wl->heart_beats    = 0;
    wl->size_array     = 0;
    wl->mapping_total  = 0;
#ifdef USE_STRUCTS
    wl->struct_total   = 0;
#endif /* USE_STRUCTS */
#if 0
    wl->quota_allowance = 0;
    wl->quota_usage   = 0;
#endif
    wl->file_name     = NULL;
    wl->error_message = NULL;
    if (wiz_info_extra_size >= 0)
        put_array(&(wl->extra), allocate_array(wiz_info_extra_size));
    else
        wl->extra = const0;
    wl->last_call_out = 0;

    /* Find the insertion point and insert the new entry */
    for ( prev = NULL, this = all_wiz
        ; this && mstrcmp(this->name, str) < 0
        ; prev = this, this = this->next
        )
    { NOOP; }

    if (!prev)
    {
        wl->next = all_wiz;
        all_wiz = wl;
    }
    else
    {
        wl->next = this;
        prev->next = wl;
    }

    return wl;
} /* add_name() */