X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FRtsFlags.c;fp=rts%2FRtsFlags.c;h=9c0ec9e2c9ae43c1686cb3edf3007d80f2a5b999;hp=14080702bf4560f2a3565de02841e49681ecbe73;hb=a6e8418a71b14ef85ee7134be654689b17765f03;hpb=f61d53d322cdf81a1cfa09cf4a4af4198611bcd5 diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index 1408070..9c0ec9e 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -33,7 +33,7 @@ int full_prog_argc = 0; /* an "int" so as to match normal "argc" */ char **full_prog_argv = NULL; char *prog_name = NULL; /* 'basename' of prog_argv[0] */ int rts_argc = 0; /* ditto */ -char *rts_argv[MAX_RTS_ARGS]; +char **rts_argv = NULL; #if defined(mingw32_HOST_OS) // On Windows, we want to use GetCommandLineW rather than argc/argv, // but we need to mutate the command line arguments for withProgName and @@ -73,6 +73,10 @@ static void read_trace_flags(char *arg); static void errorUsage (void) GNU_ATTRIBUTE(__noreturn__); +static char * copyArg (char *arg); +static char ** copyArgv (int argc, char *argv[]); +static void freeArgv (int argc, char *argv[]); + /* ----------------------------------------------------------------------------- * Command-line option parsing routines. * ---------------------------------------------------------------------------*/ @@ -387,15 +391,11 @@ static void splitRtsFlags(char *s) if (c1 == c2) { break; } - if (rts_argc < MAX_RTS_ARGS-1) { - s = stgMallocBytes(c2-c1+1, "RtsFlags.c:splitRtsFlags()"); - strncpy(s, c1, c2-c1); - s[c2-c1] = '\0'; - rts_argv[rts_argc++] = s; - } else { - barf("too many RTS arguments (max %d)", MAX_RTS_ARGS-1); - } - + s = stgMallocBytes(c2-c1+1, "RtsFlags.c:splitRtsFlags()"); + strncpy(s, c1, c2-c1); + s[c2-c1] = '\0'; + rts_argv[rts_argc++] = s; + c1 = c2; } while (*c1 != '\0'); } @@ -407,13 +407,13 @@ static void splitRtsFlags(char *s) - argv[] is *modified*, any RTS options have been stripped out - *argc contains the new count of arguments in argv[] - - rts_argv[] (global) contains the collected RTS args + - rts_argv[] (global) contains a copy of the collected RTS args - rts_argc (global) contains the count of args in rts_argv - - prog_argv[] (global) contains the non-RTS args (== argv) + - prog_argv[] (global) contains a copy of the non-RTS args (== argv) - prog_argc (global) contains the count of args in prog_argv - - prog_name (global) contains the basename of argv[0] + - prog_name (global) contains the basename of prog_argv[0] -------------------------------------------------------------------------- */ @@ -430,6 +430,8 @@ void setupRtsFlags (int *argc, char *argv[]) *argc = 1; rts_argc = 0; + rts_argv = stgCallocBytes(total_arg + 1, sizeof (char *), "setupRtsFlags"); + rts_argc0 = rts_argc; // process arguments from the ghc_rts_opts global variable first. @@ -481,14 +483,11 @@ void setupRtsFlags (int *argc, char *argv[]) else if (strequal("-RTS", argv[arg])) { mode = PGM; } - else if (mode == RTS && rts_argc < MAX_RTS_ARGS-1) { - rts_argv[rts_argc++] = argv[arg]; + else if (mode == RTS) { + rts_argv[rts_argc++] = copyArg(argv[arg]); } - else if (mode == PGM) { - argv[(*argc)++] = argv[arg]; - } - else { - barf("too many RTS arguments (max %d)", MAX_RTS_ARGS-1); + else { + argv[(*argc)++] = argv[arg]; } } // process remaining program arguments @@ -1459,6 +1458,41 @@ bad_option(const char *s) stg_exit(EXIT_FAILURE); } +/* ---------------------------------------------------------------------------- + Copying and freeing argc/argv + ------------------------------------------------------------------------- */ + +static char * copyArg(char *arg) +{ + char *new_arg = stgMallocBytes(strlen(arg) + 1, "copyArg"); + strcpy(new_arg, arg); + return new_arg; +} + +static char ** copyArgv(int argc, char *argv[]) +{ + int i; + char **new_argv; + + new_argv = stgCallocBytes(argc + 1, sizeof (char *), "copyArgv 1"); + for (i = 0; i < argc; i++) { + new_argv[i] = copyArg(argv[i]); + } + new_argv[argc] = NULL; + return new_argv; +} + +static void freeArgv(int argc, char *argv[]) +{ + int i; + if (argv != NULL) { + for (i = 0; i < argc; i++) { + stgFree(argv[i]); + } + stgFree(argv); + } +} + /* ----------------------------------------------------------------------------- Getting/Setting the program's arguments. @@ -1500,10 +1534,29 @@ void setProgArgv(int argc, char *argv[]) { prog_argc = argc; - prog_argv = argv; + prog_argv = copyArgv(argc,argv); setProgName(prog_argv); } +static void +freeProgArgv(void) +{ + freeArgv(prog_argc,prog_argv); + prog_argc = 0; + prog_argv = NULL; +} + +/* ---------------------------------------------------------------------------- + The full argv - a copy of the original program's argc/argv + ------------------------------------------------------------------------- */ + +void +setFullProgArgv(int argc, char *argv[]) +{ + full_prog_argc = argc; + full_prog_argv = copyArgv(argc,argv); +} + /* These functions record and recall the full arguments, including the +RTS ... -RTS options. The reason for adding them was so that the ghc-inplace program can pass /all/ the arguments on to the real ghc. */ @@ -1515,42 +1568,25 @@ getFullProgArgv(int *argc, char **argv[]) } void -setFullProgArgv(int argc, char *argv[]) -{ - int i; - full_prog_argc = argc; - full_prog_argv = stgCallocBytes(argc + 1, sizeof (char *), - "setFullProgArgv 1"); - for (i = 0; i < argc; i++) { - full_prog_argv[i] = stgMallocBytes(strlen(argv[i]) + 1, - "setFullProgArgv 2"); - strcpy(full_prog_argv[i], argv[i]); - } - full_prog_argv[argc] = NULL; -} - -void freeFullProgArgv (void) { - int i; - - if (full_prog_argv != NULL) { - for (i = 0; i < full_prog_argc; i++) { - stgFree(full_prog_argv[i]); - } - stgFree(full_prog_argv); - } - + freeArgv(full_prog_argc, full_prog_argv); full_prog_argc = 0; full_prog_argv = NULL; } +/* ---------------------------------------------------------------------------- + The Win32 argv + ------------------------------------------------------------------------- */ + #if defined(mingw32_HOST_OS) void freeWin32ProgArgv (void); void freeWin32ProgArgv (void) { + freeArgv(win32_prog_argc, win32_prog_argv); + int i; if (win32_prog_argv != NULL) { @@ -1594,3 +1630,29 @@ setWin32ProgArgv(int argc, wchar_t *argv[]) win32_prog_argv[argc] = NULL; } #endif + +/* ---------------------------------------------------------------------------- + The RTS argv + ------------------------------------------------------------------------- */ + +static void +freeRtsArgv(void) +{ + freeArgv(rts_argc,rts_argv); + rts_argc = 0; + rts_argv = NULL; +} + +/* ---------------------------------------------------------------------------- + All argvs + ------------------------------------------------------------------------- */ + +void freeRtsArgs(void) +{ +#if defined(mingw32_HOST_OS) + freeWin32ProgArgv(); +#endif + freeFullProgArgv(); + freeProgArgv(); + freeRtsArgv(); +}