[Vm-dev] [commit] r2517 - Add access to VM arguments to Mac. Make
Windows, Mac and Unix consistent:
commits at squeakvm.org
commits at squeakvm.org
Mon Nov 28 19:07:45 UTC 2011
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: raab at isg.cs.uni-magdeburg.de
-* 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
More information about the Vm-dev
mailing list