Exemplo n.º 1
0
/*
 * streng_of returns a new streng with the same content as str has.
 * NULL is allowed for str and will result in a NULL return value.
 * The non-existing string is allowed for for str and will result in an empty
 * string.
 */
static streng *streng_of( const tsd_t *TSD, const GCI_str *str )
{
   if ( str == NULL )
      return NULL;
   if ( GCI_ccontent( str ) == NULL )
      return nullstringptr();
   return Str_ncreTSD( GCI_ccontent( str ), GCI_strlen( str ) );
}
Exemplo n.º 2
0
/*
 * GCI_writeRexx sets the content of one variable of name "name" to the content
 * of "value".
 *
 * symbolicAccess shall be set if normal access is expected. If this variable
 * is 0, the variable's name is treated as "tail-expanded" and any further
 * interpretation of the name isn't done by the interpreter.
 *
 * Return values:
 * GCI_OK:             Everything is fine.
 * GCI_NoMemory:       Can't allocate enough memory for the return value.
 * GCI_MissingValue:   signalOnNovalue is set and this function doesn't
 *                     support to fire a NOVALUE condition.
 * GCI_IllegalName:    "name" is illegal in terms of Rexx. Especially on
 *                     non-"symbolicAccess" the caller must provide uppercased
 *                     stem names if a stem is used.
 * GCI_RexxError:      An unexpected other error is returned by the
 *                     interpreter.
 */
GCI_result GCI_writeRexx( void *hidden,
                          const GCI_str *name,
                          const GCI_str *value,
                          int symbolicAccess )
{
   int retval;
   int Lengths[2];
   char *Strings[2];
   int allocated;

   Lengths[0] = GCI_strlen( name );
   Strings[0] = (char *) GCI_ccontent( name );
   if ( GCI_ccontent( value ) == NULL )
   {
      Lengths[1] = RX_NO_STRING;
      Strings[1] = NULL;
   }
   else
   {
      Lengths[1] = GCI_strlen( value );
      Strings[1] = (char *) GCI_ccontent( value );
   }

   retval = IfcVarPool( (tsd_t *) hidden,
                        ( symbolicAccess ) ? RX_SETSVAR : RX_SETVAR,
                        Lengths,
                        Strings,
                        &allocated );

   switch ( retval )
   {
      case RX_CODE_OK:
      case RX_CODE_NOVALUE:
         break;

      case RX_CODE_INVNAME:
         return GCI_IllegalName;

      default:
         return GCI_RexxError;
   }

   return GCI_OK;
}
Exemplo n.º 3
0
/*
 * readRexx works as a merged version of the function GCI_readRexx and
 * GCI_readNewRexx below. The difference is the flag allocate. If this is
 * set, the function works aas GCI_readNewRexx, otherwise is works like
 * GCI_readRexx.
 */
static GCI_result readRexx( void *hidden,
                            const GCI_str *name,
                            GCI_str *target,
                            int symbolicAccess,
                            int signalOnNovalue,
                            int allocate,
                            int *novalue )
{
   tsd_t *TSD = (tsd_t *) hidden;
   int retval;
   GCI_result rc;
   int Lengths[2];
   char *Strings[2];
   int allocated;

   Lengths[0] = GCI_strlen( name );
   Strings[0] = (char *) GCI_ccontent( name );

   if ( !signalOnNovalue )
      set_ignore_novalue( (const tsd_t *) hidden );
   retval = IfcVarPool( (tsd_t *) hidden,
                        ( symbolicAccess ) ? RX_GETSVAR : RX_GETVAR,
                        Lengths,
                        Strings,
                        &allocated );
   if ( !signalOnNovalue )
      clear_ignore_novalue( (const tsd_t *) hidden );

   switch ( retval )
   {
      case RX_CODE_OK:
         if ( novalue )
            *novalue = 0;
         rc = GCI_OK;
         break;

      case RX_CODE_NOVALUE:
         if ( novalue )
            *novalue = 1;
         rc = GCI_OK;
         break;

      case RX_CODE_INVNAME:
         return GCI_IllegalName;

      default:
         if ( allocated )
            FreeTSD( Strings[1] );
         return GCI_RexxError;
   }
   if ( Lengths[1] == RX_NO_STRING )
      return GCI_RexxError;

   /*
    * We must copy the value's content (Strings[1]/Lengths[1]) and we must
    * destroy the value if "allocated" is set.
    */
   if ( allocate )
   {
      if ( ( rc = GCI_stralloc( hidden, target, Lengths[1] ) ) != GCI_OK )
      {
         if ( allocated )
            FreeTSD( Strings[1] );
         return rc;
      }
   }
   else if ( Lengths[1] > GCI_strmax( target ) )
   {
      if ( allocated )
         FreeTSD( Strings[1] );

      return GCI_BufferTooSmall;
   }

   memcpy( GCI_content( target ), Strings[1], Lengths[1] );
   if ( allocated )
      FreeTSD( Strings[1] );
   GCI_strsetlen( target, Lengths[1] );
   return GCI_OK;
}
Exemplo n.º 4
0
/*
 * 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 );
}