Author: eliot Date: 2011-11-28 11:07:44 -0800 (Mon, 28 Nov 2011) New Revision: 2517 Removed: branches/Cog/platforms/win32/vm/sqWin32Args.c branches/Cog/platforms/win32/vm/sqWin32Args.h Modified: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c branches/Cog/platforms/unix/vm/sqUnixMain.c branches/Cog/platforms/win32/vm/sqWin32.h branches/Cog/platforms/win32/vm/sqWin32Intel.c Log: Add access to VM arguments to Mac. Make Windows, Mac and Unix consistent: Smalltalk getSystemAttribute: -1 => executable name -2 .. -n => VM arguments *including* image (if explicitly supplied). Replace win32 command line parsing with unixesque code using CommandLineToArgvW. Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h ___________________________________________________________________ Modified: checkindate - Fri Nov 18 10:11:32 PST 2011 + Mon Nov 28 11:03:00 PST 2011 Modified: branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c =================================================================== --- branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c 2011-11-23 19:43:53 UTC (rev 2516) +++ branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c 2011-11-28 19:07:44 UTC (rev 2517) @@ -63,14 +63,14 @@ char *unixArgcInterfaceGetParm(int n) { int actual; - if (n < 0) - actual = -n; - else + if (n < 0) { + actual = -1 - n; + return actual < vmArgCnt ? vmArgVec[actual] : nil; + } + else { actual = n - 2; - - if (actual < squeakArgCnt) - return squeakArgVec[actual]; - return nil; + return actual < squeakArgCnt ? squeakArgVec[actual] : nil; + } } void unixArgcInterface(int argc, char **argv, char **envp) { Modified: branches/Cog/platforms/unix/vm/sqUnixMain.c =================================================================== --- branches/Cog/platforms/unix/vm/sqUnixMain.c 2011-11-23 19:43:53 UTC (rev 2516) +++ branches/Cog/platforms/unix/vm/sqUnixMain.c 2011-11-28 19:07:44 UTC (rev 2517) @@ -434,12 +434,12 @@ #endif static char * -getAttribute(sqInt id) +GetAttributeString(sqInt id) { if (id < 0) /* VM argument */ { - if (-id < vmArgCnt) - return vmArgVec[-id]; + if (-id <= vmArgCnt) + return vmArgVec[-id - 1]; } else switch (id) @@ -492,13 +492,13 @@ sqInt attributeSize(sqInt id) { - return strlen(getAttribute(id)); + return strlen(GetAttributeString(id)); } sqInt getAttributeIntoLength(sqInt id, sqInt byteArrayIndex, sqInt length) { if (length > 0) - strncpy(pointerForOop(byteArrayIndex), getAttribute(id), length); + strncpy(pointerForOop(byteArrayIndex), GetAttributeString(id), length); return 0; } @@ -1633,7 +1633,8 @@ # define mtfsfi(fpscr) #endif -int main(int argc, char **argv, char **envp) +int +main(int argc, char **argv, char **envp) { fldcw(0x12bf); /* signed infinity, round to nearest, REAL8, disable intrs, disable signals */ mtfsfi(0); /* disable signals, IEEE mode, round to nearest */ Modified: branches/Cog/platforms/win32/vm/sqWin32.h =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32.h 2011-11-23 19:43:53 UTC (rev 2516) +++ branches/Cog/platforms/win32/vm/sqWin32.h 2011-11-28 19:07:44 UTC (rev 2517) @@ -210,7 +210,7 @@ /* The main() function used by NT services */ int sqServiceMain(void); /* The generic main() function for starting squeak */ -int sqMain(char *lpCmdLine, int nCmdShow); +int sqMain(int argc, char *argv[]); #endif /********************************************************/ Deleted: branches/Cog/platforms/win32/vm/sqWin32Args.c =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32Args.c 2011-11-23 19:43:53 UTC (rev 2516) +++ branches/Cog/platforms/win32/vm/sqWin32Args.c 2011-11-28 19:07:44 UTC (rev 2517) @@ -1,242 +0,0 @@ -/**************************************************************************** -* PROJECT: Squeak port for Win32 (NT / Win95) -* FILE: sqWin32Args.c -* CONTENT: Command line processing -* -* AUTHOR: Andreas Raab (ar) -* ADDRESS: University of Magdeburg, Germany -* EMAIL: [hidden email] -* RCSID: $Id: sqWin32Args.c 400 2002-05-26 18:52:10Z andreasraab $ -* -* NOTES: -* -*****************************************************************************/ -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <ctype.h> -#include "sq.h" -#include "sqWin32Args.h" - -static int IsImage(char *name) { - int magic; - int byteSwapped(int); - sqImageFile fp; - - fp = sqImageFileOpen(name,"rb"); - if(!fp) return 0; /* not an image */ - if(sqImageFileRead(&magic, 1, sizeof(magic), fp) != sizeof(magic)) { - sqImageFileClose(fp); - return 0; - } - if(readableFormat(magic) || readableFormat(byteSwapped(magic))) { - sqImageFileClose(fp); - return true; - } - - /* no luck at beginning of file, seek to 512 and try again */ - sqImageFileSeek( fp, 512); - if(sqImageFileRead(&magic, 1, sizeof(magic), fp) != sizeof(magic)) { - sqImageFileClose(fp); - return 0; - } - sqImageFileClose(fp); - return readableFormat(magic) || readableFormat(byteSwapped(magic)); -} - -/* parse a possibly quoted string argument */ -static char *parseStringArg(char *src, char **argPtr) -{ - while(*src && *src == ' ') src++; /* skip blanks */ - if(*src == '"') /* double quoted string */ - { - (*argPtr)++; - do { - src++; - while(*src && *src != '"') src++; - } while(*src && *(src-1) == '\\'); - } - else /* not quoted */ - { - while(*src && *src != ' ') src++; - } - if(*src) *(src++) = 0; - return src; -} - -/* parse an unsigned integer argument */ -static char *parseUnsignedArg(char *src, unsigned *dst) -{ char buf[50]; - char *tmp = buf; - unsigned multiplier = 1; - - while(*src && *src == ' ') src++; /* skip blanks */ - while(isdigit(*src)) *(tmp++) = *(src++); - if(*src && *src != ' ') { /* suffix or strange chars at end */ - switch (*src) { - case 'k': case 'K': - multiplier = 1024; - break; - case 'm': case 'M': - multiplier = 1024*1024; - break; - default: - return NULL; - } - } - if(tmp == buf) /* no numbers found */ - return NULL; - *dst = atol(buf) * multiplier; - if(*src) *(src++) = 0; - return src; -} - -/* parse a (possibly signed) integer argument */ -static char *parseSignedArg(char *src, int *dst) -{ - int negative; - unsigned value; - - while(*src && *src == ' ') src++; /* skip blanks */ - negative = *src == '-'; - if(negative) src++; - src = parseUnsignedArg(src, &value); - if(!src) return NULL; - if(negative) *dst = 0-(int)value; - else *dst = (int) value; - return src; -} - -/* parse all arguments meaningful to the VM */ -static char* parseVMArgs(char *string, vmArg args[]) -{ vmArg *arg; - int arglen; - - while(1) - { - if(numOptionsVM >= MAX_OPTIONS) - return NULL; /* too many args */ - while(*string && *string == ' ') string++; /* skip blanks */ - if(*string != '-') return string; /* image name */ - vmOptions[numOptionsVM++] = string; - - /* search args list */ - arg = args; - while(arg->type != ARG_NONE) - { - arglen = strlen(arg->name); - if(strncmp(arg->name, string, strlen(arg->name)) == 0) - break; - arg++; - } - if(arg->type == ARG_NONE) - return string; /* done */ - - string += arglen; - /* can't just bash the string; if we have -breaksel:at:put: this would - * truncate breaksel to t:put:. - */ - if (*string) - if (*string == ' ') - *(string++) = 0; - else { - char save = *string; - *string = 0; - vmOptions[numOptionsVM - 1] = strdup(vmOptions[numOptionsVM - 1]); - *string = save; - } - - while(*string && *string == ' ') string++; /* skip blanks */ - - switch(arg->type) { - case ARG_FLAG: - *(int*)arg->value = 1; - break; - - case ARG_STRING: - case ARG_STRING_FUNC: { - char *theValue; - vmOptions[numOptionsVM++] = theValue = string; - string = parseStringArg(string, &theValue); - if (arg->type == ARG_STRING) - *(char**) arg->value = theValue; - else - ((void (*)(char *))(arg->value))(theValue); - if(!string) return NULL; - break; - } - - case ARG_INT_FUNC: { - int dummy; - vmOptions[numOptionsVM++] = string; - string = parseSignedArg(string, &dummy); - ((void (*)(int))(arg->value))(dummy); - if(!string) return NULL; - break; - } - case ARG_INT: - vmOptions[numOptionsVM++] = string; - *(char**) arg->value = string; - string = parseSignedArg(string, (int*)arg->value); - if(!string) return NULL; - break; - - case ARG_UINT: - vmOptions[numOptionsVM++] = string; - *(char**) arg->value = string; - string = parseUnsignedArg(string, (unsigned int*)arg->value); - if(!string) return NULL; - break; - - case ARG_NULL: - return NULL; - - default: - fprintf(stderr,"Unknown option encountered!\n"); - return NULL; - }; - } -} - -/* parse all arguments starting with the image name */ -static char *parseGenericArgs(char *string) -{ char *tmpImageName; - - while(*string && *string == ' ') string++; /* skip blanks */ - /* now get the image name */ - tmpImageName = string; - string = parseStringArg(string, &tmpImageName); - if(!string) return NULL; /* parse error */ - if(*imageName == 0) { - /* only attempt to use image name if none is provided */ - if(*tmpImageName && IsImage(tmpImageName)) - strcpy(imageName, tmpImageName); - } else { - /* provide image name as second argument if implicitly specified */ - imageOptions[numOptionsImage++] = imageName; - } - imageOptions[numOptionsImage++] = tmpImageName; - while(string && *string) - { - if(numOptionsImage > MAX_OPTIONS) return string; /* too many args */ - while(*string && *string == ' ') string++; /* skip blanks */ - imageOptions[numOptionsImage++] = string; - string = parseStringArg(string, &(imageOptions[numOptionsImage-1])); - if(!string) return NULL; - } - return string; -} - -int parseArguments(char *cmdLine, vmArg args[]) -{ - /* argv[0] = executable name */ - vmOptions[numOptionsVM++] = cmdLine; - cmdLine = parseStringArg(cmdLine, &(vmOptions[numOptionsVM-1])); - if(!cmdLine) return 0; - /* parse VM options */ - cmdLine = parseVMArgs(cmdLine, args); - if(cmdLine == NULL) return 0; - /* parse image and generic args */ - cmdLine = parseGenericArgs(cmdLine); - return cmdLine != NULL; -} Deleted: branches/Cog/platforms/win32/vm/sqWin32Args.h =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32Args.h 2011-11-23 19:43:53 UTC (rev 2516) +++ branches/Cog/platforms/win32/vm/sqWin32Args.h 2011-11-28 19:07:44 UTC (rev 2517) @@ -1,50 +0,0 @@ -#ifndef __SQ_ARGS_H -#define __SQ_ARGS_H - -/* Squeak command line parsing helpers */ - -#define MAX_OPTIONS 1024 - -extern int numOptionsVM; -extern char *(vmOptions[MAX_OPTIONS]); -extern int numOptionsImage; -extern char *(imageOptions[MAX_OPTIONS]); - -/* this goes separately so that we can insert the "hidden" name */ -extern char imageName[]; - -#define ARG_NONE 0 -#define ARG_FLAG 1 -#define ARG_STRING 2 -#define ARG_INT 3 -#define ARG_UINT 4 -#define ARG_STRING_FUNC 5 -#define ARG_INT_FUNC 6 -#define ARG_NULL 7 - -typedef struct vmArg{ - int type; - void *value; - char *name; -} vmArg; - -/* use like: - - int headlessFlag; - char *logFilename; - unsigned int memorySize; - - sqArg args[] = { - { ARG_FLAG, &headlessFlag, "-headless" }, - { ARG_STRING, &logFilename, "-log:" }, - { ARG_UINT, &memorySize, "-memory:"}, - { ARG_NULL, 0, "--help"}, - { ARG_NONE, NULL, NULL } - }; -*/ - - -int parseArguments(char *cmdLine, vmArg args[]); - -#endif /* sqArgs.h */ - Modified: branches/Cog/platforms/win32/vm/sqWin32Intel.c =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32Intel.c 2011-11-23 19:43:53 UTC (rev 2516) +++ branches/Cog/platforms/win32/vm/sqWin32Intel.c 2011-11-28 19:07:44 UTC (rev 2517) @@ -19,7 +19,6 @@ #include <float.h> #include <ole2.h> #include "sq.h" -#include "sqWin32Args.h" #include "sqWin32Backtrace.h" #if COGVM # include "cogmethod.h" @@ -52,11 +51,13 @@ static void printCrashDebugInformation(LPEXCEPTION_POINTERS exp); /*** Variables -- command line */ -char *initialCmdLine; -int numOptionsVM = 0; -char *(vmOptions[MAX_OPTIONS]); -int numOptionsImage = 0; -char *(imageOptions[MAX_OPTIONS]); +static char *initialCmdLine; +static int numOptionsVM = 0; +static char **vmOptions; +static int numOptionsImage = 0; +static char **imageOptions; +static int clargc; /* the Unix-style command line, saved for GetImageOption */ +static char **clargv; /* console buffer */ TCHAR consoleBuffer[4096]; @@ -1187,62 +1188,22 @@ extern sqInt minBackwardJumpCountForCompile; #endif /* COGVM */ -static vmArg args[] = { - { ARG_NULL, 0, "--help" }, /* the name of a service */ - { ARG_STRING, &installServiceName, "-service:" }, /* the name of a service */ - { ARG_FLAG, &fHeadlessImage, "-headless" }, /* do we run headless? */ - { ARG_STRING, &logName, "-log:" }, /* VM log file */ - { ARG_UINT, &dwMemorySize, "-memory:" }, /* megabyte of memory to use */ -#ifdef VISTA_SECURITY /* IE7/Vista protected mode support */ - { ARG_FLAG, &fLowRights, "-lowRights" }, /* started with low rights, - use alternate untrustedUserDirectory */ -#endif /* VISTA_SECURITY */ -#if (STACKVM || NewspeakVM) && !COGVM - { ARG_FLAG, &sendTrace, "-sendtrace"}, -#endif -#if STACKVM || NewspeakVM - { ARG_STRING_FUNC, setBreakSelector, "-breaksel:"}, /* break-point selector string */ - { ARG_INT_FUNC, ioSetMaxExtSemTableSize, "-numextsems:"}, /* set num external semaphores */ -#endif /* STACKVM || NewspeakVM */ -#if STACKVM - { ARG_UINT, &checkForLeaks, "-leakcheck:"}, /* leak check on GC */ - { ARG_UINT, &desiredEdenBytes, "-eden:" }, /* bytes of eden to use */ - { ARG_UINT, &desiredNumStackPages, "-stackpages:"}, /* n stack pages to use */ - { ARG_FLAG, &suppressHeartbeatFlag, "-noheartbeat"}, /* no heartbeat for dbg */ -#endif /* STACKVM */ -#if COGVM - { ARG_UINT, &desiredCogCodeSize, "-codesize:"}, /* machine code memory to use */ - { ARG_UINT, &traceLinkedSends, "-sendtrace:" }, /* trace sends in log */ - { ARG_INT, &traceLinkedSends, "-trace:" }, /* trace sends in log */ - { ARG_FLAG, &traceStores, "-tracestores" }, /* assert-check stores */ - { ARG_UINT, &debugPrimCallStackOffset, "-dpcso:"}, /* debug prim call stack offset */ - { ARG_UINT, &maxLiteralCountForCompile, "-cogmaxlits:"}, /* max # of literals for a method to be compiled to machine code */ - { ARG_UINT, &minBackwardJumpCountForCompile, "-cogminjumps:"}, /* max # of literals for a method to be compiled to machine code */ -#endif /* COGVM */ - /* NOTE: the following flags are "undocumented" */ - { ARG_INT, &browserWindow, "-browserWindow:"}, /* The web browser window we run in */ - - /* service support on 95 */ - { ARG_FLAG, &fRunService, "-service95" }, /* do we start as service? */ - { ARG_FLAG, &fBroadcastService95, "-broadcast95" }, /* should we notify services of a user logon? */ - { ARG_NONE, NULL, NULL } -}; - /* sqMain: - This is common entry point regardless of whether we're running - as a normal app or as a service. Note that a number of things - may have been set up before coming here. In particular, - * fRunService - to determine whether we're running as NT service - However, the command line must always contain all parameters necessary. - In other words, even though the logName may have been set before, - the command line has to include the -log: switch. + This is common entry point regardless of whether we're running as a normal + app or as a service. Note that a number of things may have been set up + before coming here. In particular, + * fRunService - to determine whether we're running as NT service + However, the command line must always contain all parameters necessary. + In other words, even though the logName may have been set before, + the command line has to include the -log switch. */ -int sqMain(char *lpCmdLine, int nCmdShow) +static int parseArguments(int argc, char *argv[]); + +int +sqMain(int argc, char *argv[]) { int virtualMemory; - WCHAR *cmdLineW; - char *cmdLineA; int sz; /* set default fpu control word */ @@ -1250,12 +1211,6 @@ LoadPreferences(); - /* Fetch the command line */ - cmdLineW = GetCommandLineW(); - sz = WideCharToMultiByte(CP_UTF8, 0, cmdLineW, -1, NULL, 0, NULL, NULL); - cmdLineA = calloc(sz, sizeof(char)); - WideCharToMultiByte(CP_UTF8, 0, cmdLineW, -1, cmdLineA, sz, NULL, NULL); - /* If running as single app, find the previous instance */ if(fRunSingleApp) { HWND win = GetTopWindow(0); @@ -1267,6 +1222,7 @@ } if(win) { + WCHAR *cmdLineW = GetCommandLineW(); /* An instance is running already. Inform it about the app. */ int bytes = (wcslen(cmdLineW)+1) * sizeof(WCHAR); HANDLE h = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, bytes); @@ -1287,7 +1243,7 @@ } /* parse command line args */ - if(!parseArguments(cmdLineA, args)) + if(!parseArguments(argc, argv)) return printUsage(1); /* a quick check if we have any argument at all */ @@ -1458,10 +1414,9 @@ /****************************************************************************/ /* WinMain */ /****************************************************************************/ -int WINAPI WinMain (HINSTANCE hInst, - HINSTANCE hPrevInstance, - LPSTR lpCmdLine, - int nCmdShow) + +int WINAPI +WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { /* a few things which need to be done first */ gatherSystemInfo(); @@ -1478,6 +1433,29 @@ GetModuleFileNameW(hInst, vmNameW, MAX_PATH); WideCharToMultiByte(CP_UTF8, 0, vmNameW, -1, vmName, MAX_PATH, NULL, NULL); } + /* parse the command line into the unix-style argc, argv, converting to + * UTF-8 on the way. */ + { LPWSTR *argList = CommandLineToArgvW(GetCommandLineW(), &clargc); + int i; + + clargv = calloc(clargc + 1, sizeof(char *)); + vmOptions = calloc(clargc + 1, sizeof(char *)); + imageOptions = calloc(clargc + 1, sizeof(char *)); + if (!clargv || !vmOptions || !imageOptions) { + fprintf(stderr,"out of memory for command line?!\n"); + return 1; + } + for (i = 0; i < clargc; i++) { + int n = WideCharToMultiByte(CP_UTF8, 0, argList[i], -1, 0, 0, 0, 0); + if (!(clargv[i] = malloc(n))) { + fprintf(stderr,"out of memory for command line?!\n"); + return 1; + } + WideCharToMultiByte(CP_UTF8, 0, argList[i], -1, clargv[i], n, 0, 0); + } + LocalFree(argList); + } + /* open all streams in binary mode */ _fmode = _O_BINARY; @@ -1518,11 +1496,257 @@ } /* start the non-service version */ - sqMain(lpCmdLine, nCmdShow); + sqMain(clargc, clargv); return 0; } +static int +strtobkm(const char *str) +{ + char *suffix; + int value = strtol(str, &suffix, 10); + switch (*suffix) { + case 'k': case 'K': value *= 1024; break; + case 'm': case 'M': value *= 1024*1024; break; + } + return value; +} + +static int +parseVMArgument(int argc, char *argv[]) +{ + /* flags */ + if (!strcmp(argv[0], "-help")) { + printUsage(1); + return 1; } + else if (!strcmp(argv[0], "-headless")) { fHeadlessImage = true; return 1; } + else if (!strcmp(argv[0], "-headfull")) { fHeadlessImage = false; return 1;} +#ifdef VISTA_SECURITY /* IE7/Vista protected mode support */ + /* started with low rights, use alternate untrustedUserDirectory */ + else if (!strcmp(argv[0], "-lowRights")) { fLowRights = true; return 1; } +#endif /* VISTA_SECURITY */ +#if (STACKVM || NewspeakVM) && !COGVM + else if (!strcmp(argv[0], "-sendtrace")) + { extern sqInt sendTrace; sendTrace = 1; return 1; } +#endif + + /* parameters */ + else if (argc > 1 && !strcmp(argv[0], "-service")) { + installServiceName = argv[1]; + return 2; + } + else if (!strncmp(argv[0], "-service:", 9)) { + installServiceName = argv[0] + 9; + return 1; + } + else if (argc > 1 && !strcmp(argv[0], "-log")) { + logName = argv[1]; + return 2; + } + else if (!strncmp(argv[0], "-log:", 5)) { + logName = argv[0] + 5; + return 1; + } + else if (argc > 1 && !strcmp(argv[0], "-memory")) { + dwMemorySize = strtobkm(argv[1]); + return 2; + } + else if (!strncmp(argv[0], "-memory:", 8)) { + dwMemorySize = strtobkm(argv[0] + 8); + return 1; + } +#if STACKVM || NewspeakVM + else if (argc > 1 && !strcmp(argv[0], "-breaksel")) { + extern void setBreakSelector(char *); + setBreakSelector(argv[1]); + return 2; } + else if (!strncmp(argv[0], "-breaksel:", 10)) { + extern void setBreakSelector(char *); + setBreakSelector(argv[0] + 10); + return 1; } + else if (argc > 1 && !strcmp(argv[0], "-numextsems")) { + ioSetMaxExtSemTableSize(atoi(argv[1])); + return 2; } + else if (!strncmp(argv[0], "-numextsems:", 12)) { + ioSetMaxExtSemTableSize(atoi(argv[1]+12)); + return 1; } +#endif /* STACKVM || NewspeakVM */ +#if STACKVM + else if (argc > 1 && !strcmp(argv[0], "-eden")) { + extern sqInt desiredEdenBytes; + desiredEdenBytes = strtobkm(argv[1]); + return 2; } + else if (!strncmp(argv[0], "-eden:", 6)) { + extern sqInt desiredEdenBytes; + desiredEdenBytes = strtobkm(argv[0]+6); + return 2; } + else if (argc > 1 && !strcmp(argv[0], "-leakcheck")) { + extern sqInt checkForLeaks; + checkForLeaks = atoi(argv[1]); + return 2; } + else if (!strncmp(argv[0], "-leakcheck:", 11)) { + extern sqInt checkForLeaks; + checkForLeaks = atoi(argv[0]+11); + return 2; } + else if (argc > 1 && !strcmp(argv[0], "-stackpages")) { + extern sqInt desiredNumStackPages; + desiredNumStackPages = atoi(argv[1]); + return 2; } + else if (!strncmp(argv[0], "-stackpages:", 12)) { + extern sqInt desiredNumStackPages; + desiredNumStackPages = atoi(argv[0]+12); + return 2; } + else if (!strcmp(argv[0], "-noheartbeat")) { + extern sqInt suppressHeartbeatFlag; + suppressHeartbeatFlag = 1; + return 1; } +#endif /* STACKVM */ #if COGVM + else if (!strcmp(argv[0], "-codesize")) { + extern sqInt desiredCogCodeSize; + desiredCogCodeSize = strtobkm(argv[1]); + return 2; } +# define TLSLEN (sizeof("-sendtrace")-1) + else if (!strncmp(argv[0], "-sendtrace", TLSLEN)) { + extern int traceLinkedSends; + char *equalsPos = strchr(argv[0],'='); + + if (!equalsPos) { + traceLinkedSends = 1; + return 1; + } + if (equalsPos - argv[0] != TLSLEN + || (equalsPos[1] != '-' && !isdigit(equalsPos[1]))) + return 0; + + traceLinkedSends = atoi(equalsPos + 1); + return 1; } + else if (!strcmp(argv[0], "-tracestores")) { + extern sqInt traceStores; + traceStores = 1; + return 1; } + else if (!strcmp(argv[0], "-dpcso")) { + extern unsigned long debugPrimCallStackOffset; + debugPrimCallStackOffset = (unsigned long)strtobkm(argv[1]); + return 2; } + else if (argc > 1 && !strcmp(argv[0], "-cogmaxlits")) { + extern sqInt maxLiteralCountForCompile; + maxLiteralCountForCompile = strtobkm(argv[1]); + return 2; } + else if (!strncmp(argv[0], "-cogmaxlits:", 12)) { + extern sqInt maxLiteralCountForCompile; + maxLiteralCountForCompile = strtobkm(argv[0]+12); + return 2; } + else if (argc > 1 && !strcmp(argv[0], "-cogminjumps")) { + extern sqInt minBackwardJumpCountForCompile; + minBackwardJumpCountForCompile = strtobkm(argv[1]); + return 2; } + else if (!strncmp(argv[0], "-cogminjumps:",13)) { + extern sqInt minBackwardJumpCountForCompile; + minBackwardJumpCountForCompile = strtobkm(argv[0]+13); + return 2; } +#endif /* COGVM */ + + /* NOTE: the following flags are "undocumented" */ + else if (argc > 1 && !strcmp(argv[0], "-browserWindow")) { + browserWindow = (HWND)atoi(argv[1]); + return 2; } + else if (!strncmp(argv[0], "-browserWindow:", 15)) { + browserWindow = (HWND)atoi(argv[0]+15); + return 1; } + + /* service support on 95 */ + else if (!strcmp(argv[0], "-service95")) { fRunService = true; return 1; } + else if (!strcmp(argv[0], "-broadcast95")) { fBroadcastService95 = true; return 1; } + + return 0; /* option not recognised */ +} + +/* parse all arguments meaningful to the VM; answer index of last VM arg + 1 */ +static int +parseVMArgs(int argc, char *argv[]) +{ int n, i = 0, j; + + while (++i < argc && *argv[i] == '-' && strcmp(argv[i],"--")) { + if ((n = parseVMArgument(argc - i, argv + i))) { + for (j = 0; j < n; j++) + vmOptions[numOptionsVM++] = argv[i+j]; + } + else { + fprintf(stderr,"Unknown option encountered!\n"); + return i; + } + } + return i; +} + +static int +IsImage(char *name) +{ + int magic; + int byteSwapped(int); + sqImageFile fp; + + fp = sqImageFileOpen(name,"rb"); + if(!fp) return 0; /* not an image */ + if(sqImageFileRead(&magic, 1, sizeof(magic), fp) != sizeof(magic)) { + sqImageFileClose(fp); + return 0; + } + if(readableFormat(magic) || readableFormat(byteSwapped(magic))) { + sqImageFileClose(fp); + return true; + } + + /* no luck at beginning of file, seek to 512 and try again */ + sqImageFileSeek( fp, 512); + if(sqImageFileRead(&magic, 1, sizeof(magic), fp) != sizeof(magic)) { + sqImageFileClose(fp); + return 0; + } + sqImageFileClose(fp); + return readableFormat(magic) || readableFormat(byteSwapped(magic)); +} + +/* parse all arguments starting with the image name */ +static int +parseGenericArgs(int argc, char *argv[]) +{ int i; + + if (argc < 1) + return 0; + + if (*imageName == 0) { /* only try to use image name if none is provided */ + if (*argv[0] && IsImage(argv[0])) { + strcpy(imageName, argv[0]); + /* if provided, the image is a vm argument. */ + vmOptions[numOptionsVM++] = argv[0]; + } + } + else /* provide image name as second argument if implicitly specified */ + imageOptions[numOptionsImage++] = imageName; + + imageOptions[numOptionsImage++] = argv[0]; + for (i = 1; i < argc; i++) + imageOptions[numOptionsImage++] = argv[i]; + + return 1; +} + +static int +parseArguments(int argc, char *argv[]) +{ + int nvmargs; + + /* argv[0] = executable name */ + vmOptions[numOptionsVM++] = argv[0]; + /* parse VM options */ + nvmargs = parseVMArgs(argc, argv); + /* parse image and generic args */ + return parseGenericArgs(argc - nvmargs, argv + nvmargs); +} + +#if COGVM /* * Support code for Cog. * a) Answer whether the C frame pointer is in use, for capture of the C stack |
Free forum by Nabble | Edit this page |