diff --git a/lib/package.gi b/lib/package.gi index ba0612a535..54ca1984d8 100644 --- a/lib/package.gi +++ b/lib/package.gi @@ -1862,19 +1862,19 @@ InstallGlobalFunction( SetPackagePath, function( pkgname, pkgpath ) #F ExtendRootDirectories( ) ## InstallGlobalFunction( ExtendRootDirectories, function( rootpaths ) - local i; - - rootpaths:= Filtered( rootpaths, path -> not path in GAPInfo.RootPaths ); - if not IsEmpty( rootpaths ) then - # 'DirectoriesLibrary' concatenates root paths with directory names. - for i in [ 1 .. Length( rootpaths ) ] do - if not EndsWith( rootpaths[i], "/" ) then - rootpaths[i]:= Concatenation( rootpaths[i], "/" ); - fi; - od; - # Append the new root paths. - GAPInfo.RootPaths:= Immutable( Concatenation( GAPInfo.RootPaths, - rootpaths ) ); + local path, changed; + + changed:= false; + for path in rootpaths do + if not EndsWith( path, "/" ) then + path:= Concatenation( path, "/" ); + fi; + if not path in GAPInfo.RootPaths then + Add( GAPInfo.RootPaths, path ); + changed:= true; + fi; + od; + if changed then # Clear the cache. GAPInfo.DirectoriesLibrary:= AtomicRecord( rec() ); # Reread the package information. diff --git a/src/gap.c b/src/gap.c index d40660e89d..03c4dbee16 100644 --- a/src/gap.c +++ b/src/gap.c @@ -405,7 +405,7 @@ int realmain(int argc, const char * argv[]) Int4 crc; // crc of file to compile // initialize everything and read init.g which runs the GAP session - InitializeGap(&argc, argv, 1); + InitializeGap(&argc, argc, argv, 1); if (!STATE(UserHasQUIT)) { /* maybe the user QUIT from the initial read of init.g somehow*/ // maybe compile in which case init.g got skipped @@ -1335,6 +1335,8 @@ static Int InitKernel ( InitGlobalBag( &WindowCmdString, "src/gap.c:WindowCmdString" ); InitGlobalBag( &KernelArgs, "src/gap.c:KernelArgs" ); + InitGlobalBag( &SyGapRootPaths, "src/gap.c:SyGapRootPaths" ); // FIXME + // init filters and functions InitHdlrFuncsFromTable( GVarFuncs ); @@ -1452,21 +1454,18 @@ StructInitInfo * InitInfoGap ( void ) ** function. We use the resulting pointer as a hint to the garbage collector ** as to where the execution stack (might) start. */ -void InitializeGap(int * pargc, const char * argv[], BOOL handleSignals) +void InitializeGap(void * stackBottom, int argc, const char * argv[], BOOL handleSignals) { - const int argc = *pargc; - // initialize the basic system and gasman InitSystem(argc, argv, handleSignals); // Initialise memory -- have to do this here to make sure we are at top of C stack - InitBags( + Bag * alignedStackBottom = (Bag *)(((UInt)stackBottom / C_STACK_ALIGN) * C_STACK_ALIGN); #if defined(USE_GASMAN) - SyStorMin, + InitBags(SyStorMin, alignedStackBottom); #else - 0, + InitBags(0, alignedStackBottom); #endif - (Bag *)(((UInt)pargc / C_STACK_ALIGN) * C_STACK_ALIGN)); STATE(UserHasQUIT) = FALSE; STATE(UserHasQuit) = FALSE; @@ -1478,6 +1477,8 @@ void InitializeGap(int * pargc, const char * argv[], BOOL handleSignals) // call kernel initialisation ModulesInitKernel(); + InitRootPaths(argc, argv); + #ifdef HPCGAP InitMainThread(); #endif diff --git a/src/gap.h b/src/gap.h index b3bab8df92..ff01637abc 100644 --- a/src/gap.h +++ b/src/gap.h @@ -83,9 +83,9 @@ BOOL IsUsingLibGap(void); /**************************************************************************** ** -*F InitializeGap( , , ) . . . . . . . init GAP +*F InitializeGap() . . . . . . . . . . . . . . . . . . . . . initialize GAP */ -void InitializeGap(int * pargc, const char * argv[], BOOL handleSignals); +void InitializeGap(void * stackBottom, int argc, const char * argv[], BOOL handleSignals); /**************************************************************************** diff --git a/src/libgap-api.c b/src/libgap-api.c index becc8858f0..55b5764099 100644 --- a/src/libgap-api.c +++ b/src/libgap-api.c @@ -59,7 +59,7 @@ void GAP_Initialize(int argc, { UsingLibGap = TRUE; - InitializeGap(&argc, (const char **)argv, handleSignals); + InitializeGap(&argc, argc, (const char **)argv, handleSignals); SetExtraMarkFuncBags(markBagsCallback); STATE(JumpToCatchCallback) = errorCallback; diff --git a/src/listfunc.c b/src/listfunc.c index c4b1818911..5da324d25a 100644 --- a/src/listfunc.c +++ b/src/listfunc.c @@ -44,86 +44,72 @@ */ static void AddList3(Obj list, Obj obj, Int pos) { - Int len; - Int i; + Int len; + Int i; len = LEN_LIST(list); - if (pos == (Int) -1) - pos = len + 1; - for (i = len +1; i > pos; i--) - ASS_LIST(list, i, ELM_LIST(list, i-1)); - ASS_LIST( list, pos, obj ); + if (pos == (Int)-1) + pos = len + 1; + for (i = len + 1; i > pos; i--) + ASS_LIST(list, i, ELM_LIST(list, i - 1)); + ASS_LIST(list, pos, obj); } -void AddList ( - Obj list, - Obj obj) +void AddList(Obj list, Obj obj) { - AddList3(list, obj, -1); + AddList3(list, obj, -1); } -static void AddPlist3(Obj list, Obj obj, Int pos) +void AddPlist3(Obj list, Obj obj, Int pos) { - UInt len; + UInt len; - if ( ! IS_PLIST_MUTABLE(list) ) { + if (!IS_PLIST_MUTABLE(list)) { ErrorMayQuit("List Assignment: must be a mutable list", 0, 0); } // in order to be optimistic when building list call assignment - len = LEN_PLIST( list ); + len = LEN_PLIST(list); if (pos == (Int)-1) - pos = len + 1; - if ( len == 0) { - AssPlistEmpty( list, pos, obj ); + pos = len + 1; + if (len == 0) { + AssPlistEmpty(list, pos, obj); return; } if (pos <= len) { - GROW_PLIST(list, len+1); - SET_LEN_PLIST(list, len+1); - Obj * ptr = ADDR_OBJ(list) + pos; - SyMemmove(ptr + 1, ptr, sizeof(Obj) * (len - pos + 1)); + GROW_PLIST(list, len + 1); + SET_LEN_PLIST(list, len + 1); + Obj * ptr = ADDR_OBJ(list) + pos; + SyMemmove(ptr + 1, ptr, sizeof(Obj) * (len - pos + 1)); } ASS_LIST(list, pos, obj); } -void AddPlist ( - Obj list, - Obj obj) +void AddPlist(Obj list, Obj obj) { - - AddPlist3(list, obj, -1); + AddPlist3(list, obj, -1); } static Obj AddListOper; static Obj FuncADD_LIST3(Obj self, Obj list, Obj obj, Obj pos) { - // dispatch - Int ipos; - if (pos == (Obj)0) - ipos = -1; - else if (IS_POS_INTOBJ(pos)) - ipos = INT_INTOBJ(pos); - else { - DoOperation3Args( self, list, obj, pos); - return (Obj) 0; - } - UInt tnum = TNUM_OBJ(list); - if ( IS_PLIST( list ) ) { - AddPlist3( list, obj, ipos ); - } else if ( FIRST_LIST_TNUM <= tnum && tnum <= LAST_LIST_TNUM ) { - AddList3( list, obj, ipos ); -#ifdef HPCGAP - // Only support adding to end of atomic lists - } else if ( tnum == T_ALIST && pos == (Obj)0 ) { - AddAList( list, obj ); -#endif - } else { - if (pos == 0) - DoOperation2Args( self, list, obj ); - else - DoOperation3Args( self, list, obj, pos); - } + if (!IS_POS_INTOBJ(pos)) { + DoOperation3Args(self, list, obj, pos); + return 0; + } + + UInt tnum = TNUM_OBJ(list); + if (FIRST_PLIST_TNUM <= tnum && tnum <= LAST_PLIST_TNUM) { + AddPlist3(list, obj, INT_INTOBJ(pos)); + return 0; + } + else if (FIRST_LIST_TNUM <= tnum && tnum <= LAST_LIST_TNUM) { + AddList3(list, obj, INT_INTOBJ(pos)); + return 0; + } + else { + DoOperation3Args(self, list, obj, pos); + } return 0; } @@ -131,8 +117,23 @@ static Obj FuncADD_LIST3(Obj self, Obj list, Obj obj, Obj pos) static Obj FuncADD_LIST(Obj self, Obj list, Obj obj) { - FuncADD_LIST3(self, list, obj, (Obj)0); - return (Obj) 0; + UInt tnum = TNUM_OBJ(list); + if (FIRST_PLIST_TNUM <= tnum && tnum <= LAST_PLIST_TNUM) { + AddPlist3(list, obj, -1); + } + else if (FIRST_LIST_TNUM <= tnum && tnum <= LAST_LIST_TNUM) { + AddList3(list, obj, -1); + } +#ifdef HPCGAP + else if (tnum == T_ALIST) { + AddAList(list, obj); + } +#endif + else { + DoOperation2Args(self, list, obj); + } + + return 0; } diff --git a/src/listfunc.h b/src/listfunc.h index 9bc7a598bc..b1609b4724 100644 --- a/src/listfunc.h +++ b/src/listfunc.h @@ -28,6 +28,7 @@ void AddList(Obj list, Obj obj); void AddPlist(Obj list, Obj obj); +void AddPlist3(Obj list, Obj obj, Int pos); /**************************************************************************** ** diff --git a/src/main.c b/src/main.c index 39457f5f3d..69d5e3dd95 100644 --- a/src/main.c +++ b/src/main.c @@ -41,7 +41,7 @@ extern int realmain(int argc, const char * argv[]); static void SetupInitialGapRoot(const char * argv0) { - SySetGapRootPath(SYS_DEFAULT_PATHS); + gap_strlcpy(SyDefaultRootPath, SYS_DEFAULT_PATHS, sizeof(SyDefaultRootPath)); } #else @@ -165,7 +165,7 @@ static void SySetInitialGapRootPaths(const char * GAPExecLocation) strxcat(initgbuf, "lib/init.g", sizeof(initgbuf)); if (SyIsReadableFile(initgbuf) == 0) { - SySetGapRootPath(pathbuf); + gap_strlcpy(SyDefaultRootPath, pathbuf, sizeof(SyDefaultRootPath)); // escape from loop return; } @@ -173,11 +173,6 @@ static void SySetInitialGapRootPaths(const char * GAPExecLocation) strxcat(pathbuf, "../", sizeof(pathbuf)); } } - - // Set GAP root path to current directory, if we have no other - // idea, and for backwards compatibility. - // Note that GAPExecLocation must always end with a slash. - SySetGapRootPath("./"); } static void SetupInitialGapRoot(const char * argv0) diff --git a/src/streams.c b/src/streams.c index 1a45a105ef..cb531ae11e 100644 --- a/src/streams.c +++ b/src/streams.c @@ -358,10 +358,8 @@ Obj READ_AS_FUNC(TypInputFile * input) */ Int READ_GAP_ROOT ( const Char * filename ) { - char path[GAP_PATH_MAX]; - // try to find the GAP file - SyFindGapRootFile(filename, path, sizeof(path)); + Obj path = SyFindGapRootFile(filename); // try to find compiled version of the GAP file if (SyUseModule) { @@ -378,7 +376,7 @@ Int READ_GAP_ROOT ( const Char * filename ) if (info) { // found a matching statically linked module; if there is also // a GAP file, compare their CRC - if (*path && info->crc != SyGAPCRC(path)) { + if (path && info->crc != SyGAPCRC(CSTR_STRING(path))) { Pr("#W Static module %s has CRC mismatch, ignoring\n", (Int)filename, 0); } @@ -395,7 +393,7 @@ Int READ_GAP_ROOT ( const Char * filename ) } // not found? - if (*path == 0) + if (path == 0) return 0; #ifdef GAP_ENABLE_SAVELOAD @@ -415,7 +413,7 @@ Int READ_GAP_ROOT ( const Char * filename ) } TypInputFile input; - if (!OpenInput(&input, path)) + if (!OpenInput(&input, CSTR_STRING(path))) return 0; GAP_TRY diff --git a/src/sysroots.c b/src/sysroots.c index 42e4e42fe9..e12a656246 100644 --- a/src/sysroots.c +++ b/src/sysroots.c @@ -12,6 +12,7 @@ #include "sysroots.h" #include "gaputils.h" +#include "listfunc.h" #include "plist.h" #include "stringobj.h" #include "sysfiles.h" @@ -21,6 +22,16 @@ #include +/**************************************************************************** +** +*V SyDefaultRootPath +** +** Default initial root path. Default is the current directory, if we have +** no other idea, for backwards compatibility. +*/ +char SyDefaultRootPath[GAP_PATH_MAX] = "./"; + + /**************************************************************************** ** *V SyGapRootPaths . . . . . . . . . . . . . . . . . . . array of root paths @@ -37,34 +48,28 @@ ** name of a library file 'strcat( SyGapRootPaths[i], "lib/init.g" );' must ** be a valid filename. */ -enum { MAX_GAP_DIRS = 16 }; -static Char SyGapRootPaths[MAX_GAP_DIRS][GAP_PATH_MAX]; +Obj SyGapRootPaths; /**************************************************************************** ** -*F SyFindGapRootFile( , , ) . find file in system area +*F SyFindGapRootFile( ) . . . . . . . . find file in system area ** -** must point to a buffer of at least characters. This function -** then searches for a readable file with the name in the system -** area. If sich a file is found then its absolute path is copied into -** , and is returned. If no file is found or if is not big -** enough, then is set to an empty string and NULL is returned. +** This function searches for a readable file with the name in +** the system area. If such a file is found then its absolute path is +** returned as a string object. If no file is found then NULL is returned. */ -Char * SyFindGapRootFile(const Char * filename, Char * buf, size_t size) +Obj SyFindGapRootFile(const Char * filename) { - for (int k = 0; k < ARRAY_SIZE(SyGapRootPaths); k++) { - if (SyGapRootPaths[k][0]) { - if (gap_strlcpy(buf, SyGapRootPaths[k], size) >= size) - continue; - if (gap_strlcat(buf, filename, size) >= size) - continue; - if (SyIsReadableFile(buf) == 0) { - return buf; - } + int len = strlen(filename); + int npaths = LEN_PLIST(SyGapRootPaths); + for (int k = 1; k <= npaths; k++) { + Obj path = CopyToStringRep(ELM_PLIST(SyGapRootPaths, k)); + AppendCStr(path, filename, len); + if (SyIsReadableFile(CSTR_STRING(path)) == 0) { + return path; } } - buf[0] = '\0'; return 0; } @@ -89,10 +94,12 @@ Char * SyFindGapRootFile(const Char * filename, Char * buf, size_t size) */ void SySetGapRootPath(const Char * string) { - const Char * p; - Char * q; - Int i; - Int n; + Int pos = 1; + + if (SyGapRootPaths == 0) { + SyGapRootPaths = NEW_PLIST(T_PLIST_EMPTY, 0); // FIXME + } + // set string to a default value if unset if (string == 0 || *string == 0) { @@ -101,110 +108,79 @@ void SySetGapRootPath(const Char * string) // check if we append, prepend or overwrite. if (string[0] == ';') { - // Count the number of root directories already present. - n = 0; - while (SyGapRootPaths[n][0] != '\0') - n++; + // append + pos = LEN_PLIST(SyGapRootPaths) + 1; // Skip leading semicolon. string++; } else if (string[strlen(string) - 1] == ';') { - // Count the number of directories in 'string'. - n = 0; - p = string; - while (*p) - if (*p++ == ';') - n++; - - // Find last root path. - for (i = 0; i < MAX_GAP_DIRS; i++) - if (SyGapRootPaths[i][0] == '\0') - break; - i--; - -#ifdef HPCGAP - n *= 2; // for each root we also add as a root -#endif - - // Move existing root paths to the back - if (i + n >= MAX_GAP_DIRS) - return; - while (i >= 0) { - memcpy(SyGapRootPaths[i + n], SyGapRootPaths[i], - sizeof(SyGapRootPaths[i + n])); - i--; - } - - n = 0; + // prepend } else { - // Make sure to wipe out all possibly existing root paths - for (i = 0; i < MAX_GAP_DIRS; i++) - SyGapRootPaths[i][0] = '\0'; - n = 0; + SET_LEN_PLIST(SyGapRootPaths, 0); + RetypeBagSM(SyGapRootPaths, T_PLIST_EMPTY); + // TODO: also adjust filters... } // unpack the argument - p = string; + const Char * p = string; while (*p) { - if (n >= MAX_GAP_DIRS) - return; - - q = SyGapRootPaths[n]; - while (*p && *p != ';') { - *q = *p++; - -#ifdef SYS_IS_CYGWIN32 - // change backslash to slash for Windows - if (*q == '\\') - *q = '/'; -#endif + Obj path; + // locate next semicolon or string end + const Char * q = p; + while (*q && *q != ';') { q++; } - if (q == SyGapRootPaths[n]) { - strxcpy(SyGapRootPaths[n], "./", sizeof(SyGapRootPaths[n])); - } - else if (q[-1] != '/') { - *q++ = '/'; - *q = '\0'; - } - else { - *q = '\0'; - } - if (*p) { - p++; + + if (q == p) { + // empty string treated as ./ + path = MakeString("./"); + // TODO: insert output of getcwd?? + } else { + if (*p == '~') { + const char * userhome = getenv("HOME"); + if (!userhome) + userhome = ""; + path = MakeString(userhome); + p++; + AppendCStr(path, p, q - p); + } + else { + path = MakeStringWithLen(p, q - p); + } + + Char * r = CSTR_STRING(path); + #ifdef SYS_IS_CYGWIN32 + while (*r) { + // change backslash to slash for Windows + if (*r == '\\') + *r = '/'; + r++; + } + #endif + + // ensure path ends with a slash + r = CSTR_STRING(path) + GET_LEN_STRING(path) - 1; + if (*r != '/') { + AppendCStr(path, "/", 1); + } } - n++; + + p = *q ? q + 1 : q; + + AddPlist3(SyGapRootPaths, path, pos); + pos++; + #ifdef HPCGAP // for each root to be added, we first add as a root - if (n < MAX_GAP_DIRS) { - gap_strlcpy(SyGapRootPaths[n], SyGapRootPaths[n - 1], - sizeof(SyGapRootPaths[n])); - } - strxcat(SyGapRootPaths[n - 1], "hpcgap/", - sizeof(SyGapRootPaths[n - 1])); - n++; -#endif - } + path = CopyToStringRep(path); + AppendCStr(path, "hpcgap/", 7); - // replace leading tilde ~ by HOME environment variable - // TODO; instead of iterating over all entries each time, just - // do this for the new entries - char * userhome = getenv("HOME"); - if (!userhome || !*userhome) - return; - const UInt userhomelen = strlen(userhome); - for (i = 0; i < MAX_GAP_DIRS && SyGapRootPaths[i][0]; i++) { - const UInt pathlen = strlen(SyGapRootPaths[i]); - if (SyGapRootPaths[i][0] == '~' && - userhomelen + pathlen < sizeof(SyGapRootPaths[i])) { - SyMemmove(SyGapRootPaths[i] + userhomelen, - // don't copy the ~ but the trailing '\0' - SyGapRootPaths[i] + 1, pathlen); - memcpy(SyGapRootPaths[i], userhome, userhomelen); - } + AddPlist3(SyGapRootPaths, path, pos); + pos++; +#endif } } @@ -215,12 +191,5 @@ void SySetGapRootPath(const Char * string) */ Obj SyGetGapRootPaths(void) { - Obj tmp = NEW_PLIST_IMM(T_PLIST, MAX_GAP_DIRS); - for (int i = 0; i < MAX_GAP_DIRS; i++) { - if (SyGapRootPaths[i][0]) { - PushPlist(tmp, MakeImmString(SyGapRootPaths[i])); - } - } - MakeImmutableNoRecurse(tmp); - return tmp; + return SyGapRootPaths; } diff --git a/src/sysroots.h b/src/sysroots.h index ae7341ce94..136c0517cf 100644 --- a/src/sysroots.h +++ b/src/sysroots.h @@ -13,8 +13,36 @@ #define GAP_SYSROOTS_H #include "common.h" +#include "system.h" -#include + +/**************************************************************************** +** +*V SyDefaultRootPath +** +** Default initial root path. Default is the current directory, if we have +** no other idea, for backwards compatibility. +*/ +extern char SyDefaultRootPath[GAP_PATH_MAX]; + + +/**************************************************************************** +** +*V SyGapRootPaths . . . . . . . . . . . . . . . . . . . array of root paths +** +** 'SyGapRootPaths' contains the names of the directories where the GAP +** files are located. +** +** It is modified by the command line option -l. +** +** It is copied into the GAP variable 'GAPInfo.RootPaths' and used by +** 'SyFindGapRootFile'. +** +** Each entry must end with the pathname separator, e.g. if 'init.g' is the +** name of a library file 'strcat( SyGapRootPaths[i], "lib/init.g" );' must +** be a valid filename. +*/ +extern Obj SyGapRootPaths; /**************************************************************************** @@ -34,15 +62,13 @@ void SySetGapRootPath(const Char * string); /**************************************************************************** ** -*F SyFindGapRootFile( , , ) . find file in system area +*F SyFindGapRootFile( ) . . . . . . . . find file in system area ** -** must point to a buffer of at least characters. This function -** then searches for a readable file with the name in the system -** area. If sich a file is found then its absolute path is copied into -** , and is returned. If no file is found or if is not big -** enough, then is set to an empty string and NULL is returned. +** This function searches for a readable file with the name in +** the system area. If such a file is found then its absolute path is +** returned as a string object. If no file is found then NULL is returned. */ -Char * SyFindGapRootFile(const Char * filename, Char * buf, size_t size); +Obj SyFindGapRootFile(const Char * filename); /**************************************************************************** diff --git a/src/system.c b/src/system.c index df3d1ef1e3..c84653caed 100644 --- a/src/system.c +++ b/src/system.c @@ -360,11 +360,12 @@ static void usage(void) } struct optInfo { - Char shortkey; - Char longkey[50]; - int (*handler)(const char * argv[], void *); - void *otherArg; - UInt minargs; + int phase; + char shortkey; + char longkey[50]; + int (*handler)(const char * argv[], void *); + void *otherArg; + UInt minargs; }; @@ -486,48 +487,48 @@ static int printVersion(const char * argv[], void * dummy) // These options must be kept in sync with those in system.g, so the help // output is correct static const struct optInfo options[] = { - { 'C', "", processCompilerArgs, 0, 4}, // must handle in kernel - { 'D', "debug-loading", toggle, &SyDebugLoading, 0}, // must handle in kernel + { 0, 'C', "", processCompilerArgs, 0, 4}, // must handle in kernel + { 0, 'D', "debug-loading", toggle, &SyDebugLoading, 0}, // must handle in kernel #if defined(USE_GASMAN) || defined(USE_BOEHM_GC) - { 'K', "maximal-workspace", storeMemory2, &SyStorKill, 1}, // could handle from library with new interface + { 0, 'K', "maximal-workspace", storeMemory2, &SyStorKill, 1}, // could handle from library with new interface #endif #ifdef GAP_ENABLE_SAVELOAD - { 'L', "", storeString, &SyRestoring, 1}, // must be handled in kernel - { 'R', "", unsetString, &SyRestoring, 0}, // kernel + { 0, 'L', "", storeString, &SyRestoring, 1}, // must be handled in kernel + { 0, 'R', "", unsetString, &SyRestoring, 0}, // kernel #endif - { 'M', "", toggle, &SyUseModule, 0}, // must be handled in kernel - { 'e', "", toggle, &SyCTRD, 0 }, // kernel - { 'f', "", forceLineEditing, (void *)2, 0 }, // probably library now - { 'E', "", toggle, &SyUseReadline, 0 }, // kernel - { 'l', "roots", setGapRootPath, 0, 1}, // kernel + { 0, 'M', "", toggle, &SyUseModule, 0}, // must be handled in kernel + { 0, 'e', "", toggle, &SyCTRD, 0 }, // kernel + { 0, 'f', "", forceLineEditing, (void *)2, 0 }, // probably library now + { 0, 'E', "", toggle, &SyUseReadline, 0 }, // kernel + { 1, 'l', "roots", setGapRootPath, 0, 1}, // kernel #ifdef USE_GASMAN - { 'm', "", storeMemory2, &SyStorMin, 1 }, // kernel + { 0, 'm', "", storeMemory2, &SyStorMin, 1 }, // kernel #endif - { 'r', "", toggle, &IgnoreGapRC, 0 }, // kernel + { 0, 'r', "", toggle, &IgnoreGapRC, 0 }, // kernel #ifdef USE_GASMAN - { 's', "", storeMemory, &SyAllocPool, 1 }, // kernel + { 0, 's', "", storeMemory, &SyAllocPool, 1 }, // kernel #endif - { 'n', "", forceLineEditing, 0, 0}, // prob library + { 0, 'n', "", forceLineEditing, 0, 0}, // prob library #ifdef USE_GASMAN - { 'o', "", storeMemory2, &SyStorMax, 1 }, // library with new interface + { 0, 'o', "", storeMemory2, &SyStorMax, 1 }, // library with new interface #endif - { 'p', "", toggle, &SyWindow, 0 }, // ?? - { 'q', "quiet", toggle, &SyQuiet, 0 }, // ?? + { 0, 'p', "", toggle, &SyWindow, 0 }, // ?? + { 0, 'q', "quiet", toggle, &SyQuiet, 0 }, // ?? #ifdef HPCGAP - { 'S', "", toggle, &ThreadUI, 0 }, // Thread UI - { 'Z', "", toggle, &DeadlockCheck, 0 }, // Deadlock prevention - { 'P', "", storePosInteger, &SyNumProcessors, 1 }, // number of CPUs - { 'G', "", storePosInteger, &SyNumGCThreads, 1 }, // number of GC threads - { 0 , "single-thread", toggle, &SingleThreadStartup, 0 }, // startup with one thread only + { 0, 'S', "", toggle, &ThreadUI, 0 }, // Thread UI + { 0, 'Z', "", toggle, &DeadlockCheck, 0 }, // Deadlock prevention + { 0, 'P', "", storePosInteger, &SyNumProcessors, 1 }, // number of CPUs + { 0, 'G', "", storePosInteger, &SyNumGCThreads, 1 }, // number of GC threads + { 0, 0 , "single-thread", toggle, &SingleThreadStartup, 0 }, // startup with one thread only #endif // The following options must be handled in the kernel so they are set up before loading the library - { 0 , "prof", enableProfilingAtStartup, 0, 1}, // enable profiling at startup - { 0 , "memprof", enableMemoryProfilingAtStartup, 0, 1 }, // enable memory profiling at startup - { 0 , "cover", enableCodeCoverageAtStartup, 0, 1}, // enable code coverage at startup - { 0 , "quitonbreak", toggle, &SyQuitOnBreak, 0}, // Quit GAP if we enter the break loop - { 0 , "enableMemCheck", enableMemCheck, 0, 0 }, - { 0 , "version", printVersion, 0, 0 }, - { 0, "", 0, 0, 0}}; + { 0, 0 , "prof", enableProfilingAtStartup, 0, 1}, // enable profiling at startup + { 0, 0 , "memprof", enableMemoryProfilingAtStartup, 0, 1 }, // enable memory profiling at startup + { 0, 0 , "cover", enableCodeCoverageAtStartup, 0, 1}, // enable code coverage at startup + { 0, 0 , "quitonbreak", toggle, &SyQuitOnBreak, 0}, // Quit GAP if we enter the break loop + { 0, 0 , "enableMemCheck", enableMemCheck, 0, 0 }, + { 0, 0 , "version", printVersion, 0, 0 }, + { 0, 0, "", 0, 0, 0}}; static void InitSysOpts(void) @@ -579,7 +580,7 @@ static void InitSysOpts(void) SyWindow = 0; } -static void ParseCommandLineOptions(int argc, const char * argv[]) +static void ParseCommandLineOptions(int argc, const char * argv[], int phase) { // scan the command line for options that we have to process in the kernel // we just scan the whole command line looking for the keys for the @@ -637,7 +638,8 @@ static void ParseCommandLineOptions(int argc, const char * argv[]) usage(); } - (*options[i].handler)(argv + 1, options[i].otherArg); + if (options[i].phase == phase) + (*options[i].handler)(argv + 1, options[i].otherArg); argv += options[i].minargs; argc -= options[i].minargs; @@ -687,7 +689,9 @@ void InitSystem(int argc, const char * argv[], BOOL handleSignals) InitSysFiles(); - ParseCommandLineOptions(argc, argv); + // first stage of command line options parsing: handle everything except + // for root paths + ParseCommandLineOptions(argc, argv, 0); #ifdef HAVE_LIBREADLINE InitReadline(); @@ -702,6 +706,14 @@ void InitSystem(int argc, const char * argv[], BOOL handleSignals) SyRedirectStderrToStdOut(); syWinPut(0, "@p", "1."); } +} + +void InitRootPaths(int argc, const char * argv[]) +{ + SySetGapRootPath(SyDefaultRootPath); + + // second stage of command line options parsing: handle root paths + ParseCommandLineOptions(argc, argv, 1); InitDotGapPath(); } diff --git a/src/system.h b/src/system.h index c530d7c4ea..cbdab82dbb 100644 --- a/src/system.h +++ b/src/system.h @@ -136,4 +136,8 @@ void Panic_(const char * file, int line, const char * fmt, ...) NORETURN */ void InitSystem(int argc, const char * argv[], BOOL handleSignals); + +void InitRootPaths(int argc, const char * argv[]); + + #endif // GAP_SYSTEM_H