Skip to content

Commit 68a8968

Browse files
committed
kernel: split CLI arg parsing into two stages
Most arguments are handled in the first stage. In particular all that are relevant for the GC. The second stage is only for the arguments which add GAP roots paths: those involve storing strings, which can be of arbitrary size. We'd like to switch their handling from C strings to GAP strings, but that requires the memory manager to be initialized. With this patch, it *is* initialized before we parse the root paths.
1 parent 3fb6b3d commit 68a8968

File tree

3 files changed

+53
-37
lines changed

3 files changed

+53
-37
lines changed

src/gap.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,8 @@ void InitializeGap(void * stackBottom, int argc, const char * argv[], BOOL handl
14751475
// call kernel initialisation
14761476
ModulesInitKernel();
14771477

1478+
InitRootPaths(argc, argv);
1479+
14781480
#ifdef HPCGAP
14791481
InitMainThread();
14801482
#endif

src/system.c

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -360,11 +360,12 @@ static void usage(void)
360360
}
361361

362362
struct optInfo {
363-
Char shortkey;
364-
Char longkey[50];
365-
int (*handler)(const char * argv[], void *);
366-
void *otherArg;
367-
UInt minargs;
363+
int phase;
364+
char shortkey;
365+
char longkey[50];
366+
int (*handler)(const char * argv[], void *);
367+
void *otherArg;
368+
UInt minargs;
368369
};
369370

370371

@@ -486,48 +487,48 @@ static int printVersion(const char * argv[], void * dummy)
486487
// These options must be kept in sync with those in system.g, so the help
487488
// output is correct
488489
static const struct optInfo options[] = {
489-
{ 'C', "", processCompilerArgs, 0, 4}, // must handle in kernel
490-
{ 'D', "debug-loading", toggle, &SyDebugLoading, 0}, // must handle in kernel
490+
{ 0, 'C', "", processCompilerArgs, 0, 4}, // must handle in kernel
491+
{ 0, 'D', "debug-loading", toggle, &SyDebugLoading, 0}, // must handle in kernel
491492
#if defined(USE_GASMAN) || defined(USE_BOEHM_GC)
492-
{ 'K', "maximal-workspace", storeMemory2, &SyStorKill, 1}, // could handle from library with new interface
493+
{ 0, 'K', "maximal-workspace", storeMemory2, &SyStorKill, 1}, // could handle from library with new interface
493494
#endif
494495
#ifdef GAP_ENABLE_SAVELOAD
495-
{ 'L', "", storeString, &SyRestoring, 1}, // must be handled in kernel
496-
{ 'R', "", unsetString, &SyRestoring, 0}, // kernel
496+
{ 0, 'L', "", storeString, &SyRestoring, 1}, // must be handled in kernel
497+
{ 0, 'R', "", unsetString, &SyRestoring, 0}, // kernel
497498
#endif
498-
{ 'M', "", toggle, &SyUseModule, 0}, // must be handled in kernel
499-
{ 'e', "", toggle, &SyCTRD, 0 }, // kernel
500-
{ 'f', "", forceLineEditing, (void *)2, 0 }, // probably library now
501-
{ 'E', "", toggle, &SyUseReadline, 0 }, // kernel
502-
{ 'l', "roots", setGapRootPath, 0, 1}, // kernel
499+
{ 0, 'M', "", toggle, &SyUseModule, 0}, // must be handled in kernel
500+
{ 0, 'e', "", toggle, &SyCTRD, 0 }, // kernel
501+
{ 0, 'f', "", forceLineEditing, (void *)2, 0 }, // probably library now
502+
{ 0, 'E', "", toggle, &SyUseReadline, 0 }, // kernel
503+
{ 1, 'l', "roots", setGapRootPath, 0, 1}, // kernel
503504
#ifdef USE_GASMAN
504-
{ 'm', "", storeMemory2, &SyStorMin, 1 }, // kernel
505+
{ 0, 'm', "", storeMemory2, &SyStorMin, 1 }, // kernel
505506
#endif
506-
{ 'r', "", toggle, &IgnoreGapRC, 0 }, // kernel
507+
{ 0, 'r', "", toggle, &IgnoreGapRC, 0 }, // kernel
507508
#ifdef USE_GASMAN
508-
{ 's', "", storeMemory, &SyAllocPool, 1 }, // kernel
509+
{ 0, 's', "", storeMemory, &SyAllocPool, 1 }, // kernel
509510
#endif
510-
{ 'n', "", forceLineEditing, 0, 0}, // prob library
511+
{ 0, 'n', "", forceLineEditing, 0, 0}, // prob library
511512
#ifdef USE_GASMAN
512-
{ 'o', "", storeMemory2, &SyStorMax, 1 }, // library with new interface
513+
{ 0, 'o', "", storeMemory2, &SyStorMax, 1 }, // library with new interface
513514
#endif
514-
{ 'p', "", toggle, &SyWindow, 0 }, // ??
515-
{ 'q', "quiet", toggle, &SyQuiet, 0 }, // ??
515+
{ 0, 'p', "", toggle, &SyWindow, 0 }, // ??
516+
{ 0, 'q', "quiet", toggle, &SyQuiet, 0 }, // ??
516517
#ifdef HPCGAP
517-
{ 'S', "", toggle, &ThreadUI, 0 }, // Thread UI
518-
{ 'Z', "", toggle, &DeadlockCheck, 0 }, // Deadlock prevention
519-
{ 'P', "", storePosInteger, &SyNumProcessors, 1 }, // number of CPUs
520-
{ 'G', "", storePosInteger, &SyNumGCThreads, 1 }, // number of GC threads
521-
{ 0 , "single-thread", toggle, &SingleThreadStartup, 0 }, // startup with one thread only
518+
{ 0, 'S', "", toggle, &ThreadUI, 0 }, // Thread UI
519+
{ 0, 'Z', "", toggle, &DeadlockCheck, 0 }, // Deadlock prevention
520+
{ 0, 'P', "", storePosInteger, &SyNumProcessors, 1 }, // number of CPUs
521+
{ 0, 'G', "", storePosInteger, &SyNumGCThreads, 1 }, // number of GC threads
522+
{ 0, 0 , "single-thread", toggle, &SingleThreadStartup, 0 }, // startup with one thread only
522523
#endif
523524
// The following options must be handled in the kernel so they are set up before loading the library
524-
{ 0 , "prof", enableProfilingAtStartup, 0, 1}, // enable profiling at startup
525-
{ 0 , "memprof", enableMemoryProfilingAtStartup, 0, 1 }, // enable memory profiling at startup
526-
{ 0 , "cover", enableCodeCoverageAtStartup, 0, 1}, // enable code coverage at startup
527-
{ 0 , "quitonbreak", toggle, &SyQuitOnBreak, 0}, // Quit GAP if we enter the break loop
528-
{ 0 , "enableMemCheck", enableMemCheck, 0, 0 },
529-
{ 0 , "version", printVersion, 0, 0 },
530-
{ 0, "", 0, 0, 0}};
525+
{ 0, 0 , "prof", enableProfilingAtStartup, 0, 1}, // enable profiling at startup
526+
{ 0, 0 , "memprof", enableMemoryProfilingAtStartup, 0, 1 }, // enable memory profiling at startup
527+
{ 0, 0 , "cover", enableCodeCoverageAtStartup, 0, 1}, // enable code coverage at startup
528+
{ 0, 0 , "quitonbreak", toggle, &SyQuitOnBreak, 0}, // Quit GAP if we enter the break loop
529+
{ 0, 0 , "enableMemCheck", enableMemCheck, 0, 0 },
530+
{ 0, 0 , "version", printVersion, 0, 0 },
531+
{ 0, 0, "", 0, 0, 0}};
531532

532533

533534
static void InitSysOpts(void)
@@ -579,7 +580,7 @@ static void InitSysOpts(void)
579580
SyWindow = 0;
580581
}
581582

582-
static void ParseCommandLineOptions(int argc, const char * argv[])
583+
static void ParseCommandLineOptions(int argc, const char * argv[], int phase)
583584
{
584585
// scan the command line for options that we have to process in the kernel
585586
// 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[])
637638
usage();
638639
}
639640

640-
(*options[i].handler)(argv + 1, options[i].otherArg);
641+
if (options[i].phase == phase)
642+
(*options[i].handler)(argv + 1, options[i].otherArg);
641643

642644
argv += options[i].minargs;
643645
argc -= options[i].minargs;
@@ -687,7 +689,9 @@ void InitSystem(int argc, const char * argv[], BOOL handleSignals)
687689

688690
InitSysFiles();
689691

690-
ParseCommandLineOptions(argc, argv);
692+
// first stage of command line options parsing: handle everything except
693+
// for root paths
694+
ParseCommandLineOptions(argc, argv, 0);
691695

692696
#ifdef HAVE_LIBREADLINE
693697
InitReadline();
@@ -702,6 +706,12 @@ void InitSystem(int argc, const char * argv[], BOOL handleSignals)
702706
SyRedirectStderrToStdOut();
703707
syWinPut(0, "@p", "1.");
704708
}
709+
}
710+
711+
void InitRootPaths(int argc, const char * argv[])
712+
{
713+
// second stage of command line options parsing: handle root paths
714+
ParseCommandLineOptions(argc, argv, 1);
705715

706716
InitDotGapPath();
707717
}

src/system.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,8 @@ void Panic_(const char * file, int line, const char * fmt, ...) NORETURN
136136
*/
137137
void InitSystem(int argc, const char * argv[], BOOL handleSignals);
138138

139+
140+
void InitRootPaths(int argc, const char * argv[]);
141+
142+
139143
#endif // GAP_SYSTEM_H

0 commit comments

Comments
 (0)