/* EMAIN.TEMPLATE - Main entry point template for VMS/Alpha. $Id$ 64/32bit clean */ #pragma module EMAIN // force uppercase module name #ifdef __cplusplus extern "C" { #endif #include #include // for $is_32bits #ifndef $is_32bits #define $is_32bits(ignore) ( (void)0 ) #endif #include "eif_macros.h" #include "eif_sig.h" extern void emain(int, char **); extern int main(int, char **, char **); extern void egc_init_plug(void); extern void egc_rcdt_init (void); int main (int argc, char ** argvxx, char ** envpxx) { #if __INITIAL_POINTER_SIZE > 32 // long (64 bit) pointers /* Problem: argv and envp are arrays of short (32 bit) pointers (documented */ /* in C User's Guide, section 1.7.2.1), but anything we pass them to expects */ /* them to be the default pointer size, and will index them incorrectly when */ /* the default pointer size is 64 bits. */ /* Solution 1: in each function that is called, specify the type of the */ /* arguments explicitly as short pointers. */ /* Solution 2: create an array of "default" size pointers and substitute it */ /* for the array of short pointers. */ /* Solution 1 is more difficult to implement, especially because at least one */ /* of the called routines is generated by the Eiffel compiler, but also */ /* because it has more maintenance ramifcations. */ /* Solution 2 requires a bit of extra code here but is confined to this */ /* module, so that is what we will do. */ #pragma __pointer_size save #pragma __pointer_size 64 char ** argv, ** envp; int ii, envc; argv = calloc (argc + 1, sizeof argv[0]); // allocate 1 extra element to have trailing NULL assert (!$is_32bits(argv)); for (ii = 0; ii < argc; ++ii) argv[ii] = argvxx[ii]; argv[argc] = NULL; if (envpxx) { // count the number of items in envpxx[] for (envc = 0; envpxx[envc]; ++envc) ; // do nothing envp = calloc (envc + 1, sizeof envp[0]); for (ii = 0; ii < envc; ++ii) envp[ii] = envpxx[ii]; envp[envc] = NULL; } else envp = NULL; #pragma __pointer_size restore #else // 32 bit pointers; use the arguments as passed char ** argv = argvxx; char ** envp = envpxx; #endif // __INITIAL_POINTER_SIZE eif_alloc_init(); #ifdef EIF_THREADS eif_thr_init_root(); #endif { GTCX struct ex_vect *exvect; jmp_buf exenv; egc_init_plug(); initsig(); initstk(); exvect = exset((char *) 0, 0, (char *) 0); exvect->ex_jbuf = &exenv; if (setjmp(exenv)) failure(); eif_rtinit(argc, argv, envp); if (egc_prof_enabled) initprf(); egc_rcdt_init (); emain(argc, argv); reclaim(); exit(0); } return 0; } #ifdef moose /* local function to create an array of default size pointers from an array */ /* of short pointers. */ /* If argv is null, then null is returned. If argc is zero then argv is */ /* assumed to be terminated by a NULL entry (like envp). */ static void ** array_of_pointers (int argc, void_ptr32 argv[]) { void ** result = NULL; int ii; if (argv != NULL) { if (argc == 0) { // count not specified, compute it for (argc =0; argv[argc]; ++argc) ; // do nothing } result = calloc (argc + 1, sizeof(void*)); // allocate 1 extra element for (ii = 0; ii < argc; ++ii) result[ii] = argv[ii]; result[argc] = NULL; // set extra element to NULL } return result; } #endif #ifdef __cplusplus } #endif