コード例 #1
0
ファイル: gci_reginabridge.c プロジェクト: ErisBlastar/osfree
/*
 * GCI_Dispatcher is the entry point of all GCI registered functions by the
 * user.
 *
 * The function's arguments and return value depend on its usage from case
 * to case.
 */
int GCI_Dispatcher( tsd_t *TSD,
                    PFN func,
                    void *treeinfo,
                    int Params,
                    const PRXSTRING params,
                    PRXSTRING retstr )
{
   GCI_result rc;
   GCI_str disposition, direct_retval;
   GCI_str args[GCI_REXX_ARGS];
   int i, retval;

   /*
    * This trivial test should come first to be sure not to access nonexisting
    * memory. parseTree has fixed this number.
    */
   if ( Params > GCI_REXX_ARGS )
      GCIcode2ReginaFuncCode( TSD, GCI_InternalError, NULL, 1 );

   memset( args, 0, sizeof( args ) );
   for ( i = 0; i < Params; i++ )
      GCI_migrateRxString( &args[i], &params[i] );

   memset( &disposition, 0, sizeof( disposition ) );
   memset( &direct_retval, 0, sizeof( direct_retval ) );

   rc = GCI_execute( TSD,
                     (void (*)()) func,
                     (const GCI_treeinfo *) treeinfo,
                     Params,
                     args,
                     &disposition,
                     &direct_retval,
                     TSD->gci_prefix );

   if ( rc != GCI_OK )
   {
      GCI_strfree( TSD, &direct_retval ); /* not really needed hopefully */
      GCIcode2ReginaFuncCode( TSD, rc, &disposition, 1 );
   }

   retval = assignRxString( TSD, retstr, &direct_retval );
   GCI_strfree( TSD, &direct_retval );

   if ( retval )
      exiterror( ERR_STORAGE_EXHAUSTED, 0 );

   return 0;
}
コード例 #2
0
ファイル: gci_reginabridge.c プロジェクト: ErisBlastar/osfree
/*
 * Returns the translated function code from GCI_result to the code that
 * Regina shall return to the caller.
 * This function set the textual representation of an error code to that value
 * that will be accessed by RxFuncErrMsg() and sets the variable GCI_RC to
 * that value, too.
 *
 * dispo is either NULL (or the content is NULL) or contains the position of
 * the error within the structure. dispo's content will be deallocated.
 */
static int GCIcode2ReginaFuncCode( tsd_t *TSD,
                                   GCI_result rc,
                                   GCI_str *dispo,
                                   int forceError )
{
   GCI_str description, fullinfo, *fi = NULL, *out;
   volatile char *tmpDispo, *tmpFull = NULL, *tmpBest;
   streng *h;
   char GCI_RC[7];
   GCI_strOfCharBuffer(GCI_RC);

   GCI_strcats( &str_GCI_RC, "GCI_RC" );
   GCI_describe( &description, rc );

   if ( ( dispo != NULL ) && ( GCI_content( dispo ) == NULL ) )
      dispo = NULL;

   if ( ( dispo != NULL ) && ( rc != GCI_OK ) )
   {
      if ( GCI_stralloc( TSD, &fullinfo, GCI_strlen( dispo ) +
                                         GCI_strlen( &description ) +
                                         3 ) == GCI_OK )
      {
         fi = &fullinfo;
         GCI_strcpy( fi, &description );
         GCI_strcats( fi, ": " );
         GCI_strcat( fi, dispo );
      }
   }

   out = ( fi != NULL ) ? fi : &description;
   GCI_writeRexx( TSD, &str_GCI_RC, out, 0 );

   if ( ( rc == GCI_OK ) && !forceError )
   {
      if ( dispo != NULL )
         GCI_strfree( TSD, dispo );
      if ( fi != NULL )
         GCI_strfree( TSD, fi );
      return 0;
   }

   h = streng_of( TSD, &description );
   tmpDispo = tmpstr_of( TSD, h );
   Free_stringTSD( h );

   if ( fi != NULL )
   {
      h = streng_of( TSD, fi );
      tmpFull = tmpstr_of( TSD, h );
      Free_stringTSD( h );
   }

   if ( dispo != NULL )
      GCI_strfree( TSD, dispo );
   if ( fi != NULL )
      GCI_strfree( TSD, fi );

   /*
    * We have two temporary strings describing the error condition.
    * All stuff we have to deallocate is deallocated. Let's go.
    */
   tmpBest = ( tmpFull != NULL ) ? tmpFull : tmpDispo;
   set_err_message( TSD, (char *) tmpBest, "" );

   switch ( rc )
   {
      case GCI_NoMemory:
         exiterror( ERR_STORAGE_EXHAUSTED, 0 );

      case GCI_WrongInput:
         exiterror( ERR_INCORRECT_CALL, 980, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_NumberRange:
         exiterror( ERR_INCORRECT_CALL, 981, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_StringRange:
         exiterror( ERR_INCORRECT_CALL, 982, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_UnsupportedType:
         if ( !forceError )
            return 71; /* RXFUNC_BADTYPE + 1 */
         exiterror( ERR_INCORRECT_CALL, 983, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_UnsupportedNumber:
         exiterror( ERR_INCORRECT_CALL, 984, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_BufferTooSmall:
         exiterror( ERR_INCORRECT_CALL, 985, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_MissingName:
         exiterror( ERR_INCORRECT_CALL, 986, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_MissingValue:
         exiterror( ERR_INCORRECT_CALL, 987, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_IllegalName:
         exiterror( ERR_INCORRECT_CALL, 988, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_RexxError:
         exiterror( ERR_INCORRECT_CALL, 989, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_NoBaseType:
         exiterror( ERR_INCORRECT_CALL, 990, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_SyntaxError:
         exiterror( ERR_INCORRECT_CALL, 991, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_ArgStackOverflow:
         exiterror( ERR_INCORRECT_CALL, 992, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      case GCI_NestingOverflow:
         exiterror( ERR_INCORRECT_CALL, 993, ( tmpDispo ) ? ": " : "", ( tmpDispo ) ? tmpDispo : "" );

      default:
         break;
   }
   exiterror( ERR_INTERPRETER_FAILURE, 1, __FILE__, __LINE__, tmpBest );
   return 0; /* Keep the compiler happy */
}
コード例 #3
0
ファイル: gci_tree.c プロジェクト: jlfaucher/builder
/*
 * parse is the local implementation of GCI_parsetree below. Most parameters
 * are in *cb. Have a look at callblock at top of file or at GCI_parsestring
 * below.
 * itemnumber is the iterator of the container item or array item, the later
 * always has number 1.
 *
 * The function loops over a type structure tree, the current node name is
 * placed in cb->buffer. We do a depth-first iteration.
 *
 * Indirect array[x] are replaced by a combination of
 * indirect container[1], array[x]. This allows a better addressing later.
 * The indirect container is flagged as "generated" in this case.
 *
 * THE GENERATED TYPES MAY HAVE ILLEGAL BIT SIZES. IT ISN'T CHECKED ALWAYS!
 *
 * Return values:
 * GCI_OK:              Everything is fine.
 *
 *                      In case of an error cb->buffer will contain the
 *                      variable's name where the problem raises first.
 *
 * GCI_MissingName:     A variable's name isn't set. This is the equivalence
 *                      for GCI_MissingValue in the type parsing step. The
 *                      system may or may not raise a NOVALUE condition instead
 *                      depending on the implementation.
 * GCI_BufferTooSmall:  The variable's name buffer cb->buffer can't hold the
 *                      complete variable's name or the type string exceeds
 *                      256 byte.
 * GCI_IllegalName:     The variables name in cb->buffer is illegal in terms of
 *                      Rexx. In general, the basename of GCI_paretree is
 *                      wrong.
 * GCI_RexxError:       An unexpected error is returned by the interpreter
 *                      while trying to access Rexx variables.
 * GCI_UnsupportedType: Wrong type of input, e.g. FLOAT31 or the empty string
 *                      in a type description string. Another reason is an
 *                      internal error since the default sizes for "unsigned"
 *                      and "integer" are not supported.
 * GCI_WrongInput:      Strange characters occur in the input string as the
 *                      bit size of the type.
 * GCI_NumberRange:     Number to small or big to fit into the desired type
 *                      with the desired destbyte-size. This applies to the
 *                      element count of an "ARRAY" or "CONTAINER" type size
 *                      or the bit size of the plain type.
 * GCI_NoBaseType:      The type won't fit the requirements for basic types.
 *
 * And there are numerous other possible errors returned by cb->callback.
 */
static GCI_result parse( callblock *cb,
                         int itemnumber )
{
    GCI_parseinfo pi;
    GCI_str newName;
    static const GCI_parseinfo indirectArray = { GCI_container, 1, 1, 1 };
    GCI_result rc;
    unsigned i;
    int origlen = GCI_strlen( cb->buffer );

    GCI_strfromascii( &newName, NULL, 0 );
    GCI_strcats( cb->buffer, "." );
    GCI_strcats( cb->buffer, cb->prefixChar );
    if ( ( rc = GCI_strcats( cb->buffer, "TYPE" ) ) != GCI_OK )
        return rc;
    if ( ( rc = GCI_readRexx( cb->hidden,
                              cb->buffer,
                              &cb->tempbuf,
                              0,
                              1,
                              NULL ) ) != GCI_OK )
    {
        if ( rc == GCI_MissingValue )
            rc = GCI_MissingName;
        return rc;
    }
    GCI_uppercase( cb->hidden, &cb->tempbuf );

    if ( ( rc = decode( cb->hidden, &cb->tempbuf, &pi, cb->depth, &newName ) )
            != GCI_OK )
        return rc;
    GCI_strsetlen( cb->buffer, origlen );

    if ( GCI_content( &newName ) != NULL ) {
        if (cb->recurCount++ >= 100) {
            GCI_strfree( cb->hidden, &newName );
            return GCI_NestingOverflow;
        }
        GCI_strswap( &newName, cb->buffer );
        origlen = GCI_strlen( cb->buffer );
    }

    /*
     * Alright, we have it, but we have to fetch the number of elements
     * if we parse a container or an array.
     */
    if ( ( pi.type == GCI_container ) || ( pi.type == GCI_array ) )
    {
        if ( ( rc = GCI_strcats( cb->buffer, ".0" ) ) != GCI_OK )
        {
            /*
             * The tmp buffer persists for error displaying, kill the other.
             */
            if ( GCI_content( &newName ) != NULL )
                GCI_strfree( cb->hidden, &newName );
            return rc;
        }
        if ( ( rc = GCI_readRexx( cb->hidden,
                                  cb->buffer,
                                  &cb->tempbuf,
                                  0,
                                  1,
                                  NULL ) ) != GCI_OK )
        {
            if ( rc == GCI_MissingValue )
                rc = GCI_MissingName;
            /*
             * The tmp buffer persists for error displaying, kill the other.
             */
            if ( GCI_content( &newName ) != NULL )
                GCI_strfree( cb->hidden, &newName );
            return rc;
        }

        /*
         * The result shall be a whole, positive number. Lets see...
         */
        if ( ( rc = GCI_string2bin( cb->hidden,
                                    GCI_content( &cb->tempbuf ),
                                    GCI_strlen( &cb->tempbuf ),
                                    &pi.size,
                                    sizeof( pi.size ),
                                    GCI_unsigned ) ) != GCI_OK )
        {
            /*
             * The tmp buffer persists for error displaying, kill the other.
             */
            if ( GCI_content( &newName ) != NULL )
                GCI_strfree( cb->hidden, &newName );
            return rc;
        }
        if ( pi.size == 0 )
        {
            /*
             * The tmp buffer persists for error displaying, kill the other.
             */
            if ( GCI_content( &newName ) != NULL )
                GCI_strfree( cb->hidden, &newName );
            return GCI_NumberRange;
        }
        GCI_strsetlen( cb->buffer, origlen );
    }

    if ( pi.indirect && ( pi.type == GCI_array ) )
    {
        if ( ( rc = cb->callback( cb->depth,
                                  itemnumber,
                                  cb->arg,
                                  &indirectArray) ) != GCI_OK )
            return rc;
        pi.indirect = 0;
        if ( ( rc = cb->callback( cb->depth,
                                  itemnumber,
                                  cb->arg,
                                  &pi) ) != GCI_OK )
            return rc;
        pi.indirect = 1;
    }
    else
    {
        if ( ( rc = cb->callback( cb->depth,
                                  itemnumber,
                                  cb->arg,
                                  &pi) ) != GCI_OK )
        {
            /*
             * The tmp buffer persists for error displaying, kill the other.
             */
            if ( GCI_content( &newName ) != NULL )
                GCI_strfree( cb->hidden, &newName );
            return rc;
        }
    }

    if ( ( pi.type != GCI_container ) && ( pi.type != GCI_array ) )
        return GCI_OK;

    cb->depth++;
    for ( i = 0; i < pi.size; i++ )
    {
        sprintf( cb->helper, ".%u", i + 1 );

        if ( ( rc = GCI_strcats( cb->buffer, cb->helper ) ) != GCI_OK )
        {
            /*
             * The tmp buffer persists for error displaying, kill the other.
             */
            if ( GCI_content( &newName ) != NULL )
                GCI_strfree( cb->hidden, &newName );
            return rc;
        }
        if ( ( rc = parse( cb, i ) ) != GCI_OK )
        {
            /*
             * The tmp buffer persists for error displaying, kill the other.
             */
            if ( GCI_content( &newName ) != NULL )
                GCI_strfree( cb->hidden, &newName );
            return rc;
        }
        GCI_strsetlen( cb->buffer, origlen );

        if ( pi.type == GCI_array )
            break;
    }
    cb->depth--;
    cb->recurCount--;
    if ( GCI_content( &newName ) != NULL )
    {
        GCI_strswap( &newName, cb->buffer );
        GCI_strfree( cb->hidden, &newName );
    }

    if ( pi.indirect && ( pi.type == GCI_array ) )
    {
        pi.indirect = 0;
        if ( ( rc = cb->callback( cb->depth, -1, cb->arg, &pi) ) != GCI_OK )
            return rc;
        return cb->callback( cb->depth, -1, cb->arg, &indirectArray );
    }
    return cb->callback( cb->depth, -1, cb->arg, &pi );
}
コード例 #4
0
ファイル: gci_tree.c プロジェクト: jlfaucher/builder
/*
 * decode decodes one line of the type structure named str into the
 * a parseinfo block called pi. depth is the current depth which may be 0.
 *
 * newName is set in case of ARRAY (to the empty string) or CONTAINER. In this
 * case is set to the LIKE parameter or to the empty string.
 *
 * Leading and trailing spaces are ignored completely, "INDIRECTFLOAT32" is
 * acceptable. Differences in case are ignored.
 *
 * THE GENERATED TYPE MAY HAVE AN ILLEGAL BIT SIZE. IT ISN'T CHECKED ALWAYS!
 *
 * Return values:
 * GCI_OK:              Line understood, *pi filled.
 * GCI_UnsupportedType: Wrong type of input, e.g. FLOAT31 or the empty string.
 * GCI_NoBaseType:      The type won't fit the requirements for basic types.
 */
static GCI_result decode( void *hidden,
                          const GCI_str *str,
                          GCI_parseinfo *pi,
                          int depth,
                          GCI_str *newName )
{
    const char *ptr = GCI_ccontent( str );
    int size = GCI_strlen( str );

    /*
     * Chop off leading and trailing spaces. We really need it.
     */
    while ( ( size > 0 ) && GCI_isspace( *ptr ) )
    {
        ptr++;
        size--;
    }
    while ( ( size > 0 ) && GCI_isspace( ptr[size - 1] ) )
        size--;

    memset( pi, 0, sizeof( GCI_parseinfo ) );

    if ( ( pi->type = checkname( &ptr, &size ) ) == GCI_unknown )
        return GCI_UnsupportedType;
    if ( pi->type == GCI_indirect )
    {
        while ( ( size > 0 ) && GCI_isspace( *ptr ) )
        {
            ptr++;
            size--;
        }
        pi->type = checkname( &ptr, &size );
        if ( ( pi->type == GCI_unknown ) || ( pi->type == GCI_indirect ) )
            return GCI_UnsupportedType;
        pi->indirect = 1;
    }
    else
        pi->indirect = 0;

    /*
     * Check for a size operand.
     */
    while ( ( size > 0 ) && GCI_isspace( *ptr ) )
    {
        ptr++;
        size--;
    }

    /*
     * We may have a size operand only if not an array or container is
     * processed!
     * This implementation shall support plain types like "INTEGER" without
     * any bit size.
     */
    switch ( pi->type )
    {
    case GCI_container:
        if ( size > 0 )
        {
            GCI_str tmp;

            if ( checkname( &ptr, &size ) != GCI_like )
                return GCI_UnsupportedType;
            while ( ( size > 0 ) && GCI_isspace( *ptr ) )
            {
                ptr++;
                size--;
            }
            if ( size == 0 )
            {
                /*
                 * Single "like" after "container".
                 */
                return GCI_UnsupportedType;
            }
            while ( GCI_isspace( ptr[size - 1] ) )
                size--;
            /*
             * Cut off a final dot, we append one later.
             */
            if ( ptr[size - 1] == '.' )
            {
                /*
                 * Check for single "." as stem.
                 */
                if ( --size == 0 )
                    return GCI_UnsupportedType;
            }
            if ( GCI_stralloc( hidden, newName, size + 256 ) != GCI_OK )
                return GCI_NoMemory;
            GCI_strfromascii( &tmp, (char *) ptr, size );
            GCI_strsetlen( &tmp, size );
            GCI_strcpy( newName, &tmp );
            size = 0;
        }
    /* fall through */

    case GCI_array:
        if ( size > 0 )
            return GCI_UnsupportedType;
        if ( ( depth == 0 ) && !pi->indirect )
        {
            if ( GCI_content( newName ) != NULL )
                GCI_strfree( hidden, newName );
            return GCI_NoBaseType;
        }
        pi->size = 0;
        return GCI_OK;

    case GCI_integer:
        if ( size == 0 )
            pi->size = 8 * sizeof( int );
        break;

    case GCI_unsigned:
        if ( size == 0 )
            pi->size = 8 * sizeof( unsigned );
        break;

    case GCI_float:
        if ( size == 0 )
            pi->size = 8 * sizeof( double ); /* surprised? */
        break;

    case GCI_char:
        if ( size == 0 )
            pi->size = 8 * 1; /* always, even in unicode or utf8 systems */
        break;

    case GCI_string:
        if ( size == 0 ) /* length must be supplied */
            return GCI_UnsupportedType;
        break;

    // JLF needed for portability: aliases which depend on the system & bitness.
    // Each alias defines a type and a size, no size accepted after these aliases.

    case GCI_long:
        if ( size > 0 )
            return GCI_UnsupportedType;
        pi->type = GCI_integer;
        pi->size = 8 * sizeof( long );
        break;

    case GCI_llong:
        if ( size > 0 )
            return GCI_UnsupportedType;
        pi->type = GCI_integer;
        pi->size = 8 * sizeof( long long );
        break;

    case GCI_pointer: // opaque
        if ( size > 0 )
            return GCI_UnsupportedType;
        pi->type = GCI_unsigned;
        pi->size = 8 * sizeof( void* );
        break;

    case GCI_size_t:
        if ( size > 0 )
            return GCI_UnsupportedType;
        pi->type = GCI_unsigned;
        pi->size = 8 * sizeof( size_t );
        break;

    case GCI_ssize_t:
        if ( size > 0 )
            return GCI_UnsupportedType;
        pi->type = GCI_integer;
        pi->size = 8 * sizeof( ssize_t );
        break;

    case GCI_ulong:
        if ( size > 0 )
            return GCI_UnsupportedType;
        pi->type = GCI_unsigned;
        pi->size = 8 * sizeof( unsigned  long );
        break;

    case GCI_ullong:
        if ( size > 0 )
            return GCI_UnsupportedType;
        pi->type = GCI_unsigned;
        pi->size = 8 * sizeof( unsigned  long long );
        break;

    default:
        return GCI_UnsupportedType;
    }

    if ( size > 0 )
    {
        if ( GCI_string2bin( hidden,
                             ptr,
                             size,
                             &pi->size,
                             sizeof( pi->size ),
                             GCI_unsigned ) != GCI_OK )
            return GCI_UnsupportedType;
    }

    if ( ( pi->type == GCI_string ) && ( pi->size > 0 ) )
        return GCI_OK;

    /*
     * A byte has 8 bit, always! We don't support PDP10.
     */
    if ( pi->type != GCI_string )
    {
        if ( pi->size % 8 )
            return GCI_UnsupportedType;
        pi->size /= 8;
    }

    return GCI_validate( pi->size, pi->type, depth || pi->indirect );
}