bringing SDL 1.2.14 from vendor into the main branch
[AROS-Contrib.git] / regina / arxfuncs.c
blobe7b32eb54680df61e1f1b41be3855f0930001fe5
1 /*
2 * ARexx functions for regina
3 * Copyright © 2002, Staf Verhaegen
4 *
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.
20 /* This files contains functions that are implemented in ARexx
21 * but that are not standard REXX functions. This file contains
22 * the functions that can be used on all platforms. amifuncs.c
23 * contains the ARexx functions that are only usable on the
24 * amiga platform or compatibles. (not implemented yet)
26 #include "rexx.h"
27 #include <stdio.h>
28 #include <ctype.h>
29 #include <stdlib.h>
30 #include <assert.h>
32 #if !defined(HAVE_DRAND48)
33 #include "rand48.c"
34 #endif
36 static const streng _fname = {1, 1, "F"}, _fstem = {4, 4, {'F', 'I', '.', 'F'}};
38 typedef struct _arexx_tsd_t {
39 proclevel amilevel;
40 } arexx_tsd_t;
44 /* Init thread data for arexx functions
46 int init_arexxf ( tsd_t *TSD )
48 arexx_tsd_t *atsd = (arexx_tsd_t *)malloc( sizeof(arexx_tsd_t) );
50 if (atsd==NULL) return 0;
52 TSD->arx_tsd = (void *)atsd;
54 /* Allocate later because systeminfo is not initialized at the moment */
55 atsd->amilevel = NULL;
57 return 1;
62 * Support functions for the ARexx IO functions
64 /* setamilevel will change the environment to the variables used for open files */
65 static proclevel setamilevel( tsd_t *TSD )
67 arexx_tsd_t *atsd = (arexx_tsd_t *)TSD->arx_tsd;
68 proclevel oldlevel = TSD->currlevel;
70 if (atsd->amilevel!=NULL)
71 TSD->currlevel = atsd->amilevel;
72 else
74 char txt[20];
76 atsd->amilevel = newlevel( TSD, NULL );
78 TSD->currlevel = atsd->amilevel;
80 setvalue( TSD, &_fname, Str_cre_TSD( TSD, "STDIN" ) );
81 sprintf( txt, "%p", stdin );
82 setvalue( TSD, &_fstem, Str_cre_TSD( TSD, txt ) );
84 setvalue( TSD, &_fname, Str_cre_TSD( TSD, "STDOUT" ) );
85 sprintf( txt, "%p", stdout );
86 setvalue( TSD, &_fstem, Str_cre_TSD( TSD, txt ) );
88 setvalue( TSD, &_fname, Str_cre_TSD( TSD, "STDERR" ) );
89 sprintf( txt, "%p", stderr );
90 setvalue( TSD, &_fstem, Str_cre_TSD( TSD, txt ) );
93 return oldlevel;
97 /* getfile will return the FILE pointer of given name */
98 static FILE *getfile( tsd_t *TSD, const streng *name )
100 proclevel oldlevel = setamilevel( TSD );
101 const streng *s;
102 char *txt;
103 FILE *file=NULL;
105 setvalue( TSD, &_fname, Str_dup_TSD( TSD, name ) );
106 if ( isvariable( TSD, &_fstem ) )
108 s = getvalue( TSD, &_fstem, 0 );
109 txt = str_of( TSD, s );
110 sscanf( txt, "%p", &file );
111 FreeTSD( txt );
114 TSD->currlevel = oldlevel;
116 return file;
120 /* getfilenames will return a list of all opened files */
121 static streng *getfilenames( tsd_t *TSD, const streng *sep )
123 proclevel oldlevel = setamilevel( TSD );
124 streng *retval, *tmpstr;
125 int first = 1;
126 variableptr var;
128 get_next_variable( TSD, 1 );
129 for ( var = get_next_variable( TSD, 0);
130 var != NULL;
131 var = get_next_variable( TSD, 0) )
133 while ( var != NULL && var->realbox != NULL )
134 var = var->realbox;
136 if ( var != NULL && ( (var->flag & (VFLAG_STR | VFLAG_NUM)) || var->stem ) )
138 if ( first )
140 retval = Str_dup_TSD( TSD, var->name );
141 first = 0;
143 else
145 tmpstr = Str_cat_TSD( TSD, retval, sep );
146 if ( tmpstr != retval )
148 Free_string_TSD( TSD, retval );
149 retval = tmpstr;
151 tmpstr = Str_cat_TSD( TSD, retval, var->name );
152 if ( tmpstr != retval )
154 Free_string_TSD( TSD, retval );
155 retval = tmpstr;
161 TSD->currlevel = oldlevel;
163 /* If no variable present return NULL string */
164 if (first)
165 retval = nullstringptr();
167 return retval;
170 /* addfile: store the FILE pointer in a given name */
171 static void addfile( tsd_t *TSD, const streng *name, FILE *file )
173 proclevel oldlevel = setamilevel( TSD );
174 char txt[20];
175 streng *s;
177 sprintf( txt, "%p", (void *)file );
178 s = Str_cre_TSD( TSD, txt );
179 setvalue( TSD, &_fname, Str_dup_TSD( TSD, name ) );
180 setvalue( TSD, &_fstem, s );
182 TSD->currlevel = oldlevel;
186 /* rmfile: remove a given of open files list */
187 static void rmfile( tsd_t *TSD, const streng *name )
189 arexx_tsd_t *atsd = (arexx_tsd_t *)TSD->arx_tsd;
190 proclevel oldlevel = setamilevel( TSD );
192 TSD->currlevel = atsd->amilevel;
194 drop_var( TSD, name );
196 TSD->currlevel = oldlevel;
202 * Implementation of the ARexx IO functions
203 * See general documentation for more information
204 * Functions implemented: OPEN, CLOSE, READCH, READLN, WRITECH, WRITELN, EOF, SEEK
206 streng *arexx_open( tsd_t *TSD, cparamboxptr parm1 )
208 cparamboxptr parm2, parm3;
209 char *filename;
210 FILE *file;
211 int mode;
212 static const char* modestrings[] = {
213 "w",
214 "r+",
218 checkparam( parm1, 2, 3, "OPEN" );
219 parm2 = parm1->next;
220 parm3 = parm2->next;
222 file = getfile( TSD, parm1->value );
223 if ( file!=NULL )
225 return int_to_streng( TSD, 0 );
228 filename = str_of( TSD, parm2->value );
230 if ( parm3==NULL
231 || parm3->value==NULL
232 || parm3->value->len==0 )
233 mode=0;
234 else switch( getoptionchar( TSD, parm3->value, "OPEN", 3, "", "WRA" ) )
236 case 'W':
237 mode=0;
238 break;
240 case 'R':
241 mode=1;
242 break;
244 case 'A':
245 mode=2;
246 break;
248 default:
249 mode=0;
250 assert(0);
251 break;
254 file = fopen( filename, modestrings[mode] );
255 FreeTSD( filename );
257 if ( file==NULL )
259 return int_to_streng( TSD, 0 );
262 addfile( TSD, parm1->value, file );
263 return int_to_streng( TSD, 1);
267 streng *arexx_close( tsd_t *TSD, cparamboxptr parm1 )
269 FILE *file;
271 checkparam( parm1, 1, 1, "CLOSE" );
273 file = getfile( TSD, parm1->value );
274 if ( file==NULL )
275 return int_to_streng( TSD, 0 );
277 fclose( file );
278 rmfile( TSD, parm1->value );
280 return int_to_streng( TSD, 1 );
284 streng *arexx_writech( tsd_t *TSD, cparamboxptr parm1 )
286 cparamboxptr parm2;
287 char *txt;
288 FILE *file;
289 int count;
291 checkparam( parm1, 2, 2, "WRITECH" );
292 parm2 = parm1->next;
294 file = getfile( TSD, parm1->value );
295 if ( file==NULL )
296 exiterror( ERR_INCORRECT_CALL, 27, "WRITECH", tmpstr_of( TSD, parm1->value ));
298 txt = str_of( TSD, parm2->value );
299 count = fprintf( file, "%s", txt );
300 FreeTSD( txt );
302 return int_to_streng( TSD, count );
306 streng *arexx_writeln( tsd_t *TSD, cparamboxptr parm1 )
308 cparamboxptr parm2;
309 char *txt;
310 FILE *file;
311 int count;
313 checkparam( parm1, 2, 2, "WRITELN" );
314 parm2 = parm1->next;
316 file = getfile( TSD, parm1->value );
317 if ( file==NULL )
318 exiterror( ERR_INCORRECT_CALL, 27, "WRITELN", tmpstr_of( TSD, parm1->value ) );
320 txt = str_of( TSD, parm2->value );
321 count = fprintf(file, "%s\n", txt);
322 FreeTSD( txt );
324 return int_to_streng( TSD, count );
328 streng *arexx_seek( tsd_t *TSD, cparamboxptr parm1 )
330 cparamboxptr parm2, parm3;
331 FILE *file;
332 int pos, error, wench;
333 long offset;
335 checkparam( parm1, 2, 3, "SEEK" );
336 parm2 = parm1->next;
337 parm3 = parm2->next;
339 file = getfile( TSD, parm1->value );
340 if ( file==NULL )
341 exiterror( ERR_INCORRECT_CALL, 27, "SEEK", tmpstr_of( TSD, parm1->value ) );
343 offset = streng_to_int( TSD, parm2->value, &error );
344 if (error)
345 exiterror( ERR_INCORRECT_CALL, 11, "SEEK", 2, tmpstr_of( TSD, parm2->value ) );
347 if ( parm3==NULL
348 || parm3->value==NULL
349 || parm3->value->len == 0 )
350 wench = SEEK_CUR;
351 else switch( getoptionchar( TSD, parm3->value, "SEEK", 3, "", "CBE" ) )
353 case 'C':
354 wench = SEEK_CUR;
355 break;
357 case 'B':
358 wench = SEEK_SET;
359 break;
361 case 'E':
362 wench = SEEK_END;
363 break;
365 default:
366 wench = SEEK_CUR;
367 assert(0);
368 break;
371 pos = fseek( file, offset, wench );
372 return int_to_streng( TSD, pos );
376 streng *arexx_readch( tsd_t *TSD, cparamboxptr parm1 )
378 cparamboxptr parm2;
379 FILE *file;
381 checkparam( parm1, 1, 2, "READCH");
382 parm2 = parm1->next;
384 file = getfile( TSD, parm1->value );
385 if ( file==NULL )
386 exiterror( ERR_INCORRECT_CALL, 27, "READCH", tmpstr_of( TSD, parm1->value ) );
388 if ( parm2==NULL )
390 char buffer[2] = { 0, 0 };
392 buffer[0] = (char)getc( file );
394 return Str_cre_TSD( TSD, buffer );
396 else
398 int count, error;
399 char *buffer;
400 streng *ret;
402 count = streng_to_int( TSD, parm2->value, &error );
404 if ( error )
405 exiterror( ERR_INCORRECT_CALL, 11, "READCH", 2, tmpstr_of( TSD, parm2->value ) );
406 if ( count<=0 )
407 exiterror( ERR_INCORRECT_CALL, 14, "READCH", 2, tmpstr_of( TSD, parm2->value ) );
409 buffer = malloc( count + 1 );
411 count = fread( buffer, 1, count, file );
412 buffer[count + 1] = 0;
414 ret = Str_cre_TSD( TSD, buffer );
415 free(buffer);
416 return ret;
421 streng *arexx_readln( tsd_t *TSD, cparamboxptr parm )
423 FILE *file;
424 char buffer[1001];
426 checkparam( parm, 1, 1, "READLN");
428 file = getfile( TSD, parm->value );
429 if ( file==NULL )
430 exiterror( ERR_INCORRECT_CALL, 27, "READLN", tmpstr_of( TSD, parm->value ) );
432 fgets( buffer, 1001, file );
433 if ( buffer[strlen(buffer)-1]=='\n' )
434 buffer[strlen(buffer)-1]=0;
436 return Str_cre_TSD( TSD, buffer );
440 streng *arexx_eof( tsd_t *TSD, cparamboxptr parm )
442 FILE *file;
444 checkparam( parm, 1, 1, "EOF" );
446 file = getfile( TSD, parm->value );
447 if ( file==NULL )
448 exiterror( ERR_INCORRECT_CALL, 27, "EOF", tmpstr_of( TSD, parm->value ) );
450 return int_to_streng( TSD, feof( file )!=0 );
455 * Implementation of the additional conversion functions from ARexx
456 * Functions: B2C, C2B
458 streng *arexx_b2c( tsd_t *TSD, cparamboxptr parm )
460 parambox parm2;
461 streng *ret;
463 checkparam( parm, 1, 1, "B2C" );
465 parm2.next = NULL;
466 parm2.value = std_b2x( TSD, parm );
468 ret = std_x2c( TSD, &parm2 );
469 Free_string_TSD( TSD, parm2.value );
471 return ret;
475 streng *arexx_c2b( tsd_t *TSD, cparamboxptr parm )
477 parambox parm2;
478 streng *ret;
480 checkparam( parm, 1, 1, "B2C" );
482 parm2.next = NULL;
483 parm2.value = std_c2x( TSD, parm );
485 ret = std_x2b( TSD, &parm2 );
486 Free_string_TSD( TSD, parm2.value );
488 return ret;
493 * Implementation of the bitwise function from ARexx
494 * Functions: BITCHG, BITCLR, BITSET, BITTST, BITCOMP
496 streng *arexx_bitchg( tsd_t *TSD, cparamboxptr parm1 )
498 cparamboxptr parm2;
499 streng *ret;
500 int bit, error, byte;
501 div_t dt;
503 checkparam( parm1, 2, 2, "BITCHG" );
504 parm2 = parm1->next;
506 bit = streng_to_int( TSD, parm2->value, &error );
507 if ( error )
508 exiterror( ERR_INCORRECT_CALL, 11, "BITCHG", 2, tmpstr_of( TSD, parm2->value ) );
509 if ( bit<0 )
510 exiterror( ERR_INCORRECT_CALL, 13, "BITCHG", 2, tmpstr_of( TSD, parm2->value ) );
512 dt = div( bit, 8 );
514 byte = parm1->value->len-dt.quot-1;
515 if ( byte<0 )
516 exiterror( ERR_INCORRECT_CALL, 0 );
518 ret = Str_dup_TSD( TSD, parm1->value );
519 ret->value[byte]^=(char)(1<<dt.rem);
520 return ret;
524 streng *arexx_bitclr( tsd_t *TSD, cparamboxptr parm1 )
526 cparamboxptr parm2;
527 streng *ret;
528 int bit, error, byte;
529 div_t dt;
531 checkparam( parm1, 2, 2, "BITCLR" );
532 parm2 = parm1->next;
534 bit = streng_to_int( TSD, parm2->value, &error );
535 if ( error )
536 exiterror( ERR_INCORRECT_CALL, 11, "BITCLR", 2, tmpstr_of( TSD, parm2->value ) );
537 if ( bit<0 )
538 exiterror( ERR_INCORRECT_CALL, 13, "BITCLR", 2, tmpstr_of( TSD, parm2->value ) );
540 dt = div( bit, 8 );
542 byte = parm1->value->len-dt.quot-1;
543 if ( byte<0 )
544 exiterror( ERR_INCORRECT_CALL, 0 );
546 ret = Str_dup_TSD( TSD, parm1->value );
547 ret->value[byte]&=~(char)(1<<dt.rem);
548 return ret;
552 streng *arexx_bitset( tsd_t *TSD, cparamboxptr parm1 )
554 cparamboxptr parm2;
555 streng *ret;
556 int bit, error, byte;
557 div_t dt;
559 checkparam( parm1, 2, 2, "BITSET" );
560 parm2 = parm1->next;
562 bit = streng_to_int( TSD, parm2->value, &error );
563 if ( error )
564 exiterror( ERR_INCORRECT_CALL, 11, "BITSET", 2, tmpstr_of( TSD, parm2->value ) );
565 if ( bit<0 )
566 exiterror( ERR_INCORRECT_CALL, 13, "BITSET", 2, tmpstr_of( TSD, parm2->value ) );
568 dt = div( bit, 8 );
570 byte = parm1->value->len-dt.quot-1;
571 if ( byte<0 )
572 exiterror( ERR_INCORRECT_CALL, 0 );
574 ret = Str_dup_TSD( TSD, parm1->value );
575 ret->value[byte]|=(char)(1<<dt.rem);
576 return ret;
580 streng *arexx_bittst( tsd_t *TSD, cparamboxptr parm1 )
582 cparamboxptr parm2;
583 streng *ret;
584 int bit, error, byte;
585 div_t dt;
587 checkparam( parm1, 2, 2, "BITTST" );
588 parm2 = parm1->next;
590 bit = streng_to_int( TSD, parm2->value, &error );
591 if ( error )
592 exiterror( ERR_INCORRECT_CALL, 11, "BITTST", 2, tmpstr_of( TSD, parm2->value ) );
593 if ( bit<0 )
594 exiterror( ERR_INCORRECT_CALL, 13, "BITTST", 2, tmpstr_of( TSD, parm2->value ) );
596 dt = div( bit, 8 );
598 byte = parm1->value->len-dt.quot-1;
599 if ( byte<0 )
600 exiterror( ERR_INCORRECT_CALL, 0 );
602 ret = int_to_streng( TSD, (parm1->value->value[byte] & (char)(1<<dt.rem))!=0 );
603 return ret;
607 /* Help function for arexx_bitcomp */
608 static int firstbit(char c)
610 int i;
611 assert(c!=0);
613 for ( i=0; i<8; i++)
615 if (c & 1)
616 return i;
617 else
618 c = c >> 1;
621 return 8;
624 /* This ARexx function has very weird usage of the pad byte,
625 * the shortest string is padded on the left with this byte
627 streng *arexx_bitcomp( tsd_t *TSD, cparamboxptr parm1 )
629 cparamboxptr parm2, parm3;
630 const streng *s1, *s2;
631 const char *cp1, *cp2;
632 char pad;
633 int i;
635 checkparam( parm1, 2, 3, "BITCOMP" );
636 parm2 = parm1->next;
638 /* Make s2 always shorter or equal to s1 */
639 if ( parm1->value->len < parm2->value->len )
641 s1 = parm2->value;
642 s2 = parm1->value;
643 } else {
644 s1 = parm1->value;
645 s2 = parm2->value;
648 for ( cp1=s1->value+s1->len-1, cp2=s2->value+s2->len-1, i=0;
649 cp2 >= s2->value;
650 cp1--, cp2--, i++ )
652 if ( *cp1 != *cp2 )
653 return int_to_streng( TSD, i*8 + firstbit( *cp1 ^ *cp2 ) );
656 parm3 = parm2->next;
657 if ( parm3==NULL || parm3->value==NULL || parm3->value->len==0 )
658 pad = 0;
659 else
660 pad = parm3->value->value[0];
662 for ( ;
663 cp1 >= s1->value;
664 cp1--, i++ )
666 if ( *cp1 != pad )
667 return int_to_streng( TSD, i*8 + firstbit( *cp1 ^ pad ) );
670 return int_to_streng( TSD, -1 );
675 * Some more misc. ARexx functions
676 * Functions: COMPRESS, HASH, RANDU, TRIM, UPPER
678 streng *arexx_hash( tsd_t *TSD, cparamboxptr parm1 )
680 unsigned char *uc;
681 int i, sum=0;
683 checkparam( parm1, 1, 1, "HASH" );
685 uc = (unsigned char *)parm1->value->value;
686 for ( i=0; i<parm1->value->len; i++)
688 sum = (sum + uc[i]) & 255;
691 return int_to_streng( TSD, sum );
695 streng *arexx_compress( tsd_t *TSD, cparamboxptr parm1 )
697 const char *match;
698 int i, start;
699 streng *ret;
701 checkparam( parm1, 1, 2, "COMPRESS" );
703 match = ( parm1->next!=NULL ) ? str_of( TSD, parm1->next->value ) : " ";
705 ret = Str_dup_TSD( TSD, parm1->value );
706 for ( i=start=0; i<ret->len; i++ )
708 /* Copy char if not found */
709 if ( strchr( match, ret->value[i] )==NULL )
711 ret->value[start] = ret->value[i];
712 start++;
715 ret->len = start;
717 if ( parm1->next!=NULL )
718 FreeTSD( (char *)match );
720 return ret;
724 static const streng T_str = { 1, 1, "T" };
725 static const parambox T_parm = { NULL, 0, (streng *)&T_str };
727 streng *arexx_trim( tsd_t *TSD, cparamboxptr parm1 )
729 parambox parm;
731 checkparam( parm1, 1, 1, "TRIM" );
733 parm = *parm1;
734 parm.next = (paramboxptr)&T_parm;
736 return std_strip( TSD, parm1 );
740 streng *arexx_upper( tsd_t *TSD, cparamboxptr parm1 )
742 streng *ret;
744 checkparam( parm1, 1, 1, "UPPER" );
746 ret = Str_dup_TSD( TSD, parm1->value );
748 return Str_upper( ret );
752 streng *arexx_randu( tsd_t *TSD, cparamboxptr parm1 )
754 int error, seed;
755 char text[30];
756 streng *s, *retval;
758 checkparam( parm1, 0, 1, "RANDU" );
760 if ( parm1!=NULL && parm1->value!=NULL )
762 seed = streng_to_int( TSD, parm1->value, &error );
763 if ( error )
764 exiterror( ERR_INCORRECT_CALL, 11, "RANDU", 1, tmpstr_of( TSD, parm1->value ) );
766 srand48( (long int)seed );
769 sprintf( text, "%.20f", drand48() );
770 s = Str_cre_TSD( TSD, text );
771 retval = str_format( TSD, s, -1, -1, -1, -1);
772 FreeTSD( s );
774 return retval;
780 * Two memory allocation/deallocation functions: getspace and freespace
782 streng *arexx_getspace( tsd_t *TSD, cparamboxptr parm1 )
784 int length, error;
785 void *ptr;
787 checkparam( parm1, 1, 1, "GETSPACE" );
789 length = streng_to_int( TSD, parm1->value, &error);
790 if ( error )
791 exiterror( ERR_INCORRECT_CALL, 11, "GETSPACE", 1, tmpstr_of( TSD, parm1->value ) );
792 if ( length<=0 )
793 exiterror( ERR_INCORRECT_CALL, 14, "GETSPACE", 1, tmpstr_of( TSD, parm1->value ) );
795 ptr = Malloc_TSD( TSD, length );
796 memset( ptr, 0, length );
797 if ( ptr == NULL )
798 exiterror( ERR_STORAGE_EXHAUSTED, 0 );
800 return Str_ncre_TSD( TSD, (char *)&ptr, sizeof(void *) );
804 #if defined(_AMIGA) || defined(__AROS__)
805 #include <exec/memory.h>
806 #include <proto/exec.h>
807 #endif
809 streng *arexx_freespace( tsd_t *TSD, cparamboxptr parm1 )
811 /* For backwards compatibility there may be two arguments
812 But the second argument is ignored in regina */
813 checkparam( parm1, 0, 2, "FREESPACE" );
815 if ( parm1 == NULL || parm1->value == NULL || parm1->value->len == 0 )
816 #if defined(_AMIGA) || defined(__AROS__)
817 return int_to_streng( TSD, AvailMem( MEMF_ANY ) );
818 #else
819 return int_to_streng( TSD, -1 );
820 #endif
822 if ( parm1->value->len != sizeof(void *) )
823 exiterror( ERR_INCORRECT_CALL, 0 );
825 Free_TSD( TSD, *((void **)parm1->value->value) );
827 return nullstringptr();
834 * ARexx memory <-> string conversion routines: IMPORT, EXPORT, STORAGE
836 streng *arexx_import( tsd_t *TSD, cparamboxptr parm1 )
838 void *memptr;
839 cparamboxptr parm2;
840 int len, error;
842 checkparam( parm1, 1, 2, "IMPORT" );
844 if ( parm1->value->len != sizeof(void *) )
845 exiterror( ERR_INCORRECT_CALL, 0 );
847 memptr = *((void **)parm1->value->value);
849 parm2 = parm1->next;
850 if ( parm2 == NULL || parm2->value == NULL || parm2->value->len == 0 )
851 len = strlen((char *)memptr);
852 else
854 len = streng_to_int( TSD, parm2->value, &error );
855 if ( error )
856 exiterror( ERR_INCORRECT_CALL, 11, "IMPORT", 2, tmpstr_of( TSD, parm2->value ) );
857 if ( len<=0 )
858 exiterror( ERR_INCORRECT_CALL, 14, "IMPORT", 2, tmpstr_of( TSD, parm2->value ) );
861 return Str_ncre_TSD( TSD, memptr, len );
865 streng *arexx_export( tsd_t *TSD, cparamboxptr parm1 )
867 void *memptr;
868 cparamboxptr parm2 = NULL, parm3 = NULL, parm4 = NULL;
869 int len, error;
870 char fill;
871 streng *src;
873 checkparam( parm1, 1, 4, "EXPORT" );
875 if ( parm1->value == NULL || parm1->value->len == 0 )
876 exiterror( ERR_INCORRECT_CALL, 21, "EXPORT", 1 );
877 memptr = *((void **)parm1->value->value);
879 parm2 = parm1->next;
880 if ( parm2 != NULL )
881 parm3 = parm2->next;
882 if ( parm3 != NULL )
883 parm4 = parm3->next;
885 if ( parm2 == NULL || parm2->value == NULL || parm2->value->len == 0 )
886 src = nullstringptr();
887 else
888 src = Str_dup_TSD( TSD, parm2->value );
890 if ( parm3 == NULL || parm3->value == NULL || parm3->value->len == 0 )
891 len = src->len;
892 else
894 len = streng_to_int( TSD, parm3->value, &error );
895 if ( error )
896 exiterror( ERR_INCORRECT_CALL, 11, "EXPORT", 3, tmpstr_of( TSD, parm3->value ) );
897 if ( len<0 )
898 exiterror( ERR_INCORRECT_CALL, 13, "EXPORT", 3, tmpstr_of( TSD, parm3->value ) );
901 if ( parm4 == NULL || parm4->value == NULL || parm4->value->len == 0 )
902 fill = 0;
903 else
904 fill = parm4->value->value[0];
906 if (len > src->len)
908 memcpy( memptr, src->value, src->len );
909 memset( ((char *)memptr)+src->len, fill, len - src->len );
911 else
912 memcpy( memptr, src->value, len );
914 Free_string_TSD( TSD, src );
916 return int_to_streng( TSD, len );
920 streng *arexx_storage( tsd_t *TSD, cparamboxptr parm1 )
922 void *memptr;
923 cparamboxptr parm2 = NULL, parm3 = NULL, parm4 = NULL;
924 int len, error;
925 char fill;
926 streng *src, *retval;
928 checkparam( parm1, 0, 4, "STORAGE" );
930 if ( parm1 == NULL )
931 return arexx_getspace( TSD, NULL );
933 if ( parm1->value == NULL || parm1->value->len == 0 )
934 exiterror( ERR_INCORRECT_CALL, 21, "STORAGE", 1 );
935 memptr = *((void **)parm1->value->value);
937 parm2 = parm1->next;
938 if ( parm2 != NULL )
939 parm3 = parm2->next;
940 if ( parm3 != NULL )
941 parm4 = parm3->next;
943 if ( parm2 == NULL || parm2->value == NULL || parm2->value->len == 0 )
944 src = nullstringptr();
945 else
946 src = Str_dup_TSD( TSD, parm2->value );
948 if ( parm3 == NULL || parm3->value == NULL || parm3->value->len == 0 )
949 len = src->len;
950 else
952 len = streng_to_int( TSD, parm3->value, &error );
953 if ( error )
954 exiterror( ERR_INCORRECT_CALL, 11, "STORAGE", 3, tmpstr_of( TSD, parm3->value ) );
955 if ( len<0 )
956 exiterror( ERR_INCORRECT_CALL, 13, "STORAGE", 3, tmpstr_of( TSD, parm3->value ) );
959 if ( parm4 == NULL || parm4->value == NULL || parm4->value->len == 0 )
960 fill = 0;
961 else
962 fill = parm4->value->value[0];
964 retval = Str_ncre_TSD( TSD, memptr, len );
966 if (len > src->len)
968 memcpy( memptr, src->value, src->len );
969 memset( ((char *)memptr)+src->len, fill, len - src->len );
971 else
972 memcpy( memptr, src->value, len );
974 Free_string_TSD( TSD, src );
976 return retval;
982 * SHOW a function the names available in different resource lists
984 streng *arexx_show( tsd_t *TSD, cparamboxptr parm1 )
986 cparamboxptr parm2 = NULL, parm3 = NULL;
987 streng *name = NULL, *sep, *retval;
989 checkparam( parm1, 1, 3, "SHOW" );
990 parm2 = parm1->next;
991 if ( parm2 != NULL )
992 parm3 = parm2->next;
994 if ( parm2 != NULL && parm2->value != NULL && parm2->value->len != 0 )
995 name = parm2->value;
997 if ( parm3 == NULL || parm3->value == NULL || parm3->value->len == 0 )
998 sep = Str_cre_TSD( TSD, " " );
999 else
1000 sep = Str_dup_TSD( TSD, parm3->value );
1002 switch( getoptionchar( TSD, parm1->value, "SHOW", 1, "", "F" ) )
1004 case 'F':
1005 if ( name == NULL )
1006 retval = getfilenames( TSD, sep );
1007 else
1009 FILE *f = getfile( TSD, name );
1010 retval = int_to_streng( TSD, f != NULL );
1012 break;
1014 Free_string_TSD( TSD, sep );
1016 return retval;