[commit] r2394 - Fix primitiveExecuteMethodArgsArray for > 2 args.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[commit] r2394 - Fix primitiveExecuteMethodArgsArray for > 2 args.

commits-3
 
Author: eliot
Date: 2011-06-07 17:36:21 -0700 (Tue, 07 Jun 2011)
New Revision: 2394

Added:
   branches/Cog/src/plugins/FT2Plugin/
   branches/Cog/src/plugins/FT2Plugin/FT2Plugin.c
   branches/Cog/src/plugins/Win32OSProcessPlugin/
   branches/Cog/src/plugins/Win32OSProcessPlugin/Win32OSProcessPlugin.c
Modified:
   branches/Cog/src/examplePlugins.ext
   branches/Cog/src/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c
   branches/Cog/src/vm/cointerp.c
   branches/Cog/src/vm/cointerp.h
   branches/Cog/src/vm/gcc3x-cointerp.c
Log:
Fix primitiveExecuteMethodArgsArray for > 2 args.
Include Win32OSProcessPlugin source.
Include FT2Plugin source.


Modified: branches/Cog/src/examplePlugins.ext
===================================================================
--- branches/Cog/src/examplePlugins.ext 2011-06-07 18:48:37 UTC (rev 2393)
+++ branches/Cog/src/examplePlugins.ext 2011-06-08 00:36:21 UTC (rev 2394)
@@ -12,6 +12,7 @@
 ZipPlugin \
 DropPlugin \
 FFTPlugin \
+FT2Plugin \
 FileCopyPlugin \
 FilePlugin \
 FloatArrayPlugin \
@@ -31,7 +32,6 @@
 Matrix2x3Plugin \
 MiscPrimitivePlugin \
 Mpeg3Plugin \
-QVMProfileMacSupportPlugin \
 QuicktimePlugin \
 RePlugin \
 SqueakFFIPrims \
@@ -42,10 +42,7 @@
 SoundGenerationPlugin \
 SoundPlugin \
 StarSqueakPlugin \
-SurfacePlugin \
-SqueakFFIPrims \
-SqueakFFIPrims \
-SqueakFFIPrims \
-SqueakFFIPrims \
 UUIDPlugin \
-VMProfileMacSupportPlugin
+UnixOSProcessPlugin \
+VMProfileMacSupportPlugin \
+Win32OSProcessPlugin

Added: branches/Cog/src/plugins/FT2Plugin/FT2Plugin.c
===================================================================
--- branches/Cog/src/plugins/FT2Plugin/FT2Plugin.c                        (rev 0)
+++ branches/Cog/src/plugins/FT2Plugin/FT2Plugin.c 2011-06-08 00:36:21 UTC (rev 2394)
@@ -0,0 +1,2017 @@
+/* Automatically generated by
+ FT2PluginCodeGenerator Freetype-Plugin-Igor.Stasenko.57 uuid: b71f9041-ec30-42ca-af6b-b4fbdb0d9e80
+   from
+ FT2Plugin Freetype-Plugin-Igor.Stasenko.57 uuid: b71f9041-ec30-42ca-af6b-b4fbdb0d9e80
+ */
+static char __buildInfo[] = "FT2Plugin Freetype-Plugin-Igor.Stasenko.57 uuid: b71f9041-ec30-42ca-af6b-b4fbdb0d9e80 " __DATE__ ;
+
+
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <ft2build.h>
+
+/* Default EXPORT macro that does nothing (see comment in sq.h): */
+#define EXPORT(returnType) returnType
+
+/* Do not include the entire sq.h file but just those parts needed. */
+/*  The virtual machine proxy definition */
+#include "sqVirtualMachine.h"
+/* Configuration options */
+#include "sqConfig.h"
+/* Platform specific definitions */
+#include "sqPlatformSpecific.h"
+
+#define true 1
+#define false 0
+#define null 0  /* using 'null' because nil is predefined in Think C */
+#ifdef SQUEAK_BUILTIN_PLUGIN
+#undef EXPORT
+// was #undef EXPORT(returnType) but screws NorCroft cc
+#define EXPORT(returnType) static returnType
+#endif
+
+#include FT_TRUETYPE_TABLES_H
+#include FT_FREETYPE_H
+#include FT_OUTLINE_H
+#include "sqMemoryAccess.h"
+
+
+/*** Constants ***/
+#define FormBitsIndex 0
+#define FormDepthIndex 3
+#define FormHeightIndex 2
+#define FormInstSize 5
+#define FormWidthIndex 1
+#define FT2GlyphSlotFaceIndex 0
+#define FT2GlyphSlotInstSize 17
+#define FT2OutlineContoursIndex 4
+#define FT2OutlineContoursSizeIndex 0
+#define FT2OutlineFlagsIndex 5
+#define FT2OutlineInstSize 6
+#define FT2OutlinePointsIndex 2
+#define FT2OutlinePointsSizeIndex 1
+#define FT2OutlineTagsIndex 3
+
+
+/*** Function Prototypes ***/
+static char * fetchByteArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize);
+static short* fetchShortArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize);
+static long * fetchWordArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize);
+static sqInt ftAllocateHandleInReceiverForPointer(void *aPointer);
+static sqInt ftAllocateStringForPointer(const char *aPointer);
+static FT_Encoding ftEncodingValueFromString(sqInt string);
+static void * ftHandleValueFromReceiver(sqInt rcvrOop);
+static int ftInitBitmapfromForm(FT_Bitmap*bitmap, sqInt formOop);
+static int ftInitBitmapfromFormrenderMode(FT_Bitmap*bitmap, sqInt formOop, sqInt mode);
+static int ftParameterError(void);
+static sqInt ftStringFromEncodingValue(FT_Encoding encoding);
+static VirtualMachine * getInterpreter(void);
+EXPORT(const char*) getModuleName(void);
+static sqInt halt(void);
+EXPORT(sqInt) initialiseModule(void);
+static sqInt msg(char *s);
+EXPORT(sqInt) primitiveCopyToExternalMemory(void);
+EXPORT(sqInt) primitiveDoneFace(void);
+EXPORT(sqInt) primitiveDoneFacePreserveFields(void);
+EXPORT(sqInt) primitiveEmboldenFaceGlyphSlotOutline(void);
+EXPORT(sqInt) primitiveErrorCode(void);
+EXPORT(sqInt) primitiveErrorString(void);
+EXPORT(sqInt) primitiveFreeExternalMemory(void);
+EXPORT(sqInt) primitiveGetFaceCharIndex(void);
+EXPORT(sqInt) primitiveGetFaceCharMap(void);
+EXPORT(sqInt) primitiveGetFaceCharMapsIntoArray(void);
+EXPORT(sqInt) primitiveGetFaceGlyphName(void);
+EXPORT(sqInt) primitiveGetKerningLeftRight(void);
+EXPORT(sqInt) primitiveGetPostscriptName(void);
+EXPORT(sqInt) primitiveGetSfntTableOS2(void);
+static sqInt primitiveGetTrackKerningPointSizedegree(sqInt pointSize, sqInt degree);
+EXPORT(sqInt) primitiveHasKerning(void);
+EXPORT(sqInt) primitiveLibraryHandle(void);
+EXPORT(sqInt) primitiveLoadCharacter(void);
+EXPORT(sqInt) primitiveLoadFaceBbox(void);
+EXPORT(sqInt) primitiveLoadFaceFields(void);
+EXPORT(sqInt) primitiveLoadGlyph(void);
+EXPORT(sqInt) primitiveLoadGlyphSlotFromFace(void);
+EXPORT(sqInt) primitiveLoadOutlineArraysFromFace(void);
+EXPORT(sqInt) primitiveLoadOutlineSizesFromFace(void);
+EXPORT(sqInt) primitiveModuleErrorCode(void);
+EXPORT(sqInt) primitiveNewFaceFromFileAndIndex(void);
+EXPORT(sqInt) primitiveNewMemoryFaceFromExternalMemoryAndIndex(void);
+EXPORT(sqInt) primitiveNumberOfOutlineCountours(void);
+EXPORT(sqInt) primitiveRenderGlyphIntoForm(void);
+EXPORT(sqInt) primitiveRenderGlyphIntoFormWithRenderMode(void);
+EXPORT(sqInt) primitiveResetErrorCode(void);
+EXPORT(sqInt) primitiveSetFaceCharMap(void);
+EXPORT(sqInt) primitiveSetPixelSizes(void);
+EXPORT(sqInt) primitiveSetTransform(void);
+EXPORT(sqInt) primitiveTransformFaceGlyphSlotOutline(void);
+EXPORT(sqInt) primitiveTranslateFaceGlyphSlotOutline(void);
+EXPORT(sqInt) primitiveVersion(void);
+EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
+EXPORT(sqInt) shutdownModule(void);
+static void sqAssert(sqInt aBool);
+
+
+/*** Variables ***/
+static int errorCode;
+
+#ifdef SQUEAK_BUILTIN_PLUGIN
+extern
+#endif
+struct VirtualMachine* interpreterProxy;
+static FT_Library library;
+static const char *moduleName =
+#ifdef SQUEAK_BUILTIN_PLUGIN
+ "FT2Plugin Freetype-Plugin-Igor.Stasenko.57 (i)"
+#else
+ "FT2Plugin Freetype-Plugin-Igor.Stasenko.57 (e)"
+#endif
+;
+
+
+static char *
+fetchByteArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize)
+{
+ sqInt array;
+
+ array = interpreterProxy->fetchPointerofObject(fieldIndex, objectPointer);
+ if ((interpreterProxy->isBytes(array))
+ && ((interpreterProxy->slotSizeOf(array)) == aSize)) {
+ return interpreterProxy->arrayValueOf(array);
+ }
+ return null;
+}
+
+static short*
+fetchShortArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize)
+{
+ sqInt array;
+
+ array = interpreterProxy->fetchPointerofObject(fieldIndex, objectPointer);
+ if ((interpreterProxy->isWords(array))
+ && ((interpreterProxy->slotSizeOf(array)) == (((sqInt) (aSize + 1) >> 1)))) {
+ return interpreterProxy->arrayValueOf(array);
+ }
+ return null;
+}
+
+static long *
+fetchWordArrayofObjectassureSize(sqInt fieldIndex, sqInt objectPointer, sqInt aSize)
+{
+ sqInt array;
+
+ array = interpreterProxy->fetchPointerofObject(fieldIndex, objectPointer);
+ if ((interpreterProxy->isWords(array))
+ && ((interpreterProxy->slotSizeOf(array)) == aSize)) {
+ return interpreterProxy->arrayValueOf(array);
+ }
+ return null;
+}
+
+
+/* given aPointer (returned from a library call),
+ set the receiver's (bottom of stack) first instance variable
+ to a ByteArray containing the pointer's bytes */
+
+static sqInt
+ftAllocateHandleInReceiverForPointer(void *aPointer)
+{
+ void **extraByteArrayPtr;
+ sqInt returnedHandle;
+
+ if (aPointer) {
+
+ /* Allocate a Smalltalk ByteArray -- lastAlloc contains the length */
+ /* Copy from the C bytecode buffer to the Smalltalk ByteArray */
+
+ returnedHandle = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), sizeof(void **));
+ extraByteArrayPtr = interpreterProxy->arrayValueOf(returnedHandle);
+ *extraByteArrayPtr = (void *)(aPointer);
+ }
+ else {
+ returnedHandle = interpreterProxy->nilObject();
+ }
+ interpreterProxy->storePointerofObjectwithValue(0, interpreterProxy->stackObjectValue(interpreterProxy->methodArgumentCount()), returnedHandle);
+ ;
+ return returnedHandle;
+}
+
+
+/* given NUL-terminated char* aPointer (returned from a library call),
+ return the oop for a String containing the pointer's bytes */
+
+static sqInt
+ftAllocateStringForPointer(const char *aPointer)
+{
+ char *extraByteArrayPtr;
+ sqInt returnedHandle;
+
+ if (aPointer) {
+
+ /* Allocate a Smalltalk ByteArray -- lastAlloc contains the length */
+ /* Copy from the C bytecode buffer to the Smalltalk ByteArray */
+
+ returnedHandle = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), strlen(aPointer));
+ extraByteArrayPtr = interpreterProxy->arrayValueOf(returnedHandle);
+ ;
+ strncpy(extraByteArrayPtr, aPointer, strlen(aPointer));
+ }
+ else {
+ returnedHandle = interpreterProxy->nilObject();
+ }
+ return returnedHandle;
+}
+
+
+/* Return a 32-bit word from the bytes held by string. */
+
+static FT_Encoding
+ftEncodingValueFromString(sqInt string)
+{
+ unsigned char*ptr;
+ unsigned long retval;
+
+ interpreterProxy->success((!((string & 1)))
+ && ((interpreterProxy->isBytes(string))
+ && ((interpreterProxy->slotSizeOf(string)) == (sizeof(FT_Encoding)))));
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ retval = 0;
+
+ /* ptr := self cCode: '(unsigned char *) (string + 4)'. */
+
+ ptr = interpreterProxy->arrayValueOf(string);
+ ;
+ retval = ((unsigned long)ptr[0]) << 24;
+ retval += ((unsigned long)ptr[1]) << 16;
+ retval += ((unsigned long)ptr[2]) << 8;
+ retval += (unsigned long)ptr[3];
+ ;
+ return (FT_Encoding)retval;
+}
+
+
+/* this is the opposite of #ftAllocateHandleIn:forPointer: .
+ It takes rcvr's first instance variable,
+ which should be a ByteArray the size of a void*,
+ and returns its value as a C pointer. */
+
+static void *
+ftHandleValueFromReceiver(sqInt rcvrOop)
+{
+ sqInt btw;
+ sqInt oop;
+
+ oop = interpreterProxy->fetchPointerofObject(0, rcvrOop);
+ interpreterProxy->success((interpreterProxy->isBytes(oop))
+ && ((interpreterProxy->slotSizeOf(oop)) == (sizeof(void *))));
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ btw = bytesPerWord();
+ return *(void**)(pointerForOop(oop + btw));
+}
+
+
+/* Initialize the values in an FT_Bitmap from the given Form */
+
+static int
+ftInitBitmapfromForm(FT_Bitmap*bitmap, sqInt formOop)
+{
+ unsigned char*buffer;
+ sqInt depth;
+ sqInt height;
+ sqInt numGrays;
+ sqInt pitch;
+ sqInt pixelMode;
+ sqInt width;
+ sqInt wordsPerRow;
+
+ interpreterProxy->success(interpreterProxy->isPointers(formOop));
+ interpreterProxy->success((interpreterProxy->slotSizeOf(formOop)) >= FormInstSize);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ width = interpreterProxy->fetchIntegerofObject(FormWidthIndex, formOop);
+ height = interpreterProxy->fetchIntegerofObject(FormHeightIndex, formOop);
+ depth = interpreterProxy->fetchIntegerofObject(FormDepthIndex, formOop);
+ buffer = ((void*) (interpreterProxy->fetchArrayofObject(FormBitsIndex, formOop)));
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (depth < 0) {
+ depth = depth * -1;
+ }
+ if (depth == 1) {
+ wordsPerRow = ((sqInt) (width + 31) >> 5);
+ numGrays = 1;
+ pixelMode = FT_PIXEL_MODE_MONO;
+ }
+ else {
+ if (depth == 8) {
+ wordsPerRow = ((sqInt) (width + 3) >> 2);
+ numGrays = 256;
+ pixelMode = FT_PIXEL_MODE_GRAY;
+ }
+ else {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+
+#ifndef WORDS_BIGENDIAN
+ depth = depth * -1;
+#endif
+;
+ interpreterProxy->storeIntegerofObjectwithValue(FormDepthIndex, formOop, depth);
+ pitch = wordsPerRow * 4;
+ bitmap->rows = height;
+ bitmap->width = width;
+ bitmap->pitch = pitch;
+ bitmap->buffer = buffer;
+ bitmap->num_grays = numGrays;
+ bitmap->pixel_mode = pixelMode;
+ return 1;
+}
+
+
+/* Initialize the values in an FT_Bitmap from the given Form */
+/* pixelMode */
+
+static int
+ftInitBitmapfromFormrenderMode(FT_Bitmap*bitmap, sqInt formOop, sqInt mode)
+{
+ unsigned char*buffer;
+ sqInt depth;
+ sqInt height;
+ sqInt numGrays;
+ sqInt pitch;
+ sqInt width;
+ sqInt wordsPerRow;
+
+ interpreterProxy->success(interpreterProxy->isPointers(formOop));
+ interpreterProxy->success((interpreterProxy->slotSizeOf(formOop)) >= FormInstSize);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ width = interpreterProxy->fetchIntegerofObject(FormWidthIndex, formOop);
+ height = interpreterProxy->fetchIntegerofObject(FormHeightIndex, formOop);
+ depth = interpreterProxy->fetchIntegerofObject(FormDepthIndex, formOop);
+ buffer = ((void*) (interpreterProxy->fetchArrayofObject(FormBitsIndex, formOop)));
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (depth < 0) {
+ depth = depth * -1;
+ }
+ if (depth == 1) {
+ wordsPerRow = ((sqInt) (width + 31) >> 5);
+ numGrays = 1;
+ }
+ else {
+ if (depth == 8) {
+ wordsPerRow = ((sqInt) (width + 3) >> 2);
+ numGrays = 256;
+ }
+ else {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+
+#ifndef WORDS_BIGENDIAN
+ depth = depth * -1;
+#endif
+;
+ interpreterProxy->storeIntegerofObjectwithValue(FormDepthIndex, formOop, depth);
+ pitch = wordsPerRow * 4;
+ bitmap->rows = height;
+ bitmap->width = width;
+ bitmap->pitch = pitch;
+ bitmap->buffer = buffer;
+ bitmap->num_grays = numGrays;
+ bitmap->pixel_mode = mode;
+ return 1;
+}
+
+static int
+ftParameterError(void)
+{
+ errorCode = 255;
+ return interpreterProxy->primitiveFail();
+}
+
+
+/* Return a newly allocated String from the given 32-bit word */
+
+static sqInt
+ftStringFromEncodingValue(FT_Encoding encoding)
+{
+ unsigned char*ptr;
+ sqInt stringOop;
+
+ stringOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), sizeof(FT_Encoding));
+ ;
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ ptr = interpreterProxy->firstIndexableField(stringOop);
+ ;
+ ptr[0] = (encoding & 0xFF000000) >> 24;
+ ptr[1] = (encoding & 0x00FF0000) >> 16;
+ ptr[2] = (encoding & 0x0000FF00) >> 8;
+ ptr[3] = (encoding & 0x000000FF);
+ return stringOop;
+}
+
+
+/* Note: This is coded so that plugins can be run from Squeak. */
+
+static VirtualMachine *
+getInterpreter(void)
+{
+ return interpreterProxy;
+}
+
+
+/* Note: This is hardcoded so it can be run from Squeak.
+ The module name is used for validating a module *after*
+ it is loaded to check if it does really contain the module
+ we're thinking it contains. This is important! */
+
+EXPORT(const char*)
+getModuleName(void)
+{
+ return moduleName;
+}
+
+static sqInt
+halt(void)
+{
+ ;
+ return 0;
+}
+
+EXPORT(sqInt)
+initialiseModule(void)
+{
+ library = null;
+
+#ifdef macintoshSqueak
+ fetchPreferences();
+#endif
+;
+ errorCode = FT_Init_FreeType(&library);
+ return errorCode == 0;
+}
+
+static sqInt
+msg(char *s)
+{
+ fprintf(stderr, "\n%s: %s", moduleName, s);
+ return 0;
+}
+
+EXPORT(sqInt)
+primitiveCopyToExternalMemory(void)
+{
+ char *aByteArray;
+ void *aPointer;
+ size_t byteSize;
+ sqInt rcvr;
+
+ interpreterProxy->success(interpreterProxy->isBytes(interpreterProxy->stackValue(0)));
+ aByteArray = ((char *) (interpreterProxy->firstIndexableField(interpreterProxy->stackValue(0))));
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FreeTypeExternalMemory"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ ;
+ errorCode = 0;
+ byteSize = interpreterProxy->byteSizeOf(((sqInt)(long)(aByteArray) - 4));
+ ;
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ aPointer = malloc(byteSize);
+ memcpy(aPointer,aByteArray,byteSize);
+ ftAllocateHandleInReceiverForPointer(aPointer);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+
+/* Call the library to release the given face record.
+ Nil out the pointer fields */
+
+EXPORT(sqInt)
+primitiveDoneFace(void)
+{
+ FT_Face face;
+ sqInt i;
+ sqInt rcvr;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ ;
+
+ /* nil out all the fields */
+
+ errorCode = FT_Done_Face(face);
+ for (i = 0; i <= 23; i += 1) {
+ interpreterProxy->storePointerofObjectwithValue(i, rcvr, interpreterProxy->nilObject());
+ }
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ return null;
+}
+
+
+/* Call the library to release the given face record.
+ Nil out the handle field, but do not nil the other fields,
+ as their values are needed even if the face cannot be re-opened
+ in the future due to a missing font file etc. */
+
+EXPORT(sqInt)
+primitiveDoneFacePreserveFields(void)
+{
+ FT_Face face;
+ sqInt rcvr;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ ;
+
+ /* nil the handle field */
+
+ errorCode = FT_Done_Face(face);
+ interpreterProxy->storePointerofObjectwithValue(0, rcvr, interpreterProxy->nilObject());
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ return null;
+}
+
+
+/* emboldens the outline in the face's glyphSlot by strength (expressed in
+ 26.6 pixel format).
+ The new outline will be at most 4 times `strength' pixels wider and
+ higher.
+ */
+
+EXPORT(sqInt)
+primitiveEmboldenFaceGlyphSlotOutline(void)
+{
+ FT_Face face;
+ sqInt rcvr;
+ sqInt strength;
+
+ strength = interpreterProxy->stackIntegerValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ errorCode = FT_Outline_Embolden( &face->glyph->outline, strength );
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+
+/* high byte is module error, low is generic error */
+
+EXPORT(sqInt)
+primitiveErrorCode(void)
+{
+ sqInt _return_value;
+
+ _return_value = interpreterProxy->positive32BitIntegerFor((FT_ERROR_BASE(errorCode)));
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->popthenPush(1, _return_value);
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveErrorString(void)
+{
+ const struct ftError *ftError;
+ const char *str;
+
+
+struct ftError { int errCode; const char* errMsg; };
+#undef __FTERRORS_H__
+#define FT_ERRORDEF( e, v, s )  { e, s },
+#define FT_ERROR_START_LIST     {
+#define FT_ERROR_END_LIST       { 0xFF, "Bad Squeak Method Parameter" }, { 0, NULL } };
+static const struct ftError ftErrors[] =
+#include FT_ERRORS_H
+;
+ ftError = ftErrors;
+ ;
+ while (((str = ftError->errMsg))
+ && (FT_ERROR_BASE(errorCode) != ftError->errCode)) {
+ ftError++;
+ }
+ ;
+ if (!(str)) {
+ interpreterProxy->success(0);
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(1, ftAllocateStringForPointer(str));
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveFreeExternalMemory(void)
+{
+ void*memPointer;
+ sqInt rcvr;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FreeTypeExternalMemory"));
+ rcvr = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ ;
+
+ /* free the memory handle */
+
+ errorCode = 0;
+ memPointer = ftHandleValueFromReceiver(rcvr);
+ if (!(memPointer == null)) {
+ free(memPointer);
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ return null;
+}
+
+
+/* Return the Freetype glyph index of the given character code, in the
+ current encoding.
+ Return value of 0 means 'undefined character code'. */
+
+EXPORT(sqInt)
+primitiveGetFaceCharIndex(void)
+{
+ sqInt charIndex;
+ FT_Face face;
+ sqInt rcvr;
+ sqInt result;
+ sqInt _return_value;
+
+ charIndex = interpreterProxy->stackIntegerValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ errorCode = 0;
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ result = FT_Get_Char_Index(face, charIndex);
+ _return_value = interpreterProxy->positive32BitIntegerFor(result);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->popthenPush(2, _return_value);
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveGetFaceCharMap(void)
+{
+ FT_CharMap charmap;
+ FT_Encoding encoding;
+ FT_Face face;
+ sqInt rcvr;
+ sqInt stringOop;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ charmap = face->charmap;
+ if (!(charmap)) {
+ return null;
+ }
+ interpreterProxy->pushRemappableOop(rcvr);
+ encoding = charmap->encoding;
+ stringOop = ftStringFromEncodingValue(encoding);
+ rcvr = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(22, rcvr, stringOop);
+ interpreterProxy->storeIntegerofObjectwithValue(23, rcvr, charmap->platform_id);
+ interpreterProxy->storeIntegerofObjectwithValue(24, rcvr, charmap->encoding_id);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveGetFaceCharMapsIntoArray(void)
+{
+ sqInt *array;
+ sqInt arrayOop;
+ FT_CharMap *charmap;
+ FT_Face face;
+ sqInt i;
+ int numCharmaps;
+ sqInt rcvr;
+ sqInt stringOop;
+
+ interpreterProxy->success(interpreterProxy->isIndexable(interpreterProxy->stackValue(0)));
+ array = ((int *) (interpreterProxy->firstIndexableField(interpreterProxy->stackValue(0))));
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ numCharmaps = face->num_charmaps;
+ arrayOop = ((int) array) - 4;
+ interpreterProxy->success((interpreterProxy->slotSizeOf(arrayOop)) == numCharmaps);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ charmap = face->charmaps;
+ ;
+ for (i = 0; i <= (numCharmaps - 1); i += 1) {
+ interpreterProxy->pushRemappableOop(arrayOop);
+ stringOop = ftStringFromEncodingValue((*charmap)->encoding);
+ arrayOop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(i, arrayOop, stringOop);
+ charmap++;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+
+/* return a String */
+
+EXPORT(sqInt)
+primitiveGetFaceGlyphName(void)
+{
+ char buffer[100];
+ FT_Face face;
+ sqInt glyphIndex;
+ sqInt rcvr;
+ sqInt string;
+
+ glyphIndex = interpreterProxy->stackIntegerValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ errorCode = FT_Get_Glyph_Name(face, glyphIndex, buffer, 100);
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ string = ftAllocateStringForPointer(buffer);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->popthenPush(2, string);
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveGetKerningLeftRight(void)
+{
+ FT_Face face;
+ sqInt kernMode;
+ sqInt leftGlyph;
+ sqInt pointOop;
+ sqInt rcvr;
+ FT_Vector result;
+ sqInt rightGlyph;
+
+ leftGlyph = interpreterProxy->stackIntegerValue(1);
+ rightGlyph = interpreterProxy->stackIntegerValue(0);
+
+ result.x=3;
+ result.y=4;;
+ ;
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(2);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ errorCode = 0;
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ kernMode = FT_KERNING_UNSCALED;
+ ;
+ FT_Get_Kerning(face, leftGlyph, rightGlyph, kernMode, &result);;
+ pointOop = interpreterProxy->makePointwithxValueyValue(result.x, result.y);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->popthenPush(3, pointOop);
+ return null;
+}
+
+
+/* return a String */
+
+EXPORT(sqInt)
+primitiveGetPostscriptName(void)
+{
+ char*buffer;
+ FT_Face face;
+ sqInt rcvr;
+ sqInt string;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ buffer = 0;
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ buffer = FT_Get_Postscript_Name(face);
+ interpreterProxy->success(buffer != 0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ string = ftAllocateStringForPointer(buffer);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->popthenPush(1, string);
+ return null;
+}
+
+
+/* return the bytes from the OS/2 table */
+
+EXPORT(sqInt)
+primitiveGetSfntTableOS2(void)
+{
+ char *buffer;
+ char *extraByteArrayPtr;
+ FT_Face face;
+ sqInt rcvr;
+ sqInt returnedHandle;
+ sqInt _return_value;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ buffer = 0;
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ buffer = FT_Get_Sfnt_Table(face,ft_sfnt_os2);
+ if (buffer == 0) {
+ _return_value = interpreterProxy->integerObjectOf(-1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->popthenPush(1, _return_value);
+ return null;
+ }
+
+ /* Copy from the C bytecode buffer to the Smalltalk ByteArray */
+
+ returnedHandle = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), sizeof(TT_OS2));
+ extraByteArrayPtr = interpreterProxy->arrayValueOf(returnedHandle);
+ ;
+ memcpy(extraByteArrayPtr, buffer, sizeof(TT_OS2));
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->popthenPush(1, returnedHandle);
+ return null;
+}
+
+
+/* disabled becaus of yet implemented */
+
+static sqInt
+primitiveGetTrackKerningPointSizedegree(sqInt pointSize, sqInt degree)
+{
+ return interpreterProxy->primitiveFail();
+}
+
+EXPORT(sqInt)
+primitiveHasKerning(void)
+{
+ FT_Face face;
+ sqInt rcvr;
+ sqInt _return_value;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ errorCode = 0;
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ _return_value = (((FT_HAS_KERNING( face )) << 1) | 1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->popthenPush(1, _return_value);
+ return null;
+}
+
+
+/* Fill in the handle in an FT2Library structure with a copy of our global
+ pointer.
+ */
+
+EXPORT(sqInt)
+primitiveLibraryHandle(void)
+{
+ sqInt rcvr;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Library"));
+ rcvr = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ errorCode = 0;
+ ftAllocateHandleInReceiverForPointer(library);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ return null;
+}
+
+
+/* Load the glyph at the given index in the current charmap.
+ The default map upon opening a font is the 'unic' or Unicode charmap, if
+ any.
+ */
+
+EXPORT(sqInt)
+primitiveLoadCharacter(void)
+{
+ FT_Face face;
+ sqInt flags;
+ sqInt index;
+ sqInt rcvr;
+
+ index = interpreterProxy->stackIntegerValue(1);
+ flags = interpreterProxy->stackIntegerValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(2);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ errorCode = FT_Load_Char(face, index, flags);
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(2);
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveLoadFaceBbox(void)
+{
+ sqInt aRectangle;
+ FT_Face face;
+ sqInt pointOop;
+ sqInt rcvr;
+ sqInt rectOop;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "Rectangle"));
+ aRectangle = interpreterProxy->stackValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ rectOop = aRectangle;
+ if (!(interpreterProxy->isPointers(rectOop))) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ if ((interpreterProxy->slotSizeOf(rectOop)) < 2) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ ;
+ if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) {
+ interpreterProxy->success(0);
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pushRemappableOop(rectOop);
+ pointOop = interpreterProxy->makePointwithxValueyValue(face->bbox.xMin, face->bbox.yMin);
+ rectOop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, rectOop, pointOop);
+ interpreterProxy->pushRemappableOop(rectOop);
+ pointOop = interpreterProxy->makePointwithxValueyValue(face->bbox.xMax, face->bbox.yMax);
+ rectOop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(1, rectOop, pointOop);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+
+/* Fill in many of the receiver's (an FT2Face) fields (other than its handle)
+ from the FT_Face record that it points to. */
+
+EXPORT(sqInt)
+primitiveLoadFaceFields(void)
+{
+ FT_Face face;
+ sqInt rcvr;
+ sqInt strOop;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ ;
+ interpreterProxy->storeIntegerofObjectwithValue(1, rcvr, face->num_faces);
+ interpreterProxy->storeIntegerofObjectwithValue(2, rcvr, face->face_index);
+ interpreterProxy->storeIntegerofObjectwithValue(3, rcvr, face->face_flags);
+ interpreterProxy->storeIntegerofObjectwithValue(4, rcvr, face->style_flags);
+ interpreterProxy->storeIntegerofObjectwithValue(5, rcvr, face->num_glyphs);
+ interpreterProxy->pushRemappableOop(rcvr);
+ strOop = ftAllocateStringForPointer(face->family_name);
+ rcvr = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(6, rcvr, strOop);
+ interpreterProxy->pushRemappableOop(rcvr);
+ strOop = ftAllocateStringForPointer(face->style_name);
+ rcvr = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(7, rcvr, strOop);
+ interpreterProxy->storeIntegerofObjectwithValue(8, rcvr, face->num_fixed_sizes);
+ interpreterProxy->storeIntegerofObjectwithValue(10, rcvr, face->num_charmaps);
+ if (face->face_flags & FT_FACE_FLAG_SCALABLE) {
+ interpreterProxy->storeIntegerofObjectwithValue(13, rcvr, face->units_per_EM);
+ interpreterProxy->storeIntegerofObjectwithValue(14, rcvr, face->ascender);
+ interpreterProxy->storeIntegerofObjectwithValue(15, rcvr, face->descender);
+ interpreterProxy->storeIntegerofObjectwithValue(16, rcvr, face->height);
+ interpreterProxy->storeIntegerofObjectwithValue(17, rcvr, face->max_advance_width);
+ interpreterProxy->storeIntegerofObjectwithValue(18, rcvr, face->max_advance_height);
+ interpreterProxy->storeIntegerofObjectwithValue(19, rcvr, face->underline_position);
+ interpreterProxy->storeIntegerofObjectwithValue(20, rcvr, face->underline_thickness);
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveLoadGlyph(void)
+{
+ FT_Face face;
+ sqInt flags;
+ sqInt index;
+ sqInt rcvr;
+
+ index = interpreterProxy->stackIntegerValue(1);
+ flags = interpreterProxy->stackIntegerValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(2);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ errorCode = FT_Load_Glyph(face, index, flags);
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(2);
+ return null;
+}
+
+
+/* Assumes that primitiveLoadGlyph:flags: has been called earlier to set
+ face->glyph.
+ */
+
+EXPORT(sqInt)
+primitiveLoadGlyphSlotFromFace(void)
+{
+ sqInt aFace;
+ sqInt btw;
+ FT_Face face;
+ sqInt gfOop;
+ FT_Glyph_Format *gfPtr;
+ FT_GlyphSlot gs;
+ sqInt rcvr;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
+ aFace = interpreterProxy->stackValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2GlyphSlot"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ errorCode = 0;
+ if ((interpreterProxy->slotSizeOf(rcvr)) < 8) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(aFace);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ gs = face->glyph;
+ if (!(gs)) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ ;
+ interpreterProxy->storePointerofObjectwithValue(0, rcvr, aFace);
+ interpreterProxy->storeIntegerofObjectwithValue(1, rcvr, gs->linearHoriAdvance);
+ interpreterProxy->storeIntegerofObjectwithValue(2, rcvr, gs->linearVertAdvance);
+ interpreterProxy->storeIntegerofObjectwithValue(3, rcvr, gs->advance.x);
+ interpreterProxy->storeIntegerofObjectwithValue(4, rcvr, gs->advance.y);
+ interpreterProxy->pushRemappableOop(rcvr);
+ gfOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), sizeof(FT_Glyph_Format));
+ ;
+ btw = bytesPerWord();
+ gfPtr = (FT_Glyph_Format *) pointerForOop(gfOop + btw);
+ ;
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ *gfPtr = gs->format;
+ rcvr = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(5, rcvr, gfOop);
+ interpreterProxy->storeIntegerofObjectwithValue(6, rcvr, gs->bitmap_left);
+ interpreterProxy->storeIntegerofObjectwithValue(7, rcvr, gs->bitmap_top);
+ interpreterProxy->storeIntegerofObjectwithValue(8, rcvr, gs->metrics.width);
+ interpreterProxy->storeIntegerofObjectwithValue(9, rcvr, gs->metrics.height);
+ interpreterProxy->storeIntegerofObjectwithValue(10, rcvr, gs->metrics.horiBearingX);
+ interpreterProxy->storeIntegerofObjectwithValue(11, rcvr, gs->metrics.horiBearingY);
+ interpreterProxy->storeIntegerofObjectwithValue(12, rcvr, gs->metrics.horiAdvance);
+ interpreterProxy->storeIntegerofObjectwithValue(13, rcvr, gs->metrics.vertBearingX);
+ interpreterProxy->storeIntegerofObjectwithValue(14, rcvr, gs->metrics.vertBearingY);
+ interpreterProxy->storeIntegerofObjectwithValue(15, rcvr, gs->metrics.vertAdvance);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+
+/* Assumes that primitiveLoadGlyph:flags: has been called earlier to set
+ face->glyph.
+ */
+
+EXPORT(sqInt)
+primitiveLoadOutlineArraysFromFace(void)
+{
+ sqInt aFace;
+ sqInt array;
+ sqInt array1;
+ sqInt array2;
+ short *contours;
+ sqInt contoursSize;
+ FT_Face face;
+ FT_GlyphSlot gs;
+ sqInt i;
+ long *points;
+ sqInt pointsSize;
+ sqInt rcvr;
+ char*tags;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
+ aFace = interpreterProxy->stackValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Outline"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ errorCode = 0;
+ if ((interpreterProxy->slotSizeOf(rcvr)) < FT2OutlineInstSize) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(aFace);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ gs = face->glyph;
+ if (!(gs)) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ ;
+ pointsSize = gs->outline.n_points;
+ /* begin fetchWordArray:ofObject:assureSize: */
+ array = interpreterProxy->fetchPointerofObject(FT2OutlinePointsIndex, rcvr);
+ if ((interpreterProxy->isWords(array))
+ && ((interpreterProxy->slotSizeOf(array)) == (pointsSize * 2))) {
+ points = interpreterProxy->arrayValueOf(array);
+ goto l1;
+ }
+ points = null;
+l1: /* end fetchWordArray:ofObject:assureSize: */;
+ if (points == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ /* begin fetchByteArray:ofObject:assureSize: */
+ array1 = interpreterProxy->fetchPointerofObject(FT2OutlineTagsIndex, rcvr);
+ if ((interpreterProxy->isBytes(array1))
+ && ((interpreterProxy->slotSizeOf(array1)) == pointsSize)) {
+ tags = ((char *) (interpreterProxy->arrayValueOf(array1)));
+ goto l2;
+ }
+ tags = ((char *) null);
+l2: /* end fetchByteArray:ofObject:assureSize: */;
+ if (tags == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ for (i = 0; i <= (pointsSize - 1); i += 1) {
+ points[2 * i] = (gs->outline.points[i].x);
+ points[(2 * i) + 1] = (gs->outline.points[i].y);
+ tags[i] = (gs->outline.tags[i]);
+ }
+ contoursSize = gs->outline.n_contours;
+ /* begin fetchShortArray:ofObject:assureSize: */
+ array2 = interpreterProxy->fetchPointerofObject(FT2OutlineContoursIndex, rcvr);
+ if ((interpreterProxy->isWords(array2))
+ && ((interpreterProxy->slotSizeOf(array2)) == (((sqInt) (contoursSize + 1) >> 1)))) {
+ contours = ((short*) (interpreterProxy->arrayValueOf(array2)));
+ goto l3;
+ }
+ contours = ((short*) null);
+l3: /* end fetchShortArray:ofObject:assureSize: */;
+ for (i = 0; i <= (contoursSize - 1); i += 1) {
+ contours[i] = (gs->outline.contours[i]);
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+
+/* Assumes that primitiveLoadGlyph:flags: has been called earlier to set
+ face->glyph.
+ */
+
+EXPORT(sqInt)
+primitiveLoadOutlineSizesFromFace(void)
+{
+ sqInt aFace;
+ FT_Face face;
+ FT_GlyphSlot gs;
+ sqInt rcvr;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Face"));
+ aFace = interpreterProxy->stackValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Outline"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ errorCode = 0;
+ if ((interpreterProxy->slotSizeOf(rcvr)) < FT2OutlineInstSize) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(aFace);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ gs = face->glyph;
+ if (!(gs)) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ ;
+ interpreterProxy->storeIntegerofObjectwithValue(FT2OutlineContoursSizeIndex, rcvr, gs->outline.n_contours);
+ interpreterProxy->storeIntegerofObjectwithValue(FT2OutlinePointsSizeIndex, rcvr, gs->outline.n_points);
+ interpreterProxy->storeIntegerofObjectwithValue(FT2OutlineFlagsIndex, rcvr, gs->outline.flags);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+
+/* high byte is module error, low is generic error */
+
+EXPORT(sqInt)
+primitiveModuleErrorCode(void)
+{
+ sqInt _return_value;
+
+ _return_value = interpreterProxy->positive32BitIntegerFor((FT_ERROR_MODULE(errorCode)));
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->popthenPush(1, _return_value);
+ return null;
+}
+
+
+/* Fill in the receiver's (a FT2Face object) fields
+ from the address and fields of a newly opened FT_Face object. */
+
+EXPORT(sqInt)
+primitiveNewFaceFromFileAndIndex(void)
+{
+ sqInt anInteger;
+ size_t byteSize;
+ FT_Face face;
+ char *fontFilePath;
+ sqInt rcvr;
+ char translatedFilePath[1024];
+
+ interpreterProxy->success(interpreterProxy->isBytes(interpreterProxy->stackValue(1)));
+ fontFilePath = ((char *) (interpreterProxy->firstIndexableField(interpreterProxy->stackValue(1))));
+ anInteger = interpreterProxy->stackIntegerValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(2);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ ;
+ errorCode = 0;
+ byteSize = interpreterProxy->byteSizeOf(((sqInt)(long)(fontFilePath) - 4));
+ ;
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (byteSize > 1000) {
+ interpreterProxy->success(0);
+ return null;
+ }
+ interpreterProxy->ioFilenamefromStringofLengthresolveAliases(translatedFilePath, fontFilePath, byteSize, 1);
+ errorCode = FT_New_Face(library, translatedFilePath, anInteger, &face);
+ ;
+ ;
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ ftAllocateHandleInReceiverForPointer(face);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(2);
+ return null;
+}
+
+
+/* Fill in the receiver's (a FT2Face object) fields
+ from the address and fields of a newly opened FT_Face object. */
+
+EXPORT(sqInt)
+primitiveNewMemoryFaceFromExternalMemoryAndIndex(void)
+{
+ sqInt aFreeTypeExternalMemory;
+ sqInt anInteger;
+ sqInt byteSize;
+ FT_Face face;
+ void *memPointer;
+ sqInt rcvr;
+
+ aFreeTypeExternalMemory = interpreterProxy->stackValue(2);
+ byteSize = interpreterProxy->stackIntegerValue(1);
+ anInteger = interpreterProxy->stackIntegerValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(3), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(3);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ ;
+ errorCode = 0;
+ memPointer = ftHandleValueFromReceiver(aFreeTypeExternalMemory);
+ ;
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ errorCode = FT_New_Memory_Face(library, memPointer, byteSize, anInteger, &face);
+ ;
+ ;
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ ftAllocateHandleInReceiverForPointer(face);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(3);
+ return null;
+}
+
+
+/* Assumes that primitiveLoadGlyph:flags: has been called earlier to set
+ face->glyph.
+ */
+
+EXPORT(sqInt)
+primitiveNumberOfOutlineCountours(void)
+{
+ sqInt aFace;
+ sqInt contoursSize;
+ FT_Face face;
+ FT_GlyphSlot gs;
+ sqInt rcvr;
+ sqInt _return_value;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2GlyphSlot"));
+ rcvr = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ errorCode = 0;
+ if ((interpreterProxy->slotSizeOf(rcvr)) < FT2GlyphSlotInstSize) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ aFace = interpreterProxy->fetchPointerofObject(FT2GlyphSlotFaceIndex, rcvr);
+ face = ftHandleValueFromReceiver(aFace);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ gs = face->glyph;
+ if (!(gs)) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ ;
+ contoursSize = gs->outline.n_contours;
+ _return_value = ((contoursSize << 1) | 1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->popthenPush(1, _return_value);
+ return null;
+}
+
+
+/* Render this face into the given form */
+
+EXPORT(sqInt)
+primitiveRenderGlyphIntoForm(void)
+{
+ FT_Bitmap bitmap;
+ FT_Face face;
+ sqInt faceOop;
+ sqInt formOop;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "Form"));
+ formOop = interpreterProxy->stackValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
+ faceOop = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(faceOop);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ ftInitBitmapfromForm(&bitmap, formOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ errorCode = FT_Outline_Get_Bitmap(library, &face->glyph->outline, &bitmap);
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+
+/* Render this face into the given form */
+
+EXPORT(sqInt)
+primitiveRenderGlyphIntoFormWithRenderMode(void)
+{
+ FT_Bitmap bitmap;
+ FT_Face face;
+ sqInt faceOop;
+ sqInt formOop;
+ sqInt mode;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "Form"));
+ formOop = interpreterProxy->stackValue(1);
+ mode = interpreterProxy->stackIntegerValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
+ faceOop = interpreterProxy->stackValue(2);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(faceOop);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ ftInitBitmapfromFormrenderMode(&bitmap, formOop, mode);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ errorCode = FT_Outline_Get_Bitmap(library, &face->glyph->outline, &bitmap);
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(2);
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveResetErrorCode(void)
+{
+ sqInt oldError;
+ sqInt _return_value;
+
+ oldError = errorCode;
+ errorCode = 0;
+ _return_value = interpreterProxy->positive32BitIntegerFor(oldError);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->popthenPush(1, _return_value);
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveSetFaceCharMap(void)
+{
+ FT_Encoding encoding;
+ sqInt encodingString;
+ FT_Face face;
+ sqInt rcvr;
+
+ encodingString = interpreterProxy->stackValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ encoding = ftEncodingValueFromString(encodingString);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ ;
+ errorCode = FT_Select_Charmap(face, encoding);
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveSetPixelSizes(void)
+{
+ FT_Face face;
+ sqInt rcvr;
+ sqInt x;
+ sqInt y;
+
+ x = interpreterProxy->stackIntegerValue(1);
+ y = interpreterProxy->stackIntegerValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(2);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ errorCode = FT_Set_Pixel_Sizes(face, x, y);
+ interpreterProxy->success(errorCode == 0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(2);
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveSetTransform(void)
+{
+ FT_Vector delta;
+ sqInt *deltasqIntPtr;
+ sqInt deltaWordArray;
+ FT_Face face;
+ FT_Matrix matrix;
+ sqInt *matrixsqIntPtr;
+ sqInt matrixWordArray;
+ sqInt rcvr;
+
+ matrixWordArray = interpreterProxy->stackValue(1);
+ deltaWordArray = interpreterProxy->stackValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(2);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ matrixsqIntPtr = interpreterProxy->arrayValueOf(matrixWordArray);
+ deltasqIntPtr = interpreterProxy->arrayValueOf(deltaWordArray);
+ delta.x = deltasqIntPtr[0]; delta.y = deltasqIntPtr[1];;
+ matrix.xx = matrixsqIntPtr[0]; matrix.xy = matrixsqIntPtr[1];
+ matrix.yx = matrixsqIntPtr[2]; matrix.yy = matrixsqIntPtr[3]; ;
+ if (!(interpreterProxy->failed())) {
+ FT_Set_Transform( face, &matrix, &delta);
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(2);
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveTransformFaceGlyphSlotOutline(void)
+{
+ FT_Face face;
+ FT_Matrix matrix;
+ sqInt *matrixsqIntPtr;
+ sqInt matrixWordArray;
+ sqInt rcvr;
+
+ matrixWordArray = interpreterProxy->stackValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ matrixsqIntPtr = interpreterProxy->arrayValueOf(matrixWordArray);
+ matrix.xx = matrixsqIntPtr[0]; matrix.xy = matrixsqIntPtr[1];
+ matrix.yx = matrixsqIntPtr[2]; matrix.yy = matrixsqIntPtr[3]; ;
+ if (!(interpreterProxy->failed())) {
+ FT_Outline_Transform( &face->glyph->outline, &matrix );
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveTranslateFaceGlyphSlotOutline(void)
+{
+ FT_Vector delta;
+ sqInt *deltasqIntPtr;
+ sqInt deltaWordArray;
+ FT_Face face;
+ sqInt rcvr;
+
+ deltaWordArray = interpreterProxy->stackValue(0);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "FT2Face"));
+ rcvr = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ face = ftHandleValueFromReceiver(rcvr);
+ if (face == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ deltasqIntPtr = interpreterProxy->arrayValueOf(deltaWordArray);
+ delta.x = deltasqIntPtr[0]; delta.y = deltasqIntPtr[1];;
+ if (!(interpreterProxy->failed())) {
+ FT_Outline_Translate( &face->glyph->outline, delta.x, delta.y );
+ }
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt)
+primitiveVersion(void)
+{
+ int amajor;
+ int aminor;
+ int apatch;
+ sqInt rcvr;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "FT2Version"));
+ rcvr = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ errorCode = 0;
+ FT_Library_Version(library, &amajor, &aminor, &apatch);
+ ;
+ interpreterProxy->storeIntegerofObjectwithValue(0, rcvr, amajor);
+ ;
+ interpreterProxy->storeIntegerofObjectwithValue(1, rcvr, aminor);
+ ;
+ interpreterProxy->storeIntegerofObjectwithValue(2, rcvr, apatch);
+ if (interpreterProxy->failed()) {
+ ftParameterError();
+ return null;
+ }
+ return null;
+}
+
+
+/* Note: This is coded so that is can be run from Squeak. */
+
+EXPORT(sqInt)
+setInterpreter(struct VirtualMachine*anInterpreter)
+{
+ sqInt ok;
+
+ interpreterProxy = anInterpreter;
+ ok = interpreterProxy->majorVersion() == VM_PROXY_MAJOR;
+ if (ok == 0) {
+ return 0;
+ }
+ ok = interpreterProxy->minorVersion() >= VM_PROXY_MINOR;
+ return ok;
+}
+
+EXPORT(sqInt)
+shutdownModule(void)
+{
+ errorCode = FT_Done_FreeType(library);
+ if (errorCode == 0) {
+ library = null;
+ }
+ return errorCode == 0;
+}
+
+static void
+sqAssert(sqInt aBool)
+{
+ /* missing DebugCode */;
+}
+
+
+#ifdef SQUEAK_BUILTIN_PLUGIN
+
+void* FT2Plugin_exports[][3] = {
+ {"FT2Plugin", "getModuleName", (void*)getModuleName},
+ {"FT2Plugin", "initialiseModule", (void*)initialiseModule},
+ {"FT2Plugin", "primitiveCopyToExternalMemory", (void*)primitiveCopyToExternalMemory},
+ {"FT2Plugin", "primitiveDoneFace", (void*)primitiveDoneFace},
+ {"FT2Plugin", "primitiveDoneFacePreserveFields", (void*)primitiveDoneFacePreserveFields},
+ {"FT2Plugin", "primitiveEmboldenFaceGlyphSlotOutline", (void*)primitiveEmboldenFaceGlyphSlotOutline},
+ {"FT2Plugin", "primitiveErrorCode", (void*)primitiveErrorCode},
+ {"FT2Plugin", "primitiveErrorString", (void*)primitiveErrorString},
+ {"FT2Plugin", "primitiveFreeExternalMemory", (void*)primitiveFreeExternalMemory},
+ {"FT2Plugin", "primitiveGetFaceCharIndex", (void*)primitiveGetFaceCharIndex},
+ {"FT2Plugin", "primitiveGetFaceCharMap", (void*)primitiveGetFaceCharMap},
+ {"FT2Plugin", "primitiveGetFaceCharMapsIntoArray", (void*)primitiveGetFaceCharMapsIntoArray},
+ {"FT2Plugin", "primitiveGetFaceGlyphName", (void*)primitiveGetFaceGlyphName},
+ {"FT2Plugin", "primitiveGetKerningLeftRight", (void*)primitiveGetKerningLeftRight},
+ {"FT2Plugin", "primitiveGetPostscriptName", (void*)primitiveGetPostscriptName},
+ {"FT2Plugin", "primitiveGetSfntTableOS2", (void*)primitiveGetSfntTableOS2},
+ {"FT2Plugin", "primitiveHasKerning", (void*)primitiveHasKerning},
+ {"FT2Plugin", "primitiveLibraryHandle", (void*)primitiveLibraryHandle},
+ {"FT2Plugin", "primitiveLoadCharacter", (void*)primitiveLoadCharacter},
+ {"FT2Plugin", "primitiveLoadFaceBbox", (void*)primitiveLoadFaceBbox},
+ {"FT2Plugin", "primitiveLoadFaceFields", (void*)primitiveLoadFaceFields},
+ {"FT2Plugin", "primitiveLoadGlyph", (void*)primitiveLoadGlyph},
+ {"FT2Plugin", "primitiveLoadGlyphSlotFromFace", (void*)primitiveLoadGlyphSlotFromFace},
+ {"FT2Plugin", "primitiveLoadOutlineArraysFromFace", (void*)primitiveLoadOutlineArraysFromFace},
+ {"FT2Plugin", "primitiveLoadOutlineSizesFromFace", (void*)primitiveLoadOutlineSizesFromFace},
+ {"FT2Plugin", "primitiveModuleErrorCode", (void*)primitiveModuleErrorCode},
+ {"FT2Plugin", "primitiveNewFaceFromFileAndIndex", (void*)primitiveNewFaceFromFileAndIndex},
+ {"FT2Plugin", "primitiveNewMemoryFaceFromExternalMemoryAndIndex", (void*)primitiveNewMemoryFaceFromExternalMemoryAndIndex},
+ {"FT2Plugin", "primitiveNumberOfOutlineCountours", (void*)primitiveNumberOfOutlineCountours},
+ {"FT2Plugin", "primitiveRenderGlyphIntoForm", (void*)primitiveRenderGlyphIntoForm},
+ {"FT2Plugin", "primitiveRenderGlyphIntoFormWithRenderMode", (void*)primitiveRenderGlyphIntoFormWithRenderMode},
+ {"FT2Plugin", "primitiveResetErrorCode", (void*)primitiveResetErrorCode},
+ {"FT2Plugin", "primitiveSetFaceCharMap", (void*)primitiveSetFaceCharMap},
+ {"FT2Plugin", "primitiveSetPixelSizes", (void*)primitiveSetPixelSizes},
+ {"FT2Plugin", "primitiveSetTransform", (void*)primitiveSetTransform},
+ {"FT2Plugin", "primitiveTransformFaceGlyphSlotOutline", (void*)primitiveTransformFaceGlyphSlotOutline},
+ {"FT2Plugin", "primitiveTranslateFaceGlyphSlotOutline", (void*)primitiveTranslateFaceGlyphSlotOutline},
+ {"FT2Plugin", "primitiveVersion", (void*)primitiveVersion},
+ {"FT2Plugin", "setInterpreter", (void*)setInterpreter},
+ {"FT2Plugin", "shutdownModule", (void*)shutdownModule},
+ {NULL, NULL, NULL}
+};
+
+#endif /* ifdef SQ_BUILTIN_PLUGIN */

Modified: branches/Cog/src/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c
===================================================================
--- branches/Cog/src/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c 2011-06-07 18:48:37 UTC (rev 2393)
+++ branches/Cog/src/plugins/UnixOSProcessPlugin/UnixOSProcessPlugin.c 2011-06-08 00:36:21 UTC (rev 2394)
@@ -1,15 +1,30 @@
-/* Automatically generated from Squeak on #(16 January 2010 4:48:23 pm) */
+/* Automatically generated by
+ VMPluginCodeGenerator VMMaker.oscog-eem.75 uuid: e1bb08e3-482d-4bfd-a416-d203d9fe4c57
+   from
+ UnixOSProcessPlugin * VMConstruction-Plugins-OSProcessPlugin-eem.28 uuid: 9dd4e012-1f25-4946-9b7b-feb93153e08a
+ */
+static char __buildInfo[] = "UnixOSProcessPlugin * VMConstruction-Plugins-OSProcessPlugin-eem.28 uuid: 9dd4e012-1f25-4946-9b7b-feb93153e08a " __DATE__ ;
 
-static char __buildInfo[] = "Generated on #(16 January 2010 4:48:23 pm). Compiled on "__DATE__ ;
 
 
-
-
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <sys/types.h>
+/* D T Lewis - UnixOSProcessPlugin.c translated from class
+   UnixOSProcessPlugin of OSProcessPlugin version 4.3.2 */
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <errno.h>
 
 /* Default EXPORT macro that does nothing (see comment in sq.h): */
 #define EXPORT(returnType) returnType
@@ -30,33 +45,16 @@
 // was #undef EXPORT(returnType) but screws NorCroft cc
 #define EXPORT(returnType) static returnType
 #endif
-#include <sys/types.h>
-/* D T Lewis - UnixOSProcessPlugin.c translated from class
-   UnixOSProcessPlugin of OSProcessPlugin version 4.3.2 */
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <pthread.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include "config.h"
-#define FILEHANDLETYPE FILE *  /* the type of low level stream to be used in a struct SQFile */
-#ifndef SQAIO_H
-# define SQAIO_H "aio.h"          /* aio.h has been renamed to sqaio.h */
-#endif
-#include SQAIO_H
+
 #include "FilePlugin.h"
 #include "SocketPlugin.h"
 #define SESSIONIDENTIFIERTYPE int
-
+#include "config.h"
+#define FILEHANDLETYPE FILE *  /* the type of low level stream to be used in a struct SQFile */
+#include "sqaio.h"
 #include "sqMemoryAccess.h"
 
 
-
 /*** Constants ***/
 #define PrimErrNoMemory 9
 #define PrimErrUnsupported 7
@@ -253,9 +251,9 @@
 struct VirtualMachine* interpreterProxy;
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
- "UnixOSProcessPlugin 16 January 2010 (i)"
+ "UnixOSProcessPlugin * VMConstruction-Plugins-OSProcessPlugin-eem.28 (i)"
 #else
- "UnixOSProcessPlugin 16 January 2010 (e)"
+ "UnixOSProcessPlugin * VMConstruction-Plugins-OSProcessPlugin-eem.28 (e)"
 #endif
 ;
 static void *originalSigHandlers[NSIG];
@@ -281,7 +279,8 @@
  */
 
 static void
-aioForwardwithDataandFlags(int fd, void *data, int flags) {
+aioForwardwithDataandFlags(int fd, void *data, int flags)
+{
     sqInt *pfd;
     sqInt semaIndex;
 
@@ -291,13 +290,14 @@
 }
 
 
-/* Using malloc() and calloc() is something I would like to avoid, since it is
- likely to cause problems some time in the future if somebody redesigns
+/* Using malloc() and calloc() is something I would like to avoid, since it
+ is likely to cause problems some time in the future if somebody redesigns
  object memory allocation. This wrapper just makes it easy to find senders
  of calloc() in my code. -dtl */
 
 static void *
-callocWrappersize(sqInt count, sqInt objectSize) {
+callocWrappersize(sqInt count, sqInt objectSize)
+{
  return calloc(count, objectSize);
 }
 
@@ -305,7 +305,8 @@
 /* self cCode: 'memcpy(charArray2, charArray1, len' */
 
 static sqInt
-copyBytesFromtolength(void *charArray1, void *charArray2, sqInt len) {
+copyBytesFromtolength(void *charArray1, void *charArray2, sqInt len)
+{
  memcpy(charArray2, charArray1, len);
 }
 
@@ -317,7 +318,8 @@
  */
 
 static sqInt
-createPipeForReaderwriter(FILEHANDLETYPE *readerIOStreamPtr, FILEHANDLETYPE *writerIOStreamPtr) {
+createPipeForReaderwriter(FILEHANDLETYPE *readerIOStreamPtr, FILEHANDLETYPE *writerIOStreamPtr)
+{
     int filedes[2];
 
  if ((pipe(filedes)) == -1) {
@@ -337,7 +339,8 @@
  Caution: This may invoke the garbage collector. */
 
 static char *
-cStringFromString(sqInt aString) {
+cStringFromString(sqInt aString)
+{
     char *cString;
     sqInt len;
     char *sPtr;
@@ -353,34 +356,37 @@
 }
 
 
-/* Answer the size of the file descriptor table for a process. I am not sure of
- the most portable
+/* Answer the size of the file descriptor table for a process. I am not sure
+ of the most portable
  way to do this. If this implementation does not work on your Unix
  platform, try changing
  it to answer the value of FOPEN:=MAX, which will hopefully be defined in
  stdio.h. If
- all else fails, just hard code it to answer 20, which would be safe for any
- Unix.
+ all else fails, just hard code it to answer 20, which would be safe for
+ any Unix.
  */
 
 static sqInt
-descriptorTableSize(void) {
+descriptorTableSize(void)
+{
  return getdtablesize();
 }
 
 
-/* Dup a file descriptor to allow it to be attached as the standard error when
- we exec() a new executable. This is Unix specific, in that it assumes that
+/* Dup a file descriptor to allow it to be attached as the standard error
+ when we
+ exec() a new executable. This is Unix specific, in that it assumes that
  file descriptor
- 0 is stdin, 1 is stdout, and 2 is stderr. The dup2() call is used to copy the
- open file
+ 0 is stdin, 1 is stdout, and 2 is stderr. The dup2() call is used to copy
+ the open file
  descriptors into file descriptors 0, 1 and 2 so that the image which we
  execute will
  use them as stdin, stdout, and stderr.
  */
 
 static void
-dupToStdErr(sqInt anSQFileDataStructure) {
+dupToStdErr(sqInt anSQFileDataStructure)
+{
     sqInt filenoToDup;
 
  /* begin fileDescriptorFrom: */
@@ -402,18 +408,20 @@
 }
 
 
-/* Dup a file descriptor to allow it to be attached as the standard input when
- we exec() a new executable. This is Unix specific, in that it assumes that
+/* Dup a file descriptor to allow it to be attached as the standard input
+ when we
+ exec() a new executable. This is Unix specific, in that it assumes that
  file descriptor
- 0 is stdin, 1 is stdout, and 2 is stderr. The dup2() call is used to copy the
- open file
+ 0 is stdin, 1 is stdout, and 2 is stderr. The dup2() call is used to copy
+ the open file
  descriptors into file descriptors 0, 1 and 2 so that the image which we
  execute will
  use them as stdin, stdout, and stderr.
  */
 
 static void
-dupToStdIn(sqInt anSQFileDataStructure) {
+dupToStdIn(sqInt anSQFileDataStructure)
+{
     sqInt filenoToDup;
 
  /* begin fileDescriptorFrom: */
@@ -438,16 +446,18 @@
 
 /* Dup a file descriptor to allow it to be attached as the standard output
  when we
- exec() a new executable. This is Unix specific, in that it assumes that file
- descriptor 0 is stdin, 1 is stdout, and 2 is stderr. The dup2() call is used to
- copy the open file
+ exec() a new executable. This is Unix specific, in that it assumes that
+ file descriptor
+ 0 is stdin, 1 is stdout, and 2 is stderr. The dup2() call is used to copy
+ the open file
  descriptors into file descriptors 0, 1 and 2 so that the image which we
  execute will
  use them as stdin, stdout, and stderr.
  */
 
 static void
-dupToStdOut(sqInt anSQFileDataStructure) {
+dupToStdOut(sqInt anSQFileDataStructure)
+{
     sqInt filenoToDup;
 
  /* begin fileDescriptorFrom: */
@@ -477,7 +487,8 @@
 /* return type should be int, but skip the declaration to permit inlining */
 
 static sqInt
-fileDescriptorFrom(sqInt aSQFileByteArray) {
+fileDescriptorFrom(sqInt aSQFileByteArray)
+{
  if (!((((interpreterProxy->isBytes(aSQFileByteArray))
  && ((interpreterProxy->byteSizeOf(aSQFileByteArray)) == (fileRecordSize())))
  && ((interpreterProxy->getThisSessionID()) == (sessionIdentifierFromSqFile(interpreterProxy->arrayValueOf(aSQFileByteArray)))))
@@ -492,7 +503,8 @@
  will be a (FILE *). On Win32, it is a HANDLE. */
 
 static FILEHANDLETYPE
-fileHandleFrom(sqInt sqFileStructByteArray) {
+fileHandleFrom(sqInt sqFileStructByteArray)
+{
     SQFile *sqFile;
 
  sqFile = interpreterProxy->arrayValueOf(sqFileStructByteArray);
@@ -503,29 +515,33 @@
 /* Answer the size of a SQFile data structure in bytes. */
 
 static sqInt
-fileRecordSize(void) {
+fileRecordSize(void)
+{
  return sizeof(SQFile);
 }
 
 
-/* Return a pointer to the first byte of of the SQFile data structure file record
- within anSQFileRecord, which is expected to be a ByteArray of size
+/* Return a pointer to the first byte of of the SQFile data structure file
+ record within
+ anSQFileRecord, which is expected to be a ByteArray of size
  self>>fileRecordSize.
  */
 
 static SQFile *
-fileValueOf(sqInt anSQFileRecord) {
+fileValueOf(sqInt anSQFileRecord)
+{
  return interpreterProxy->arrayValueOf(anSQFileRecord);
 }
 
 
 /* Use the address offsets in offsetArray to fix up the pointers in
- cStringArray. The result is a C array of pointers to char, used for argv and
- env vectors.
+ cStringArray. The result is a C array of pointers to char, used for argv
+ and env vectors.
  */
 
 static sqInt
-fixPointersInArrayOfStringswithOffsetscount(char *flattenedArrayOfStrings, sqInt *offsetArray, sqInt count) {
+fixPointersInArrayOfStringswithOffsetscount(char *flattenedArrayOfStrings, sqInt *offsetArray, sqInt count)
+{
     sqInt idx;
     char **ptr;
 
@@ -541,13 +557,14 @@
 /* Fork a child OS process, and do an exec in the child. The parent continues
  on in
  Smalltalk, and this method answers the pid of the child which was created.
- If useSignalHandler is true, set the signal handler for SIGCHLD. Otherwise,
- assume that death of child events are handled through some other
- mechanism.
- In this implementation, memory for the argument and environment arrays
- is allocated
- in the image prior to calling this primitive. This allows us to avoid invoking
- the garbage collector in this primitive (thereby moving the locations of
+ If useSignalHandler is true, set the signal handler for SIGCHLD.
+ Otherwise, assume
+ that death of child events are handled through some other mechanism.
+
+ In this implementation, memory for the argument and environment arrays is
+ allocated in the image prior to calling this primitive. This allows us to
+ avoid invoking the
+ garbage collector in this primitive (thereby moving the locations of
  environment and argument memory), but comes at the cost of twiddling C
  pointers here in the
  primitive. An alternative to this whole mess is just to malloc the
@@ -555,31 +572,32 @@
  argument vectors, but I think it is a good idea to avoid malloc as much as
  possible so as not to limit future ObjectMemory implementations.
 
- This primitive replaces #primitiveForkAndExec from earlier versions of
- the plugin.
- The new name permits backward compatibility for an image running on a
- VM which does not yet have the updated plugin. This implementation uses
- a different
- argument format on the stack, and differs functionally in that the child
- now closes
+ This primitive replaces #primitiveForkAndExec from earlier versions of the
+ plugin. The new name permits backward compatibility for an image running
+ on a VM
+ which does not yet have the updated plugin. This implementation uses a
+ different argument format on the stack, and differs functionally in that
+ the child now closes
  all file descriptors (including sockets) not required (that is, everything
  except stdin,
  stdout, and stderr on descriptors 0, 1 and 2). This eliminates some flakey
  behavior in child processes connected to Squeak by pipes, which failed to
  exit at expected times
- due to the old file descriptors remaining open. This is also cleaner in that
- garbage descriptors are not left hanging around the the child.
+ due to the old file descriptors remaining open. This is also cleaner in
+ that garbage
+ descriptors are not left hanging around the the child.
 
  On entry, the stack contains:
- 0: workingDir, a null terminated string specifying the working directory to
- use, or nil.
+ 0: workingDir, a null terminated string specifying the working directory
+ to use, or nil.
  1: envOffsets, an array of integers for calculating environment string
  address offsets.
  2: envVecBuffer, a String buffer containing environment strings arranged
  to look like char **.
- 3: argOffsets, an array of integers for calculating argument string address
- offsets. 4: argVecBuffer, a String buffer containing argument strings
- arranged to look like char **.
+ 3: argOffsets, an array of integers for calculating argument string
+ address offsets.
+ 4: argVecBuffer, a String buffer containing argument strings arranged to
+ look like char **.
  5: stdErr, a ByteArray handle.
  6: stdOut, a ByteArray handle.
  7: stdIn, a ByteArray handle.
@@ -588,7 +606,8 @@
  */
 
 static sqInt
-forkAndExecInDirectory(sqInt useSignalHandler) {
+forkAndExecInDirectory(sqInt useSignalHandler)
+{
     sqInt argCount;
     sqInt *argOffsetPtr;
     sqInt argOffsets;
@@ -750,27 +769,25 @@
 /* Fork a child process, and continue running squeak in the child process.
  Answer the result of the fork() call, either the child pid or zero.
 
- After calling fork(), two OS processes exist, one of which is the child of the
- other. On
- systems which implement copy-on-write memory management, and which
- support the
- fork() system call, both processes will be running Smalltalk images, and
- will be sharing
+ After calling fork(), two OS processes exist, one of which is the child of
+ the other. On
+ systems which implement copy-on-write memory management, and which support
+ the fork() system call, both processes will be running Smalltalk images,
+ and will be sharing
  the same memory space. In the original OS process, the resulting value of
  pid is the
- process id of the child process (a non-zero integer). In the child process,
- the value of
+ process id of the child process (a non-zero integer). In the child
+ process, the value of
  pid is zero.
 
- The child recreates sufficient external resources to continue running. This
- is done by
+ The child recreates sufficient external resources to continue running.
+ This is done by
  attaching to a new X session. The child is otherwise a copy of the parent
  process, and
  will continue executing the Smalltalk image at the same point as its
  parent. The return
- value of this primitive may be used by the two running Smalltalk images
- to determine
- which is the parent and which is the child.
+ value of this primitive may be used by the two running Smalltalk images to
+ determine which is the parent and which is the child.
 
  The child should not depend on using existing connections to external
  resources. For
@@ -782,10 +799,10 @@
  system; rather it is
  a clone of the parent image as it existed at the time of
  primitiveForkSqueak. For this
- reason, the parent and child should agree in advance as to whom is
- allowed to save the
- image to the file system, otherwise one Smalltalk may overwrite the
- image of the other.
+ reason, the parent and child should agree in advance as to whom is allowed
+ to save the
+ image to the file system, otherwise one Smalltalk may overwrite the image
+ of the other.
 
  This is a simple call to fork(), rather than the more common idiom of
  vfork() followed
@@ -797,7 +814,8 @@
  */
 
 EXPORT(pid_t)
-forkSqueak(sqInt useSignalHandler) {
+forkSqueak(sqInt useSignalHandler)
+{
     struct itimerval intervalTimer;
     pid_t pid;
     struct itimerval saveIntervalTimer;
@@ -820,21 +838,21 @@
 
 
 /* Set a signal handler in the VM which will signal a Smalltalk semaphore at
- semaphoreIndex whenever an external signal sigNum is received. Answer
- the prior value of the signal handler. If semaphoreIndex is zero, the
- handler is
- unregistered, and the VM returns to its default behavior for handling that
- signal. A handler must be unregistered before it can be registered again.
-
- The Smalltalk semaphore is expected to be kept at the same index
- location indefinitely during the lifetime of a Squeak session. If that is not
- the case, the
+ semaphoreIndex whenever an external signal sigNum is received. Answer the
+ prior value of the signal handler. If semaphoreIndex is zero, the handler
+ is unregistered, and the VM returns to its default behavior for handling
+ that signal. A handler must be unregistered before it can be registered
+ again.
+ The Smalltalk semaphore is expected to be kept at the same index location
+ indefinitely during the lifetime of a Squeak session. If that is not the
+ case, the
  handler must be unregistered prior to unregistering the Smalltalk
  semaphore.
  */
 
 static void *
-forwardSignaltoSemaphoreAt(sqInt sigNum, sqInt semaphoreIndex) {
+forwardSignaltoSemaphoreAt(sqInt sigNum, sqInt semaphoreIndex)
+{
     void *oldHandler;
     void *signalHandlerAddress;
 
@@ -870,7 +888,8 @@
 /* Note: This is coded so that plugins can be run from Squeak. */
 
 static VirtualMachine *
-getInterpreter(void) {
+getInterpreter(void)
+{
  return interpreterProxy;
 }
 
@@ -881,16 +900,18 @@
  we're thinking it contains. This is important! */
 
 EXPORT(const char*)
-getModuleName(void) {
+getModuleName(void)
+{
  return moduleName;
 }
 
 
-/* Answer the standard i/o file handle with the given index of my OS
- process. 0 = stdin, 1 = stdout, 2 = stderr. */
+/* Answer the standard i/o file handle with the given index of my OS process.
+ 0 = stdin, 1 = stdout, 2 = stderr. */
 
 static sqInt
-getStdHandle(sqInt n) {
+getStdHandle(sqInt n)
+{
     sqInt fileOop;
     SQFile fileRecords[3];
     sqInt validMask;
@@ -908,18 +929,21 @@
 }
 
 static sqInt
-getThisSessionIdentifier(void) {
+getThisSessionIdentifier(void)
+{
  return interpreterProxy->getThisSessionID();
 }
 
 static sqInt
-halt(void) {
+halt(void)
+{
  ;
  return 0;
 }
 
 static void *
-handleSignalFunctionAddress(void) {
+handleSignalFunctionAddress(void)
+{
  return handleSignal;
 }
 
@@ -932,7 +956,8 @@
  */
 
 static void
-handleSignal(int sigNum) {
+handleSignal(int sigNum)
+{
     sqInt semaIndex;
 
  semaIndex = (semaphoreIndices())[sigNum];
@@ -950,7 +975,8 @@
 }
 
 EXPORT(sqInt)
-initialiseModule(void) {
+initialiseModule(void)
+{
  osprocessSandboxSecurity = -1;
  initializeModuleForPlatform();
  return 1;
@@ -960,7 +986,8 @@
 /* Platform specific initialization */
 
 static sqInt
-initializeModuleForPlatform(void) {
+initializeModuleForPlatform(void)
+{
  pidCount = 0;
  atexit(sendSignalToPids);
  vmThread = pthread_self();
@@ -970,7 +997,8 @@
 /* Check for the common failure mode of a SQFile record with all zeros. */
 
 static sqInt
-isNonNullSQFile(sqInt objectPointer) {
+isNonNullSQFile(sqInt objectPointer)
+{
     sqInt idx;
     unsigned char *sqFileBytes;
 
@@ -989,7 +1017,8 @@
 /* Check for the common failure mode of a SQSocket record with all zeros. */
 
 static sqInt
-isNullSQSocket(sqInt objectPointer) {
+isNullSQSocket(sqInt objectPointer)
+{
     sqInt idx;
     unsigned char *sqSocketBytes;
 
@@ -1010,7 +1039,8 @@
  to a primitive, and is expected to represent a valid file reference. */
 
 static sqInt
-isSQFileObject(sqInt objectPointer) {
+isSQFileObject(sqInt objectPointer)
+{
  return (((interpreterProxy->isBytes(objectPointer))
  && ((interpreterProxy->byteSizeOf(objectPointer)) == (fileRecordSize())))
  && ((interpreterProxy->getThisSessionID()) == (sessionIdentifierFromSqFile(interpreterProxy->arrayValueOf(objectPointer)))))
@@ -1026,7 +1056,8 @@
  */
 
 static sqInt
-isSQSocketObject(sqInt objectPointer) {
+isSQSocketObject(sqInt objectPointer)
+{
  return ((interpreterProxy->isBytes(objectPointer))
  && ((interpreterProxy->byteSizeOf(objectPointer)) == (socketRecordSize())))
  && (!(isNullSQSocket(objectPointer)));
@@ -1038,7 +1069,8 @@
  */
 
 static sqInt
-isValidFileSession(sqInt objectPointer) {
+isValidFileSession(sqInt objectPointer)
+{
  return (interpreterProxy->getThisSessionID()) == (sessionIdentifierFromSqFile(interpreterProxy->arrayValueOf(objectPointer)));
 }
 
@@ -1047,7 +1079,8 @@
  which the interpreter executes. */
 
 static sqInt
-isVmThread(void) {
+isVmThread(void)
+{
     pthread_t thisThread;
 
  thisThread = pthread_self();
@@ -1062,7 +1095,8 @@
  */
 
 static sqInt
-makePipeForReaderwriter(FILEHANDLETYPE *readerIOStreamPtr, FILEHANDLETYPE *writerIOStreamPtr) {
+makePipeForReaderwriter(FILEHANDLETYPE *readerIOStreamPtr, FILEHANDLETYPE *writerIOStreamPtr)
+{
     sqInt anInteger;
     int filedes[2];
     void *signalHandlerAddress;
@@ -1092,7 +1126,8 @@
  thread. */
 
 static sqInt
-maskForThisThreadAndResend(int sigNum) {
+maskForThisThreadAndResend(int sigNum)
+{
  maskSignalForThisThread(sigNum);
  resendSignal(sigNum);
 }
@@ -1103,7 +1138,8 @@
  */
 
 static sqInt
-maskSignalForThisThread(int sigNum) {
+maskSignalForThisThread(int sigNum)
+{
     sigset_t sigset;
 
  sigemptyset(&sigset);
@@ -1116,11 +1152,13 @@
  Make sure we have no dangling references. */
 
 EXPORT(sqInt)
-moduleUnloaded(char *aModuleName) {
+moduleUnloaded(char *aModuleName)
+{
 }
 
 static sqInt
-msg(char *s) {
+msg(char *s)
+{
  fprintf(stderr, "\n%s: %s", moduleName, s);
  return 0;
 }
@@ -1131,7 +1169,8 @@
  passed to the image. */
 
 static sqInt
-newPthreadTypeByteArray(sqInt aPthreadType) {
+newPthreadTypeByteArray(sqInt aPthreadType)
+{
     sqInt byteArray;
     sqInt len;
     pthread_t *ptr;
@@ -1147,7 +1186,8 @@
 /* Answer a new ByteArray sized to contain a SQFile data structure. */
 
 static sqInt
-newSQFileByteArray(void) {
+newSQFileByteArray(void)
+{
  return interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
 }
 
@@ -1155,7 +1195,8 @@
 /* Answer a new ByteArray sized to contain a SQSocket data structure. */
 
 static sqInt
-newSQSocketByteArray(void) {
+newSQSocketByteArray(void)
+{
  return interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), socketRecordSize());
 }
 
@@ -1167,7 +1208,8 @@
  */
 
 static void **
-originalSignalHandlers(void) {
+originalSignalHandlers(void)
+{
  return originalSigHandlers;
 }
 
@@ -1175,7 +1217,8 @@
 /* Answer the pointer represented by aByteArray. */
 
 static void *
-pointerFrom(sqInt aByteArray) {
+pointerFrom(sqInt aByteArray)
+{
     sqInt idx;
     union {void *address; unsigned char bytes[sizeof(void *)];} pointerUnion;
     unsigned char *ptr;
@@ -1201,7 +1244,8 @@
  parameter is a sqFile ByteArray representing the ioHandle for a file. */
 
 EXPORT(sqInt)
-primitiveAioDisable(void) {
+primitiveAioDisable(void)
+{
     int fd;
     sqInt sqFile;
 
@@ -1228,17 +1272,20 @@
 /* Deprecated. This primitive has been replaced by a similar implementation
  in AioPlugin.
  */
-/* Enable asynchronous notification for a descriptor. The first parameter is a
- sqFile ByteArray representing the ioHandle for a file, the second
- parameter is the index
- of a Semaphore to be notified, and the third parameter is a flag indicating
- that sqFile represents an external object and should not be closed on
+/* Enable asynchronous notification for a descriptor. The first parameter is
+ a sqFile
+ ByteArray representing the ioHandle for a file, the second parameter is
+ the index
+ of a Semaphore to be notified, and the third parameter is a flag
+ indicating that
+ sqFile represents an external object and should not be closed on
  termination of
  aio handling. Answer the semaphore index.
  */
 
 EXPORT(sqInt)
-primitiveAioEnable(void) {
+primitiveAioEnable(void)
+{
     static int eventSemaphoreIndices[FD_SETSIZE];
     sqInt externalObject;
     int fd;
@@ -1294,7 +1341,8 @@
  AIO_W (1<<2) handle for write */
 
 EXPORT(sqInt)
-primitiveAioHandle(void) {
+primitiveAioHandle(void)
+{
     sqInt exceptionWatch;
     int fd;
     int flags;
@@ -1343,11 +1391,11 @@
  in AioPlugin.
  */
 /* Temporarily suspend asynchronous event notification for a descriptor. The
- first parameter is a sqFile ByteArray representing the ioHandle for a file,
- and the
+ first parameter is a sqFile ByteArray representing the ioHandle for a
+ file, and the
  remaining three parameters are Boolean flags representing the types of
- events for which notification is being requested: handle exceptions, handle
- for read,
+ events for which notification is being requested: handle exceptions,
+ handle for read,
  and handle for write.
  Flags are defined in the aio.h source as:
  AIO_X (1<<0) handle for exceptions
@@ -1355,7 +1403,8 @@
  AIO_W (1<<2) handle for write */
 
 EXPORT(sqInt)
-primitiveAioSuspend(void) {
+primitiveAioSuspend(void)
+{
     sqInt exceptionWatch;
     int fd;
     int flags;
@@ -1406,7 +1455,8 @@
  */
 
 EXPORT(sqInt)
-primitiveArgumentAt(void) {
+primitiveArgumentAt(void)
+{
     extern int argCnt;
     extern char **argVec;
     sqInt index;
@@ -1435,16 +1485,17 @@
 
 /* Send a null signal to the OS process identified by anIntegerPid. Answer
  false for
- a bad parameter on the stack (the common case is for anIntegerPid equal
- to nil,
- for which case we should answer false). Answer true if the process exists
- and can
- receive signals from this process, otherwise false. This test is useful for
- determining if a child process still exists following a Squeak image restart.
+ a bad parameter on the stack (the common case is for anIntegerPid equal to
+ nil, for which case we should answer false). Answer true if the process
+ exists and can
+ receive signals from this process, otherwise false. This test is useful
+ for determining
+ if a child process still exists following a Squeak image restart.
  */
 
 EXPORT(sqInt)
-primitiveCanReceiveSignals(sqInt anIntegerPid) {
+primitiveCanReceiveSignals(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
 
@@ -1472,7 +1523,8 @@
  */
 
 EXPORT(sqInt)
-primitiveChdir(void) {
+primitiveChdir(void)
+{
     extern int errno;
     char *path;
 
@@ -1493,13 +1545,14 @@
  The readerIOStream and writerIOStream variables represent the low level
  pipe streams,
  which will be of type (FILE *) or HANDLE, depending on what the FilePlugin
- support code is using to represent file streams. FILEHANDLETYPE is
- defined in my subclasses
+ support code is using to represent file streams. FILEHANDLETYPE is defined
+ in my subclasses
  in the #declareCVarsIn: class method.
  */
 
 EXPORT(sqInt)
-primitiveCreatePipe(void) {
+primitiveCreatePipe(void)
+{
     sqInt arrayResult;
     sqInt reader;
     FILEHANDLETYPE readerIOStream;
@@ -1548,19 +1601,20 @@
  and reader.
  The session identifier is passed as the parameter to this primitive. Use
  this variant
- if the session identifier is not available directly in the VM (as may be the
- case if
+ if the session identifier is not available directly in the VM (as may be
+ the case if
  it is not possible to link from this plugin to a variable elsewhere in the
  VM). The readerIOStream and writerIOStream variables represent the low
  level pipe streams,
  which will be of type (FILE *) or HANDLE, depending on what the FilePlugin
- support code is using to represent file streams. FILEHANDLETYPE is
- defined in my subclasses
+ support code is using to represent file streams. FILEHANDLETYPE is defined
+ in my subclasses
  in the #declareCVarsIn: class method.
  */
 
 EXPORT(sqInt)
-primitiveCreatePipeWithSessionIdentifier(void) {
+primitiveCreatePipeWithSessionIdentifier(void)
+{
     sqInt arrayResult;
     sqInt reader;
     FILEHANDLETYPE readerIOStream;
@@ -1609,7 +1663,8 @@
  Integer) in the environment list. */
 
 EXPORT(sqInt)
-primitiveEnvironmentAt(void) {
+primitiveEnvironmentAt(void)
+{
     sqInt envCnt;
     extern char **envVec;
     sqInt index;
@@ -1646,7 +1701,8 @@
 /* Answer the value of an environment variable keyed by a Symbol. */
 
 EXPORT(sqInt)
-primitiveEnvironmentAtSymbol(void) {
+primitiveEnvironmentAtSymbol(void)
+{
     char * getenvResult;
 
  getenvResult = getenv(transientCStringFromString(interpreterProxy->stackObjectValue(0)));
@@ -1663,7 +1719,8 @@
 /* Answer a string describing an error message */
 
 EXPORT(sqInt)
-primitiveErrorMessageAt(void) {
+primitiveErrorMessageAt(void)
+{
     sqInt errMessage;
     sqInt index;
     sqInt len;
@@ -1682,13 +1739,13 @@
 }
 
 
-/* Call stat(2) to obtain the file protection mask for a file. Answer an Array of
+/* Call stat(2) to obtain the file protection mask for a file. Answer an
+ Array of
  four integers representing the protection mask, or answer errno on
  failure. The
- protection mask is four Integers, each of which may be considered an
- octal digit
- (0-7), with bit values 4, 2, and 1. The first digit selects the set user ID (4)
- and set
+ protection mask is four Integers, each of which may be considered an octal
+ digit (0-7), with bit values 4, 2, and 1. The first digit selects the set
+ user ID (4) and set
  group ID (2) and save text image (1) attributes. The second digit selects
  permissions for the user who owns the file: read (4), write (2), and
  execute (1); the third
@@ -1698,7 +1755,8 @@
  */
 
 EXPORT(sqInt)
-primitiveFileProtectionMask(void) {
+primitiveFileProtectionMask(void)
+{
     sqInt buffer;
     extern int errno;
     sqInt mode;
@@ -1727,18 +1785,20 @@
 }
 
 
-/* Call stat(2) to obtain the file protection mask for a file. Answer errno on
- failure, or on success answer an array with: UID with: GID with:
- protectionMask. The
- protectionMask is an Array of four integers representing the protection
- mask, or
+/* Call stat(2) to obtain the file protection mask for a file. Answer errno
+ on failure,
+ or on success answer an array with: UID with: GID with: protectionMask.
+ The protectionMask is an Array of four integers representing the
+ protection mask, or
  answer errno on failure. The protection mask is four Integers, each of
  which may
- be considered an octal digit (0-7), with bit values 4, 2, and 1. The first digit
- selects the set user ID (4) and set group ID (2) and save text image (1)
+ be considered an octal digit (0-7), with bit values 4, 2, and 1. The first
+ digit selects
+ the set user ID (4) and set group ID (2) and save text image (1)
  attributes. The second
- digit selects permissions for the user who owns the file: read (4), write (2),
- and execute (1); the third selects permissions for other users in the file's
+ digit selects permissions for the user who owns the file: read (4), write
+ (2), and
+ execute (1); the third selects permissions for other users in the file's
  group, with
  the same values; and the fourth for other users not in the file's group,
  with the
@@ -1746,7 +1806,8 @@
  */
 
 EXPORT(sqInt)
-primitiveFileStat(void) {
+primitiveFileStat(void)
+{
     sqInt buffer;
     extern int errno;
     sqInt gid;
@@ -1786,14 +1847,13 @@
 
 /* This primitive exists only for purposes of testing the
  fixPointersInArrayOfStrings:withOffsets:count: method. I believe it to be
- reasonably machine and compiler independent, but have no way of
- verifying this on a variety of machines, so I'll leave this test method here
- in case
- someone runs into problems on other hardware or compilers. -dtl
- */
+ reasonably machine and compiler independent, but have no way of verifying
+ this on a variety of machines, so I'll leave this test method here in case
+ someone runs into problems on other hardware or compilers. -dtl */
 
 EXPORT(sqInt)
-primitiveFixPointersInArrayOfStrings(void) {
+primitiveFixPointersInArrayOfStrings(void)
+{
     sqInt count;
     sqInt cStringArray;
     char *flattenedArrayOfStrings;
@@ -1824,15 +1884,16 @@
  Smalltalk, and this method answers the pid of the child which was created.
 
  On entry, the stack contains:
- 0: workingDir, a null terminated string specifying the working directory to
- use, or nil.
+ 0: workingDir, a null terminated string specifying the working directory
+ to use, or nil.
  1: envOffsets, an array of integers for calculating environment string
  address offsets.
  2: envVecBuffer, a String buffer containing environment strings arranged
  to look like char **.
- 3: argOffsets, an array of integers for calculating argument string address
- offsets. 4: argVecBuffer, a String buffer containing argument strings
- arranged to look like char **.
+ 3: argOffsets, an array of integers for calculating argument string
+ address offsets.
+ 4: argVecBuffer, a String buffer containing argument strings arranged to
+ look like char **.
  5: stdErr, a ByteArray handle.
  6: stdOut, a ByteArray handle.
  7: stdIn, a ByteArray handle.
@@ -1840,7 +1901,8 @@
  execute. 9: the sender */
 
 EXPORT(sqInt)
-primitiveForkAndExecInDirectory(void) {
+primitiveForkAndExecInDirectory(void)
+{
  return forkAndExecInDirectory(1);
 }
 
@@ -1850,15 +1912,16 @@
  Smalltalk, and this method answers the pid of the child which was created.
 
  On entry, the stack contains:
- 0: workingDir, a null terminated string specifying the working directory to
- use, or nil.
+ 0: workingDir, a null terminated string specifying the working directory
+ to use, or nil.
  1: envOffsets, an array of integers for calculating environment string
  address offsets.
  2: envVecBuffer, a String buffer containing environment strings arranged
  to look like char **.
- 3: argOffsets, an array of integers for calculating argument string address
- offsets. 4: argVecBuffer, a String buffer containing argument strings
- arranged to look like char **.
+ 3: argOffsets, an array of integers for calculating argument string
+ address offsets.
+ 4: argVecBuffer, a String buffer containing argument strings arranged to
+ look like char **.
  5: stdErr, a ByteArray handle.
  6: stdOut, a ByteArray handle.
  7: stdIn, a ByteArray handle.
@@ -1866,15 +1929,16 @@
  execute. 9: the sender */
 
 EXPORT(sqInt)
-primitiveForkExec(void) {
+primitiveForkExec(void)
+{
  return forkAndExecInDirectory(0);
 }
 
 
 /* Fork a child process, and continue running squeak in the child process.
  Leave the
- X session connected to the parent process, but close its file descriptor for
- the child
+ X session connected to the parent process, but close its file descriptor
+ for the child
  process. Open a new X session for the child.
 
  The child should not depend on using existing connections to external
@@ -1885,7 +1949,8 @@
  */
 
 EXPORT(sqInt)
-primitiveForkSqueak(void) {
+primitiveForkSqueak(void)
+{
     pid_t pid;
 
  if ((sandboxSecurity()) == 1) {
@@ -1902,8 +1967,8 @@
 
 /* Fork a child process, and continue running squeak in the child process.
  Leave the
- X session connected to the parent process, but close its file descriptor for
- the child
+ X session connected to the parent process, but close its file descriptor
+ for the child
  process. Open a new X session for the child.
 
  The child should not depend on using existing connections to external
@@ -1914,7 +1979,8 @@
  */
 
 EXPORT(sqInt)
-primitiveForkSqueakWithoutSigHandler(void) {
+primitiveForkSqueakWithoutSigHandler(void)
+{
     pid_t pid;
 
  if ((sandboxSecurity()) == 1) {
@@ -1930,21 +1996,22 @@
 
 
 /* Set a signal handler in the VM which will signal a Smalltalk semaphore at
- semaphoreIndex whenever an external signal sigNum is received. Answer
- the prior value of the signal handler. If semaphoreIndex is zero or nil, the
+ semaphoreIndex whenever an external signal sigNum is received. Answer the
+ prior value of the signal handler. If semaphoreIndex is zero or nil, the
  handler is unregistered, and the VM returns to its default behavior for
  handling that
  signal.
 
- The Smalltalk semaphore is expected to be kept at the same index
- location indefinitely during the lifetime of a Squeak session. If that is not
- the case, the
+ The Smalltalk semaphore is expected to be kept at the same index location
+ indefinitely during the lifetime of a Squeak session. If that is not the
+ case, the
  handler must be unregistered prior to unregistering the Smalltalk
  semaphore.
  */
 
 EXPORT(sqInt)
-primitiveForwardSignalToSemaphore(void) {
+primitiveForwardSignalToSemaphore(void)
+{
     void *handler;
     char *hPtr;
     sqInt idx;
@@ -1986,7 +2053,8 @@
 /* Answer a string containing the current working directory. */
 
 EXPORT(sqInt)
-primitiveGetCurrentWorkingDirectory(void) {
+primitiveGetCurrentWorkingDirectory(void)
+{
     char *buffer;
     sqInt bufferSize;
     char *cwd;
@@ -2028,7 +2096,8 @@
 /* Answer the effective group ID of my OS process */
 
 EXPORT(sqInt)
-primitiveGetEGid(void) {
+primitiveGetEGid(void)
+{
     gid_t eGid;
 
  eGid = getegid();
@@ -2040,7 +2109,8 @@
 /* Answer the effective user ID of my OS process */
 
 EXPORT(sqInt)
-primitiveGetEUid(void) {
+primitiveGetEUid(void)
+{
     uid_t eUid;
 
  eUid = geteuid();
@@ -2052,7 +2122,8 @@
 /* Answer the group ID of my OS process */
 
 EXPORT(sqInt)
-primitiveGetGid(void) {
+primitiveGetGid(void)
+{
     gid_t gid;
 
  gid = getgid();
@@ -2064,7 +2135,8 @@
 /* Answer the process group ID of the process identified by pid */
 
 EXPORT(sqInt)
-primitiveGetPGid(void) {
+primitiveGetPGid(void)
+{
     pid_t pgid;
     pid_t pid;
 
@@ -2081,7 +2153,8 @@
 /* Answer the process group ID of this OS process */
 
 EXPORT(sqInt)
-primitiveGetPGrp(void) {
+primitiveGetPGrp(void)
+{
     pid_t pgid;
 
  pgid = getpgrp();
@@ -2096,7 +2169,8 @@
 /* Answer the process ID of my OS process */
 
 EXPORT(sqInt)
-primitiveGetPid(void) {
+primitiveGetPid(void)
+{
     pid_t pid;
 
  pid = getpid();
@@ -2108,7 +2182,8 @@
 /* Answer the process ID of the parent process of my OS process */
 
 EXPORT(sqInt)
-primitiveGetPPid(void) {
+primitiveGetPPid(void)
+{
     pid_t ppid;
 
  ppid = getppid();
@@ -2117,14 +2192,15 @@
 }
 
 
-/* Answer the unique session identifier for this Smalltalk instance running in
- this OS process. The C integer value is coerced into a Smalltalk ByteArray
- to preserve
- the full range of possible values.
+/* Answer the unique session identifier for this Smalltalk instance running
+ in this
+ OS process. The C integer value is coerced into a Smalltalk ByteArray to
+ preserve the full range of possible values.
  */
 
 EXPORT(sqInt)
-primitiveGetSession(void) {
+primitiveGetSession(void)
+{
     void *charArray1;
     unsigned char *sessionByteArrayPointer;
     sqInt sessionIDSize;
@@ -2149,19 +2225,21 @@
 /* Answer the file handle for standard error of my OS process */
 
 EXPORT(sqInt)
-primitiveGetStdErrHandle(void) {
+primitiveGetStdErrHandle(void)
+{
  getStdHandle(2);
 }
 
 
 /* Answer the file handle for standard error of my OS process. The session
- identifier is passed as the parameter to this primitive. Use this variant if
- the session identifier is not available directly in the VM (as may be the
- case if it is not possible to link from this plugin to a variable elsewhere
- in the VM). */
+ identifier is passed as the parameter to this primitive. Use this variant
+ if the session identifier is not available directly in the VM (as may be
+ the case if it is not possible to link from this plugin to a variable
+ elsewhere in the VM). */
 
 EXPORT(sqInt)
-primitiveGetStdErrHandleWithSessionIdentifier(void) {
+primitiveGetStdErrHandleWithSessionIdentifier(void)
+{
     SQFile *file;
     sqInt fileOop;
     SESSIONIDENTIFIERTYPE thisSession;
@@ -2182,19 +2260,21 @@
 /* Answer the file handle for standard input of my OS process */
 
 EXPORT(sqInt)
-primitiveGetStdInHandle(void) {
+primitiveGetStdInHandle(void)
+{
  getStdHandle(0);
 }
 
 
 /* Answer the file handle for standard input of my OS process. The session
- identifier is passed as the parameter to this primitive. Use this variant if
- the session identifier is not available directly in the VM (as may be the
- case if it is not possible to link from this plugin to a variable elsewhere
- in the VM). */
+ identifier is passed as the parameter to this primitive. Use this variant
+ if the session identifier is not available directly in the VM (as may be
+ the case if it is not possible to link from this plugin to a variable
+ elsewhere in the VM). */
 
 EXPORT(sqInt)
-primitiveGetStdInHandleWithSessionIdentifier(void) {
+primitiveGetStdInHandleWithSessionIdentifier(void)
+{
     SQFile *file;
     sqInt fileOop;
     SESSIONIDENTIFIERTYPE thisSession;
@@ -2215,19 +2295,21 @@
 /* Answer the file handle for standard output of my OS process */
 
 EXPORT(sqInt)
-primitiveGetStdOutHandle(void) {
+primitiveGetStdOutHandle(void)
+{
  getStdHandle(1);
 }
 
 
 /* Answer the file handle for standard output of my OS process. The session
- identifier is passed as the parameter to this primitive. Use this variant if
- the session identifier is not available directly in the VM (as may be the
- case if it is not possible to link from this plugin to a variable elsewhere
- in the VM). */
+ identifier is passed as the parameter to this primitive. Use this variant
+ if the session identifier is not available directly in the VM (as may be
+ the case if it is not possible to link from this plugin to a variable
+ elsewhere in the VM). */
 
 EXPORT(sqInt)
-primitiveGetStdOutHandleWithSessionIdentifier(void) {
+primitiveGetStdOutHandleWithSessionIdentifier(void)
+{
     SQFile *file;
     sqInt fileOop;
     SESSIONIDENTIFIERTYPE thisSession;
@@ -2246,13 +2328,14 @@
 
 
 /* Answer the ID of the pthread that is currently executing (the interpreter
- thread). A thread ID may be a 64 bit value on some platforms, so answer
- a byte array
+ thread). A thread ID may be a 64 bit value on some platforms, so answer a
+ byte array
  containing the value in machine-dependent byte order.
  */
 
 EXPORT(sqInt)
-primitiveGetThreadID(void) {
+primitiveGetThreadID(void)
+{
  interpreterProxy->popthenPush(1, newPthreadTypeByteArray(vmThread));
 }
 
@@ -2260,7 +2343,8 @@
 /* Answer the user ID of my OS process */
 
 EXPORT(sqInt)
-primitiveGetUid(void) {
+primitiveGetUid(void)
+{
     uid_t uid;
 
  uid = getuid();
@@ -2269,14 +2353,17 @@
 }
 
 
-/* Take a struct SQFile from the stack, and call feof(3) to determine if the file
- has reached end of file. */
+/* Take a struct SQFile from the stack, and call feof(3) to determine if the
+ file has
+ reached end of file.
+ */
 /* Deprecated. The return values are reversed. Use
  primitiveTestEndOfFileFlag.
  */
 
 EXPORT(sqInt)
-primitiveIsAtEndOfFile(void) {
+primitiveIsAtEndOfFile(void)
+{
     FILEHANDLETYPE file;
     sqInt result;
     sqInt sqFileOop;
@@ -2307,7 +2394,8 @@
  parameter is nil, the default value of SIGTERM will be used. */
 
 EXPORT(sqInt)
-primitiveKillOnExit(void) {
+primitiveKillOnExit(void)
+{
     sqInt count;
     pid_t *p;
     pid_t pid;
@@ -2353,13 +2441,15 @@
  file. Otherwise, request a shared (F_RDLCK) lock. Any number of Unix
  processes may hold a read lock (shared lock) on a file region, but only
  one process may
- hold a write lock (exclusive lock). Answer the result of the call to fcntl().
-
- If length is zero, then the entire file will be locked, including region extents
- that have not yet been allocated for the file. */
+ hold a write lock (exclusive lock). Answer the result of the call to
+ fcntl().
+ If length is zero, then the entire file will be locked, including region
+ extents that
+ have not yet been allocated for the file. */
 
 EXPORT(sqInt)
-primitiveLockFileRegion(void) {
+primitiveLockFileRegion(void)
+{
     sqInt exclusive;
     FILEHANDLETYPE fileHandle;
     int fileNo;
@@ -2406,13 +2496,14 @@
  The readerIOStream and writerIOStream variables represent the low level
  pipe streams,
  which will be of type (FILE *) or HANDLE, depending on what the FilePlugin
- support code is using to represent file streams. FILEHANDLETYPE is
- defined in my subclasses
+ support code is using to represent file streams. FILEHANDLETYPE is defined
+ in my subclasses
  in the #declareCVarsIn: class method.
  */
 
 EXPORT(sqInt)
-primitiveMakePipe(void) {
+primitiveMakePipe(void)
+{
     sqInt arrayResult;
     sqInt reader;
     FILEHANDLETYPE readerIOStream;
@@ -2461,19 +2552,20 @@
  and reader.
  The session identifier is passed as the parameter to this primitive. Use
  this variant
- if the session identifier is not available directly in the VM (as may be the
- case if
+ if the session identifier is not available directly in the VM (as may be
+ the case if
  it is not possible to link from this plugin to a variable elsewhere in the
  VM). The readerIOStream and writerIOStream variables represent the low
  level pipe streams,
  which will be of type (FILE *) or HANDLE, depending on what the FilePlugin
- support code is using to represent file streams. FILEHANDLETYPE is
- defined in my subclasses
+ support code is using to represent file streams. FILEHANDLETYPE is defined
+ in my subclasses
  in the #declareCVarsIn: class method.
  */
 
 EXPORT(sqInt)
-primitiveMakePipeWithSessionIdentifier(void) {
+primitiveMakePipeWithSessionIdentifier(void)
+{
     sqInt arrayResult;
     sqInt reader;
     FILEHANDLETYPE readerIOStream;
@@ -2521,23 +2613,26 @@
 /* Answer a string containing the module name string for this plugin. */
 
 EXPORT(sqInt)
-primitiveModuleName(void) {
+primitiveModuleName(void)
+{
  interpreterProxy->popthenPush(1, stringFromCString(getModuleName()));
 }
 
 
 /* Change the scheduling priority of this process by the given nice
- increment. A positive increment decreases the priority. Only the
- superuser can specify
+ increment. A positive increment decreases the priority. Only the superuser
+ can specify
  a negative value (to increase the priority). See man(2) nice.
 
- Different versions of Unix are inconsistent in their return values. The only
- reliable test for success is to clear errno prior to the call, and test its
- value if the result of nice() is -1.
+ Different versions of Unix are inconsistent in their return values. The
+ only reliable test for success is to clear errno prior to the call, and
+ test its value
+ if the result of nice() is -1.
  */
 
 EXPORT(sqInt)
-primitiveNice(void) {
+primitiveNice(void)
+{
     extern int errno;
     int niceIncrement;
     sqInt result;
@@ -2562,7 +2657,8 @@
  the string into separately allocated environment memory. */
 
 EXPORT(sqInt)
-primitivePutEnv(void) {
+primitivePutEnv(void)
+{
     char *cStringPtr;
     sqInt keyValueString;
 
@@ -2581,7 +2677,8 @@
 /* Answer the real path for a path string as determined by realpath(). */
 
 EXPORT(sqInt)
-primitiveRealpath(void) {
+primitiveRealpath(void)
+{
     char *buffer;
     sqInt bufferSize;
     sqInt len;
@@ -2618,12 +2715,13 @@
 
 
 /* Clean up after the death of a child, and answer an array with the pid and
- the exit status of the child process. Answer nil if the pidToHandle does not
- exist.
+ the exit status of the child process. Answer nil if the pidToHandle does
+ not exist.
  */
 
 EXPORT(sqInt)
-primitiveReapChildProcess(void) {
+primitiveReapChildProcess(void)
+{
     sqInt *arrayPtr;
     int exitStatus;
     pid_t pidResult;
@@ -2658,7 +2756,8 @@
  the signal handler for sigNum. */
 
 EXPORT(sqInt)
-primitiveSemaIndexFor(void) {
+primitiveSemaIndexFor(void)
+{
     sqInt index;
     sqInt sigNum;
 
@@ -2676,7 +2775,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigabrtTo(sqInt anIntegerPid) {
+primitiveSendSigabrtTo(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -2710,7 +2810,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigalrmTo(sqInt anIntegerPid) {
+primitiveSendSigalrmTo(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -2745,7 +2846,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigchldTo(sqInt anIntegerPid) {
+primitiveSendSigchldTo(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -2771,15 +2873,16 @@
 }
 
 
-/* Send SIGCONT (continue) to the OS process identified by anIntegerPid.
- Use an explicit
+/* Send SIGCONT (continue) to the OS process identified by anIntegerPid. Use
+ an explicit
  check for isIntegerObject so we can return -1 on error (the
  stackIntegerValue: method
  answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSigcontTo(sqInt anIntegerPid) {
+primitiveSendSigcontTo(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -2805,15 +2908,15 @@
 }
 
 
-/* Send SIGHUP (hangup) to the OS process identified by anIntegerPid. Use
- an explicit
- check for isIntegerObject so we can return -1 on error (the
+/* Send SIGHUP (hangup) to the OS process identified by anIntegerPid. Use an
+ explicit check for isIntegerObject so we can return -1 on error (the
  stackIntegerValue: method
  answers 1 on error, and 1 is a valid pid number).
  */
 
 EXPORT(sqInt)
-primitiveSendSighupTo(sqInt anIntegerPid) {
+primitiveSendSighupTo(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -2847,7 +2950,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigintTo(sqInt anIntegerPid) {
+primitiveSendSigintTo(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -2881,7 +2985,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigkillTo(sqInt anIntegerPid) {
+primitiveSendSigkillTo(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -2915,7 +3020,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigpipeTo(sqInt anIntegerPid) {
+primitiveSendSigpipeTo(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -2948,7 +3054,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigquitTo(sqInt anIntegerPid) {
+primitiveSendSigquitTo(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -2982,7 +3089,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigstopTo(sqInt anIntegerPid) {
+primitiveSendSigstopTo(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -3016,7 +3124,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigtermTo(sqInt anIntegerPid) {
+primitiveSendSigtermTo(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -3050,7 +3159,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigusr1To(sqInt anIntegerPid) {
+primitiveSendSigusr1To(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -3084,7 +3194,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSendSigusr2To(sqInt anIntegerPid) {
+primitiveSendSigusr2To(sqInt anIntegerPid)
+{
     pid_t pidToSignal;
     int result;
     sqInt sig;
@@ -3114,7 +3225,8 @@
  group ID. */
 
 EXPORT(sqInt)
-primitiveSetPGid(void) {
+primitiveSetPGid(void)
+{
     pid_t pgid;
     pid_t pid;
 
@@ -3127,15 +3239,14 @@
 }
 
 
-/* Set a new process group for this OS process. Newly created child
- processes will be members of the new process group. Note: Use
- setpgid(0,0) rather than
- the equivalent setpgrp() because setpgrp() is implemented differently on
- some flavors of Unix.
- */
+/* Set a new process group for this OS process. Newly created child processes
+ will be members of the new process group. Note: Use setpgid(0,0) rather
+ than the equivalent setpgrp() because setpgrp() is implemented differently
+ on some flavors of Unix. */
 
 EXPORT(sqInt)
-primitiveSetPGrp(void) {
+primitiveSetPGrp(void)
+{
  if ((setpgid(0, 0)) == -1) {
  return interpreterProxy->primitiveFail();
  }
@@ -3144,17 +3255,17 @@
 
 /* Set the index of the semaphore used by the OSProcess with which I
  collaborate. My
- OSProcess should set this value so that I can use it when handling
- SIGCHLD signals
- (death of child). In the C translation this is a static int which would be
- shared by all
+ OSProcess should set this value so that I can use it when handling SIGCHLD
+ signals (death of child). In the C translation this is a static int which
+ would be shared by all
  instances of UnixOSProcessPlugin, which is expected to be a singleton.
  Answer the
  value of the semaphore index.
  */
 
 EXPORT(sqInt)
-primitiveSetSemaIndex(void) {
+primitiveSetSemaIndex(void)
+{
  sigChldSemaIndex = interpreterProxy->stackIntegerValue(0);
  interpreterProxy->pop(2);
  interpreterProxy->pushInteger(sigChldSemaIndex);
@@ -3162,9 +3273,10 @@
 
 
 /* Quoted from Linux man pages:
- setsid() creates a new session if the calling process is not a process group
- leader. The calling process is the leader of the new session, the process
- group leader of
+ setsid() creates a new session if the calling process is not a process
+ group leader.
+ The calling process is the leader of the new session, the process group
+ leader of
  the new process group, and has no controlling tty. The process group ID
  and session
  ID of the calling process are set to the PID of the calling process. The
@@ -3172,7 +3284,8 @@
  this new session. */
 
 EXPORT(sqInt)
-primitiveSetSid(void) {
+primitiveSetSid(void)
+{
     pid_t sessionId;
 
  sessionId = setsid();
@@ -3187,7 +3300,8 @@
 /* Integer value corresponding to SIGCHLD */
 
 EXPORT(sqInt)
-primitiveSigChldNumber(void) {
+primitiveSigChldNumber(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->pushInteger(sigChldNumber());
 }
@@ -3196,7 +3310,8 @@
 /* Integer value corresponding to SIGHUP */
 
 EXPORT(sqInt)
-primitiveSigHupNumber(void) {
+primitiveSigHupNumber(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->pushInteger(sigHupNumber());
 }
@@ -3205,7 +3320,8 @@
 /* Integer value corresponding to SIGINT */
 
 EXPORT(sqInt)
-primitiveSigIntNumber(void) {
+primitiveSigIntNumber(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->pushInteger(sigIntNumber());
 }
@@ -3214,7 +3330,8 @@
 /* Integer value corresponding to SIGKILL */
 
 EXPORT(sqInt)
-primitiveSigKillNumber(void) {
+primitiveSigKillNumber(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->pushInteger(sigKillNumber());
 }
@@ -3223,7 +3340,8 @@
 /* Integer value corresponding to SIGPIPE */
 
 EXPORT(sqInt)
-primitiveSigPipeNumber(void) {
+primitiveSigPipeNumber(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->pushInteger(sigPipeNumber());
 }
@@ -3232,7 +3350,8 @@
 /* Integer value corresponding to SIGQUIT */
 
 EXPORT(sqInt)
-primitiveSigQuitNumber(void) {
+primitiveSigQuitNumber(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->pushInteger(sigQuitNumber());
 }
@@ -3241,7 +3360,8 @@
 /* Integer value corresponding to SIGTERM */
 
 EXPORT(sqInt)
-primitiveSigTermNumber(void) {
+primitiveSigTermNumber(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->pushInteger(sigTermNumber());
 }
@@ -3250,7 +3370,8 @@
 /* Integer value corresponding to SIGUSR1 */
 
 EXPORT(sqInt)
-primitiveSigUsr1Number(void) {
+primitiveSigUsr1Number(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->pushInteger(sigUsr1Number());
 }
@@ -3259,7 +3380,8 @@
 /* Integer value corresponding to SIGUSR2 */
 
 EXPORT(sqInt)
-primitiveSigUsr2Number(void) {
+primitiveSigUsr2Number(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->pushInteger(sigUsr2Number());
 }
@@ -3268,7 +3390,8 @@
 /* Size in bytes of an integer, for this C compiler on this machine. */
 
 EXPORT(sqInt)
-primitiveSizeOfInt(void) {
+primitiveSizeOfInt(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->pushInteger(sizeOfInt());
 }
@@ -3277,7 +3400,8 @@
 /* Size in bytes of a void pointer, for this C compiler on this machine. */
 
 EXPORT(sqInt)
-primitiveSizeOfPointer(void) {
+primitiveSizeOfPointer(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->pushInteger(sizeOfPointer());
 }
@@ -3287,12 +3411,13 @@
  stream. This flushes the
  file stream in the C library, not the stream in Smalltalk. For output
  streams, consider setting
- the OS stream (C library) to unbuffered output, and letting Smalltalk do all
- the buffering.
+ the OS stream (C library) to unbuffered output, and letting Smalltalk do
+ all the buffering.
  */
 
 EXPORT(sqInt)
-primitiveSQFileFlush(void) {
+primitiveSQFileFlush(void)
+{
     int result;
     sqInt sqFileOop;
 
@@ -3313,17 +3438,18 @@
  stream. This flushes the
  file stream in the C library, not the stream in Smalltalk. For output
  streams, consider setting
- the OS stream (C library) to unbuffered output, and letting Smalltalk do all
- the buffering.
+ the OS stream (C library) to unbuffered output, and letting Smalltalk do
+ all the buffering.
  The session identifier is passed as the parameter to this primitive. Use
  this variant if the session
- identifier is not available directly in the VM (as may be the case if it is not
- possible to link from
+ identifier is not available directly in the VM (as may be the case if it
+ is not possible to link from
  this plugin to a variable elsewhere in the VM).
  */
 
 EXPORT(sqInt)
-primitiveSQFileFlushWithSessionIdentifier(void) {
+primitiveSQFileFlushWithSessionIdentifier(void)
+{
     int result;
     sqInt sqFileOop;
 
@@ -3345,7 +3471,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSQFileSetBlocking(void) {
+primitiveSQFileSetBlocking(void)
+{
     sqInt descriptor;
     int flags;
     sqInt retVal;
@@ -3380,14 +3507,15 @@
 
 /* Take a struct SQFile from the stack, and call fcntl() to set the file for
  blocking I/O.
- Use this variant if the session identifier is not available directly in the VM
- (as may be
- the case if it is not possible to link from this plugin to a variable elsewhere
- in the VM).
+ Use this variant if the session identifier is not available directly in
+ the VM (as may be
+ the case if it is not possible to link from this plugin to a variable
+ elsewhere in the VM).
  */
 
 EXPORT(sqInt)
-primitiveSQFileSetBlockingWithSessionIdentifier(void) {
+primitiveSQFileSetBlockingWithSessionIdentifier(void)
+{
     sqInt descriptor;
     sqInt flags;
     sqInt retVal;
@@ -3434,7 +3562,8 @@
  */
 
 EXPORT(sqInt)
-primitiveSQFileSetNonBlocking(void) {
+primitiveSQFileSetNonBlocking(void)
+{
     sqInt descriptor;
     sqInt flags;
     sqInt retVal;
@@ -3469,14 +3598,15 @@
 
 /* Take a struct SQFile from the stack, and call fcntl() to set the file
  non-blocking I/O.
- Use this variant if the session identifier is not available directly in the VM
- (as may be
- the case if it is not possible to link from this plugin to a variable elsewhere
- in the VM).
+ Use this variant if the session identifier is not available directly in
+ the VM (as may be
+ the case if it is not possible to link from this plugin to a variable
+ elsewhere in the VM).
  */
 
 EXPORT(sqInt)
-primitiveSQFileSetNonBlockingWithSessionIdentifier(void) {
+primitiveSQFileSetNonBlockingWithSessionIdentifier(void)
+{
     sqInt descriptor;
     sqInt flags;
     sqInt retVal;
@@ -3521,13 +3651,15 @@
 /* Take a struct SQFile from the stack, and call setbuf() to set the OS file
  stream (implemented in the C library) for unbuffered I/O. Answers the
  result of a fflush()
- call, not the result of the setbuf() call (which is type void). This is nearly
- useless, but may at least provide an indicator that we are operating on a
- valid file stream.
+ call, not the result of the setbuf() call (which is type void). This is
+ nearly useless,
+ but may at least provide an indicator that we are operating on a valid
+ file stream.
  */
 
 EXPORT(sqInt)
-primitiveSQFileSetUnbuffered(void) {
+primitiveSQFileSetUnbuffered(void)
+{
     FILEHANDLETYPE file;
     sqInt retVal;
     sqInt sqFileOop;
@@ -3549,19 +3681,20 @@
 
 /* Take a struct SQFile from the stack, and call setbuf() to set the OS file
  stream (implemented in
- the C library) for unbuffered I/O. Answers the result of a fflush() call, not
- the result of the
- setbuf() call (which is type void). This is nearly useless, but may at least
- provide an indicator
- that we are operating on a valid file stream. Use this variant if the session
- identifier is not
- available directly in the VM (as may be the case if it is not possible to link
- from this plugin
+ the C library) for unbuffered I/O. Answers the result of a fflush() call,
+ not the result of the
+ setbuf() call (which is type void). This is nearly useless, but may at
+ least provide an indicator
+ that we are operating on a valid file stream. Use this variant if the
+ session identifier is not
+ available directly in the VM (as may be the case if it is not possible to
+ link from this plugin
  to a variable elsewhere in the VM).
  */
 
 EXPORT(sqInt)
-primitiveSQFileSetUnbufferedWithSessionIdentifier(void) {
+primitiveSQFileSetUnbufferedWithSessionIdentifier(void)
+{
     sqInt retVal;
     SQFile *sqFile;
     sqInt sqFileOop;
@@ -3588,15 +3721,17 @@
 }
 
 
-/* Take a struct SQFile from the stack, and call feof(3) to determine if the file
- has reached end of file. The flag is set only by a previous read operation,
- so end of
+/* Take a struct SQFile from the stack, and call feof(3) to determine if the
+ file has
+ reached end of file. The flag is set only by a previous read operation, so
+ end of
  file is not detected until an actual EOF condition has been detected by a
  read attempt.
  */
 
 EXPORT(sqInt)
-primitiveTestEndOfFileFlag(void) {
+primitiveTestEndOfFileFlag(void)
+{
     FILEHANDLETYPE file;
     sqInt result;
     sqInt sqFileOop;
@@ -3634,19 +3769,20 @@
  If length is zero, then the request is for the entire file to be locked,
  including region extents that have not yet been allocated for the file.
 
- If the fcntl() call fails, answer -1 (the result of the failed call). Otherwise,
- answer an array with the following six fields:
+ If the fcntl() call fails, answer -1 (the result of the failed call).
+ Otherwise, answer an array with the following six fields:
  lockable (true or false)
  l_pid (pid of the process preventing this lock request, or nil)
- l_type (request type F_WRLCK or F_RDLOCK of the process preventing
- this lock request)
- l_whence (the SEEK_SET, SEEK_CUR, or SEEK_END value of the lock
- preventing this lock request).
+ l_type (request type F_WRLCK or F_RDLOCK of the process preventing this
+ lock request)
+ l_whence (the SEEK_SET, SEEK_CUR, or SEEK_END value of the lock preventing
+ this lock request).
  l_start (offset of the region lock preventing this lock request)
  l_len (length of the region lock preventing this lock request) */
 
 EXPORT(sqInt)
-primitiveTestLockableFileRegion(void) {
+primitiveTestLockableFileRegion(void)
+{
     sqInt canObtainLock;
     sqInt exclusive;
     FILEHANDLETYPE fileHandle;
@@ -3712,7 +3848,8 @@
  #primitiveUnixFileNumber. */
 
 EXPORT(sqInt)
-primitiveUnixFileClose(sqInt anIntegerFileNumber) {
+primitiveUnixFileClose(sqInt anIntegerFileNumber)
+{
  interpreterProxy->pop(2);
  interpreterProxy->pushInteger(close(interpreterProxy->stackIntegerValue(0)));
 }
@@ -3725,7 +3862,8 @@
  */
 
 EXPORT(sqInt)
-primitiveUnixFileNumber(void) {
+primitiveUnixFileNumber(void)
+{
     FILEHANDLETYPE fileHandle;
     int fileNo;
     sqInt sqFileOop;
@@ -3746,7 +3884,8 @@
 
 
 /* Take a struct SQFile from the stack, and unlock the specified region.
- Answer the result of the call to fcntl(). If the region is in the file lock cache,
+ Answer the result of the call to fcntl(). If the region is in the file
+ lock cache,
  remove it, but otherwise ignore the cache. The cache supports Win32
  semantics within a single Squeak image, but not across separate images,
  therefore the
@@ -3756,7 +3895,8 @@
  */
 
 EXPORT(sqInt)
-primitiveUnlockFileRegion(void) {
+primitiveUnlockFileRegion(void)
+{
     FILEHANDLETYPE fileHandle;
     int fileNo;
     sqInt len;
@@ -3799,7 +3939,8 @@
  */
 
 EXPORT(sqInt)
-primitiveUnsetEnv(void) {
+primitiveUnsetEnv(void)
+{
  unsetenv(transientCStringFromString(interpreterProxy->stackObjectValue(0)));
  interpreterProxy->pop(1);
 }
@@ -3808,7 +3949,8 @@
 /* Answer a string containing the version string for this plugin. */
 
 EXPORT(sqInt)
-primitiveVersionString(void) {
+primitiveVersionString(void)
+{
  interpreterProxy->pop(1);
  interpreterProxy->push(stringFromCString(versionString()));
 }
@@ -3819,21 +3961,22 @@
  child signal from
  the operating system.
 
- Child processes must be cleaned up by the parent, otherwise they
- continue to exist as zombies until the parent exits. This handler resets the
- signal handler
- to catch the next SIGCHLD signal, then sets a semaphore to notify the
- system that a child process needs to be cleaned up. The actual clean up is
- done by a
+ Child processes must be cleaned up by the parent, otherwise they continue
+ to exist as zombies until the parent exits. This handler resets the signal
+ handler to catch the next SIGCHLD signal, then sets a semaphore to notify
+ the system
+ that a child process needs to be cleaned up. The actual clean up is done
+ by a
  Smalltalk process which waits on the semaphore, then calls
  primitiveReapChildProcess.
- Note: If child processes die faster than we can clean them up, signals will
- be lost
+ Note: If child processes die faster than we can clean them up, signals
+ will be lost
  and child processes will remain as zombies.
  */
 
 static void
-reapChildProcess(int sigNum) {
+reapChildProcess(int sigNum)
+{
 
 #if !defined(SA_NOCLDSTOP)
  setSigChldHandler();
@@ -3845,12 +3988,13 @@
 }
 
 
-/* Signal sigNum has been caught by a thread other than the pthread in
- which the interpreter is executing. Rather than handling it in this thread,
+/* Signal sigNum has been caught by a thread other than the pthread in which
+ the interpreter is executing. Rather than handling it in this thread,
  resend it to the interpreter thread. */
 
 static sqInt
-resendSignal(int sigNum) {
+resendSignal(int sigNum)
+{
  pthread_kill(vmThread, sigNum);
 }
 
@@ -3858,7 +4002,8 @@
 /* Restore signal handlers to their original behaviors. */
 
 static void
-restoreDefaultSignalHandlers(void) {
+restoreDefaultSignalHandlers(void)
+{
     sqInt sigNum;
     void *signalHandlerAddress;
 
@@ -3874,15 +4019,17 @@
 }
 
 
-/* Answer 1 if running in secure mode, else 0. The
- osprocessSandboxSecurity variable is initialized to -1. On the first call to
- this method, set its value to
- either 0 (user has full access to the plugin) or 1 (user is not permitted to
- do dangerous things).
+/* Answer 1 if running in secure mode, else 0. The osprocessSandboxSecurity
+ variable is initialized to -1. On the first call to this method, set its
+ value to
+ either 0 (user has full access to the plugin) or 1 (user is not permitted
+ to do
+ dangerous things).
  */
 
 static sqInt
-sandboxSecurity(void) {
+sandboxSecurity(void)
+{
  if (osprocessSandboxSecurity < 0) {
  osprocessSandboxSecurity = securityHeurisitic();
  }
@@ -3894,13 +4041,16 @@
  should be
  restricted for dangerous functions. The rules are:
  - If the security plugin is not present, grant full access
- - If the security plugin can be loaded, restrict access unless user has all
- of secCanWriteImage, secHasFileAccess and secHasSocketAccess */
+ - If the security plugin can be loaded, restrict access unless user has
+ all of secCanWriteImage, secHasFileAccess and secHasSocketAccess */
 /* FIXME: This function has not been tested. -dtl */
-/* If the security plugin can be loaded, use it to check. If not, assume it's ok */
+/* If the security plugin can be loaded, use it to check. If not, assume it's
+ ok
+ */
 
 static sqInt
-securityHeurisitic(void) {
+securityHeurisitic(void)
+{
     sqInt canWriteImage;
     sqInt hasFileAccess;
     sqInt hasSocketAccess;
@@ -3940,17 +4090,19 @@
  */
 
 static unsigned char *
-semaphoreIndices(void) {
+semaphoreIndices(void)
+{
  return semaIndices;
 }
 
 
-/* Exit function to be registered with atexit() to signal child processes on VM
- exit.
+/* Exit function to be registered with atexit() to signal child processes on
+ VM exit.
  */
 
 static void
-sendSignalToPids(void) {
+sendSignalToPids(void)
+{
     sqInt count;
     pid_t pid;
 
@@ -3966,7 +4118,8 @@
 /* kill(pid, sig) */
 
 static sqInt
-sendSignaltoPid(sqInt sig, sqInt pid) {
+sendSignaltoPid(sqInt sig, sqInt pid)
+{
  return kill(pid, sig);
 }
 
@@ -3976,7 +4129,8 @@
  the interpreter. */
 
 static SESSIONIDENTIFIERTYPE
-sessionIdentifierFromSqFile(SQFile *sqFile) {
+sessionIdentifierFromSqFile(SQFile *sqFile)
+{
  return sqFile->sessionID;
 }
 
@@ -3986,7 +4140,8 @@
  compiler warnings about type mismatch with SESSIONIDENTIFIERTYPE. */
 
 static SESSIONIDENTIFIERTYPE
-sessionIdentifierFrom(sqInt aByteArray) {
+sessionIdentifierFrom(sqInt aByteArray)
+{
     sqInt idx;
     unsigned char *session;
     union {SESSIONIDENTIFIERTYPE session; unsigned char bytes[sizeof(SESSIONIDENTIFIERTYPE)];} sessionUnion;
@@ -4008,7 +4163,8 @@
 /* Note: This is coded so that is can be run from Squeak. */
 
 EXPORT(sqInt)
-setInterpreter(struct VirtualMachine*anInterpreter) {
+setInterpreter(struct VirtualMachine*anInterpreter)
+{
     sqInt ok;
 
  interpreterProxy = anInterpreter;
@@ -4024,7 +4180,8 @@
 /* Set the SIGCHLD signal handler in the virtual machine. */
 
 static void
-setSigChldHandler(void) {
+setSigChldHandler(void)
+{
     struct sigaction sigchldHanderAction;
 
 
@@ -4045,7 +4202,8 @@
 }
 
 static void
-setSigIntDefaultHandler(void) {
+setSigIntDefaultHandler(void)
+{
     sqInt anInteger;
     void *signalHandlerAddress;
 
@@ -4059,7 +4217,8 @@
 /* Set the SIGINT signal handler in the virtual machine to ignore interrupts. */
 
 static void
-setSigIntIgnore(void) {
+setSigIntIgnore(void)
+{
     sqInt anInteger;
     void *signalHandlerAddress;
 
@@ -4075,12 +4234,14 @@
  */
 
 static void *
-setSignalNumberhandler(sqInt anInteger, void *signalHandlerAddress) {
+setSignalNumberhandler(sqInt anInteger, void *signalHandlerAddress)
+{
  return signal(anInteger, signalHandlerAddress);
 }
 
 static void
-setSigPipeDefaultHandler(void) {
+setSigPipeDefaultHandler(void)
+{
     sqInt anInteger;
     void *signalHandlerAddress;
 
@@ -4094,12 +4255,14 @@
 /* Set the SIGPIPE signal handler in the virtual machine to ignore pipe error
  signals. If a pipe is opened to a child process, and the child exits, then
  subsequent writes to
- the pipe generate a SIGPIPE signal. If this signal is not handled, the VM will
- exit without warning.
+ the pipe generate a SIGPIPE signal. If this signal is not handled, the VM
+ will exit
+ without warning.
  */
 
 static sqInt
-setSigPipeHandler(void) {
+setSigPipeHandler(void)
+{
     sqInt anInteger;
     void *signalHandlerAddress;
 
@@ -4116,7 +4279,8 @@
  */
 
 static void
-setSigPipeIgnore(void) {
+setSigPipeIgnore(void)
+{
     sqInt anInteger;
     void *signalHandlerAddress;
 
@@ -4127,7 +4291,8 @@
 }
 
 EXPORT(sqInt)
-shutdownModule(void) {
+shutdownModule(void)
+{
     sqInt sigNum;
     void *signalHandlerAddress;
 
@@ -4147,7 +4312,8 @@
 /* Abort signal from abort(3) */
 
 static sqInt
-sigAbrtNumber(void) {
+sigAbrtNumber(void)
+{
  return SIGABRT;
 }
 
@@ -4155,7 +4321,8 @@
 /* Timer signal from alarm(2) */
 
 static sqInt
-sigAlrmNumber(void) {
+sigAlrmNumber(void)
+{
  return SIGALRM;
 }
 
@@ -4163,7 +4330,8 @@
 /* Child status has changed (POSIX). */
 
 static sqInt
-sigChldNumber(void) {
+sigChldNumber(void)
+{
  return SIGCHLD;
 }
 
@@ -4171,7 +4339,8 @@
 /* Continue if stopped */
 
 static sqInt
-sigContNumber(void) {
+sigContNumber(void)
+{
  return SIGCONT;
 }
 
@@ -4179,7 +4348,8 @@
 /* Default action for a signal */
 
 static void *
-sigDefaultNumber(void) {
+sigDefaultNumber(void)
+{
  return SIG_DFL;
 }
 
@@ -4187,7 +4357,8 @@
 /* Error return from signal() */
 
 static void *
-sigErrorNumber(void) {
+sigErrorNumber(void)
+{
  return SIG_ERR;
 }
 
@@ -4195,7 +4366,8 @@
 /* Hangup detected on controlling terminal or death of controlling process */
 
 static sqInt
-sigHupNumber(void) {
+sigHupNumber(void)
+{
  return SIGHUP;
 }
 
@@ -4203,7 +4375,8 @@
 /* Ignore action for a signal */
 
 static void *
-sigIgnoreNumber(void) {
+sigIgnoreNumber(void)
+{
  return SIG_IGN;
 }
 
@@ -4211,7 +4384,8 @@
 /* Interrupt (ANSI). */
 
 static sqInt
-sigIntNumber(void) {
+sigIntNumber(void)
+{
  return SIGINT;
 }
 
@@ -4219,7 +4393,8 @@
 /* Kill signal */
 
 static sqInt
-sigKillNumber(void) {
+sigKillNumber(void)
+{
  return SIGKILL;
 }
 
@@ -4228,7 +4403,8 @@
  declared in #declareCVarsIn: are this size. */
 
 static sqInt
-signalArraySize(void) {
+signalArraySize(void)
+{
  return NSIG;
 }
 
@@ -4237,7 +4413,8 @@
  corresponding to a signal type. */
 
 static void **
-signalHandlers(void) {
+signalHandlers(void)
+{
  return sigHandlers;
 }
 
@@ -4245,7 +4422,8 @@
 /* Broken pipe (POSIX). */
 
 static sqInt
-sigPipeNumber(void) {
+sigPipeNumber(void)
+{
  return SIGPIPE;
 }
 
@@ -4253,7 +4431,8 @@
 /* Quit from keyboard */
 
 static sqInt
-sigQuitNumber(void) {
+sigQuitNumber(void)
+{
  return SIGQUIT;
 }
 
@@ -4261,7 +4440,8 @@
 /* Stop process */
 
 static sqInt
-sigStopNumber(void) {
+sigStopNumber(void)
+{
  return SIGSTOP;
 }
 
@@ -4271,7 +4451,8 @@
  */
 
 static sqInt
-sigTermNumber(void) {
+sigTermNumber(void)
+{
  return SIGTERM;
 }
 
@@ -4280,7 +4461,8 @@
  inSmalltalk default of 10 may be wrong on some platforms. */
 
 static sqInt
-sigUsr1Number(void) {
+sigUsr1Number(void)
+{
  return SIGUSR1;
 }
 
@@ -4289,7 +4471,8 @@
  inSmalltalk default of 12 may be wrong on some platforms. */
 
 static sqInt
-sigUsr2Number(void) {
+sigUsr2Number(void)
+{
  return SIGUSR2;
 }
 
@@ -4297,7 +4480,8 @@
 /* Size in bytes of an integer, for this C compiler on this machine. */
 
 static sqInt
-sizeOfInt(void) {
+sizeOfInt(void)
+{
  return sizeof(int);
 }
 
@@ -4305,7 +4489,8 @@
 /* Size in bytes of a void pointer, for this C compiler on this machine. */
 
 static sqInt
-sizeOfPointer(void) {
+sizeOfPointer(void)
+{
  return sizeof(void *);
 }
 
@@ -4314,14 +4499,15 @@
  structure, otherwise we should get compiler warnings. */
 
 static sqInt
-sizeOfSession(void) {
+sizeOfSession(void)
+{
  return sizeof(SESSIONIDENTIFIERTYPE);
 }
 
 
 /* Answer the OS file descriptor, an integer value, from a SQSocket data
- structure, or answer -1 if unable to obtain the file descriptor (probably due
- to receiving
+ structure, or answer -1 if unable to obtain the file descriptor (probably
+ due to receiving
  an incorrect type of object as aFileHandle).
 
  Warning: The first element of privateSocketStruct happens to be the Unix
@@ -4332,7 +4518,8 @@
  */
 
 static int
-socketDescriptorFrom(sqInt sqSocketOop) {
+socketDescriptorFrom(sqInt sqSocketOop)
+{
     void *privateSocketStruct;
     SocketPtr sqSocket;
 
@@ -4349,19 +4536,21 @@
 /* Answer the size of a SQSocket data structure in bytes. */
 
 static sqInt
-socketRecordSize(void) {
+socketRecordSize(void)
+{
  return sizeof(SQSocket);
 }
 
 
-/* Return a pointer to the first byte of of the SQsocket data structure socket
- record within
+/* Return a pointer to the first byte of of the SQsocket data structure
+ socket record within
  anSQSocketRecord, which is expected to be a ByteArray of size
  self>>socketRecordSize.
  */
 
 static SocketPtr
-socketValueOf(sqInt anSQSocketRecord) {
+socketValueOf(sqInt anSQSocketRecord)
+{
  return interpreterProxy->arrayValueOf(anSQSocketRecord);
 }
 
@@ -4370,7 +4559,8 @@
  Caution: This may invoke the garbage collector. */
 
 static sqInt
-stringFromCString(const char *aCString) {
+stringFromCString(const char *aCString)
+{
     sqInt len;
     sqInt newString;
 
@@ -4398,7 +4588,8 @@
  */
 
 static char *
-transientCStringFromString(sqInt aString) {
+transientCStringFromString(sqInt aString)
+{
     char *cString;
     sqInt len;
     sqInt newString;
@@ -4426,7 +4617,8 @@
  */
 
 static int
-unixFileNumber(FILEHANDLETYPE fileHandle) {
+unixFileNumber(FILEHANDLETYPE fileHandle)
+{
  return fileno(fileHandle);
 }
 
@@ -4435,13 +4627,14 @@
  errors, which can occur if class InterpreterPlugin has been removed from
  the system.
 
- Important: When this method is changed, the class side method must also
- be changed to match.
+ Important: When this method is changed, the class side method must also be
+ changed to match.
  */
 /* 4.0 supports 64bit code base */
 
 static char *
-versionString(void) {
+versionString(void)
+{
     static char version[]= "4.3.2";
 
  return version;

Added: branches/Cog/src/plugins/Win32OSProcessPlugin/Win32OSProcessPlugin.c
===================================================================
--- branches/Cog/src/plugins/Win32OSProcessPlugin/Win32OSProcessPlugin.c                        (rev 0)
+++ branches/Cog/src/plugins/Win32OSProcessPlugin/Win32OSProcessPlugin.c 2011-06-08 00:36:21 UTC (rev 2394)
@@ -0,0 +1,2265 @@
+/* Automatically generated by
+ VMPluginCodeGenerator VMMaker.oscog-eem.75 uuid: e1bb08e3-482d-4bfd-a416-d203d9fe4c57
+   from
+ Win32OSProcessPlugin * VMConstruction-Plugins-OSProcessPlugin-eem.28 uuid: 9dd4e012-1f25-4946-9b7b-feb93153e08a
+ */
+static char __buildInfo[] = "Win32OSProcessPlugin * VMConstruction-Plugins-OSProcessPlugin-eem.28 uuid: 9dd4e012-1f25-4946-9b7b-feb93153e08a " __DATE__ ;
+
+
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+/* D T Lewis - Win32OSProcessPlugin.c translated from class
+   Win32OSProcessPlugin of OSProcessPlugin version 4.3.2 */
+#include <windows.h>
+#include <process.h>
+
+/* Default EXPORT macro that does nothing (see comment in sq.h): */
+#define EXPORT(returnType) returnType
+
+/* Do not include the entire sq.h file but just those parts needed. */
+/*  The virtual machine proxy definition */
+#include "sqVirtualMachine.h"
+/* Configuration options */
+#include "sqConfig.h"
+/* Platform specific definitions */
+#include "sqPlatformSpecific.h"
+
+#define true 1
+#define false 0
+#define null 0  /* using 'null' because nil is predefined in Think C */
+#ifdef SQUEAK_BUILTIN_PLUGIN
+#undef EXPORT
+// was #undef EXPORT(returnType) but screws NorCroft cc
+#define EXPORT(returnType) static returnType
+#endif
+
+#include "FilePlugin.h"
+#include "SocketPlugin.h"
+#define SESSIONIDENTIFIERTYPE int
+#include "sqWin32.h"
+#define FILEHANDLETYPE HANDLE /* The type of low level stream to be used in a struct SQFile */
+#define READCHARARRAYSIZE 512 /* Corresponds to expected max size of external semaphore table */
+ /* Table expands dynamically, so just use a big number */
+#include "sqMemoryAccess.h"
+
+
+/*** Constants ***/
+
+
+/*** Function Prototypes ***/
+static void * callocWrappersize(sqInt count, sqInt objectSize);
+static sqInt copyBytesFromtolength(void *charArray1, void *charArray2, sqInt len);
+static sqInt createPipeForReaderwriter(FILEHANDLETYPE *readerIOStreamPtr, FILEHANDLETYPE *writerIOStreamPtr);
+static HANDLE createThreadMutex(void);
+static char * cStringFromString(sqInt aString);
+static HANDLE exitThreadMutexHandle(void);
+static FILEHANDLETYPE fileHandleFrom(sqInt sqFileStructByteArray);
+static sqInt fileRecordSize(void);
+static SQFile * fileValueOf(sqInt anSQFileRecord);
+static sqInt fixPointersInArrayOfStringswithOffsetscount(char *flattenedArrayOfStrings, sqInt *offsetArray, sqInt count);
+static VirtualMachine * getInterpreter(void);
+EXPORT(const char*) getModuleName(void);
+static sqInt getThisSessionIdentifier(void);
+static sqInt halt(void);
+static DWORD WINAPI handleAnyChildProc(void *args);
+static HANDLE handleFromSQFile(sqInt anSQFileRecord);
+static HANDLE handleFrom(sqInt aHandleObject);
+static sqInt handleObjectFrom(HANDLE aHandle);
+EXPORT(sqInt) initialiseModule(void);
+static sqInt initializeModuleForPlatform(void);
+static sqInt isNonNullSQFile(sqInt objectPointer);
+static sqInt isNullSQSocket(sqInt objectPointer);
+static sqInt isSQFileObject(sqInt objectPointer);
+static sqInt isSQSocketObject(sqInt objectPointer);
+static sqInt isValidFileSession(sqInt objectPointer);
+static sqInt makePipeForReaderwriter(FILEHANDLETYPE *readerIOStreamPtr, FILEHANDLETYPE *writerIOStreamPtr);
+EXPORT(sqInt) moduleUnloaded(char *aModuleName);
+static sqInt msg(char *s);
+static sqInt newSQFileByteArray(void);
+static sqInt newSQSocketByteArray(void);
+static void * pointerFrom(sqInt aByteArray);
+EXPORT(sqInt) primitiveAllocConsole(void);
+EXPORT(sqInt) primitiveBufferValuesAt(void);
+EXPORT(sqInt) primitiveCanAccessChildProcess(void);
+EXPORT(sqInt) primitiveCloseHandle(void);
+EXPORT(sqInt) primitiveCommand(void);
+EXPORT(sqInt) primitiveCommandWithInputOutputError(void);
+EXPORT(sqInt) primitiveCreatePipe(void);
+EXPORT(sqInt) primitiveCreatePipeWithSessionIdentifier(void);
+EXPORT(sqInt) primitiveFixPointersInArrayOfStrings(void);
+EXPORT(sqInt) primitiveFreeConsole(void);
+EXPORT(sqInt) primitiveGetCurrentWorkingDirectory(void);
+EXPORT(sqInt) primitiveGetEnvironmentStrings(void);
+EXPORT(sqInt) primitiveGetExitStatusForHandle(void);
+EXPORT(sqInt) primitiveGetMainThreadHandle(void);
+EXPORT(sqInt) primitiveGetMainThreadID(void);
+EXPORT(sqInt) primitiveGetPid(void);
+EXPORT(sqInt) primitiveGetPidHandle(void);
+EXPORT(sqInt) primitiveGetSession(void);
+EXPORT(sqInt) primitiveGetStdError(void);
+EXPORT(sqInt) primitiveGetStdInput(void);
+EXPORT(sqInt) primitiveGetStdOutput(void);
+EXPORT(sqInt) primitiveLastReadFor(void);
+EXPORT(sqInt) primitiveLastReadForStoreIn(void);
+EXPORT(sqInt) primitiveMakePipe(void);
+EXPORT(sqInt) primitiveMakePipeWithSessionIdentifier(void);
+EXPORT(sqInt) primitiveModuleName(void);
+EXPORT(sqInt) primitiveNextFromSignaling(void);
+EXPORT(sqInt) primitiveOneShot(void);
+EXPORT(sqInt) primitiveSetStdErr(void);
+EXPORT(sqInt) primitiveSetStdIn(void);
+EXPORT(sqInt) primitiveSetStdOut(void);
+EXPORT(sqInt) primitiveSetWaitForAnyProcessExitThenSignalSemaphoreWithIndex(void);
+EXPORT(sqInt) primitiveSizeOfInt(void);
+EXPORT(sqInt) primitiveSizeOfPointer(void);
+EXPORT(sqInt) primitiveTerminateThread(void);
+EXPORT(sqInt) primitiveVersionString(void);
+static DWORD WINAPI readCharThreadIndexhandle(sqInt index, HANDLE handle);
+static DWORD WINAPI readCharThread(void *args);
+static HANDLE readThreadMutexHandle(void);
+static BOOL releaseThreadMutex(HANDLE aHandle);
+static sqInt sandboxSecurity(void);
+static sqInt securityHeurisitic(void);
+static SESSIONIDENTIFIERTYPE sessionIdentifierFromSqFile(SQFile *sqFile);
+static SESSIONIDENTIFIERTYPE sessionIdentifierFrom(sqInt aByteArray);
+EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
+EXPORT(sqInt) shutdownModule(void);
+static sqInt sizeOfHandle(void);
+static sqInt sizeOfInt(void);
+static sqInt sizeOfPointer(void);
+static sqInt sizeOfSession(void);
+static int socketDescriptorFrom(sqInt sqSocketOop);
+static sqInt socketRecordSize(void);
+static SocketPtr socketValueOf(sqInt anSQSocketRecord);
+static sqInt startHandlerThreadForAnycountsignalingSemaphoreAt(HANDLE *handleArrayPointer, sqInt arraySize, sqInt semaphoreIndex);
+static HANDLE stdErrHandle(void);
+static HANDLE stderrHandle(void);
+static HANDLE stdInHandle(void);
+static HANDLE stdinHandle(void);
+static HANDLE stdOutHandle(void);
+static HANDLE stdoutHandle(void);
+static sqInt stringFromCString(const char *aCString);
+static HANDLE threadMutexHandle(void);
+static char * transientCStringFromString(sqInt aString);
+static char * versionString(void);
+static DWORD waitForThreadMutex(HANDLE aHandle);
+
+
+/*** Variables ***/
+
+#ifdef SQUEAK_BUILTIN_PLUGIN
+extern
+#endif
+struct VirtualMachine* interpreterProxy;
+static const char *moduleName =
+#ifdef SQUEAK_BUILTIN_PLUGIN
+ "Win32OSProcessPlugin * VMConstruction-Plugins-OSProcessPlugin-eem.28 (i)"
+#else
+ "Win32OSProcessPlugin * VMConstruction-Plugins-OSProcessPlugin-eem.28 (e)"
+#endif
+;
+static int osprocessSandboxSecurity;
+static int readCharArraySize = READCHARARRAYSIZE;
+static unsigned char readCharBufferArray[READCHARARRAYSIZE];
+static DWORD readCharCountArray[READCHARARRAYSIZE];
+static int readCharStatusArray[READCHARARRAYSIZE];
+static DWORD readCharThreadIdArray[READCHARARRAYSIZE];
+
+
+
+/* Using malloc() and calloc() is something I would like to avoid, since it
+ is likely to cause problems some time in the future if somebody redesigns
+ object memory allocation. This wrapper just makes it easy to find senders
+ of calloc() in my code. -dtl */
+
+static void *
+callocWrappersize(sqInt count, sqInt objectSize)
+{
+ return calloc(count, objectSize);
+}
+
+
+/* self cCode: 'memcpy(charArray2, charArray1, len' */
+
+static sqInt
+copyBytesFromtolength(void *charArray1, void *charArray2, sqInt len)
+{
+ memcpy(charArray2, charArray1, len);
+}
+
+
+/* Create a pipe and populate the readerIOStream and writerIOStream
+ variables. Answer true for success, else false */
+
+static sqInt
+createPipeForReaderwriter(FILEHANDLETYPE *readerIOStreamPtr, FILEHANDLETYPE *writerIOStreamPtr)
+{
+ return CreatePipe(readerIOStreamPtr, writerIOStreamPtr, NULL, 0);
+}
+
+
+/* Answer a HANDLE for a new mutex semaphore. */
+
+static HANDLE
+createThreadMutex(void)
+{
+ return CreateMutex(NULL, false, NULL);
+}
+
+
+/* Answer a new null-terminated C string copied from aString. The C string
+ is allocated from the C runtime heap. See transientCStringFromString for
+ a version which allocates from object memory.
+ Caution: This may invoke the garbage collector. */
+
+static char *
+cStringFromString(sqInt aString)
+{
+    char *cString;
+    sqInt len;
+    char *sPtr;
+
+ sPtr = interpreterProxy->arrayValueOf(aString);
+ len = interpreterProxy->sizeOfSTArrayFromCPrimitive(sPtr);
+
+ /* Space for a null terminated C string. */
+
+ cString = callocWrappersize(len + 1, 1);
+ (char *) strncpy (cString, sPtr, len);
+ return cString;
+}
+
+
+/* Answer a HANDLE for a mutex semaphore for the child handler thread. */
+
+static HANDLE
+exitThreadMutexHandle(void)
+{
+    static HANDLE h= 0;
+
+ if (h == null) {
+ h = createThreadMutex();
+ }
+ return h;
+}
+
+
+/* Answer a file handle from a SQFile structure. On most platforms, this
+ will be a (FILE *). On Win32, it is a HANDLE. */
+
+static FILEHANDLETYPE
+fileHandleFrom(sqInt sqFileStructByteArray)
+{
+    SQFile *sqFile;
+
+ sqFile = interpreterProxy->arrayValueOf(sqFileStructByteArray);
+ return sqFile->file;
+}
+
+
+/* Answer the size of a SQFile data structure in bytes. */
+
+static sqInt
+fileRecordSize(void)
+{
+ return sizeof(SQFile);
+}
+
+
+/* Return a pointer to the first byte of of the SQFile data structure file
+ record within
+ anSQFileRecord, which is expected to be a ByteArray of size
+ self>>fileRecordSize.
+ */
+
+static SQFile *
+fileValueOf(sqInt anSQFileRecord)
+{
+ return interpreterProxy->arrayValueOf(anSQFileRecord);
+}
+
+
+/* Use the address offsets in offsetArray to fix up the pointers in
+ cStringArray. The result is a C array of pointers to char, used for argv
+ and env vectors.
+ */
+
+static sqInt
+fixPointersInArrayOfStringswithOffsetscount(char *flattenedArrayOfStrings, sqInt *offsetArray, sqInt count)
+{
+    sqInt idx;
+    char **ptr;
+
+ ptr = ((char **) flattenedArrayOfStrings);
+ idx = 0;
+ while (idx < count) {
+ ptr[idx] = (flattenedArrayOfStrings + (((offsetArray[idx]) >> 1)));
+ idx += 1;
+ }
+}
+
+
+/* Note: This is coded so that plugins can be run from Squeak. */
+
+static VirtualMachine *
+getInterpreter(void)
+{
+ return interpreterProxy;
+}
+
+
+/* Note: This is hardcoded so it can be run from Squeak.
+ The module name is used for validating a module *after*
+ it is loaded to check if it does really contain the module
+ we're thinking it contains. This is important! */
+
+EXPORT(const char*)
+getModuleName(void)
+{
+ return moduleName;
+}
+
+static sqInt
+getThisSessionIdentifier(void)
+{
+ return interpreterProxy->getThisSessionID();
+}
+
+static sqInt
+halt(void)
+{
+ ;
+ return 0;
+}
+
+
+/* Wait for a process HANDLE to exit, then signal the Semaphore at index.
+ Answer the exit status of the process. This is the code to be executed in
+ a thread to provide
+ asychronous notification of an external process exit.
+ */
+
+static DWORD WINAPI
+handleAnyChildProc(void *args)
+{
+    HANDLE aHandle;
+    volatile int count;
+    DWORD exitStatus;
+    volatile LPHANDLE handles;
+    volatile int index;
+    struct {int count; HANDLE *handles; int semaIndex;} *threadArgs;
+
+ threadArgs = args;
+ count= threadArgs->count;
+ handles= threadArgs->handles;
+ index= threadArgs->semaIndex;
+ /* begin releaseThreadMutex: */
+ aHandle = exitThreadMutexHandle();
+ ReleaseMutex(aHandle);
+ exitStatus = WaitForMultipleObjects(count, handles, FALSE, INFINITE);
+ interpreterProxy->signalSemaphoreWithIndex(index);
+ return exitStatus;
+}
+
+static HANDLE
+handleFromSQFile(sqInt anSQFileRecord)
+{
+    SQFile *sqFile;
+
+ if (!((interpreterProxy->isBytes(anSQFileRecord))
+ && ((interpreterProxy->stSizeOf(anSQFileRecord)) == (fileRecordSize())))) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ /* begin fileValueOf: */
+ sqFile = interpreterProxy->arrayValueOf(anSQFileRecord);
+ return sqFile->file;
+}
+
+
+/* Answer the HANDLE represented by aHandleObject. */
+
+static HANDLE
+handleFrom(sqInt aHandleObject)
+{
+    union {void *address; unsigned char bytes[sizeof(void *)];} handleUnion;
+    sqInt idx;
+    unsigned char *ptr;
+
+ if (!((interpreterProxy->isBytes(aHandleObject))
+ && ((interpreterProxy->stSizeOf(aHandleObject)) == (sizeOfHandle())))) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ ptr = interpreterProxy->arrayValueOf(aHandleObject);
+ idx = 0;
+ while (idx < (sizeOfHandle())) {
+ handleUnion.bytes[idx] = ptr[idx];
+ idx += 1;
+ }
+ return handleUnion.address;
+}
+
+
+/* Answer an object which contains the value of a HANDLE. */
+
+static sqInt
+handleObjectFrom(HANDLE aHandle)
+{
+    sqInt handleOop;
+    union {HANDLE handle; char bytes[sizeof(HANDLE)];} handleUnion;
+    sqInt idx;
+    unsigned char *ptr;
+    sqInt size;
+
+ handleUnion.handle = aHandle;
+ size = sizeOfHandle();
+ handleOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), size);
+ ptr = interpreterProxy->arrayValueOf(handleOop);
+ idx = 0;
+ while (idx < size) {
+ ptr[idx]= handleUnion.bytes[idx];
+ idx += 1;
+ }
+ return handleOop;
+}
+
+EXPORT(sqInt)
+initialiseModule(void)
+{
+ osprocessSandboxSecurity = -1;
+ /* begin initializeModuleForPlatform */
+ return 1;
+}
+
+
+/* Platform specific initialization */
+
+static sqInt
+initializeModuleForPlatform(void)
+{
+}
+
+
+/* Check for the common failure mode of a SQFile record with all zeros. */
+
+static sqInt
+isNonNullSQFile(sqInt objectPointer)
+{
+    sqInt idx;
+    unsigned char *sqFileBytes;
+
+ sqFileBytes = interpreterProxy->arrayValueOf(objectPointer);
+ idx = 0;
+ while (idx < (fileRecordSize())) {
+ if ((sqFileBytes[idx]) != 0) {
+ return 1;
+ }
+ idx += 1;
+ }
+ return 0;
+}
+
+
+/* Check for the common failure mode of a SQSocket record with all zeros. */
+
+static sqInt
+isNullSQSocket(sqInt objectPointer)
+{
+    sqInt idx;
+    unsigned char *sqSocketBytes;
+
+ sqSocketBytes = interpreterProxy->arrayValueOf(objectPointer);
+ idx = 0;
+ while (idx < (socketRecordSize())) {
+ if ((sqSocketBytes[idx]) != 0) {
+ return 0;
+ }
+ idx += 1;
+ }
+ return 1;
+}
+
+
+/* Answer true if objectPointer appears to be a valid SQFile ByteArray.
+ This check is appropriate if objectPointer has been passed as a parameter
+ to a primitive, and is expected to represent a valid file reference. */
+
+static sqInt
+isSQFileObject(sqInt objectPointer)
+{
+ return (((interpreterProxy->isBytes(objectPointer))
+ && ((interpreterProxy->byteSizeOf(objectPointer)) == (fileRecordSize())))
+ && ((interpreterProxy->getThisSessionID()) == (sessionIdentifierFromSqFile(interpreterProxy->arrayValueOf(objectPointer)))))
+ && (isNonNullSQFile(objectPointer));
+}
+
+
+/* Answer true if objectPointer appears to be a valid SQSocket ByteArray.
+ This check
+ is appropriate if objectPointer has been passed as a parameter to a
+ primitive, and
+ is expected to represent a valid socket reference.
+ */
+
+static sqInt
+isSQSocketObject(sqInt objectPointer)
+{
+ return ((interpreterProxy->isBytes(objectPointer))
+ && ((interpreterProxy->byteSizeOf(objectPointer)) == (socketRecordSize())))
+ && (!(isNullSQSocket(objectPointer)));
+}
+
+
+/* Answer true if the file session matches the current interpreter session
+ identifier.
+ */
+
+static sqInt
+isValidFileSession(sqInt objectPointer)
+{
+ return (interpreterProxy->getThisSessionID()) == (sessionIdentifierFromSqFile(interpreterProxy->arrayValueOf(objectPointer)));
+}
+
+
+/* Create a pipe and populate the readerIOStream and writerIOStream
+ variables. Answer true for success, else false */
+
+static sqInt
+makePipeForReaderwriter(FILEHANDLETYPE *readerIOStreamPtr, FILEHANDLETYPE *writerIOStreamPtr)
+{
+ return CreatePipe(readerIOStreamPtr, writerIOStreamPtr, NULL, 0);
+}
+
+
+/* The module with the given name was just unloaded.
+ Make sure we have no dangling references. */
+
+EXPORT(sqInt)
+moduleUnloaded(char *aModuleName)
+{
+}
+
+static sqInt
+msg(char *s)
+{
+ fprintf(stderr, "\n%s: %s", moduleName, s);
+ return 0;
+}
+
+
+/* Answer a new ByteArray sized to contain a SQFile data structure. */
+
+static sqInt
+newSQFileByteArray(void)
+{
+ return interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+}
+
+
+/* Answer a new ByteArray sized to contain a SQSocket data structure. */
+
+static sqInt
+newSQSocketByteArray(void)
+{
+ return interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), socketRecordSize());
+}
+
+
+/* Answer the pointer represented by aByteArray. */
+
+static void *
+pointerFrom(sqInt aByteArray)
+{
+    sqInt idx;
+    union {void *address; unsigned char bytes[sizeof(void *)];} pointerUnion;
+    unsigned char *ptr;
+
+ if (!((interpreterProxy->isBytes(aByteArray))
+ && ((interpreterProxy->stSizeOf(aByteArray)) == (sizeOfPointer())))) {
+ return null;
+ }
+ ptr = interpreterProxy->arrayValueOf(aByteArray);
+ idx = 0;
+ while (idx < (sizeOfPointer())) {
+ pointerUnion.bytes[idx] = ptr[idx];
+ idx += 1;
+ }
+ return pointerUnion.address;
+}
+
+
+/* Allocate a console if not already allocated. Answer true on success. */
+
+EXPORT(sqInt)
+primitiveAllocConsole(void)
+{
+ if (AllocConsole()) {
+ interpreterProxy->popthenPush(1, interpreterProxy->trueObject());
+ }
+ else {
+ interpreterProxy->popthenPush(1, interpreterProxy->falseObject());
+ }
+}
+
+
+/* For debugging only. Answer the current values of readCharBufferArray,
+ readCharCountArray, and readCharStatusArray at index, an integer
+ corresponding to a semaphore for one read handler thread. Answer an Array
+ with the buffered
+ character, the character count, and the status value.
+ */
+
+EXPORT(sqInt)
+primitiveBufferValuesAt(void)
+{
+    unsigned char byte;
+    DWORD count;
+    sqInt index;
+    sqInt result;
+    int status;
+
+ index = interpreterProxy->stackIntegerValue(0);
+ byte = readCharBufferArray[index];
+ count = readCharCountArray[index];
+ status = readCharStatusArray[index];
+ result = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 3);
+ interpreterProxy->storePointerofObjectwithValue(0, result, interpreterProxy->positive32BitIntegerFor(byte));
+ interpreterProxy->storePointerofObjectwithValue(1, result, interpreterProxy->positive32BitIntegerFor(count));
+ interpreterProxy->storePointerofObjectwithValue(2, result, interpreterProxy->positive32BitIntegerFor(status));
+ interpreterProxy->popthenPush(2, result);
+}
+
+
+/* Answer true if the OS process represented by a HANDLE can be accessed by
+ this OS process.
+ */
+
+EXPORT(sqInt)
+primitiveCanAccessChildProcess(void)
+{
+    DWORD exitStatus;
+    HANDLE handle;
+
+ if (((handle = handleFrom(interpreterProxy->stackObjectValue(0)))) == null) {
+ return null;
+ }
+ if (((GetExitCodeProcess(handle, &exitStatus)) != 0)
+ && (exitStatus == STILL_ACTIVE)) {
+ interpreterProxy->popthenPush(2, interpreterProxy->trueObject());
+ }
+ else {
+ interpreterProxy->popthenPush(2, interpreterProxy->falseObject());
+ }
+}
+
+
+/* Close the specified handle, which may refer to a process, a thread, or
+ some other Win32 object. */
+
+EXPORT(sqInt)
+primitiveCloseHandle(void)
+{
+    HANDLE handle;
+    sqInt handleOop;
+    BOOL result;
+
+ handleOop = interpreterProxy->stackObjectValue(0);
+ if (((handle = handleFrom(handleOop))) == null) {
+ return null;
+ }
+ result = CloseHandle(handle);
+ interpreterProxy->pop(2);
+ if (result != 0) {
+ interpreterProxy->push(interpreterProxy->trueObject());
+ }
+ else {
+ interpreterProxy->push(interpreterProxy->falseObject());
+ }
+}
+
+
+/* Create a process to run commandString. Answer an Array formed from the
+ PROCESS_INFORMATION structure for the new process. The caller is expected
+ to close the process and thread handles when they are no longer needed.
+ The result array contains hProcess, hThread, dwProcessId, dwThreadId.
+
+ This primitive has been replaced by #primitiveCommandWithInputOutputError,
+ and will be removed in future versions of OSProcess.
+ */
+
+EXPORT(sqInt)
+primitiveCommand(void)
+{
+    sqInt commandString;
+    void *cStringPtr;
+    sqInt processInformation;
+    PROCESS_INFORMATION procInfo;
+    STARTUPINFO startUp;
+
+ commandString = interpreterProxy->stackObjectValue(0);
+ cStringPtr = cStringFromString(commandString);
+ GetStartupInfo (&startUp);
+ startUp.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ startUp.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ startUp.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ if (!(CreateProcess(NULL, cStringPtr, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startUp, &procInfo))) {
+ return interpreterProxy->primitiveFail();
+ }
+ interpreterProxy->pushRemappableOop(interpreterProxy->positive32BitIntegerFor(procInfo.dwThreadId));
+ interpreterProxy->pushRemappableOop(interpreterProxy->positive32BitIntegerFor(procInfo.dwProcessId));
+ interpreterProxy->pushRemappableOop(handleObjectFrom(procInfo.hThread));
+ interpreterProxy->pushRemappableOop(handleObjectFrom(procInfo.hProcess));
+ processInformation = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 4);
+ interpreterProxy->storePointerofObjectwithValue(0, processInformation, interpreterProxy->popRemappableOop());
+ interpreterProxy->storePointerofObjectwithValue(1, processInformation, interpreterProxy->popRemappableOop());
+ interpreterProxy->storePointerofObjectwithValue(2, processInformation, interpreterProxy->popRemappableOop());
+ interpreterProxy->storePointerofObjectwithValue(3, processInformation, interpreterProxy->popRemappableOop());
+ interpreterProxy->pop(2);
+ interpreterProxy->push(processInformation);
+}
+
+
+/* Create a process to run commandString, using the specified input, output,
+ and error streams. If any of the input, output, or error streams is nil,
+ then the current values of these handles in this OS process will be passed
+ to the
+ new process. Answer an Array formed from the PROCESS_INFORMATION
+ structure for the new process. The caller is expected to close the process
+ and thread handles when they are no longer needed. The result array
+ contains hProcess, hThread, dwProcessId, dwThreadId.
+ */
+
+EXPORT(sqInt)
+primitiveCommandWithInputOutputError(void)
+{
+    sqInt commandString;
+    void *cStringPtr;
+    HANDLE errorHandle;
+    HANDLE inputHandle;
+    HANDLE outputHandle;
+    sqInt processInformation;
+    PROCESS_INFORMATION procInfo;
+    STARTUPINFO startUp;
+    sqInt stdErr;
+    sqInt stdIn;
+    sqInt stdOut;
+
+ stdErr = interpreterProxy->stackObjectValue(0);
+ stdOut = interpreterProxy->stackObjectValue(1);
+ stdIn = interpreterProxy->stackObjectValue(2);
+ commandString = interpreterProxy->stackObjectValue(3);
+ cStringPtr = cStringFromString(commandString);
+ if (stdIn == (interpreterProxy->nilObject())) {
+ inputHandle = stdInHandle();
+ }
+ else {
+ inputHandle = handleFromSQFile(stdIn);
+ }
+ if (stdOut == (interpreterProxy->nilObject())) {
+ outputHandle = stdOutHandle();
+ }
+ else {
+ outputHandle = handleFromSQFile(stdOut);
+ }
+ if (stdErr == (interpreterProxy->nilObject())) {
+ errorHandle = stdErrHandle();
+ }
+ else {
+ errorHandle = handleFromSQFile(stdErr);
+ }
+ GetStartupInfo (&startUp);
+ startUp.hStdInput = inputHandle;
+ startUp.hStdOutput = outputHandle;
+ startUp.hStdError = errorHandle;
+ if (!(CreateProcess(NULL, cStringPtr, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startUp, &procInfo))) {
+ return interpreterProxy->primitiveFail();
+ }
+ interpreterProxy->pushRemappableOop(interpreterProxy->positive32BitIntegerFor(procInfo.dwThreadId));
+ interpreterProxy->pushRemappableOop(interpreterProxy->positive32BitIntegerFor(procInfo.dwProcessId));
+ interpreterProxy->pushRemappableOop(handleObjectFrom(procInfo.hThread));
+ interpreterProxy->pushRemappableOop(handleObjectFrom(procInfo.hProcess));
+ processInformation = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 4);
+ interpreterProxy->storePointerofObjectwithValue(0, processInformation, interpreterProxy->popRemappableOop());
+ interpreterProxy->storePointerofObjectwithValue(1, processInformation, interpreterProxy->popRemappableOop());
+ interpreterProxy->storePointerofObjectwithValue(2, processInformation, interpreterProxy->popRemappableOop());
+ interpreterProxy->storePointerofObjectwithValue(3, processInformation, interpreterProxy->popRemappableOop());
+ interpreterProxy->pop(5);
+ interpreterProxy->push(processInformation);
+}
+
+
+/* Create a pipe, and answer an array of two file handles for the pipe writer
+ and reader.
+ The readerIOStream and writerIOStream variables represent the low level
+ pipe streams,
+ which will be of type (FILE *) or HANDLE, depending on what the FilePlugin
+ support code is using to represent file streams. FILEHANDLETYPE is defined
+ in my subclasses
+ in the #declareCVarsIn: class method.
+ */
+
+EXPORT(sqInt)
+primitiveCreatePipe(void)
+{
+    sqInt arrayResult;
+    sqInt reader;
+    FILEHANDLETYPE readerIOStream;
+    FILEHANDLETYPE *readerIOStreamPtr;
+    SQFile *readerPtr;
+    SESSIONIDENTIFIERTYPE thisSession;
+    sqInt writer;
+    FILEHANDLETYPE writerIOStream;
+    FILEHANDLETYPE *writerIOStreamPtr;
+    SQFile *writerPtr;
+
+
+ /* Create the anonymous OS pipe */
+
+ thisSession = interpreterProxy->getThisSessionID();
+ readerIOStreamPtr = &readerIOStream;
+ writerIOStreamPtr = &writerIOStream;
+ if (!(createPipeForReaderwriter(readerIOStreamPtr, writerIOStreamPtr))) {
+ return interpreterProxy->primitiveFail();
+ }
+ writer = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+ /* begin fileValueOf: */
+ writerPtr = interpreterProxy->arrayValueOf(writer);
+ writerPtr->file = writerIOStream;
+ writerPtr->sessionID = thisSession;
+ writerPtr->writable = 1;
+ writerPtr->lastOp = 0;
+ interpreterProxy->pushRemappableOop(writer);
+ reader = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+ /* begin fileValueOf: */
+ readerPtr = interpreterProxy->arrayValueOf(reader);
+ readerPtr->file = readerIOStream;
+ readerPtr->sessionID = thisSession;
+ readerPtr->writable = 0;
+ readerPtr->lastOp = 0;
+ interpreterProxy->pushRemappableOop(reader);
+ arrayResult = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 2);
+ interpreterProxy->stObjectatput(arrayResult, 1, interpreterProxy->popRemappableOop());
+ interpreterProxy->stObjectatput(arrayResult, 2, interpreterProxy->popRemappableOop());
+ interpreterProxy->pop(1);
+ interpreterProxy->push(arrayResult);
+}
+
+
+/* Create a pipe, and answer an array of two file handles for the pipe writer
+ and reader.
+ The session identifier is passed as the parameter to this primitive. Use
+ this variant
+ if the session identifier is not available directly in the VM (as may be
+ the case if
+ it is not possible to link from this plugin to a variable elsewhere in the
+ VM). The readerIOStream and writerIOStream variables represent the low
+ level pipe streams,
+ which will be of type (FILE *) or HANDLE, depending on what the FilePlugin
+ support code is using to represent file streams. FILEHANDLETYPE is defined
+ in my subclasses
+ in the #declareCVarsIn: class method.
+ */
+
+EXPORT(sqInt)
+primitiveCreatePipeWithSessionIdentifier(void)
+{
+    sqInt arrayResult;
+    sqInt reader;
+    FILEHANDLETYPE readerIOStream;
+    FILEHANDLETYPE *readerIOStreamPtr;
+    SQFile *readerPtr;
+    SESSIONIDENTIFIERTYPE thisSession;
+    sqInt writer;
+    FILEHANDLETYPE writerIOStream;
+    FILEHANDLETYPE *writerIOStreamPtr;
+    SQFile *writerPtr;
+
+
+ /* Create the anonymous OS pipe */
+
+ thisSession = sessionIdentifierFrom(interpreterProxy->stackObjectValue(0));
+ readerIOStreamPtr = &readerIOStream;
+ writerIOStreamPtr = &writerIOStream;
+ if (!(createPipeForReaderwriter(readerIOStreamPtr, writerIOStreamPtr))) {
+ return interpreterProxy->primitiveFail();
+ }
+ writer = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+ /* begin fileValueOf: */
+ writerPtr = interpreterProxy->arrayValueOf(writer);
+ writerPtr->file = writerIOStream;
+ writerPtr->sessionID = thisSession;
+ writerPtr->writable = 1;
+ writerPtr->lastOp = 0;
+ interpreterProxy->pushRemappableOop(writer);
+ reader = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+ /* begin fileValueOf: */
+ readerPtr = interpreterProxy->arrayValueOf(reader);
+ readerPtr->file = readerIOStream;
+ readerPtr->sessionID = thisSession;
+ readerPtr->writable = 0;
+ readerPtr->lastOp = 0;
+ interpreterProxy->pushRemappableOop(reader);
+ arrayResult = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 2);
+ interpreterProxy->stObjectatput(arrayResult, 1, interpreterProxy->popRemappableOop());
+ interpreterProxy->stObjectatput(arrayResult, 2, interpreterProxy->popRemappableOop());
+ interpreterProxy->pop(2);
+ interpreterProxy->push(arrayResult);
+}
+
+
+/* This primitive exists only for purposes of testing the
+ fixPointersInArrayOfStrings:withOffsets:count: method. I believe it to be
+ reasonably machine and compiler independent, but have no way of verifying
+ this on a variety of machines, so I'll leave this test method here in case
+ someone runs into problems on other hardware or compilers. -dtl */
+
+EXPORT(sqInt)
+primitiveFixPointersInArrayOfStrings(void)
+{
+    sqInt count;
+    sqInt cStringArray;
+    char *flattenedArrayOfStrings;
+    sqInt idx;
+    sqInt offsetArray;
+    sqInt *offsets;
+    char **ptr;
+
+ count = interpreterProxy->stackIntegerValue(0);
+ offsetArray = interpreterProxy->stackObjectValue(1);
+ cStringArray = interpreterProxy->stackObjectValue(2);
+ offsets = interpreterProxy->firstIndexableField(offsetArray);
+ flattenedArrayOfStrings = interpreterProxy->arrayValueOf(cStringArray);
+ /* begin fixPointersInArrayOfStrings:withOffsets:count: */
+ ptr = ((char **) flattenedArrayOfStrings);
+ idx = 0;
+ while (idx < count) {
+ ptr[idx] = (flattenedArrayOfStrings + (((offsets[idx]) >> 1)));
+ idx += 1;
+ }
+ interpreterProxy->pop(4);
+ interpreterProxy->push(cStringArray);
+}
+
+
+/* Deallocate the console if allocated. Answer true on success. */
+
+EXPORT(sqInt)
+primitiveFreeConsole(void)
+{
+ if (FreeConsole()) {
+ interpreterProxy->popthenPush(1, interpreterProxy->trueObject());
+ }
+ else {
+ interpreterProxy->popthenPush(1, interpreterProxy->falseObject());
+ }
+}
+
+
+/* Answer a string containing the current working directory. */
+
+EXPORT(sqInt)
+primitiveGetCurrentWorkingDirectory(void)
+{
+    char *buffer;
+    sqInt charSize;
+    DWORD cwdLen;
+    sqInt cwdString;
+    DWORD requiredLen;
+
+
+ /* Allocate a dummy buffer buffer with no space (force a failure to GetCurrentDirectory) */
+
+ charSize = sizeof(TCHAR);
+ cwdString = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), 0);
+
+ /* Determine required size of result buffer */
+
+ buffer = interpreterProxy->arrayValueOf(cwdString);
+ requiredLen = GetCurrentDirectory(0, buffer);
+ if (requiredLen == 0) {
+ return interpreterProxy->primitiveFail();
+ }
+ cwdString = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), requiredLen * charSize);
+
+ /* Call GetCurrentDirectory() again to get the actual result */
+
+ buffer = interpreterProxy->arrayValueOf(cwdString);
+ cwdLen = GetCurrentDirectory(requiredLen, buffer);
+ if (cwdLen == 0) {
+ return interpreterProxy->primitiveFail();
+ }
+ if (cwdLen > requiredLen) {
+ return interpreterProxy->primitiveFail();
+ }
+ interpreterProxy->pop(1);
+ interpreterProxy->push(cwdString);
+}
+
+
+/* Answer the environment block in the form of an Array of Strings. The
+ caller is expected to parse the strings into a dictionary of keys and
+ values.
+ */
+
+EXPORT(sqInt)
+primitiveGetEnvironmentStrings(void)
+{
+    sqInt count;
+    sqInt envArray;
+    sqInt len;
+    sqInt newString;
+    TCHAR *p;
+    TCHAR *pVarBlock;
+    sqInt string;
+
+
+ /* Count the environment strings so the result array can be pre-allocated.
+ This minimizes the number of objects which must be pushed onto the
+ stack of remappable objects. */
+
+ pVarBlock = GetEnvironmentStrings();
+ p = pVarBlock;
+ count = 0;
+ while (*p != 0) {
+ count += 1;
+ while (*p != 0) {
+ p += 1;
+ }
+ p += 1;
+ }
+
+ /* Populate the array. */
+
+ envArray = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), count);
+ p = pVarBlock;
+ count = 0;
+ while (*p != 0) {
+ count += 1;
+ interpreterProxy->pushRemappableOop(envArray);
+ /* begin stringFromCString: */
+ len = strlen(p);
+ newString = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), len);
+ strncpy(interpreterProxy->arrayValueOf(newString), p, len);
+ string = newString;
+ envArray = interpreterProxy->popRemappableOop();
+ interpreterProxy->stObjectatput(envArray, count, string);
+ while (*p != 0) {
+ p += 1;
+ }
+ p += 1;
+ }
+ FreeEnvironmentStrings(pVarBlock);
+ interpreterProxy->popthenPush(1, envArray);
+}
+
+
+/* Answer the exit status for the process represented by a HANDLE. Fail if
+ the process is still active, or if the GetExitCodeProcess call fails. */
+
+EXPORT(sqInt)
+primitiveGetExitStatusForHandle(void)
+{
+    DWORD exitStatus;
+    HANDLE handle;
+
+ if (((handle = handleFrom(interpreterProxy->stackObjectValue(0)))) == null) {
+ return null;
+ }
+ if ((GetExitCodeProcess(handle, &exitStatus)) != 0) {
+ if (exitStatus == STILL_ACTIVE) {
+ return interpreterProxy->primitiveFail();
+ }
+ interpreterProxy->popthenPush(2, interpreterProxy->positive32BitIntegerFor(exitStatus));
+ }
+ else {
+ return interpreterProxy->primitiveFail();
+ }
+}
+
+
+/* Answer the ID of my main thread. */
+
+EXPORT(sqInt)
+primitiveGetMainThreadHandle(void)
+{
+    HANDLE handle;
+    sqInt handleOop;
+
+ handle = GetCurrentThread();
+ handleOop = handleObjectFrom(handle);
+ interpreterProxy->popthenPush(1, handleOop);
+}
+
+
+/* Answer the ID of my main thread. */
+
+EXPORT(sqInt)
+primitiveGetMainThreadID(void)
+{
+    DWORD tid;
+    sqInt tidOop;
+
+ tid = GetCurrentThreadId();
+ tidOop = interpreterProxy->positive32BitIntegerFor(tid);
+ interpreterProxy->popthenPush(1, tidOop);
+}
+
+
+/* Answer the process ID of my OS process */
+
+EXPORT(sqInt)
+primitiveGetPid(void)
+{
+    DWORD pid;
+    sqInt pidOop;
+
+ pid = GetCurrentProcessId();
+ pidOop = interpreterProxy->positive32BitIntegerFor(pid);
+ interpreterProxy->popthenPush(1, pidOop);
+}
+
+
+/* Answer the handle for my OS process */
+
+EXPORT(sqInt)
+primitiveGetPidHandle(void)
+{
+    HANDLE handle;
+    sqInt handleOop;
+
+ handle = GetCurrentProcess();
+ handleOop = handleObjectFrom(handle);
+ interpreterProxy->popthenPush(1, handleOop);
+}
+
+
+/* Answer the unique session identifier for this Smalltalk instance running
+ in this
+ OS process. The C integer value is coerced into a Smalltalk ByteArray to
+ preserve the full range of possible values.
+ */
+
+EXPORT(sqInt)
+primitiveGetSession(void)
+{
+    void *charArray1;
+    unsigned char *sessionByteArrayPointer;
+    sqInt sessionIDSize;
+    sqInt sessionOop;
+    SESSIONIDENTIFIERTYPE thisSessionID;
+
+ thisSessionID = interpreterProxy->getThisSessionID();
+ sessionIDSize = sizeof(thisSessionID);
+ sessionOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), sessionIDSize);
+ sessionByteArrayPointer = interpreterProxy->arrayValueOf(sessionOop);
+ if (thisSessionID == null) {
+ return interpreterProxy->primitiveFail();
+ }
+ /* begin copyBytesFrom:to:length: */
+ charArray1 = (unsigned char *)&thisSessionID;
+ memcpy(sessionByteArrayPointer, charArray1, sessionIDSize);
+ interpreterProxy->pop(1);
+ interpreterProxy->push(sessionOop);
+}
+
+
+/* Answer a two element array containing the sqFile data structure
+ representing standard error stream for my OS process, and a flag (true or
+ false) to indicate
+ whether the sqFile data structure contains a valid HANDLE. If no standard
+ error stream is available for this OS process, the sqFile data structure
+ will contain an
+ invalid HANDLE value, which will result in failures on subsequent
+ accesses.
+ */
+
+EXPORT(sqInt)
+primitiveGetStdError(void)
+{
+    SQFile *file;
+    sqInt fileOop;
+    HANDLE handle;
+    HANDLE invalid;
+    sqInt result;
+    sqInt thisSession;
+
+ thisSession = sessionIdentifierFrom(interpreterProxy->stackObjectValue(0));
+ invalid = INVALID_HANDLE_VALUE;
+ result = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 2);
+ fileOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+ /* begin fileValueOf: */
+ file = interpreterProxy->arrayValueOf(fileOop);
+ handle = GetStdHandle(STD_ERROR_HANDLE);
+ if (handle != invalid) {
+ interpreterProxy->stObjectatput(result, 2, interpreterProxy->trueObject());
+ }
+ else {
+ interpreterProxy->stObjectatput(result, 2, interpreterProxy->falseObject());
+ }
+ file->file = handle;
+ file->sessionID = thisSession;
+ file->writable = 1;
+ file->lastOp = 0;
+ interpreterProxy->stObjectatput(result, 1, fileOop);
+ interpreterProxy->pop(2);
+ interpreterProxy->push(result);
+}
+
+
+/* Answer a two element array containing the sqFile data structure
+ representing standard input stream for my OS process, and a flag (true or
+ false) to indicate
+ whether the sqFile data structure contains a valid HANDLE. If no standard
+ input stream is available for this OS process, the sqFile data structure
+ will contain an
+ invalid HANDLE value, which will result in failures on subsequent
+ accesses.
+ */
+
+EXPORT(sqInt)
+primitiveGetStdInput(void)
+{
+    SQFile *file;
+    sqInt fileOop;
+    HANDLE handle;
+    HANDLE invalid;
+    sqInt result;
+    sqInt thisSession;
+
+ thisSession = sessionIdentifierFrom(interpreterProxy->stackObjectValue(0));
+ invalid = INVALID_HANDLE_VALUE;
+ result = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 2);
+ fileOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+ /* begin fileValueOf: */
+ file = interpreterProxy->arrayValueOf(fileOop);
+ handle = GetStdHandle(STD_INPUT_HANDLE);
+ if (handle != invalid) {
+ interpreterProxy->stObjectatput(result, 2, interpreterProxy->trueObject());
+ }
+ else {
+ interpreterProxy->stObjectatput(result, 2, interpreterProxy->falseObject());
+ }
+ file->file = handle;
+ file->sessionID = thisSession;
+ file->writable = 0;
+ file->lastOp = 0;
+ interpreterProxy->stObjectatput(result, 1, fileOop);
+ interpreterProxy->pop(2);
+ interpreterProxy->push(result);
+}
+
+
+/* Answer a two element array containing the sqFile data structure
+ representing standard output stream for my OS process, and a flag (true or
+ false) to indicate
+ whether the sqFile data structure contains a valid HANDLE. If no standard
+ output stream is available for this OS process, the sqFile data structure
+ will contain an
+ invalid HANDLE value, which will result in failures on subsequent
+ accesses.
+ */
+
+EXPORT(sqInt)
+primitiveGetStdOutput(void)
+{
+    SQFile *file;
+    sqInt fileOop;
+    HANDLE handle;
+    HANDLE invalid;
+    sqInt result;
+    sqInt thisSession;
+
+ thisSession = sessionIdentifierFrom(interpreterProxy->stackObjectValue(0));
+ invalid = INVALID_HANDLE_VALUE;
+ result = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 2);
+ fileOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+ /* begin fileValueOf: */
+ file = interpreterProxy->arrayValueOf(fileOop);
+ handle = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (handle != invalid) {
+ interpreterProxy->stObjectatput(result, 2, interpreterProxy->trueObject());
+ }
+ else {
+ interpreterProxy->stObjectatput(result, 2, interpreterProxy->falseObject());
+ }
+ file->file = handle;
+ file->sessionID = thisSession;
+ file->writable = 1;
+ file->lastOp = 0;
+ interpreterProxy->stObjectatput(result, 1, fileOop);
+ interpreterProxy->pop(2);
+ interpreterProxy->push(result);
+}
+
+
+/* A character has been read into an external buffer corresponding to
+ aSemaphoreIndex, and is now available. Answer the integer value of the
+ character, or nil if no character
+ was read, or -1 if an error occurred on the read.
+ */
+
+EXPORT(sqInt)
+primitiveLastReadFor(void)
+{
+    sqInt index;
+    sqInt result;
+
+ index = interpreterProxy->stackIntegerValue(0);
+ if (readCharStatusArray[index]) {
+ if ((readCharCountArray[index]) < 1) {
+ result = interpreterProxy->nilObject();
+ }
+ else {
+ result = (((readCharBufferArray[index]) << 1) | 1);
+ }
+ }
+ else {
+ result = ((-1 << 1) | 1);
+ }
+ interpreterProxy->popthenPush(2, result);
+}
+
+
+/* A character has been read into an external buffer corresponding to
+ aSemaphoreIndex, and is now available. Answer the integer value of the
+ character, or nil if no character
+ was read, or -1 if an error occurred on the read. Store the full results
+ of the most
+ recent read into a three element array provided by the sender. Contents of
+ the array
+ will be status of the read call, character read, and character count
+ (which should
+ always be 1).
+ */
+
+EXPORT(sqInt)
+primitiveLastReadForStoreIn(void)
+{
+    sqInt index;
+    sqInt result;
+    sqInt resultArray;
+
+ index = interpreterProxy->stackIntegerValue(1);
+ resultArray = interpreterProxy->stackValue(0);
+ interpreterProxy->stObjectatput(resultArray, 1, interpreterProxy->positive32BitIntegerFor(readCharStatusArray[index]));
+ interpreterProxy->stObjectatput(resultArray, 2, (((readCharBufferArray[index]) << 1) | 1));
+ interpreterProxy->stObjectatput(resultArray, 3, (((readCharCountArray[index]) << 1) | 1));
+ if (readCharStatusArray[index]) {
+ if ((readCharCountArray[index]) < 1) {
+ result = interpreterProxy->nilObject();
+ }
+ else {
+ result = (((readCharBufferArray[index]) << 1) | 1);
+ }
+ }
+ else {
+ result = ((-1 << 1) | 1);
+ }
+ interpreterProxy->popthenPush(3, result);
+}
+
+
+/* Create a pipe, and answer an array of two file handles for the pipe writer
+ and reader.
+ The readerIOStream and writerIOStream variables represent the low level
+ pipe streams,
+ which will be of type (FILE *) or HANDLE, depending on what the FilePlugin
+ support code is using to represent file streams. FILEHANDLETYPE is defined
+ in my subclasses
+ in the #declareCVarsIn: class method.
+ */
+
+EXPORT(sqInt)
+primitiveMakePipe(void)
+{
+    sqInt arrayResult;
+    sqInt reader;
+    FILEHANDLETYPE readerIOStream;
+    FILEHANDLETYPE *readerIOStreamPtr;
+    SQFile *readerPtr;
+    SESSIONIDENTIFIERTYPE thisSession;
+    sqInt writer;
+    FILEHANDLETYPE writerIOStream;
+    FILEHANDLETYPE *writerIOStreamPtr;
+    SQFile *writerPtr;
+
+
+ /* Create the anonymous OS pipe */
+
+ thisSession = interpreterProxy->getThisSessionID();
+ readerIOStreamPtr = &readerIOStream;
+ writerIOStreamPtr = &writerIOStream;
+ if (!(makePipeForReaderwriter(readerIOStreamPtr, writerIOStreamPtr))) {
+ return interpreterProxy->primitiveFail();
+ }
+ writer = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+ /* begin fileValueOf: */
+ writerPtr = interpreterProxy->arrayValueOf(writer);
+ writerPtr->file = writerIOStream;
+ writerPtr->sessionID = thisSession;
+ writerPtr->writable = 1;
+ writerPtr->lastOp = 0;
+ interpreterProxy->pushRemappableOop(writer);
+ reader = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+ /* begin fileValueOf: */
+ readerPtr = interpreterProxy->arrayValueOf(reader);
+ readerPtr->file = readerIOStream;
+ readerPtr->sessionID = thisSession;
+ readerPtr->writable = 0;
+ readerPtr->lastOp = 0;
+ interpreterProxy->pushRemappableOop(reader);
+ arrayResult = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 2);
+ interpreterProxy->stObjectatput(arrayResult, 1, interpreterProxy->popRemappableOop());
+ interpreterProxy->stObjectatput(arrayResult, 2, interpreterProxy->popRemappableOop());
+ interpreterProxy->pop(1);
+ interpreterProxy->push(arrayResult);
+}
+
+
+/* Create a pipe, and answer an array of two file handles for the pipe writer
+ and reader.
+ The session identifier is passed as the parameter to this primitive. Use
+ this variant
+ if the session identifier is not available directly in the VM (as may be
+ the case if
+ it is not possible to link from this plugin to a variable elsewhere in the
+ VM). The readerIOStream and writerIOStream variables represent the low
+ level pipe streams,
+ which will be of type (FILE *) or HANDLE, depending on what the FilePlugin
+ support code is using to represent file streams. FILEHANDLETYPE is defined
+ in my subclasses
+ in the #declareCVarsIn: class method.
+ */
+
+EXPORT(sqInt)
+primitiveMakePipeWithSessionIdentifier(void)
+{
+    sqInt arrayResult;
+    sqInt reader;
+    FILEHANDLETYPE readerIOStream;
+    FILEHANDLETYPE *readerIOStreamPtr;
+    SQFile *readerPtr;
+    SESSIONIDENTIFIERTYPE thisSession;
+    sqInt writer;
+    FILEHANDLETYPE writerIOStream;
+    FILEHANDLETYPE *writerIOStreamPtr;
+    SQFile *writerPtr;
+
+
+ /* Create the anonymous OS pipe */
+
+ thisSession = sessionIdentifierFrom(interpreterProxy->stackObjectValue(0));
+ readerIOStreamPtr = &readerIOStream;
+ writerIOStreamPtr = &writerIOStream;
+ if (!(makePipeForReaderwriter(readerIOStreamPtr, writerIOStreamPtr))) {
+ return interpreterProxy->primitiveFail();
+ }
+ writer = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+ /* begin fileValueOf: */
+ writerPtr = interpreterProxy->arrayValueOf(writer);
+ writerPtr->file = writerIOStream;
+ writerPtr->sessionID = thisSession;
+ writerPtr->writable = 1;
+ writerPtr->lastOp = 0;
+ interpreterProxy->pushRemappableOop(writer);
+ reader = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), fileRecordSize());
+ /* begin fileValueOf: */
+ readerPtr = interpreterProxy->arrayValueOf(reader);
+ readerPtr->file = readerIOStream;
+ readerPtr->sessionID = thisSession;
+ readerPtr->writable = 0;
+ readerPtr->lastOp = 0;
+ interpreterProxy->pushRemappableOop(reader);
+ arrayResult = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 2);
+ interpreterProxy->stObjectatput(arrayResult, 1, interpreterProxy->popRemappableOop());
+ interpreterProxy->stObjectatput(arrayResult, 2, interpreterProxy->popRemappableOop());
+ interpreterProxy->pop(2);
+ interpreterProxy->push(arrayResult);
+}
+
+
+/* Answer a string containing the module name string for this plugin. */
+
+EXPORT(sqInt)
+primitiveModuleName(void)
+{
+ interpreterProxy->popthenPush(1, stringFromCString(getModuleName()));
+}
+
+
+/* Read the next character from anIOHandle (a SQFile struct) into a buffer in
+ the VM. When
+ the read completes, signal the specified Semaphore to notify that the
+ character is available.
+ Answer the handle of the new thread, or nil on error.
+ */
+
+EXPORT(sqInt)
+primitiveNextFromSignaling(void)
+{
+    HANDLE handle;
+    HANDLE hThread;
+    static int index;
+    static struct {int index; HANDLE handle;} threadArgs;
+    DWORD threadID;
+
+ index = interpreterProxy->stackIntegerValue(0);
+ if (index >= readCharArraySize) {
+ return interpreterProxy->primitiveFail();
+ }
+ waitForThreadMutex(readThreadMutexHandle());
+ handle = handleFromSQFile(interpreterProxy->stackObjectValue(1));
+ if (handle == null) {
+ return null;
+ }
+ readCharBufferArray[index] = 0;
+ readCharCountArray[index] = 0;
+ readCharStatusArray[index] = 0;
+ threadArgs.index = index;
+ threadArgs.handle = handle;
+
+#if !defined(STACK_SIZE_PARAM_IS_A_RESERVATION)
+
+#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x10000
+
+#endif
+
+ /* Safety net: Remember the identity of the thread which should be active for this
+ semaphore index. */
+
+ hThread = CreateThread(NULL, 1024, readCharThread, &threadArgs, STACK_SIZE_PARAM_IS_A_RESERVATION, &threadID);
+ readCharThreadIdArray[index] = threadID;
+ if (hThread == null) {
+ return interpreterProxy->nilObject();
+ }
+ interpreterProxy->popthenPush(3, handleObjectFrom(hThread));
+}
+
+
+/* Anwer true the first time this primitive is called in a Squeak session,
+ and false thereafter.
+ */
+
+EXPORT(sqInt)
+primitiveOneShot(void)
+{
+    static int thisPrimHasBeenCalled= 0;
+
+ if (thisPrimHasBeenCalled == 0) {
+ thisPrimHasBeenCalled = 1;
+ interpreterProxy->popthenPush(1, interpreterProxy->trueObject());
+ }
+ else {
+ interpreterProxy->popthenPush(1, interpreterProxy->falseObject());
+ }
+}
+
+
+/* Set the file handle for standard error of my OS process to the handle
+ passed in a SQFile struct.
+ */
+
+EXPORT(sqInt)
+primitiveSetStdErr(void)
+{
+    FILEHANDLETYPE handle;
+    sqInt sqFileOop;
+
+ sqFileOop = interpreterProxy->stackValue(0);
+ if (!((((interpreterProxy->isBytes(sqFileOop))
+ && ((interpreterProxy->byteSizeOf(sqFileOop)) == (fileRecordSize())))
+ && ((interpreterProxy->getThisSessionID()) == (sessionIdentifierFromSqFile(interpreterProxy->arrayValueOf(sqFileOop)))))
+ && (isNonNullSQFile(sqFileOop)))) {
+ return interpreterProxy->primitiveFail();
+ }
+ handle = fileHandleFrom(sqFileOop);
+ if (SetStdHandle(STD_ERROR_HANDLE, handle)) {
+ interpreterProxy->popthenPush(2, interpreterProxy->trueObject());
+ }
+ else {
+ interpreterProxy->popthenPush(2, interpreterProxy->falseObject());
+ }
+}
+
+
+/* Set the file handle for standard input of my OS process to the handle
+ passed in a SQFile struct.
+ */
+
+EXPORT(sqInt)
+primitiveSetStdIn(void)
+{
+    FILEHANDLETYPE handle;
+    sqInt sqFileOop;
+
+ sqFileOop = interpreterProxy->stackValue(0);
+ if (!((((interpreterProxy->isBytes(sqFileOop))
+ && ((interpreterProxy->byteSizeOf(sqFileOop)) == (fileRecordSize())))
+ && ((interpreterProxy->getThisSessionID()) == (sessionIdentifierFromSqFile(interpreterProxy->arrayValueOf(sqFileOop)))))
+ && (isNonNullSQFile(sqFileOop)))) {
+ return interpreterProxy->primitiveFail();
+ }
+ handle = fileHandleFrom(sqFileOop);
+ if (SetStdHandle(STD_INPUT_HANDLE, handle)) {
+ interpreterProxy->popthenPush(2, interpreterProxy->trueObject());
+ }
+ else {
+ interpreterProxy->popthenPush(2, interpreterProxy->falseObject());
+ }
+}
+
+
+/* Set the file handle for standard output of my OS process to the handle
+ passed in a SQFile struct.
+ */
+
+EXPORT(sqInt)
+primitiveSetStdOut(void)
+{
+    FILEHANDLETYPE handle;
+    sqInt sqFileOop;
+
+ sqFileOop = interpreterProxy->stackValue(0);
+ if (!((((interpreterProxy->isBytes(sqFileOop))
+ && ((interpreterProxy->byteSizeOf(sqFileOop)) == (fileRecordSize())))
+ && ((interpreterProxy->getThisSessionID()) == (sessionIdentifierFromSqFile(interpreterProxy->arrayValueOf(sqFileOop)))))
+ && (isNonNullSQFile(sqFileOop)))) {
+ return interpreterProxy->primitiveFail();
+ }
+ handle = fileHandleFrom(sqFileOop);
+ if (SetStdHandle(STD_OUTPUT_HANDLE, handle)) {
+ interpreterProxy->popthenPush(2, interpreterProxy->trueObject());
+ }
+ else {
+ interpreterProxy->popthenPush(2, interpreterProxy->falseObject());
+ }
+}
+
+
+/* Set up a thread to wait for a process HANDLE to exit, then signal the
+ Semaphore at index. This provides asychronous notification of an external
+ process exit. Answer
+ the handle of the handler thread.
+ */
+
+EXPORT(sqInt)
+primitiveSetWaitForAnyProcessExitThenSignalSemaphoreWithIndex(void)
+{
+    sqInt arraySize;
+    static HANDLE handleArray[MAXIMUM_WAIT_OBJECTS];
+    sqInt handleArrayOop;
+    unsigned int *handleArrayOopPtr;
+    static HANDLE *handleArrayPtr;
+    sqInt handleCount;
+    sqInt idx;
+    sqInt semaIndex;
+    sqInt threadInformation;
+
+ semaIndex = interpreterProxy->stackIntegerValue(0);
+ handleArrayOop = interpreterProxy->stackObjectValue(1);
+ handleArrayOopPtr = interpreterProxy->firstIndexableField(handleArrayOop);
+ handleCount = interpreterProxy->stSizeOf(handleArrayOop);
+ arraySize = MAXIMUM_WAIT_OBJECTS;
+ if (handleCount > arraySize) {
+ return interpreterProxy->primitiveFail();
+ }
+ idx = 0;
+ while (idx < handleCount) {
+ handleArray[idx] = (handleFrom(handleArrayOopPtr[idx]));
+ idx += 1;
+ }
+ handleArrayPtr = handleArray;
+ threadInformation = startHandlerThreadForAnycountsignalingSemaphoreAt(handleArrayPtr, handleCount, semaIndex);
+ interpreterProxy->popthenPush(3, threadInformation);
+}
+
+
+/* Size in bytes of an integer, for this C compiler on this machine. */
+
+EXPORT(sqInt)
+primitiveSizeOfInt(void)
+{
+ interpreterProxy->pop(1);
+ interpreterProxy->pushInteger(sizeOfInt());
+}
+
+
+/* Size in bytes of a void pointer, for this C compiler on this machine. */
+
+EXPORT(sqInt)
+primitiveSizeOfPointer(void)
+{
+ interpreterProxy->pop(1);
+ interpreterProxy->pushInteger(sizeOfPointer());
+}
+
+
+/* Kill the thread. No cleanup is performed, so use with caution for a thread
+ which is (for example) manipulating a mutex. Answer true for success, else
+ false.
+ */
+
+EXPORT(sqInt)
+primitiveTerminateThread(void)
+{
+    HANDLE handle;
+
+ if (((handle = handleFrom(interpreterProxy->stackObjectValue(0)))) == null) {
+ return null;
+ }
+ if (TerminateThread(handle, 0)) {
+ return interpreterProxy->popthenPush(2, interpreterProxy->trueObject());
+ }
+ else {
+ return interpreterProxy->popthenPush(2, interpreterProxy->falseObject());
+ }
+}
+
+
+/* Answer a string containing the version string for this plugin. */
+
+EXPORT(sqInt)
+primitiveVersionString(void)
+{
+ interpreterProxy->pop(1);
+ interpreterProxy->push(stringFromCString(versionString()));
+}
+
+
+/* This is the thread procedure for reading one character from a file or pipe
+ handle. The values of index and handle have been passed on the local
+ thread stack, so they are now local to the thread which is executing this
+ method. Once the values are safely on a local thread stack, the mutex
+ semaphore is released, allowing other threads to be created. */
+
+static DWORD WINAPI
+readCharThreadIndexhandle(sqInt index, HANDLE handle)
+{
+    HANDLE aHandle;
+    sqInt status;
+
+ /* begin releaseThreadMutex: */
+ aHandle = readThreadMutexHandle();
+ ReleaseMutex(aHandle);
+ status = ReadFile(handle, &readCharBufferArray[index], 1, &readCharCountArray[index], NULL);
+ readCharStatusArray[index] = status;
+ if ((GetCurrentThreadId()) == (readCharThreadIdArray[index])) {
+ interpreterProxy->signalSemaphoreWithIndex(index);
+ }
+ else {
+ readCharBufferArray[index] = 0;
+ readCharCountArray[index] = 0;
+ readCharStatusArray[index] = 0;
+ }
+ return status;
+}
+
+
+/* This is the entry point for the thread procedure for reading one character
+ from a file or pipe handle. There may be many instances of this thread
+ procedure, in
+ which case each thread may be distinguished by the index value with which
+ it is
+ called. Remember the index value by saving it in a variable on the thread
+ stack. Read one character, and signal a Smalltalk Semaphore to indicate
+ completion.
+ */
+
+static DWORD WINAPI
+readCharThread(void *args)
+{
+    HANDLE handle;
+    sqInt index;
+    struct {int index; HANDLE handle;} *threadArgs;
+
+ threadArgs = args;
+ index = threadArgs->index;
+ handle = threadArgs->handle;
+ return readCharThreadIndexhandle(index, handle);
+}
+
+
+/* Answer a HANDLE for a mutex semaphore for sychronizing setup of read
+ threads.
+ */
+
+static HANDLE
+readThreadMutexHandle(void)
+{
+    static HANDLE h= 0;
+
+ if (h == null) {
+ h = createThreadMutex();
+ }
+ return h;
+}
+
+
+/* To be called at the end of a critical section. */
+
+static BOOL
+releaseThreadMutex(HANDLE aHandle)
+{
+ return ReleaseMutex(aHandle);
+}
+
+
+/* Answer 1 if running in secure mode, else 0. The osprocessSandboxSecurity
+ variable is initialized to -1. On the first call to this method, set its
+ value to
+ either 0 (user has full access to the plugin) or 1 (user is not permitted
+ to do
+ dangerous things).
+ */
+
+static sqInt
+sandboxSecurity(void)
+{
+ if (osprocessSandboxSecurity < 0) {
+ osprocessSandboxSecurity = securityHeurisitic();
+ }
+ return osprocessSandboxSecurity;
+}
+
+
+/* Answer 0 to permit full access to OSProcess functions, or 1 if access
+ should be
+ restricted for dangerous functions. The rules are:
+ - If the security plugin is not present, grant full access
+ - If the security plugin can be loaded, restrict access unless user has
+ all of secCanWriteImage, secHasFileAccess and secHasSocketAccess */
+/* FIXME: This function has not been tested. -dtl */
+/* If the security plugin can be loaded, use it to check. If not, assume it's
+ ok
+ */
+
+static sqInt
+securityHeurisitic(void)
+{
+    sqInt canWriteImage;
+    sqInt hasFileAccess;
+    sqInt hasSocketAccess;
+    void (*sCWIfn)(void);
+    void (*sHFAfn)(void);
+    void (*sHSAfn)(void);
+
+ sCWIfn = interpreterProxy->ioLoadFunctionFrom("secCanWriteImage", "SecurityPlugin");
+ if (sCWIfn == 0) {
+ return 0;
+ }
+ canWriteImage =  ((int (*) (void)) sCWIfn)();
+ sHFAfn = interpreterProxy->ioLoadFunctionFrom("secHasFileAccess", "SecurityPlugin");
+ if (sHFAfn == 0) {
+ return 0;
+ }
+ hasFileAccess =  ((int (*) (void)) sHFAfn)();
+ sHSAfn = interpreterProxy->ioLoadFunctionFrom("secHasSocketAccess", "SecurityPlugin");
+ if (sHSAfn == 0) {
+ return 0;
+ }
+ hasSocketAccess =  ((int (*) (void)) sHSAfn)();
+ if ((canWriteImage
+ && (hasFileAccess))
+ && (hasSocketAccess)) {
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+
+
+/* Answer the session identifier from a SQFile structure. For a valid file
+ reference, this identifier will match the session identifier supplied by
+ the interpreter. */
+
+static SESSIONIDENTIFIERTYPE
+sessionIdentifierFromSqFile(SQFile *sqFile)
+{
+ return sqFile->sessionID;
+}
+
+
+/* Answer a session ID represented by aByteArray. The session ID is used in
+ the SQFile structure. If that data structure changes, we should see
+ compiler warnings about type mismatch with SESSIONIDENTIFIERTYPE. */
+
+static SESSIONIDENTIFIERTYPE
+sessionIdentifierFrom(sqInt aByteArray)
+{
+    sqInt idx;
+    unsigned char *session;
+    union {SESSIONIDENTIFIERTYPE session; unsigned char bytes[sizeof(SESSIONIDENTIFIERTYPE)];} sessionUnion;
+
+ if (!((interpreterProxy->isBytes(aByteArray))
+ && ((interpreterProxy->stSizeOf(aByteArray)) == (sizeOfSession())))) {
+ return null;
+ }
+ session = interpreterProxy->arrayValueOf(aByteArray);
+ idx = 0;
+ while (idx < (sizeOfSession())) {
+ sessionUnion.bytes[idx] = session[idx];
+ idx += 1;
+ }
+ return sessionUnion.session;
+}
+
+
+/* Note: This is coded so that is can be run from Squeak. */
+
+EXPORT(sqInt)
+setInterpreter(struct VirtualMachine*anInterpreter)
+{
+    sqInt ok;
+
+ interpreterProxy = anInterpreter;
+ ok = interpreterProxy->majorVersion() == VM_PROXY_MAJOR;
+ if (ok == 0) {
+ return 0;
+ }
+ ok = interpreterProxy->minorVersion() >= VM_PROXY_MINOR;
+ return ok;
+}
+
+EXPORT(sqInt)
+shutdownModule(void)
+{
+}
+
+static sqInt
+sizeOfHandle(void)
+{
+ return sizeof(HANDLE);
+}
+
+
+/* Size in bytes of an integer, for this C compiler on this machine. */
+
+static sqInt
+sizeOfInt(void)
+{
+ return sizeof(int);
+}
+
+
+/* Size in bytes of a void pointer, for this C compiler on this machine. */
+
+static sqInt
+sizeOfPointer(void)
+{
+ return sizeof(void *);
+}
+
+
+/* Size of a SESSIONIDENTIFIERTYPE. Should match usage in the SQFile data
+ structure, otherwise we should get compiler warnings. */
+
+static sqInt
+sizeOfSession(void)
+{
+ return sizeof(SESSIONIDENTIFIERTYPE);
+}
+
+
+/* Answer the OS file descriptor, an integer value, from a SQSocket data
+ structure, or answer -1 if unable to obtain the file descriptor (probably
+ due to receiving
+ an incorrect type of object as aFileHandle).
+
+ Warning: The first element of privateSocketStruct happens to be the Unix
+ file number of the socket. See sqUnixSocket.c for the definition. This
+ method takes
+ advantage of this, and will break if anyone ever redefines the data
+ structure.
+ */
+
+static int
+socketDescriptorFrom(sqInt sqSocketOop)
+{
+    void *privateSocketStruct;
+    SocketPtr sqSocket;
+
+ /* begin socketValueOf: */
+ sqSocket = interpreterProxy->arrayValueOf(sqSocketOop);
+ privateSocketStruct = sqSocket->privateSocketPtr;
+ if (privateSocketStruct == 0) {
+ return -1;
+ }
+ return * (int *) privateSocketStruct;
+}
+
+
+/* Answer the size of a SQSocket data structure in bytes. */
+
+static sqInt
+socketRecordSize(void)
+{
+ return sizeof(SQSocket);
+}
+
+
+/* Return a pointer to the first byte of of the SQsocket data structure
+ socket record within
+ anSQSocketRecord, which is expected to be a ByteArray of size
+ self>>socketRecordSize.
+ */
+
+static SocketPtr
+socketValueOf(sqInt anSQSocketRecord)
+{
+ return interpreterProxy->arrayValueOf(anSQSocketRecord);
+}
+
+
+/* Wait for a process HANDLE to exit, then signal the Semaphore at index.
+ Answer the thread ID of the handler. This is the code to be executed in a
+ thread to provide
+ asychronous notification of an external process exit.
+ */
+
+static sqInt
+startHandlerThreadForAnycountsignalingSemaphoreAt(HANDLE *handleArrayPointer, sqInt arraySize, sqInt semaphoreIndex)
+{
+    HANDLE hThread;
+    static struct {int count; HANDLE *handles; int semaIndex;} threadArgs;
+    DWORD threadID;
+    sqInt threadInformation;
+
+ waitForThreadMutex(exitThreadMutexHandle());
+ threadArgs.count= arraySize;
+ threadArgs.handles= handleArrayPointer;
+ threadArgs.semaIndex= semaphoreIndex;
+
+#if !defined(STACK_SIZE_PARAM_IS_A_RESERVATION)
+
+#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x10000
+
+#endif
+ hThread = CreateThread(NULL, 1024, handleAnyChildProc, &threadArgs, STACK_SIZE_PARAM_IS_A_RESERVATION, &threadID);
+ if (hThread == null) {
+ return interpreterProxy->nilObject();
+ }
+ interpreterProxy->pushRemappableOop(interpreterProxy->positive32BitIntegerFor(threadID));
+ interpreterProxy->pushRemappableOop(handleObjectFrom(hThread));
+ threadInformation = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 2);
+ interpreterProxy->storePointerofObjectwithValue(0, threadInformation, interpreterProxy->popRemappableOop());
+ interpreterProxy->storePointerofObjectwithValue(1, threadInformation, interpreterProxy->popRemappableOop());
+ return threadInformation;
+}
+
+
+/* Answer the pseudo HANDLE for standard error. */
+
+static HANDLE
+stdErrHandle(void)
+{
+ return (HANDLE) STD_ERROR_HANDLE;
+}
+
+static HANDLE
+stderrHandle(void)
+{
+    HANDLE h;
+
+ h = GetStdHandle(STD_ERROR_HANDLE);
+ if (h == INVALID_HANDLE_VALUE) {
+ interpreterProxy->primitiveFail();
+ }
+ return h;
+}
+
+
+/* Answer the pseudo HANDLE for standard input. */
+
+static HANDLE
+stdInHandle(void)
+{
+ return (HANDLE) STD_INPUT_HANDLE;
+}
+
+static HANDLE
+stdinHandle(void)
+{
+    HANDLE h;
+
+ h = GetStdHandle(STD_INPUT_HANDLE);
+ if (h == INVALID_HANDLE_VALUE) {
+ interpreterProxy->primitiveFail();
+ }
+ return h;
+}
+
+
+/* Answer the pseudo HANDLE for standard output. */
+
+static HANDLE
+stdOutHandle(void)
+{
+ return (HANDLE) STD_OUTPUT_HANDLE;
+}
+
+static HANDLE
+stdoutHandle(void)
+{
+    HANDLE h;
+
+ h = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (h == INVALID_HANDLE_VALUE) {
+ interpreterProxy->primitiveFail();
+ }
+ return h;
+}
+
+
+/* Answer a new String copied from a null-terminated C string.
+ Caution: This may invoke the garbage collector. */
+
+static sqInt
+stringFromCString(const char *aCString)
+{
+    sqInt len;
+    sqInt newString;
+
+ len = strlen(aCString);
+ newString = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), len);
+ strncpy(interpreterProxy->arrayValueOf(newString), aCString, len);
+ return newString;
+}
+
+
+/* Answer a HANDLE for a mutex semaphore. */
+
+static HANDLE
+threadMutexHandle(void)
+{
+    static HANDLE h= 0;
+
+ if (h == 0) {
+ h = CreateMutex(NULL, false, NULL);
+ }
+ return h;
+}
+
+
+/* Answer a new null-terminated C string copied from aString.
+ The string is allocated in object memory, and will be moved
+ without warning by the garbage collector. Any C pointer
+ reference the the result is valid only until the garbage
+ collector next runs. Therefore, this method should only be used
+ within a single primitive in a section of code in which the
+ garbage collector is guaranteed not to run. Note also that
+ this method may itself invoke the garbage collector prior
+ to allocating the new C string.
+
+ Warning: The result of this method will be invalidated by the
+ next garbage collection, including a GC triggered by creation
+ of a new object within a primitive. Do not call this method
+ twice to obtain two string pointers.
+ */
+
+static char *
+transientCStringFromString(sqInt aString)
+{
+    char *cString;
+    sqInt len;
+    sqInt newString;
+    char *stringPtr;
+
+
+ /* Allocate space for a null terminated C string. */
+
+ len = interpreterProxy->sizeOfSTArrayFromCPrimitive(interpreterProxy->arrayValueOf(aString));
+ interpreterProxy->pushRemappableOop(aString);
+ newString = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), len + 1);
+ stringPtr = interpreterProxy->arrayValueOf(interpreterProxy->popRemappableOop());
+
+ /* Point to the actual C string. */
+
+ cString = interpreterProxy->arrayValueOf(newString);
+ (char *)strncpy(cString, stringPtr, len);
+ cString[len] = 0;
+ return cString;
+}
+
+
+/* Answer a string containing the version string for this plugin. Handle MNU
+ errors, which can occur if class InterpreterPlugin has been removed from
+ the system.
+
+ Important: When this method is changed, the class side method must also be
+ changed to match.
+ */
+/* 4.0 supports 64bit code base */
+
+static char *
+versionString(void)
+{
+    static char version[]= "4.3.2";
+
+ return version;
+}
+
+
+/* To be called before entering a critical section. */
+
+static DWORD
+waitForThreadMutex(HANDLE aHandle)
+{
+ return WaitForSingleObject(aHandle, INFINITE);
+}
+
+
+#ifdef SQUEAK_BUILTIN_PLUGIN
+
+void* Win32OSProcessPlugin_exports[][3] = {
+ {"Win32OSProcessPlugin", "getModuleName", (void*)getModuleName},
+ {"Win32OSProcessPlugin", "initialiseModule", (void*)initialiseModule},
+ {"Win32OSProcessPlugin", "moduleUnloaded", (void*)moduleUnloaded},
+ {"Win32OSProcessPlugin", "primitiveAllocConsole", (void*)primitiveAllocConsole},
+ {"Win32OSProcessPlugin", "primitiveBufferValuesAt", (void*)primitiveBufferValuesAt},
+ {"Win32OSProcessPlugin", "primitiveCanAccessChildProcess", (void*)primitiveCanAccessChildProcess},
+ {"Win32OSProcessPlugin", "primitiveCloseHandle", (void*)primitiveCloseHandle},
+ {"Win32OSProcessPlugin", "primitiveCommand", (void*)primitiveCommand},
+ {"Win32OSProcessPlugin", "primitiveCommandWithInputOutputError", (void*)primitiveCommandWithInputOutputError},
+ {"Win32OSProcessPlugin", "primitiveCreatePipe", (void*)primitiveCreatePipe},
+ {"Win32OSProcessPlugin", "primitiveCreatePipeWithSessionIdentifier", (void*)primitiveCreatePipeWithSessionIdentifier},
+ {"Win32OSProcessPlugin", "primitiveFixPointersInArrayOfStrings", (void*)primitiveFixPointersInArrayOfStrings},
+ {"Win32OSProcessPlugin", "primitiveFreeConsole", (void*)primitiveFreeConsole},
+ {"Win32OSProcessPlugin", "primitiveGetCurrentWorkingDirectory", (void*)primitiveGetCurrentWorkingDirectory},
+ {"Win32OSProcessPlugin", "primitiveGetEnvironmentStrings", (void*)primitiveGetEnvironmentStrings},
+ {"Win32OSProcessPlugin", "primitiveGetExitStatusForHandle", (void*)primitiveGetExitStatusForHandle},
+ {"Win32OSProcessPlugin", "primitiveGetMainThreadHandle", (void*)primitiveGetMainThreadHandle},
+ {"Win32OSProcessPlugin", "primitiveGetMainThreadID", (void*)primitiveGetMainThreadID},
+ {"Win32OSProcessPlugin", "primitiveGetPid", (void*)primitiveGetPid},
+ {"Win32OSProcessPlugin", "primitiveGetPidHandle", (void*)primitiveGetPidHandle},
+ {"Win32OSProcessPlugin", "primitiveGetSession", (void*)primitiveGetSession},
+ {"Win32OSProcessPlugin", "primitiveGetStdError", (void*)primitiveGetStdError},
+ {"Win32OSProcessPlugin", "primitiveGetStdInput", (void*)primitiveGetStdInput},
+ {"Win32OSProcessPlugin", "primitiveGetStdOutput", (void*)primitiveGetStdOutput},
+ {"Win32OSProcessPlugin", "primitiveLastReadFor", (void*)primitiveLastReadFor},
+ {"Win32OSProcessPlugin", "primitiveLastReadForStoreIn", (void*)primitiveLastReadForStoreIn},
+ {"Win32OSProcessPlugin", "primitiveMakePipe", (void*)primitiveMakePipe},
+ {"Win32OSProcessPlugin", "primitiveMakePipeWithSessionIdentifier", (void*)primitiveMakePipeWithSessionIdentifier},
+ {"Win32OSProcessPlugin", "primitiveModuleName", (void*)primitiveModuleName},
+ {"Win32OSProcessPlugin", "primitiveNextFromSignaling", (void*)primitiveNextFromSignaling},
+ {"Win32OSProcessPlugin", "primitiveOneShot", (void*)primitiveOneShot},
+ {"Win32OSProcessPlugin", "primitiveSetStdErr", (void*)primitiveSetStdErr},
+ {"Win32OSProcessPlugin", "primitiveSetStdIn", (void*)primitiveSetStdIn},
+ {"Win32OSProcessPlugin", "primitiveSetStdOut", (void*)primitiveSetStdOut},
+ {"Win32OSProcessPlugin", "primitiveSetWaitForAnyProcessExitThenSignalSemaphoreWithIndex", (void*)primitiveSetWaitForAnyProcessExitThenSignalSemaphoreWithIndex},
+ {"Win32OSProcessPlugin", "primitiveSizeOfInt", (void*)primitiveSizeOfInt},
+ {"Win32OSProcessPlugin", "primitiveSizeOfPointer", (void*)primitiveSizeOfPointer},
+ {"Win32OSProcessPlugin", "primitiveTerminateThread", (void*)primitiveTerminateThread},
+ {"Win32OSProcessPlugin", "primitiveVersionString", (void*)primitiveVersionString},
+ {"Win32OSProcessPlugin", "setInterpreter", (void*)setInterpreter},
+ {"Win32OSProcessPlugin", "shutdownModule", (void*)shutdownModule},
+ {NULL, NULL, NULL}
+};
+
+#endif /* ifdef SQ_BUILTIN_PLUGIN */

Modified: branches/Cog/src/vm/cointerp.c
===================================================================
--- branches/Cog/src/vm/cointerp.c 2011-06-07 18:48:37 UTC (rev 2393)
+++ branches/Cog/src/vm/cointerp.c 2011-06-08 00:36:21 UTC (rev 2394)
@@ -1,9 +1,9 @@
 /* Automatically generated by
- CCodeGeneratorGlobalStructure VMMaker.oscog-eem.70 uuid: 36b63465-1b05-401f-bcb2-f9cae49422b8
+ CCodeGeneratorGlobalStructure VMMaker.oscog-eem.75 uuid: e1bb08e3-482d-4bfd-a416-d203d9fe4c57
    from
- CoInterpreter VMMaker.oscog-eem.70 uuid: 36b63465-1b05-401f-bcb2-f9cae49422b8
+ CoInterpreter VMMaker.oscog-eem.75 uuid: e1bb08e3-482d-4bfd-a416-d203d9fe4c57
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.70 uuid: 36b63465-1b05-401f-bcb2-f9cae49422b8 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.75 uuid: e1bb08e3-482d-4bfd-a416-d203d9fe4c57 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -81,7 +81,7 @@
 #define AllButRootBit 0xBFFFFFFFUL
 #define AllButTypeMask 0xFFFFFFFCUL
 #if !defined(AllocationCheckFiller)
-# define AllocationCheckFiller 0x55AA55AA
+# define AllocationCheckFiller 182275669
 #endif
 #define AtCacheFixedFields 4
 #define AtCacheFmt 3
@@ -1865,7 +1865,7 @@
  /* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.70]";
+const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.75]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -26867,10 +26867,10 @@
 
 
 /* receiver, argsArray, then method are on top of stack. Execute method
- against receiver and args.
+ against receiver and args. Allow for up to two extra arguments (e.g. for
+ mirror primitives).
  Set primitiveFunctionPointer because no cache lookup has been done for the
- method, and
- hence primitiveFunctionPointer is stale. */
+ method, and hence primitiveFunctionPointer is stale. */
 
 static void
 primitiveExecuteMethodArgsArray(void)
@@ -26904,8 +26904,14 @@
  if (!(argCnt == (fetchWordLengthOf(argumentArray)))) {
  GIV(primFailCode) = PrimErrBadNumArgs; return;
  }
+ if (GIV(argumentCount) > 2) {
+ if (GIV(argumentCount) > 4) {
+ GIV(primFailCode) = PrimErrUnsupported; return;
+ }
+ longAtput(GIV(stackPointer) + (GIV(argumentCount) * BytesPerWord), longAt(GIV(stackPointer) + (2 * BytesPerWord)));
+ }
  /* begin pop: */
- GIV(stackPointer) += 2 * BytesPerWord;
+ GIV(stackPointer) += GIV(argumentCount) * BytesPerWord;
  for (i = 0; i <= (argCnt - 1); i += 1) {
  /* begin push: */
  longAtput(sp = GIV(stackPointer) - BytesPerWord, longAt((argumentArray + BaseHeaderSize) + (i << ShiftForWord)));

Modified: branches/Cog/src/vm/cointerp.h
===================================================================
--- branches/Cog/src/vm/cointerp.h 2011-06-07 18:48:37 UTC (rev 2393)
+++ branches/Cog/src/vm/cointerp.h 2011-06-08 00:36:21 UTC (rev 2394)
@@ -1,5 +1,5 @@
 /* Automatically generated by
- CCodeGeneratorGlobalStructure VMMaker.oscog-eem.70 uuid: 36b63465-1b05-401f-bcb2-f9cae49422b8
+ CCodeGeneratorGlobalStructure VMMaker.oscog-eem.75 uuid: e1bb08e3-482d-4bfd-a416-d203d9fe4c57
  */
 
 

Modified: branches/Cog/src/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/src/vm/gcc3x-cointerp.c 2011-06-07 18:48:37 UTC (rev 2393)
+++ branches/Cog/src/vm/gcc3x-cointerp.c 2011-06-08 00:36:21 UTC (rev 2394)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
- CCodeGeneratorGlobalStructure VMMaker.oscog-eem.70 uuid: 36b63465-1b05-401f-bcb2-f9cae49422b8
+ CCodeGeneratorGlobalStructure VMMaker.oscog-eem.75 uuid: e1bb08e3-482d-4bfd-a416-d203d9fe4c57
    from
- CoInterpreter VMMaker.oscog-eem.70 uuid: 36b63465-1b05-401f-bcb2-f9cae49422b8
+ CoInterpreter VMMaker.oscog-eem.75 uuid: e1bb08e3-482d-4bfd-a416-d203d9fe4c57
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.70 uuid: 36b63465-1b05-401f-bcb2-f9cae49422b8 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.75 uuid: e1bb08e3-482d-4bfd-a416-d203d9fe4c57 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -84,7 +84,7 @@
 #define AllButRootBit 0xBFFFFFFFUL
 #define AllButTypeMask 0xFFFFFFFCUL
 #if !defined(AllocationCheckFiller)
-# define AllocationCheckFiller 0x55AA55AA
+# define AllocationCheckFiller 182275669
 #endif
 #define AtCacheFixedFields 4
 #define AtCacheFmt 3
@@ -1868,7 +1868,7 @@
  /* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.70]";
+const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.75]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -26871,10 +26871,10 @@
 
 
 /* receiver, argsArray, then method are on top of stack. Execute method
- against receiver and args.
+ against receiver and args. Allow for up to two extra arguments (e.g. for
+ mirror primitives).
  Set primitiveFunctionPointer because no cache lookup has been done for the
- method, and
- hence primitiveFunctionPointer is stale. */
+ method, and hence primitiveFunctionPointer is stale. */
 
 static void
 primitiveExecuteMethodArgsArray(void)
@@ -26908,8 +26908,14 @@
  if (!(argCnt == (fetchWordLengthOf(argumentArray)))) {
  GIV(primFailCode) = PrimErrBadNumArgs; return;
  }
+ if (GIV(argumentCount) > 2) {
+ if (GIV(argumentCount) > 4) {
+ GIV(primFailCode) = PrimErrUnsupported; return;
+ }
+ longAtput(GIV(stackPointer) + (GIV(argumentCount) * BytesPerWord), longAt(GIV(stackPointer) + (2 * BytesPerWord)));
+ }
  /* begin pop: */
- GIV(stackPointer) += 2 * BytesPerWord;
+ GIV(stackPointer) += GIV(argumentCount) * BytesPerWord;
  for (i = 0; i <= (argCnt - 1); i += 1) {
  /* begin push: */
  longAtput(sp = GIV(stackPointer) - BytesPerWord, longAt((argumentArray + BaseHeaderSize) + (i << ShiftForWord)));