2 * The Regina Rexx Interpreter
3 * Copyright (C) 1992-1994 Anders Christensen <anders@pvv.unit.no>
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.
21 * Bug in LCC complier wchar.h that incorrectly says it defines stat struct
25 # include <sys/stat.h>
30 #if defined(WIN32) && defined(__IBMC__)
32 #pragma warning(default: 4115 4201 4214)
36 # if defined(__WATCOMC__) && defined(__NT__)
40 # if defined(__MINGW32__) || defined(__LCC__)
44 # if defined(WIN32) && defined(__BORLANDC__)
49 # if defined(_MSC_VER)
52 /* Stupid MSC can't compile own headers without warning at least in VC 5.0 */
53 # pragma warning(disable: 4115 4201 4214 4514)
57 # pragma warning(default: 4115 4201 4214)
60 # else /* not RXLIB */
61 # if defined(__WATCOMC__) && defined(__NT__)
64 # if defined(__MINGW32__) || defined(__LCC__)
67 # if defined(WIN32) && defined(__BORLANDC__)
71 # if defined(_MSC_VER) && !defined(__WINS__)
73 /* Stupid MSC can't compile own headers without warning at least in VC 5.0 */
74 # pragma warning(disable: 4115 4201 4214 4514)
78 # pragma warning(default: 4115 4201 4214)
84 #if defined(OS2) || defined(__EMX__)
85 # if defined(__WATCOMC__) && defined(RXLIB)
87 # elif defined(__INNOTEK_LIBC__)
89 # define APIENTRY _System
93 # define DONT_TYPEDEF_PFN
106 # include <sys/stat.h>
109 #if defined(DJGPP) || defined(__EMX__) || defined(_MSC_VER) || (defined(__WATCOMC__) && !defined(__QNX__)) || defined(__EPOC32__)
111 # if !defined(__WINS__) && !defined(__EPOC32__)
121 * Since development of Ultrix has ceased, and they never managed to
122 * fix a few things, we want to define a few things, just in order
123 * to kill a few warnings ...
125 #if defined(FIX_PROTOS) && defined(FIX_ALL_PROTOS) && defined(ultrix)
126 int fstat( int fd
, struct stat
*buf
) ;
127 int stat( char *path
, struct stat
*buf
) ;
131 /* Don't terminate the following lines by a semicolon */
132 GLOBAL_PROTECTION_VAR(regina_globals
)
136 * Note: must match the settings of NUM_FORM_* in flags.h
138 const char *numeric_forms
[] = { "SCIENTIFIC", "ENGINEERING" } ;
141 * Note: these must match the definitions of INVO_* in defs.h
143 const char *invo_strings
[] = { "COMMAND", "FUNCTION", "SUBROUTINE" } ;
145 const char *argv0
= NULL
;
148 * The following global is to store the TSD of the currently running
149 * interpreter instance.
150 * Each API call checks this variable, and if not NULL, this is used
152 * This enables multiple threads to run within the one interpreter instance.
153 * Set by OPTIONS SINGLE_INTERPRETER
155 tsd_t
*__regina_global_TSD
= NULL
;
157 static void usage( char * );
160 void marksubtree( nodeptr ptr
)
166 markmemory( ptr
, TRC_TREENODE
);
169 markmemory( ptr
->name
, TRC_TREENODE
);
171 for ( i
= 0; i
< sizeof( ptr
->p
) / sizeof( ptr
->p
[0] ); i
++ )
172 marksubtree( ptr
->p
[i
] );
175 if ( ( ptr
->type
== X_STRING
) || ( ptr
->type
== X_CON_SYMBOL
) )
179 markmemory( ptr
->u
.number
, TRC_TREENODE
);
180 markmemory( ptr
->u
.number
->num
, TRC_TREENODE
);
183 else if ( ptr
->type
== X_CEXPRLIST
)
186 markmemory( ptr
->u
.strng
, TRC_TREENODE
);
192 #endif /* TRACEMEM */
196 * GetArgv0 tries to find the fully qualified filename of the current program.
197 * It uses some ugly and system specific tricks and it may return NULL if
198 * it can't find any useful value.
199 * The argument should be argv[0] of main() and it may be returned.
200 * This function must not be called from another as the sole one when starting
203 static const char *GetArgv0(const char *argv0
)
208 if (GetModuleFileName(NULL
, buf
, sizeof(buf
)) != 0)
209 return(strdup(buf
)); /* never freed up */
210 #elif defined(__QNX__) && defined(__WATCOMC__)
211 char buffer
[PATH_MAX
];
213 if ( (buf
= _cmdname(buffer
) ) != NULL
)
214 return(strdup(buf
)); /* never freed up */
220 if (_osmode
== OS2_MODE
)
223 if (DosGetInfoBlocks(NULL
, &ppib
) == 0)
224 if (DosQueryModuleName(ppib
->pib_hmte
, sizeof(buf
), buf
) == 0)
234 * will work on Linux 2.1+
238 result
= readlink("/proc/self/exe", buf
, sizeof( buf
) );
239 if ( ( result
> 0 ) && ( result
< (int) sizeof( buf
) ) && ( buf
[0] != '[' ) )
242 return strdup( buf
);
246 /* No specific code has found the right file name. Maybe, it's coded
247 * in argv0. Check it, if it is an absolute path. Be absolutely sure
248 * to detect it safely!
253 if (argv0
[0] == '/') /* unix systems and some others */
256 if ((argv0
[0] == '\\') && (argv0
[1] == '\\')) /* MS and OS/2 UNC names */
259 if (rx_isalpha(argv0
[0]) && (argv0
[1] == ':') && (argv0
[2] == '\\'))
260 return(argv0
); /* MS and OS/2 drive letter with path */
262 return(NULL
); /* not a proven argv0 argument */
267 * setup_system sets up some basics which are needed to use parts of the
269 * This is a common routine of rexx's or regina's main() and every
271 * isclient should be set to 1 if called from the SAA interface, 0 otherwise.
273 * Note that you have to set TSD->currlevel->script_exit as fast as possible.
274 * Otherwise you are at high risk that an error will stop the whole process,
275 * which is fatal if an application uses us via SAA API.
277 void setup_system( tsd_t
*TSD
, int isclient
)
279 TSD
->stddump
= stderr
;
281 TSD
->systeminfo
= creat_sysinfo( TSD
, Str_creTSD( "SYSTEM" ) );
283 TSD
->systeminfo
->currlevel0
= TSD
->currlevel
= newlevel( TSD
, NULL
);
284 TSD
->systeminfo
->trace_override
= 0;
285 TSD
->isclient
= isclient
;
289 * check_args examines the arguments of the program and assigns the values
290 * to the various structures.
292 * A process exit of 0 is required if 0 is returned. Otherwise the number
293 * of processed args including the zeroth is returned.
295 static int check_args( tsd_t
*TSD
, int argc
, char **argv
,
296 int *compile_to_tokens
, int *execute_from_tokens
,
302 for ( i
= 1; i
< argc
; i
++ )
315 set_trace_char( TSD
, 'A' );
321 #if !defined(__WINS__) && !defined(__EPOC32__)
327 fprintf( stderr
, "%s\n", PARSE_VERSION_STRING
);
329 * Also display any staticall linked packages
331 #if defined( DYNAMIC_STATIC )
332 static_list_packages();
338 __reginadebug
= 1; /* yacc-debugging */
342 case 'r': /* safe-rexx */
347 if ( strlen( arg
) > 1 )
350 fprintf( stdout
, "\n"
351 "The passed switch `-t' allows just "
352 "one additional character, Regina "
357 queue_trace_char( TSD
, *arg
);
359 queue_trace_char( TSD
, 'A' );
360 arg
+= strlen( arg
);
361 TSD
->systeminfo
->trace_override
= 1;
366 TSD
->listleakedmemory
= 1;
367 arg
+= strlen( arg
);
370 case 'a': /* multiple args */
371 TSD
->systeminfo
->invoked
= INVO_SUBROUTINE
;
374 case 'c': /* compile to tokenised file */
375 if ( *execute_from_tokens
)
378 fprintf( stdout
, "\n"
379 "The flags `-c' and `-e' are mutually "
380 "exclusive, Regina exits.\n" );
383 *compile_to_tokens
= 1;
386 case 'e': /* execute from tokenised file */
387 if ( *compile_to_tokens
)
390 fprintf( stdout
, "\n"
391 "The flags `-c' and `-e' are mutually "
392 "exclusive, Regina exits.\n" );
395 *execute_from_tokens
= 1;
398 case 'l': /* set locale information, accept empty string */
400 set_locale_info( arg
);
401 arg
+= strlen( arg
);
404 case 'h': /* usage */
405 case '?': /* usage */
411 fprintf( stdout
, "\n"
412 "The passed switch `-%c' is unknown, "
413 "Regina exits.\n", c
);
427 * just_compile does a compile step without execution of the assigned input
428 * file (TSD->systeminfo's input_file) to the file named outputname.
430 * On exit everything has been done.
432 static void just_compile( tsd_t
*TSD
, char *outputname
)
436 internal_parser_type ipt
;
438 unsigned long instore_length
;
444 fseek( TSD
->systeminfo
->input_fp
, 0, SEEK_END
);
445 len
= (int) ftell( TSD
->systeminfo
->input_fp
);
446 rewind( TSD
->systeminfo
->input_fp
);
448 SrcStr
= Str_makeTSD( len
);
449 if ( fread( Str_val( SrcStr
), len
, 1, TSD
->systeminfo
->input_fp
) != 1 )
450 exiterror( ERR_PROG_UNREADABLE
, 1, "Unable to read input file" );
454 * enter_macro() actually does the tokenising...
456 ipt
= enter_macro( TSD
, SrcStr
, &instore_buf
, &instore_length
);
457 (void)ipt
; // FIXME: Should this be tested for success?
458 fclose( TSD
->systeminfo
->input_fp
);
460 outfp
= fopen( outputname
, "wb" );
462 exiterror( ERR_PROG_UNREADABLE
, 1, "Unable to open output file for "
464 if ( instore_buf
== NULL
)
465 exiterror( ERR_PROG_UNREADABLE
, 1, "Error tokenising input file" );
466 if ( fwrite( instore_buf
, instore_length
, 1, outfp
) != 1 )
467 exiterror( ERR_PROG_UNREADABLE
, 1, "Unable to write contents of output "
473 * assign_args sets the current argument list to that one in argv. We count
474 * from the next_arg element to to excluding argc.
476 * The value is put in TSD->currlevel->args which has to be preeassigned to
479 static void assign_args( tsd_t
*TSD
, int argc
, int next_arg
, char **argv
)
483 paramboxptr args
, prev
;
485 if ( next_arg
>= argc
)
488 if ( TSD
->systeminfo
->invoked
== INVO_SUBROUTINE
)
491 for ( i
= next_arg
; i
< argc
; i
++ )
493 args
= (paramboxptr
)MallocTSD( sizeof( parambox
) );
494 memset( args
, 0, sizeof( parambox
) );
497 TSD
->currlevel
->args
= args
;
500 args
->value
= Str_cre_TSD( TSD
, argv
[i
] );
507 for ( i
= next_arg
, len
= 0; i
< argc
; i
++ )
508 len
+= strlen( argv
[i
] ) + 1; /* delimiter or terminator */
510 TSD
->currlevel
->args
= (paramboxptr
)MallocTSD( sizeof( parambox
) );
511 if ( TSD
->currlevel
->args
== NULL
)
512 exiterror( ERR_STORAGE_EXHAUSTED
, 0 );
513 args
= TSD
->currlevel
->args
;
514 memset( args
, 0, sizeof(parambox
) );
515 args
->value
= string
= Str_makeTSD( len
);
517 for ( i
= next_arg
; i
< argc
; i
++ )
519 string
= Str_catstrTSD( string
, argv
[i
] );
520 string
->value
[string
->len
++] = ' ';
522 if ( string
&& string
->len
)
527 * codeFromString translates string into a number and returns it. If this is
528 * not possible, EXIT_SUCCESS is returned.
530 static int codeFromString( tsd_t
*TSD
, streng
*string
)
536 /* fixes bug 657345 */
537 rcode
= streng_to_int( TSD
, string
, &error
);
539 rcode
= EXIT_SUCCESS
;
542 rcode
= EXIT_SUCCESS
;
548 * execute_tokenized executes a tokenized script that has already been assigned
551 * The arguments must have been assigned, too.
553 * The return value is the value that the main routine should return to the OS.
555 static int execute_tokenized( tsd_t
*TSD
)
558 unsigned long TinnedTreeLen
;
565 * Read the file into TinnedTree.
567 fseek( TSD
->systeminfo
->input_fp
, 0, SEEK_END
);
568 TinnedTreeLen
= ftell( TSD
->systeminfo
->input_fp
);
569 rewind( TSD
->systeminfo
->input_fp
);
570 TinnedTree
= MallocTSD( TinnedTreeLen
);
571 if ( TinnedTree
== NULL
)
572 exiterror( ERR_STORAGE_EXHAUSTED
, 0 );
573 if ( fread( TinnedTree
, TinnedTreeLen
, 1, TSD
->systeminfo
->input_fp
) != 1 )
574 exiterror( ERR_PROG_UNREADABLE
, 1, "Unable to read input file" );
576 * Don't close the file because the plain text file remains open as well.
577 * This inhibits the deletion or modification on most systems.
581 * Check if the file being read is a valid tokenised file.
583 if ( !IsValidTin( (const external_parser_type
*)TinnedTree
, TinnedTreeLen
) )
584 exiterror( ERR_PROG_UNREADABLE
,
586 "The supplied file is not a valid Regina tokenised file" );
589 * Set program file name and environment. The argument have been assigned
592 command
= Str_dupTSD( TSD
->systeminfo
->input_file
);
595 * Changed after 3.3RC1: The environment is set to SYSTEM instead of
596 * the externally bound (ENVIR_PIPE) "DEFAULT".
598 environment
= Str_creTSD( "SYSTEM" );
600 flush_trace_chars( TSD
);
603 * do_instore() actually does the execution...
605 result
= do_instore( TSD
, command
, TSD
->currlevel
->args
, environment
,
608 TinnedTree
, TinnedTreeLen
,
609 NULL
, 0, /* source file contents */
611 TSD
->systeminfo
->invoked
);
613 FreeTSD( TinnedTree
);
614 Free_stringTSD( command
);
615 Free_stringTSD( environment
);
619 RetCode
= codeFromString( TSD
, result
);
620 Free_stringTSD( result
);
629 * execute_file executes a plain text script that has already been assigned
632 * The arguments must have been assigned, too.
634 * The return value is the value that the main routine should return to the OS.
636 static int execute_file( tsd_t
*TSD
)
638 FILE *fptr
= TSD
->systeminfo
->input_fp
;
639 internal_parser_type parsing
;
644 * From here we are interpreting...
646 fetch_file( TSD
, fptr
? fptr
: stdin
, &parsing
);
649 TSD
->systeminfo
->input_fp
= NULL
;
651 if ( parsing
.result
!= 0 )
652 exiterror( ERR_YACC_SYNTAX
, 1, parsing
.tline
);
654 TSD
->systeminfo
->tree
= parsing
;
656 #if !defined(MINIMAL) && !defined(VMS) && !defined(DOS) && !defined(_MSC_VER) && !defined(__IBMC__) && !defined(MAC)
662 rc
= fstat( fileno( stdin
), &buffer
);
663 if ( ( rc
== 0 ) && S_ISCHR( buffer
.st_mode
) )
667 * When does this happen. Add debugging code to determine this, because
668 * after 2 glasses of rocket fuel it seems silly to have this code!
678 flush_trace_chars( TSD
);
680 string
= interpret( TSD
, TSD
->systeminfo
->tree
.root
);
681 RetCode
= codeFromString( TSD
, string
);
683 Free_stringTSD( string
);
689 # if defined(__LCC__)
690 int __regina_faked_main(int argc
,char *argv
[])
692 int APIENTRY
__regina_faked_main(int argc
,char *argv
[])
694 # define CALL_MAIN __regina_faked_main
696 int main(int argc
,char *argv
[])
697 # define CALL_MAIN main
702 int compile_to_tokens
=0;
703 int execute_from_tokens
=0;
709 InitCursorCtl( nil
);
713 argv0
= GetArgv0( argv
[0] );
715 TSD
= GLOBAL_ENTRY_POINT();
717 setup_system( TSD
, 0 );
719 if ( setjmp( jbuf
) )
722 * We may either be jumped normally after an EXIT instruction or after
723 * an error. The first reason means normal continuation, the other
724 * means that we have to do an immediate stop.
726 if ( !TSD
->instore_is_errorfree
)
728 if ( TSD
->systeminfo
->result
)
729 return atoi( TSD
->systeminfo
->result
->value
);
734 if ( TSD
->systeminfo
->result
)
735 rcode
= codeFromString( TSD
, TSD
->systeminfo
->result
);
737 rcode
= EXIT_SUCCESS
;
742 TSD
->systeminfo
->script_exit
= &jbuf
;
744 processed
= check_args( TSD
, argc
, argv
, &compile_to_tokens
,
745 &execute_from_tokens
, &locale_set
);
747 if ( processed
== 0 )
753 * Check for a comma separated default locale in REGINA_LANG.
755 char *ptr
= getenv( "REGINA_LANG" );
757 ptr
= strchr( ptr
, ',' );
759 set_locale_info( ptr
+ 1 );
762 if ( processed
< argc
)
764 TSD
->systeminfo
->input_file
= get_external_routine( TSD
,
765 argv
[processed
], &TSD
->systeminfo
->input_fp
);
766 if ( !TSD
->systeminfo
->input_file
)
768 TSD
->systeminfo
->input_file
= Str_crestrTSD( argv
[processed
] );
769 exiterror( ERR_PROG_UNREADABLE
, 1, "Program was not found" );
775 TSD
->systeminfo
->input_file
= Str_crestrTSD( "<stdin>" );
776 TSD
->systeminfo
->input_fp
= NULL
;
777 if ( compile_to_tokens
)
778 exiterror( ERR_PROG_UNREADABLE
, 1, "Too few arguments when "
779 "tokenising. Usage: -c inputfile outputfile" );
780 if ( execute_from_tokens
)
781 exiterror( ERR_PROG_UNREADABLE
, 1, "Cannot run tokenised code "
787 * -c switch specified - tokenise the input file before mucking around
788 * with parameters etc.
790 if ( compile_to_tokens
)
792 if ( processed
>= argc
)
793 exiterror( ERR_PROG_UNREADABLE
, 1, "Too few arguments when "
794 "tokenising. Usage: -c inputfile outputfile" );
795 if ( processed
+ 1 < argc
)
796 exiterror( ERR_PROG_UNREADABLE
, 1, "Too many arguments when "
797 "tokenising. Usage: -c inputfile outputfile" );
799 just_compile( TSD
, argv
[processed
] );
804 * Under DJGPP setmode screws up Parse Pull and entering code
807 #if defined(__EMX__) || (defined(_MSC_VER) && !defined(__WINS__)) || (defined(__WATCOMC__) && !defined(__QNX__))
808 setmode( fileno( stdin
), O_BINARY
);
809 setmode( fileno( stdout
), O_BINARY
);
810 setmode( fileno( stderr
), O_BINARY
);
813 assign_args( TSD
, argc
, processed
, argv
);
817 * -e switch specified - execute from tokenised code
819 if ( execute_from_tokens
)
820 rcode
= execute_tokenized( TSD
);
822 rcode
= execute_file( TSD
);
825 #if defined(DEBUG) || defined(TRACEMEM)
827 * Now do the cleanup. We don't need in real life, but for a proper cleanup
828 * and for debugging aid it is a good idea to track down the whole beast.
831 purge_filetable( TSD
);
832 # if defined(FLISTS) && defined(NEW_FLISTS)
838 * Remove all external function package functions
839 * and libraries. Only valid for the DYNAMIC library.
841 purge_library( TSD
);
845 if ( TSD
->listleakedmemory
)
846 listleaked( TSD
, MEMTRC_LEAKED
);
849 TSD
->systeminfo
->script_exit
= NULL
; /* cannot be freed, it's on the stack*/
850 killsystem( TSD
, TSD
->systeminfo
);
851 TSD
->systeminfo
= NULL
;
854 * Remove all memory allocated by the flists internal memory manager.
865 /* reexecute_main is possibly called by one of the fork_exec routines.
866 * This functions cleans up some stuff to reexecute without problems.
867 * The most useful thing to be done here is freeing all used memory.
868 * NOTE: usage is always the last thing you should try. Better use
869 * spawn or exec to let a fresh interpreter do the work.
871 int __regina_reexecute_main(int argc
, char **argv
)
875 TSD
= __regina_get_tsd(); /* hopefully not multithreading! */
877 if (TSD
!= NULL
) /* yes! I don't know what happens on forking */
878 { /* and active multi-threading */
880 purge_stacks(TSD
); /* see main above for comments */
881 purge_filetable(TSD
);
886 # if defined(NEW_FLISTS)
893 return(CALL_MAIN(argc
, argv
));
897 void mark_systeminfo( const tsd_t
*TSD
)
900 labelbox
*lptr
=NULL
;
901 lineboxptr llptr
=NULL
;
903 for (sinfo
=TSD
->systeminfo
; sinfo
; sinfo
=sinfo
->previous
)
905 markmemory(sinfo
, TRC_SYSINFO
) ;
906 markmemory(sinfo
->input_file
, TRC_SYSINFO
) ;
907 markmemory(sinfo
->environment
, TRC_SYSINFO
) ;
908 markmemory(sinfo
->callstack
, TRC_SYSINFO
) ;
910 markvariables( TSD
, sinfo
->currlevel0
) ;
911 marksource( sinfo
->tree
.first_source_line
) ;
912 /* FGC, FIXME: rewrite this: marksubtree( sinfo->tree.root ) ; */
914 for (lptr
=sinfo
->tree
.first_label
; lptr
; lptr
=lptr
->next
)
916 markmemory( lptr
, TRC_SYSINFO
) ;
919 for (llptr
=sinfo
->tree
.first_source_line
; llptr
; llptr
=llptr
->next
)
921 markmemory( llptr
, TRC_SYSINFO
) ;
922 markmemory( llptr
->line
, TRC_SYSINFO
) ;
926 markmemory( TSD
->mem_tsd
, TRC_SYSINFO
);
927 markmemory( TSD
->var_tsd
, TRC_SYSINFO
);
928 markmemory( TSD
->stk_tsd
, TRC_SYSINFO
);
929 markmemory( TSD
->fil_tsd
, TRC_SYSINFO
);
930 markmemory( TSD
->itp_tsd
, TRC_SYSINFO
);
931 markmemory( TSD
->tra_tsd
, TRC_SYSINFO
);
932 markmemory( TSD
->err_tsd
, TRC_SYSINFO
);
934 markmemory( TSD
->vms_tsd
, TRC_SYSINFO
);
935 markmemory( TSD
->bui_tsd
, TRC_SYSINFO
);
937 markmemory( TSD
->vmf_tsd
, TRC_SYSINFO
);
938 markmemory( TSD
->lib_tsd
, TRC_SYSINFO
);
940 markmemory( TSD
->rex_tsd
, TRC_SYSINFO
);
941 markmemory( TSD
->shl_tsd
, TRC_SYSINFO
);
942 markmemory( TSD
->mat_tsd
, TRC_SYSINFO
);
944 markmemory( TSD
->cli_tsd
, TRC_SYSINFO
);
945 markmemory( TSD
->arx_tsd
, TRC_SYSINFO
);
946 markmemory( TSD
->mt_tsd
, TRC_SYSINFO
);
951 sysinfobox
*creat_sysinfo( const tsd_t
*TSD
, streng
*envir
)
955 sinfo
= (sysinfobox
*)MallocTSD( sizeof(sysinfobox
) );
956 sinfo
->environment
= envir
;
957 sinfo
->tracing
= DEFAULT_TRACING
;
958 sinfo
->interactive
= DEFAULT_INT_TRACING
;
959 sinfo
->previous
= NULL
;
960 sinfo
->invoked
= INVO_COMMAND
;
961 sinfo
->input_file
= NULL
;
962 sinfo
->input_fp
= NULL
;
963 sinfo
->script_exit
= NULL
;
965 sinfo
->callstack
= (nodeptr
*)MallocTSD( sizeof( nodeptr
) * 10 );
966 sinfo
->result
= NULL
;
967 sinfo
->cstackcnt
= 0;
968 sinfo
->cstackmax
= 10;
969 sinfo
->trace_override
= 0;
970 sinfo
->ctrlcounter
= 0;
971 memset( &sinfo
->tree
, 0, sizeof( sinfo
->tree
) );
976 * The following two functions are used to set and retrieve the value of
979 void setGlobalTSD( tsd_t
*TSD
)
981 __regina_global_TSD
= TSD
;
984 tsd_t
*getGlobalTSD( void )
986 return __regina_global_TSD
;
989 #if !defined(RXLIB) && !defined(VMS)
991 static void NoAPI( void )
993 fprintf (stderr
, "Warning: SAA API not compiled into interpreter\n" ) ;
996 int hookup( tsd_t
*TSD
, int dummy
)
998 /* This should never happen, if we don't have support for SAA API,
999 * Then we should never get a system exit!
1002 dummy
= dummy
; /* keep compiler happy */
1003 TSD
= TSD
; /* keep compiler happy */
1004 return 1 ; /* to keep compiler happy */
1006 int hookup_input( tsd_t
*TSD
, int dummy1
, streng
**dummy2
)
1008 /* This should never happen, if we don't have support for SAA API,
1009 * Then we should never get a system exit!
1011 TSD
= TSD
; /* keep compiler happy */
1012 dummy1
= dummy1
; /* keep compiler happy */
1013 dummy2
= dummy2
; /* keep compiler happy */
1015 return 1 ; /* to keep compiler happy */
1017 int hookup_input_output( tsd_t
*TSD
, int dummy1
, const streng
*dummy2
, streng
**dummy3
)
1019 /* This should never happen, if we don't have support for SAA API,
1020 * Then we should never get a system exit!
1022 TSD
= TSD
; /* keep compiler happy */
1023 dummy1
= dummy1
; /* keep compiler happy */
1024 dummy2
= dummy2
; /* keep compiler happy */
1025 dummy3
= dummy3
; /* keep compiler happy */
1027 return 1 ; /* to keep compiler happy */
1029 int hookup_output( tsd_t
*TSD
, int dummy1
, const streng
*dummy2
)
1031 /* This should never happen, if we don't have support for SAA API,
1032 * Then we should never get a system exit!
1035 dummy1
= dummy1
; /* keep compiler happy */
1036 dummy2
= dummy2
; /* keep compiler happy */
1037 TSD
= TSD
; /* keep compiler happy */
1038 return 1 ; /* to keep compiler happy */
1040 int hookup_output2( tsd_t
*TSD
, int dummy1
, const streng
*dummy2
, const streng
*dummy3
)
1042 /* This should never happen, if we don't have support for SAA API,
1043 * Then we should never get a system exit!
1046 dummy1
= dummy1
; /* keep compiler happy */
1047 dummy2
= dummy2
; /* keep compiler happy */
1048 dummy3
= dummy3
; /* keep compiler happy */
1049 TSD
= TSD
; /* keep compiler happy */
1050 return 1 ; /* to keep compiler happy */
1053 static void Exit( const tsd_t
*TSD
)
1056 * cheat about the const, we go away anyway :-)
1058 jump_interpreter_exit( ( tsd_t
* ) TSD
, 1 );
1061 streng
*call_unknown_external( tsd_t
*TSD
, const streng
*dummy1
, cparamboxptr dummy2
, char dummy3
)
1064 dummy1
= dummy1
; /* keep compiler happy */
1065 dummy2
= dummy2
; /* keep compiler happy */
1066 dummy3
= dummy3
; /* keep compiler happy */
1071 streng
*call_known_external( tsd_t
*TSD
, const struct entry_point
*dummy1
, cparamboxptr dummy2
, char dummy3
)
1074 dummy1
= dummy1
; /* keep compiler happy */
1075 dummy2
= dummy2
; /* keep compiler happy */
1076 dummy3
= dummy3
; /* keep compiler happy */
1082 streng
*SubCom( tsd_t
*TSD
, const streng
*dummy1
, const streng
*dummy2
, int *dummy3
)
1085 dummy1
= dummy1
; /* keep compiler happy */
1086 dummy2
= dummy2
; /* keep compiler happy */
1087 dummy3
= dummy3
; /* keep compiler happy */
1092 int IfcHaveFunctionExit(const tsd_t
*TSD
)
1094 TSD
= TSD
; /* keep compiler happy */
1100 static void usage( char *argv0
)
1102 fprintf( stdout
, "\nRegina %s. All rights reserved.\n", PARSE_VERSION_STRING
);
1103 fprintf( stdout
,"Regina is distributed under the terms of the GNU Library Public License \n" );
1104 fprintf( stdout
,"and comes with NO WARRANTY. See the file COPYING-LIB for details.\n" );
1105 fprintf( stdout
,"\nTo run a Rexx program:\n" );
1106 fprintf( stdout
,"%s [-h?vrt[ir]ap] program [arguments...]\n", argv0
);
1107 fprintf( stdout
,"where:\n\n" );
1108 fprintf( stdout
,"-h,-? show this message\n" );
1109 fprintf( stdout
,"-v display Regina version and exit\n" );
1110 fprintf( stdout
,"-r run Regina in \"safe\" mode\n" );
1111 fprintf( stdout
,"-t[trace_char] set TRACE any valid TRACE character - default A\n" );
1112 fprintf( stdout
,"-a pass command line to Rexx program as separate arguments\n");
1113 fprintf( stdout
,"-p pause after execution (Win32 only)\n");
1114 fprintf( stdout
,"-l[locale] use the system's default charset or a supplied one\n");
1115 fprintf( stdout
,"\nTo tokenise a Rexx program:\n" );
1116 fprintf( stdout
,"%s -c program(input) tokenisedfile(output)\n", argv0
);
1117 fprintf( stdout
,"\nTo execute a tokenised file:\n" );
1118 fprintf( stdout
,"%s -e tokenisedfile [arguments...]\n", argv0
);
1119 fprintf( stdout
,"\nIf you intend using external functions (using RxFuncAdd) you need to run the \"regina\" executable\n" );