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 contains little helper routines.
30 /*****************************************************************************
31 *****************************************************************************
32 ** GLOBAL FUNCTIONS *********************************************************
33 *****************************************************************************
34 *****************************************************************************/
37 * GCI_strlen returns the current length of the string.
39 int GCI_strlen( const GCI_str
*str
)
45 * GCI_strmax returns the maximum length of the string including any
48 int GCI_strmax( const GCI_str
*str
)
54 * GCI_content returns a pointer to the content of str. The content may not be
57 char * GCI_content( GCI_str
*str
)
63 * GCI_content returns a pointer to the content of str. The content may not be
66 const char * GCI_ccontent( const GCI_str
*str
)
72 * GCI_streq returns 1 if two string have an equal content, 0 otherwise.
74 int GCI_streq( const GCI_str
*s1
,
81 return ( memcmp( s1
->val
, s2
->val
, l
) == 0 ) ? 1 : 0;
85 * concat appends the content of second to first. second_len contains the
86 * length of second. second may not be 0-terminated.
87 * The return value is either GCI_OK or GCI_BufferTooSmall.
89 static GCI_result
concat( GCI_str
*first
,
93 if ( first
->used
+ size
> first
->max
)
94 return GCI_BufferTooSmall
;
96 memcpy( first
->val
+ first
->used
, second
, size
);
102 * GCI_strcat appends the content of second to first.
103 * The return value is either GCI_OK or GCI_BufferTooSmall.
105 GCI_result
GCI_strcat( GCI_str
*first
,
106 const GCI_str
*second
)
108 return concat( first
, second
->val
, second
->used
);
112 * GCI_strcats appends the content of the 0-terminated string second to first.
113 * The return value is either GCI_OK or GCI_BufferTooSmall.
115 GCI_result
GCI_strcats( GCI_str
*first
,
118 return concat( first
, second
, strlen( second
) );
122 * GCI_strsetlen sets the length of str to max. If max if bigger than the
123 * string's internal maximum it is set to the string's internal maximum.
125 void GCI_strsetlen( GCI_str
*str
,
128 if ( str
->max
< max
)
129 str
->used
= str
->max
;
135 * GCI_strcpy sets the content of first to the content of second.
136 * The return value is either GCI_OK or GCI_BufferTooSmall.
138 GCI_result
GCI_strcpy( GCI_str
*first
,
139 const GCI_str
*second
)
141 if ( first
->max
< second
->used
)
142 return GCI_BufferTooSmall
;
144 memcpy( first
->val
, second
->val
, second
->used
);
145 first
->used
= second
->used
;
150 * GCI_strfromascii creates a GCI_str from a character pointer. The content's
151 * maximum is set to max, the content itself is taken from ptr.
152 * The used length is set to 0.
153 * THE FILLED GCI_str MUST NEVER BE PASSED TO GCI_strfree!
154 * The passed string is returned.
156 GCI_str
*GCI_strfromascii( GCI_str
*str
,
168 * GCI_migratefromascii creates a GCI_str from a character pointer.
169 * The content's maximum and its length is set to length of the zero-terminated
170 * string in ptr, the content itself is taken from ptr.
171 * THE FILLED GCI_str MUST NEVER BE PASSED TO GCI_strfree!
172 * The passed string is returned.
174 const GCI_str
*GCI_migratefromascii( GCI_str
*str
,
177 str
->val
= (char *) ptr
;
178 str
->used
= strlen( ptr
);
179 str
->max
= str
->used
;
185 * GCI_stralloc allocates the content of a string. The content will have
186 * size bytes. The former content won't be freed if there is something
188 * The return value is either GCI_OK or GCI_NoMemory.
190 GCI_result
GCI_stralloc( void *hidden
,
198 if ( ( str
->val
= (char *) GCI_malloc( hidden
, size
) ) == NULL
)
207 * GCI_strfree deallocates the content of a string. The string itself isn't
208 * freed. The content is set to NULL.
210 void GCI_strfree( void *hidden
,
215 if ( str
->val
!= NULL
)
216 GCI_free( hidden
, str
->val
);
219 str
->max
= str
->used
= 0;
223 * GCI_strdup duplicates the content of a string second and assigns it to
224 * first. The content of first will be overwritten without any cleanup.
225 * This function allocates the needed bytes only.
226 * The return value is either GCI_OK or GCI_NoMemory.
228 GCI_result
GCI_strdup( void *hidden
,
230 const GCI_str
*second
)
234 if ( ( first
->val
= (char *) GCI_malloc( hidden
, second
->used
) ) == NULL
)
237 memcpy( first
->val
, second
->val
, second
->used
);
238 first
->used
= first
->max
= second
->used
;
243 * GCI_strtoascii duplicates the content of the string str to a newly created
244 * ASCIIZ string which is returned. NULL is returned in case of an error or
245 * if str describes a NULL string (in opposite to an empty string).
247 char *GCI_strtoascii( void *hidden
,
254 if ( ( str
== NULL
) || ( str
->val
== NULL
) )
256 if ( ( retval
= (char *) GCI_malloc( hidden
, str
->used
+ 1 ) ) == NULL
)
259 memcpy( retval
, str
->val
, str
->used
);
260 retval
[str
->used
] = '\0';
265 * GCI_uppercase transforms the content of str to its uppercased value.
266 * We may or may not convert foreign characters. It depends on the runtime
267 * system and on the environment settings of codepage/language.
269 void GCI_uppercase( void *hidden
,
272 int i
, len
= str
->used
;
273 char *ptr
= str
->val
;
277 for ( i
= 0; i
< len
; i
++, ptr
++ )
278 *ptr
= (char) GCI_toupper( *ptr
);
282 * GCI_describe converts a GCI_result to a more or less human readable
283 * string. The caller shall provide a string with at least 80 byte.
284 * THIS FUNCTION IS NOT THREAD SAFE.
286 void GCI_describe( GCI_str
*description
,
293 { /* oversized lines! */ /* here is the limit for the text: -->blahblah" */
294 case GCI_OK
: ptr
= "GCI completed successfully"; break;
295 case GCI_NoMemory
: ptr
= "Out of memory while processing a GCI request"; break;
296 case GCI_WrongInput
: ptr
= "Unexpected input, either unknown type or illegal data"; break;
297 case GCI_NumberRange
: ptr
= "Number out of the allowed range"; break;
298 case GCI_StringRange
: ptr
= "String too big for the defined buffer"; break;
299 case GCI_UnsupportedType
: ptr
= "Illegal combination of type/size"; break;
300 case GCI_UnsupportedNumber
: ptr
= "Unsupported number like NAN, +INF, -INF"; break;
301 case GCI_BufferTooSmall
: ptr
= "Structure too complex for static internal buffer"; break;
302 case GCI_MissingName
: ptr
= "An element of the structure is missing"; break;
303 case GCI_MissingValue
: ptr
= "A value of the structure is missing"; break;
304 case GCI_IllegalName
: ptr
= "The name or part of the name is illegal for the interpreter"; break;
305 case GCI_RexxError
: ptr
= "A problem raises when communicating with the interpreter"; break;
306 case GCI_NoBaseType
: ptr
= "The type won't fit the requirements for basic types (arguments/return value)"; break;
307 case GCI_InternalError
: ptr
= "An unknown internal GCI error occured"; break;
308 case GCI_FunctionAlreadyKnown
: ptr
= "New REXX function already registered to the interpreter"; break;
309 case GCI_LibraryNotFound
: ptr
= "The external library was not found or can't be loaded"; break;
310 case GCI_NoLibraryFunction
: ptr
= "The external function can't be found in the external library"; break;
311 case GCI_FunctionNotFound
: ptr
= "The REXX function was not or no longer registered by the interpreter"; break;
312 case GCI_SyntaxError
: ptr
= "The number of arguments is wrong or an argument is missing"; break;
313 case GCI_CoreConfused
: ptr
= "The core of GCI can't determine how to invoke generic functions"; break;
314 case GCI_ArgStackOverflow
: ptr
= "GCI's internal stack for arguments got an overflow"; break;
315 case GCI_NestingOverflow
: ptr
= "GCI counted too many nested LIKE containers"; break;
323 sprintf( buf
, "Unknown GCI error %d", rc
);
325 description
->val
= ptr
;
326 description
->used
= strlen(ptr
);
327 description
->max
= description
->used
;
331 * GCI_strswap exchanges two strings' content completely.
333 void GCI_strswap( GCI_str
*first
,