[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