2 * Generic Call Interface for Rexx
3 * Copyright © 2003-2004, Florian Große-Coosmann
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * ----------------------------------------------------------------------------
21 * This file converts numerical string values to binary values and vice versa.
23 * Supported datatypes must be configured from outside in the file
24 * gci_convert.h. We need functions for parsing and printing floating points
27 * We support integers with a size of a power of 2 only, typically
28 * 1, 2, 4, 8 and probably 16; every type with a smaller value will be
29 * accepted automatically.
31 * This is expected by the include file to be defined:
32 * GCI_I_x signed integer data type with x bytes.
33 * GCI_I_xm minimum value for GCI_I_x.
34 * GCI_I_xM maximum value for GCI_I_x.
35 * GCI_Ir function for converting GCI_I_x, x largest of all x, which
36 * converts a string into a binary representation. The function
37 * must behave as strtol with the fitting data type.
38 * GCI_Iw function for converting GCI_I_x, x largest of all x, which
39 * converts a binary representation of a number into a zero
40 * terminated string. The prototype must fit "GCI_Iw(string,GCI_I)".
41 * No error throwing is allowed. The maximum number of characters to
42 * write is 127. The function must return the length of string
43 * without the terminating '\0'.
50 * GCI_Uw same as above but for unsigned datatypes.
56 * GCI_Fw same as above but for floating point data types. GCI_Fw may
57 * write a maximum of 127 characters and may use "NaN", etc to
58 * present anomal numbers.
61 * One can take advantage of strtobigl and strtobigul for GCI_Ir and GCI_Ur
62 * is NEED_STRTOBIGL or NEED_STRTOBIGUL are defined. They are slow but work.
64 * strtobigf can be used for GCI_Fr if NEED_STRTOBIGF is defined. In this case,
65 * F_SCAN must be defined and should be the scanf() compatible mask for parsing
66 * a GCI_F_x value. Most systems need a '#define F_SCAN "%Lf"' in this case.
69 #include "gci_convert.h"
86 * Determine the maximum size for each family.
89 # define GCI_I GCI_I_16
91 # define GCI_Im GCI_I_16m
92 # define GCI_IM GCI_I_16M
93 #elif defined(GCI_I_8)
94 # define GCI_I GCI_I_8
96 # define GCI_Im GCI_I_8m
97 # define GCI_IM GCI_I_8M
99 # define GCI_I GCI_I_4
101 # define GCI_Im GCI_I_4m
102 # define GCI_IM GCI_I_4M
105 #if defined(GCI_U_16)
106 # define GCI_U GCI_U_16
108 # define GCI_UM GCI_U_16M
109 #elif defined(GCI_U_8)
110 # define GCI_U GCI_U_8
112 # define GCI_UM GCI_U_8M
114 # define GCI_U GCI_U_4
116 # define GCI_UM GCI_U_4M
119 #if defined(GCI_F_16)
120 # define GCI_F GCI_F_16
122 #elif defined(GCI_F_12)
123 # define GCI_F GCI_F_12
125 #elif defined(GCI_F_10)
126 # define GCI_F GCI_F_10
128 #elif defined(GCI_F_8)
129 # define GCI_F GCI_F_8
131 #elif defined(GCI_F_4)
132 # define GCI_F GCI_F_4
138 #if ( GCI_Imax >= GCI_Umax ) && ( GCI_Imax >= GCI_Fmax )
139 # define GCI_max GCI_Imax
140 #elif ( GCI_Umax >= GCI_Imax ) && ( GCI_Umax >= GCI_Fmax )
141 # define GCI_max GCI_Umax
143 # define GCI_max GCI_Fmax
147 * Create a table for conversion functions. We know the maximum entry
151 GCI_result (*s2ifunc
)( void *hidden
, const char *str
, int strsize
,
153 GCI_result (*s2ufunc
)( void *hidden
, const char *str
, int strsize
,
155 GCI_result (*s2ffunc
)( void *hidden
, const char *str
, int strsize
,
157 GCI_result (*i2sfunc
)( void *hidden
, const void *data
, char *str
,
159 GCI_result (*u2sfunc
)( void *hidden
, const void *data
, char *str
,
161 GCI_result (*f2sfunc
)( void *hidden
, const void *data
, char *str
,
163 } functable
[GCI_max
+1] = {
166 static int functable_assigned
= 0;
168 #ifdef NEED_STRTOBIGL
169 static GCI_I
strtobigl( void *hidden
, const char *nptr
, char **end
, int base
)
172 char *run
= (char *) nptr
;
177 assert( base
== 10 );
179 while ( GCI_isspace( *run
) )
187 if ( !GCI_isdigit( *run
) )
189 *end
= (char *) nptr
;
193 while ( GCI_isdigit( *run
) )
197 if ( retval
<= GCI_Im
/ 10 )
199 if ( retval
== GCI_Im
/ 10 )
201 if ( (char ) -( GCI_Im
- 10 * retval
) < ( *run
- '0' ) )
209 retval
-= ( GCI_I
) ( *run
- '0' );
221 retval
-= ( GCI_I
) ( *run
- '0' );
226 if ( retval
>= GCI_IM
/ 10 )
228 if ( retval
== GCI_IM
/ 10 )
230 if ( (char ) ( GCI_IM
- 10 * retval
) < ( *run
- '0' ) )
238 retval
+= ( GCI_I
) ( *run
- '0' );
250 retval
+= ( GCI_I
) ( *run
- '0' );
262 #ifdef NEED_STRTOBIGUL
263 static GCI_U
strtobigul( void *hidden
, const char *nptr
, char **end
, int base
)
265 char *run
= (char *) nptr
;
270 assert( base
== 10 );
272 while ( GCI_isspace( *run
) )
275 if ( !GCI_isdigit( *run
) )
277 *end
= (char *) nptr
;
281 while ( GCI_isdigit( *run
) )
283 if ( retval
>= GCI_UM
/ 10 )
285 if ( retval
== GCI_UM
/ 10 )
287 if ( (char ) ( GCI_UM
- 10 * retval
) < ( *run
- '0' ) )
295 retval
+= ( GCI_U
) ( *run
- '0' );
307 retval
+= ( GCI_U
) ( *run
- '0' );
318 #ifdef NEED_STRTOBIGF
319 static GCI_F
strtobigf( const char *nptr
, char **end
)
326 rc
= sscanf( nptr
, F_SCAN
" %c", &f
, &c
);
329 *end
= (char *) nptr
;
332 return f
; /* pro forma */
337 if ( ( *end
= strrchr( nptr
, c
) ) == NULL
)
338 *end
= (char *) nptr
;
341 *end
= (char *) nptr
+ strlen( nptr
);
348 * preparenum chops off leading and trailing whitespaces from *str with the
349 * initial length of *size. Leading zeros will be cut off, too.
350 * *str and *size represent the final string after the stripping.
351 * A resulting length of 0 may occur only if the complete string contain
354 static void preparenum( void *hidden
,
358 const char *s
= *str
;
364 * We prepare the number by hand and strip away blanks and useless zeros.
366 while ( len
&& GCI_isspace( *s
) )
378 * We know from the previous test that at least one non-space exists.
380 while ( GCI_isspace( s
[len
- 1] ) )
386 * At least one non-space exist. Strip leading zeros; if no character
387 * remains, we have cut off one or more zeros. Undo one step then.
389 while ( len
&& ( *s
== '0' ) )
405 * iswhole returns 1 exactly if all characters in str are decimal digits,
408 static int iswhole( void *hidden
,
414 while ( size
&& GCI_isdigit( *str
) )
423 * string2int is the basic routine which implements GCI_Ir. size characters
424 * of str (not strongly 0-terminated) are converted and the number is placed
427 * The string may contain garbage whitespace.
429 * The return code may be GCI_OK, GCI_WrongInput, GCI_NumberRange.
431 static GCI_result
string2int( void *hidden
,
436 char buf
[80]; /* enough even for 256 bit numbers */
440 preparenum( hidden
, &str
, &size
);
441 if ( !size
|| ( size
> (int) sizeof( buf
) - 1 ) )
442 return GCI_WrongInput
;
444 if ( ( *str
== '-' ) || ( *str
== '+' ) )
445 rc
= iswhole( hidden
, str
+ 1, size
- 1 );
447 rc
= iswhole( hidden
, str
, size
);
449 return GCI_WrongInput
;
451 memcpy( buf
, str
, size
);
455 * Carefully try to detect an overflow. We have to set errno for that
456 * cases where MAX_??? is given in str.
459 *retval
= GCI_Ir( buf
, &p
, 10 );
460 if ( ( *p
!= '\0' ) || errno
)
461 return GCI_NumberRange
;
467 * int2string is the basic routine which implements GCI_Iw. bin is converted
468 * into a string which is placed into str. strsize must hold the buffer width
469 * of str and must be greater than 79.
471 * The return code will be GCI_OK.
473 * *strsize is set to the resulting length without the terminator.
475 static GCI_result
int2string( void *hidden
,
481 assert( *strsize
>= 80 );
483 *strsize
= GCI_Iw( str
, bin
);
488 * string2uint is the basic routine which implements GCI_Ur. size characters
489 * of str (not strongly 0-terminated) are converted and the number is placed
492 * The string may contain garbage whitespace.
494 * The return code may be GCI_OK, GCI_WrongInput, GCI_NumberRange.
496 static GCI_result
string2uint( void *hidden
,
501 char buf
[80]; /* enough even for 256 bit numbers */
504 preparenum( hidden
, &str
, &size
);
506 ( size
> (int) sizeof( buf
) - 1 ) ||
507 !iswhole( hidden
, str
, size
) )
508 return GCI_WrongInput
;
510 memcpy( buf
, str
, size
);
514 * Carefully try to detect an overflow. We have to set errno for that
515 * cases where MAX_??? is given in str.
518 *retval
= GCI_Ur( buf
, &p
, 10 );
519 if ( ( *p
!= '\0' ) || errno
)
520 return GCI_NumberRange
;
526 * uint2string is the basic routine which implements GCI_Uw. bin is converted
527 * into a string which is placed into str. strsize must hold the buffer width
528 * of str and must be greater than 79.
530 * The return code will be GCI_OK.
532 * *strsize is set to the resulting length without the terminator.
534 static GCI_result
uint2string( void *hidden
,
540 assert( *strsize
>= 80 );
542 *strsize
= GCI_Uw( str
, bin
);
548 * string2float is the basic routine which implements GCI_Fr. size characters
549 * of str (not strongly 0-terminated) are converted and the number is placed
552 * The string may contain garbage whitespace.
554 * The return code may be GCI_OK, GCI_NoMemory, GCI_WrongInput,
557 static GCI_result
string2float( void *hidden
,
566 preparenum( hidden
, &str
, &size
);
568 return GCI_WrongInput
;
570 if ( ( buf
= (char *) GCI_malloc( hidden
, size
+ 1 ) ) == NULL
)
573 memcpy( buf
, str
, size
);
577 * Carefully try to detect an overflow. We have to set errno for that
578 * cases where MAX_??? is given in str.
581 *retval
= GCI_Fr( buf
, &p
);
582 while ( GCI_isspace( *p
) )
587 GCI_free( hidden
, buf
);
588 return GCI_WrongInput
;
593 GCI_free( hidden
, buf
);
594 return GCI_NumberRange
;
597 GCI_free( hidden
, buf
);
602 * float2string is the basic routine which implements GCI_Uw. bin is converted
603 * into a string which is placed into str. *strsize must hold the buffer width
604 * of str and must be greater than 127.
606 * The return code will be GCI_OK or GCI_UnsupportedNumber if the generated
607 * number cannot be represented by digits (e.g. NaN).
609 * *strsize is set to the resulting length without the terminator.
611 static GCI_result
float2string( void *hidden
,
617 assert( *strsize
>= 128 );
619 *strsize
= GCI_Fw( str
, bin
);
620 if ( ( *str
== '-' ) || ( *str
== '+' ) )
622 if ( !GCI_isdigit( *str
) )
623 return GCI_UnsupportedNumber
;
626 #endif /* ifdef GCI_F */
629 * We define a set of functions which bases on string2int and int2string.
630 * Each function will either convert to a smaller sized number or display a
631 * smaller sized number.
633 * usage: AUTOIFUNC(x) create the two functions s2ifuncx and i2sfuncx.
635 #define AUTOIFUNC(size) static GCI_result s2ifunc##size( void *hidden, \
642 if ( ( rc = string2int( hidden, str, strsize, &val ) ) != GCI_OK ) \
645 if ( ( (GCI_I) val < GCI_I_##size##m ) || \
646 ( (GCI_I) val > GCI_I_##size##M ) ) \
647 return GCI_NumberRange; \
649 *((GCI_I_##size *) target) = (GCI_I_##size) val; \
652 static GCI_result i2sfunc##size( void *hidden, \
658 val = (GCI_I) *( (GCI_I_##size *) data ); \
659 return int2string( hidden, val, str, strsize ); \
683 * We define a set of functions which bases on string2uint and uint2string.
684 * Each function will either convert to a smaller sized number or display a
685 * smaller sized number.
687 * usage: AUTOUFUNC(x) create the two functions s2ufuncx and u2sfuncx.
689 #define AUTOUFUNC(size) static GCI_result s2ufunc##size( void *hidden, \
696 if ( ( rc = string2uint( hidden, str, strsize, &val ) ) != GCI_OK ) \
699 if ( (GCI_U) val > GCI_U_##size##M ) \
700 return GCI_NumberRange; \
702 *((GCI_U_##size *) target) = (GCI_U_##size) val; \
705 static GCI_result u2sfunc##size( void *hidden, \
711 val = (GCI_U) *( (GCI_U_##size *) data ); \
712 return uint2string( hidden, val, str, strsize ); \
738 * We define a set of functions which bases on string2float and float2string.
739 * Each function will either convert to a smaller sized number or display a
740 * smaller sized number.
742 * usage: AUTOFFUNC(x) create the two functions s2ffuncx and f2sfuncx.
744 #define AUTOFFUNC(size) static GCI_result s2ffunc##size( void *hidden, \
751 if ( ( rc = string2float( hidden, str, strsize, &val ) ) != GCI_OK ) \
754 if ( ( (GCI_F) val < GCI_F_##size##m ) || \
755 ( (GCI_F) val > GCI_F_##size##M ) ) \
756 return GCI_NumberRange; \
758 *((GCI_F_##size *) target) = (GCI_F_##size) val; \
761 static GCI_result f2sfunc##size( void *hidden, \
767 val = (GCI_F) *( (GCI_F_##size *) data ); \
768 return float2string( hidden, val, str, strsize ); \
790 #endif /* ifdef GCI_F */
793 * setup_functable initializes the functable table without setting illegal
795 * This allows simultaneous access without locking in multi-threading systems.
797 static void setup_functable( void )
801 if ( functable_assigned
)
804 for ( i
= 0; i
<= GCI_max
; i
++)
810 functable
[i
].s2ifunc
= s2ifunc1
;
811 functable
[i
].i2sfunc
= i2sfunc1
;
813 functable
[i
].s2ifunc
= NULL
;
814 functable
[i
].i2sfunc
= NULL
;
817 functable
[i
].s2ufunc
= s2ufunc1
;
818 functable
[i
].u2sfunc
= u2sfunc1
;
820 functable
[i
].s2ufunc
= NULL
;
821 functable
[i
].u2sfunc
= NULL
;
823 functable
[i
].s2ffunc
= NULL
;
824 functable
[i
].f2sfunc
= NULL
;
829 functable
[i
].s2ifunc
= s2ifunc2
;
830 functable
[i
].i2sfunc
= i2sfunc2
;
832 functable
[i
].s2ifunc
= NULL
;
833 functable
[i
].i2sfunc
= NULL
;
836 functable
[i
].s2ufunc
= s2ufunc2
;
837 functable
[i
].u2sfunc
= u2sfunc2
;
839 functable
[i
].s2ufunc
= NULL
;
840 functable
[i
].u2sfunc
= NULL
;
842 functable
[i
].s2ffunc
= NULL
;
843 functable
[i
].f2sfunc
= NULL
;
848 functable
[i
].s2ifunc
= s2ifunc4
;
849 functable
[i
].i2sfunc
= i2sfunc4
;
851 functable
[i
].s2ifunc
= NULL
;
852 functable
[i
].i2sfunc
= NULL
;
855 functable
[i
].s2ufunc
= s2ufunc4
;
856 functable
[i
].u2sfunc
= u2sfunc4
;
858 functable
[i
].s2ufunc
= NULL
;
859 functable
[i
].u2sfunc
= NULL
;
862 functable
[i
].s2ffunc
= s2ffunc4
;
863 functable
[i
].f2sfunc
= f2sfunc4
;
865 functable
[i
].s2ffunc
= NULL
;
866 functable
[i
].f2sfunc
= NULL
;
872 functable
[i
].s2ifunc
= s2ifunc8
;
873 functable
[i
].i2sfunc
= i2sfunc8
;
875 functable
[i
].s2ifunc
= NULL
;
876 functable
[i
].i2sfunc
= NULL
;
879 functable
[i
].s2ufunc
= s2ufunc8
;
880 functable
[i
].u2sfunc
= u2sfunc8
;
882 functable
[i
].s2ufunc
= NULL
;
883 functable
[i
].u2sfunc
= NULL
;
886 functable
[i
].s2ffunc
= s2ffunc8
;
887 functable
[i
].f2sfunc
= f2sfunc8
;
889 functable
[i
].s2ffunc
= NULL
;
890 functable
[i
].f2sfunc
= NULL
;
895 functable
[i
].s2ifunc
= NULL
;
896 functable
[i
].i2sfunc
= NULL
;
897 functable
[i
].s2ufunc
= NULL
;
898 functable
[i
].u2sfunc
= NULL
;
900 functable
[i
].s2ffunc
= s2ffunc10
;
901 functable
[i
].f2sfunc
= f2sfunc10
;
903 functable
[i
].s2ffunc
= NULL
;
904 functable
[i
].f2sfunc
= NULL
;
909 functable
[i
].s2ifunc
= NULL
;
910 functable
[i
].i2sfunc
= NULL
;
911 functable
[i
].s2ufunc
= NULL
;
912 functable
[i
].u2sfunc
= NULL
;
914 functable
[i
].s2ffunc
= s2ffunc12
;
915 functable
[i
].f2sfunc
= f2sfunc12
;
917 functable
[i
].s2ffunc
= NULL
;
918 functable
[i
].f2sfunc
= NULL
;
924 functable
[i
].s2ifunc
= s2ifunc16
;
925 functable
[i
].i2sfunc
= i2sfunc16
;
927 functable
[i
].s2ifunc
= NULL
;
928 functable
[i
].i2sfunc
= NULL
;
931 functable
[i
].s2ufunc
= s2ufunc16
;
932 functable
[i
].u2sfunc
= u2sfunc16
;
934 functable
[i
].s2ufunc
= NULL
;
935 functable
[i
].u2sfunc
= NULL
;
938 functable
[i
].s2ffunc
= s2ffunc16
;
939 functable
[i
].f2sfunc
= f2sfunc16
;
941 functable
[i
].s2ffunc
= NULL
;
942 functable
[i
].f2sfunc
= NULL
;
947 functable
[i
].s2ifunc
= NULL
;
948 functable
[i
].i2sfunc
= NULL
;
949 functable
[i
].s2ufunc
= NULL
;
950 functable
[i
].u2sfunc
= NULL
;
951 functable
[i
].s2ffunc
= NULL
;
952 functable
[i
].f2sfunc
= NULL
;
957 functable_assigned
= 1;
960 /*****************************************************************************
961 *****************************************************************************
962 ** GLOBAL FUNCTIONS *********************************************************
963 *****************************************************************************
964 *****************************************************************************/
967 * GCI_string2bin converts size characters of the not strongly 0-terminated
968 * string in str to a number.
969 * The desired datatype is taken from type. It must be GCI_integer,
970 * GCI_unsigned, GCI_float or GCI_char.
971 * destbyte contains the number of bytes of the desired type.
972 * Exactly destbyte bytes will be written to *dest on success. No checks for
973 * alignment errors are done.
975 * The return code may be
976 * GCI_OK Everything is perfect.
977 * GCI_NoMemory Out of memory when converting a floating point number.
978 * GCI_WrongInput Strange characters occur in the input string.
979 * GCI_NumberRange Number to small or big to fit into the desired type
980 * with the desired destbyte-size.
981 * GCI_UnsupportedType The combination of destbyte/type is unknown or not
984 GCI_result
GCI_string2bin( void *hidden
,
991 if ( !functable_assigned
)
994 if ( ( destbyte
< 0 ) || ( destbyte
>= (int) elements( functable
) ) )
995 return GCI_UnsupportedType
;
1000 if ( functable
[destbyte
].s2ifunc
== NULL
)
1001 return GCI_UnsupportedType
;
1002 return functable
[destbyte
].s2ifunc( hidden
, str
, size
, dest
);
1005 if ( functable
[destbyte
].s2ufunc
== NULL
)
1006 return GCI_UnsupportedType
;
1007 return functable
[destbyte
].s2ufunc( hidden
, str
, size
, dest
);
1010 if ( functable
[destbyte
].s2ffunc
== NULL
)
1011 return GCI_UnsupportedType
;
1012 return functable
[destbyte
].s2ffunc( hidden
, str
, size
, dest
);
1015 if ( destbyte
!= 1 )
1016 return GCI_UnsupportedType
;
1018 return GCI_WrongInput
;
1019 *((char *) dest
) = *str
;
1025 return GCI_UnsupportedType
;
1029 * GCI_bin2string converts size byte of base into a 0-terminated string with
1030 * a maximum target size of *strsize including the terminator.
1031 * The desired datatype is taken from type. It must be GCI_integer,
1032 * GCI_unsigned, GCI_float or GCI_char. GCI_string is not handled.
1033 * size contains the number of bytes of the desired type.
1034 * Exactly size bytes will be taken from *base. No checks for alignment errors
1036 * *strsize is set to the new size of the resulting string without the
1039 * The return code may be
1040 * GCI_OK Everything is perfect.
1041 * GCI_UnsupportedNumber The floating point value in base is not a number
1042 * which can be displayed by digits (e.g. NaN).
1043 * GCI_BufferTooSmall The target buffer size strsize is less than 128.
1044 * GCI_UnsupportedType The combination of size/type is unknown or not
1047 GCI_result
GCI_bin2string( void *hidden
,
1054 if ( !functable_assigned
)
1057 if ( ( size
< 0 ) || ( size
>= (int) elements( functable
) ) )
1058 return GCI_UnsupportedType
;
1060 if ( *strsize
< 128 )
1061 return GCI_BufferTooSmall
;
1066 if ( functable
[size
].i2sfunc
== NULL
)
1067 return GCI_UnsupportedType
;
1068 return functable
[size
].i2sfunc( hidden
, base
, str
, strsize
);
1071 if ( functable
[size
].u2sfunc
== NULL
)
1072 return GCI_UnsupportedType
;
1073 return functable
[size
].u2sfunc( hidden
, base
, str
, strsize
);
1076 if ( functable
[size
].f2sfunc
== NULL
)
1077 return GCI_UnsupportedType
;
1078 return functable
[size
].f2sfunc( hidden
, base
, str
, strsize
);
1082 return GCI_BufferTooSmall
;
1084 return GCI_UnsupportedType
;
1085 str
[0] = *((char *) base
);
1093 return GCI_UnsupportedType
;
1097 * GCI_validate tests whether a specific type is supported by both conversion
1098 * routines. If basetype is set, an additional test is done for a base type.
1100 * The return code is
1101 * GCI_OK Everything is perfect.
1102 * GCI_UnsupportedType The combination of size/type is unknown or not
1104 * GCI_NoBaseType The type won't fit the requirements for basic types.
1106 GCI_result
GCI_validate( int size
,
1110 if ( !functable_assigned
)
1114 return GCI_UnsupportedType
;
1116 if ( ( type
== GCI_string
) ||
1117 ( type
== GCI_raw
) ||
1118 ( type
== GCI_container
) ||
1119 ( type
== GCI_array
) )
1120 return ( basetype
) ? GCI_NoBaseType
: GCI_OK
;
1122 if ( size
>= (int) elements( functable
) )
1123 return GCI_UnsupportedType
;
1128 if ( ( functable
[size
].i2sfunc
== NULL
) ||
1129 ( functable
[size
].s2ifunc
== NULL
) )
1130 return GCI_UnsupportedType
;
1134 if ( ( functable
[size
].u2sfunc
== NULL
) ||
1135 ( functable
[size
].s2ufunc
== NULL
) )
1136 return GCI_UnsupportedType
;
1140 if ( ( functable
[size
].f2sfunc
== NULL
) ||
1141 ( functable
[size
].s2ffunc
== NULL
) )
1142 return GCI_UnsupportedType
;
1146 if ( size
!= 1 ) /* we don't support unicode or other MBCS */
1147 return GCI_UnsupportedType
;
1153 return GCI_UnsupportedType
;