You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
(27) |
Apr
(11) |
May
(112) |
Jun
(8) |
Jul
(10) |
Aug
(68) |
Sep
(12) |
Oct
(3) |
Nov
(19) |
Dec
(3) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(15) |
Mar
(20) |
Apr
(22) |
May
(131) |
Jun
(27) |
Jul
(19) |
Aug
(207) |
Sep
(61) |
Oct
(27) |
Nov
(28) |
Dec
(21) |
| 2004 |
Jan
(7) |
Feb
(25) |
Mar
(14) |
Apr
(55) |
May
(15) |
Jun
(2) |
Jul
(14) |
Aug
(28) |
Sep
(29) |
Oct
|
Nov
|
Dec
|
|
From: Brenda L. <asp...@us...> - 2003-05-13 21:51:11
|
Update of /cvsroot/squeak/squeak/platforms/Cross/plugins/B3DAcceleratorPlugin In directory sc8-pr-cvs1:/tmp/cvs-serv8007 Modified Files: B3DAcceleratorPlugin.h Log Message: Ian Piumarta's release 3.5-1devel Index: B3DAcceleratorPlugin.h =================================================================== RCS file: /cvsroot/squeak/squeak/platforms/Cross/plugins/B3DAcceleratorPlugin/B3DAcceleratorPlugin.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** B3DAcceleratorPlugin.h 5 Sep 2002 19:29:13 -0000 1.4 --- B3DAcceleratorPlugin.h 13 May 2003 21:51:04 -0000 1.5 *************** *** 80,84 **** # endif #else ! #define B3DX_GL #endif --- 80,84 ---- # endif #else ! # define B3DX_GL #endif |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:39:39
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/SecurityPlugin In directory sc8-pr-cvs1:/tmp/cvs-serv6251/plugins/SecurityPlugin Modified Files: sqUnixSecurity.c Log Message: Ian Piumarta's release 3.4.1 Index: sqUnixSecurity.c =================================================================== RCS file: /cvsroot/squeak/squeak/platforms/unix/plugins/SecurityPlugin/sqUnixSecurity.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** sqUnixSecurity.c 6 Mar 2002 23:59:11 -0000 1.2 --- sqUnixSecurity.c 12 May 2003 07:39:04 -0000 1.3 *************** *** 1,15 **** /* sqUnixSecurity.c -- directory operations for Unix * * Note: According to Ian Piumarta, the Unix VM is inherently insecure since * pluggable primitives can access all of libc! It would need * some linker magic to hide these from dlsym(). ! * * A workaround would be to disallow lookups via dlsym() when * fileaccess is disallowed - internal plugins should still work ... - * - * Author: Bert Freudenberg (heavily based on Andreas Raab's sqWin32Security.c) */ #include "sq.h" #include <sys/param.h> --- 1,19 ---- /* sqUnixSecurity.c -- directory operations for Unix * + * Author: Bert Freudenberg (heavily based on Andreas Raab's sqWin32Security.c) + * + * Last edited: 2002-10-26 14:43:23 by piumarta on emilia.inria.fr + * * Note: According to Ian Piumarta, the Unix VM is inherently insecure since * pluggable primitives can access all of libc! It would need * some linker magic to hide these from dlsym(). ! * * A workaround would be to disallow lookups via dlsym() when * fileaccess is disallowed - internal plugins should still work ... */ #include "sq.h" + #include "SecurityPlugin.h" + #include <sys/param.h> *************** *** 179,183 **** ! int ioCanListenOnPort(void* s, int port) { return allowSocketAccess; --- 183,187 ---- ! int ioCanListenOnPort(int s, int port) { return allowSocketAccess; *************** *** 203,206 **** --- 207,212 ---- char *ioGetSecureUserDirectory(void) { + if (secureUserDirectory[0] == '\0') + return (char *)success(false); return secureUserDirectory; } |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:39:38
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/B3DAcceleratorPlugin
In directory sc8-pr-cvs1:/tmp/cvs-serv6251/plugins/B3DAcceleratorPlugin
Modified Files:
sqUnixOpenGL.c
Log Message:
Ian Piumarta's release 3.4.1
Index: sqUnixOpenGL.c
===================================================================
RCS file: /cvsroot/squeak/squeak/platforms/unix/plugins/B3DAcceleratorPlugin/sqUnixOpenGL.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** sqUnixOpenGL.c 28 May 2002 20:16:54 -0000 1.1
--- sqUnixOpenGL.c 12 May 2003 07:39:02 -0000 1.2
***************
*** 5,9 ****
* Based on Andreas Raab's sqWin32OpenGL.c
*
! * Last edited: 19 May 2001 bert@faust
*/
--- 5,14 ----
* Based on Andreas Raab's sqWin32OpenGL.c
*
! * Last edited: Mon 11 Nov 2002 15:43:31 by bert on balloon
! *
! * History
! * Nov 02: added TGraphicsTest conformant log support
! * Oct 02: added Tea initialization support w/ stencil
! * May 01: initial revision
*/
***************
*** 26,29 ****
--- 31,37 ----
extern struct VirtualMachine *interpreterProxy;
+ static void printVisual(XVisualInfo* visinfo);
+ static void listVisuals();
+
static Display *stDisplay= NULL; /* Squeak's display */
static Window stWindow= 0; /* Squeak's main window */
***************
*** 34,46 ****
static int visualAttributes[]= {
GLX_RGBA, /* no indexed colors */
GLX_DOUBLEBUFFER, /* will swap */
GLX_LEVEL, 0, /* frame buffer, not overlay */
- GLX_RED_SIZE, 1, /* need rgb & alpha */
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- GLX_ALPHA_SIZE, 1,
GLX_DEPTH_SIZE, 16, /* decent depth */
- GLX_STENCIL_SIZE, 0, /* need no stencil */
GLX_AUX_BUFFERS, 0, /* no aux buffers */
GLX_ACCUM_RED_SIZE, 0, /* no accumulation */
--- 42,51 ----
static int visualAttributes[]= {
+ GLX_STENCIL_SIZE, 0, /* filled in later - must be first item! */
+ GLX_ALPHA_SIZE, 1, /* filled in later - must be second item! */
GLX_RGBA, /* no indexed colors */
GLX_DOUBLEBUFFER, /* will swap */
GLX_LEVEL, 0, /* frame buffer, not overlay */
GLX_DEPTH_SIZE, 16, /* decent depth */
GLX_AUX_BUFFERS, 0, /* no aux buffers */
GLX_ACCUM_RED_SIZE, 0, /* no accumulation */
***************
*** 68,72 ****
/*** create / destroy a renderer ***/
! int glCreateRenderer(int allowSoftware, int allowHardware, int x, int y, int w, int h)
{
glRenderer *renderer;
--- 73,77 ----
/*** create / destroy a renderer ***/
! int glCreateRendererFlags(int x, int y, int w, int h, int flags)
{
glRenderer *renderer;
***************
*** 74,77 ****
--- 79,93 ----
int index= -1;
+ if (flags & ~(B3D_HARDWARE_RENDERER | B3D_SOFTWARE_RENDERER | B3D_STENCIL_BUFFER))
+ {
+ DPRINTF(1, (fp, "ERROR: Unsupported renderer flags (%d)\r", flags));
+ return -1;
+ }
+
+ if (flags & B3D_STENCIL_BUFFER)
+ visualAttributes[1]= 1;
+ else
+ visualAttributes[1]= 0;
+
/* find unused renderer */
{
***************
*** 89,93 ****
if (index == -1)
{
! DPRINTF(1, (fp, "ERROR: Maximum number of renderers (%d) exceeded\n", MAX_RENDERER));
return 0;
}
--- 105,109 ----
if (index == -1)
{
! DPRINTF(1, (fp, "ERROR: Maximum number of renderers (%d) exceeded\r", MAX_RENDERER));
return 0;
}
***************
*** 99,103 ****
renderer->context= NULL;
! DPRINTF(3, (fp, "---- Creating new renderer ----\n\n"));
/* sanity checks */
--- 115,119 ----
renderer->context= NULL;
! DPRINTF(3, (fp, "---- Creating new renderer ----\r\r"));
/* sanity checks */
***************
*** 105,109 ****
if (w < 0 || h < 0)
{
! DPRINTF(1, (fp, "Negative extent (%i@%i)!\n", w, h));
goto FAILED;
}
--- 121,125 ----
if (w < 0 || h < 0)
{
! DPRINTF(1, (fp, "Negative extent (%i@%i)!\r", w, h));
goto FAILED;
}
***************
*** 111,126 ****
/* choose visual and create context */
{
visinfo= glXChooseVisual(stDisplay,
! DefaultScreen(stDisplay),
! visualAttributes);
if (!visinfo)
{
! DPRINTF(1, (fp, "No OpenGL visual found!\n"));
goto FAILED;
}
! DPRINTF(3, (fp, "\n#### Selected GLX visual #%ld (depth: %d) ####\n",
! visinfo->visualid, visinfo->depth));
renderer->context= glXCreateContext(stDisplay, visinfo, 0, GL_TRUE);
--- 127,157 ----
/* choose visual and create context */
+ if (verboseLevel >= 3)
+ listVisuals();
+
{
visinfo= glXChooseVisual(stDisplay,
! DefaultScreen(stDisplay),
! visualAttributes);
!
if (!visinfo)
{
! /* retry without alpha */
! visualAttributes[3]= 0;
! visinfo= glXChooseVisual(stDisplay,
! DefaultScreen(stDisplay),
! visualAttributes);
! }
!
! if (!visinfo)
! {
! DPRINTF(1, (fp, "No OpenGL visual found!\r"));
goto FAILED;
}
! DPRINTF(3, (fp, "\r#### Selected GLX visual ID 0x%lx ####\r",
! visinfo->visualid));
! if (verboseLevel >= 3)
! printVisual(visinfo);
renderer->context= glXCreateContext(stDisplay, visinfo, 0, GL_TRUE);
***************
*** 128,136 ****
if (!renderer->context)
{
! DPRINTF(1, (fp, "Creating GLX context failed!\n"));
goto FAILED;
}
! DPRINTF(3, (fp, "\n#### Created GLX context ####\n" ));
/* create window */
--- 159,167 ----
if (!renderer->context)
{
! DPRINTF(1, (fp, "Creating GLX context failed!\r"));
goto FAILED;
}
! DPRINTF(3, (fp, "\r#### Created GLX context ####\r" ));
/* create window */
***************
*** 153,157 ****
if (!renderer->window)
{
! DPRINTF(1, (fp, "Failed to create client window\n"));
goto FAILED;
}
--- 184,188 ----
if (!renderer->window)
{
! DPRINTF(1, (fp, "Failed to create client window\r"));
goto FAILED;
}
***************
*** 161,165 ****
}
! DPRINTF(3, (fp, "\n#### Created window ####\n" ));
XFree(visinfo);
--- 192,196 ----
}
! DPRINTF(3, (fp, "\r#### Created window ####\r" ));
XFree(visinfo);
***************
*** 170,174 ****
if (!glXMakeCurrent(stDisplay, renderer->window, renderer->context))
{
! DPRINTF(1, (fp, "Failed to make context current\n"));
goto FAILED;
}
--- 201,205 ----
if (!glXMakeCurrent(stDisplay, renderer->window, renderer->context))
{
! DPRINTF(1, (fp, "Failed to make context current\r"));
goto FAILED;
}
***************
*** 179,183 ****
renderer->bufferRect[3]= h;
! DPRINTF(3, (fp, "\n### Renderer created! ###\n"));
/* setup user context */
--- 210,214 ----
renderer->bufferRect[3]= h;
! DPRINTF(3, (fp, "\r### Renderer created! ###\r"));
/* setup user context */
***************
*** 199,203 ****
FAILED:
/* do necessary cleanup */
! DPRINTF(1, (fp, "OpenGL initialization failed\n"));
if (visinfo)
--- 230,234 ----
FAILED:
/* do necessary cleanup */
! DPRINTF(1, (fp, "OpenGL initialization failed\r"));
if (visinfo)
***************
*** 216,220 ****
glRenderer *renderer= glRendererFromHandle(handle);
! DPRINTF(3, (fp, "\n--- Destroying renderer ---\n"));
if (!renderer)
--- 247,251 ----
glRenderer *renderer= glRendererFromHandle(handle);
! DPRINTF(3, (fp, "\r--- Destroying renderer ---\r"));
if (!renderer)
***************
*** 241,245 ****
glRenderer *glRendererFromHandle(int handle)
{
! DPRINTF(7, (fp, "Looking for renderer id: %i\n", handle));
if (handle < 0 || handle >= MAX_RENDERER)
--- 272,276 ----
glRenderer *glRendererFromHandle(int handle)
{
! DPRINTF(7, (fp, "Looking for renderer id: %i\r", handle));
if (handle < 0 || handle >= MAX_RENDERER)
***************
*** 283,287 ****
if (!glXMakeCurrent(stDisplay, renderer->window, renderer->context))
{
! DPRINTF(1, (fp, "Failed to make context current\n"));
return 0;
}
--- 314,318 ----
if (!glXMakeCurrent(stDisplay, renderer->window, renderer->context))
{
! DPRINTF(1, (fp, "Failed to make context current\r"));
return 0;
}
***************
*** 327,331 ****
! int glGetIntProperty(int handle, int prop)
{
GLint v;
--- 358,362 ----
! int glGetIntPropertyOS(int handle, int prop)
{
GLint v;
***************
*** 358,362 ****
! int glSetIntProperty(int handle, int prop, int value)
{
glRenderer *renderer= glRendererFromHandle(handle);
--- 389,393 ----
! int glSetIntPropertyOS(int handle, int prop, int value)
{
glRenderer *renderer= glRendererFromHandle(handle);
***************
*** 395,398 ****
--- 426,477 ----
+ /* GLX_CONFIG_CAVEAT might not be supported */
+ /* but the test below is worded so it does not matter */
+ #ifndef GLX_CONFIG_CAVEAT
+ # define GLX_CONFIG_CAVEAT 0x20
+ # define GLX_SLOW_CONFIG 0x8001
+ #endif
+
+ static void printVisual(XVisualInfo* visinfo)
+ {
+ int isOpenGL;
+ glXGetConfig(stDisplay, visinfo, GLX_USE_GL, &isOpenGL);
+ if (isOpenGL)
+ {
+ int slow= 0;
+ int red, green, blue, alpha, stencil, depth;
+ glXGetConfig(stDisplay, visinfo, GLX_CONFIG_CAVEAT, &slow);
+ glXGetConfig(stDisplay, visinfo, GLX_RED_SIZE, &red);
+ glXGetConfig(stDisplay, visinfo, GLX_GREEN_SIZE, &green);
+ glXGetConfig(stDisplay, visinfo, GLX_BLUE_SIZE, &blue);
+ glXGetConfig(stDisplay, visinfo, GLX_ALPHA_SIZE, &alpha);
+ glXGetConfig(stDisplay, visinfo, GLX_STENCIL_SIZE, &stencil);
+ glXGetConfig(stDisplay, visinfo, GLX_DEPTH_SIZE, &depth);
+
+ if (slow != GLX_SLOW_CONFIG)
+ DPRINTF(3, (fp,"===> OpenGL visual\r"))
+ else
+ DPRINTF(3, (fp,"---> slow OpenGL visual\r"));
+
+ DPRINTF(3, (fp,"rgbaBits = %i+%i+%i+%i\r", red, green, blue, alpha));
+ DPRINTF(3, (fp,"stencilBits = %i\r", stencil));
+ DPRINTF(3, (fp,"depthBits = %i\r", depth));
+ }
+ }
+
+ static void listVisuals()
+ {
+ XVisualInfo* visinfo;
+ int nvisuals, i;
+
+ visinfo= XGetVisualInfo(stDisplay, VisualNoMask, NULL, &nvisuals);
+
+ for (i= 0; i < nvisuals; i++)
+ {
+ DPRINTF(3, (fp,"#### Checking pixel format (visual ID 0x%lx)\r", visinfo[i].visualid));
+ printVisual(&visinfo[i]);
+ }
+ XFree(visinfo);
+ }
***************
*** 404,423 ****
{
int i, p;
! p= interpreterProxy->ioLoadFunctionFrom("stDisplay", NULL);
! if (!p)
{
! DPRINTF(1,(fp,"ERROR: Failed to look up stDisplay\n"));
return 0;
}
- stDisplay= *(Display**) p;
! p= interpreterProxy->ioLoadFunctionFrom("stWindow", NULL);
! if (!p)
{
! DPRINTF(1,(fp,"ERROR: Failed to look up stWindow\n"));
return 0;
}
- stWindow= *(Window*) p;
for (i= 0; i < MAX_RENDERER; i++)
--- 483,503 ----
{
int i, p;
+ int fn;
! fn= interpreterProxy->ioLoadFunctionFrom("ioGetDisplay", NULL);
! stDisplay= (fn ? ((Display *(*)(void))fn)() : 0);
! if (!stDisplay)
{
! DPRINTF(1,(fp,"ERROR: Failed to look up stDisplay\r"));
return 0;
}
! fn= interpreterProxy->ioLoadFunctionFrom("ioGetWindow", NULL);
! stWindow= (fn ? ((Window (*)(void))fn)() : 0);
! if (!stWindow)
{
! DPRINTF(1,(fp,"ERROR: Failed to look up stWindow\r"));
return 0;
}
for (i= 0; i < MAX_RENDERER; i++)
|
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:39:38
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/FilePlugin
In directory sc8-pr-cvs1:/tmp/cvs-serv6251/plugins/FilePlugin
Modified Files:
sqUnixFile.c
Log Message:
Ian Piumarta's release 3.4.1
Index: sqUnixFile.c
===================================================================
RCS file: /cvsroot/squeak/squeak/platforms/unix/plugins/FilePlugin/sqUnixFile.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** sqUnixFile.c 29 Mar 2002 11:44:50 -0000 1.5
--- sqUnixFile.c 12 May 2003 07:39:03 -0000 1.6
***************
*** 1,6 ****
/* sqUnixFile.c -- directory operations for Unix
*
! * Copyright (C) 1996 1997 1998 1999 2000 2001 Ian Piumarta and individual
! * authors/contributors listed elsewhere in this file.
* All rights reserved.
*
--- 1,6 ----
/* sqUnixFile.c -- directory operations for Unix
*
! * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
! * as listed elsewhere in this file.
* All rights reserved.
*
***************
*** 21,41 ****
* would be appreciated but is not required.
*
! * 2. This notice may not be removed or altered in any source distribution.
*
! * Using or modifying this file for use in any context other than Squeak
! * changes these copyright conditions. Read the file `COPYING' in the base
! * of the distribution before proceeding with any such use.
*
! * You are STRONGLY DISCOURAGED from distributing a modified version of
! * this file under its original name without permission. If you must
! * change it, rename it first.
*/
/* Author: Ian...@IN...
*
! * Last edited: Fri 29 Mar 2002 12:39:53 by bert on balloon
*/
#include "sq.h"
#ifdef HAVE_DIRENT_H
--- 21,42 ----
* would be appreciated but is not required.
*
! * 2. This notice must not be removed or altered in any source distribution.
*
! * Using (or modifying this file for use) in any context other than Squeak
! * changes these copyright conditions. Read the file `COPYING' in the
! * directory `platforms/unix/doc' before proceeding with any such use.
*
! * You are not allowed to distribute a modified version of this file
! * under its original name without explicit permission to do so. If
! * you change it, rename it.
*/
/* Author: Ian...@IN...
*
! * Last edited: 2003-02-06 16:29:22 by piumarta on emilia.local.
*/
#include "sq.h"
+ #include "FilePlugin.h"
#ifdef HAVE_DIRENT_H
***************
*** 62,69 ****
#include <time.h>
- #include <sys/param.h>
- #include <sys/stat.h>
#include <errno.h>
#include <string.h>
/***
--- 63,70 ----
#include <time.h>
#include <errno.h>
#include <string.h>
+ #include <sys/param.h>
+ #include <sys/stat.h>
/***
***************
*** 91,98 ****
/*** Functions ***/
extern time_t convertToSqueakTime(time_t unixTime);
- int equalsLastPath(char *pathString, int pathStringLength);
- int recordPath(char *pathString, int pathStringLength, int refNum, int volNum);
int maybeOpenDir(char *unixPath);
--- 92,98 ----
/*** Functions ***/
+
extern time_t convertToSqueakTime(time_t unixTime);
int maybeOpenDir(char *unixPath);
***************
*** 118,124 ****
if (pathStringLength >= MAXPATHLEN)
return false;
! for (i = 0; i < pathStringLength; i++)
! name[i] = pathString[i];
! name[i] = 0; /* string terminator */
return rmdir(name) == 0;
}
--- 118,126 ----
if (pathStringLength >= MAXPATHLEN)
return false;
! for (i= 0; i < pathStringLength; ++i)
! name[i]= pathString[i];
! if (!strcmp(lastPath, name))
! lastPathValid= false;
! name[i]= '\0'; /* string terminator */
return rmdir(name) == 0;
}
***************
*** 131,135 ****
int dir_Lookup(char *pathString, int pathStringLength, int index,
/* outputs: */ char *name, int *nameLength, int *creationDate, int *modificationDate,
! int *isDirectory, int *sizeIfFile)
{
/* Lookup the index-th entry of the directory with the given path, starting
--- 133,137 ----
int dir_Lookup(char *pathString, int pathStringLength, int index,
/* outputs: */ char *name, int *nameLength, int *creationDate, int *modificationDate,
! int *isDirectory, squeakFileOffsetType *sizeIfFile)
{
/* Lookup the index-th entry of the directory with the given path, starting
***************
*** 181,194 ****
{
nextEntry:
! do {
! errno= 0;
! dirEntry= readdir(openDir);
! } while(dirEntry==0 && errno==EINTR);
if (!dirEntry)
! {
! return NO_MORE_ENTRIES;
! }
nameLen= NAMLEN(dirEntry);
/* ignore '.' and '..' (these are not *guaranteed* to be first) */
if (nameLen < 3 && dirEntry->d_name[0] == '.')
--- 183,198 ----
{
nextEntry:
! do
! {
! errno= 0;
! dirEntry= readdir(openDir);
! }
! while ((dirEntry == 0) && (errno == EINTR));
if (!dirEntry)
! return NO_MORE_ENTRIES;
!
nameLen= NAMLEN(dirEntry);
+
/* ignore '.' and '..' (these are not *guaranteed* to be first) */
if (nameLen < 3 && dirEntry->d_name[0] == '.')
***************
*** 261,263 ****
return true;
}
-
--- 265,266 ----
|
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:39:38
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/SerialPlugin In directory sc8-pr-cvs1:/tmp/cvs-serv6251/plugins/SerialPlugin Modified Files: sqUnixSerial.c Log Message: Ian Piumarta's release 3.4.1 Index: sqUnixSerial.c =================================================================== RCS file: /cvsroot/squeak/squeak/platforms/unix/plugins/SerialPlugin/sqUnixSerial.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** sqUnixSerial.c 8 Apr 2002 19:57:52 -0000 1.2 --- sqUnixSerial.c 12 May 2003 07:39:04 -0000 1.3 *************** *** 3,7 **** * Author: Ned Konz, July 14, 2000 * ! * Last edited: Wed Sep 6 03:39:38 2000 by piumarta (Ian Piumarta) on emilia * * Separated from MIDI, plus various portability problems fixed, by: --- 3,7 ---- * Author: Ned Konz, July 14, 2000 * ! * Last edited: 2002-10-26 14:36:11 by piumarta on emilia.inria.fr * * Separated from MIDI, plus various portability problems fixed, by: *************** *** 10,13 **** --- 10,14 ---- #include "sq.h" + #include "SerialPlugin.h" #include <termios.h> |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:39:13
|
Update of /cvsroot/squeak/squeak/platforms/unix/vm
In directory sc8-pr-cvs1:/tmp/cvs-serv6251/vm
Modified Files:
osExports.c sqConfig.h sqPlatformSpecific.h
sqUnixExternalPrims.c sqUnixMozilla.c sqXWindow.c sunos.h
Log Message:
Ian Piumarta's release 3.4.1
Index: osExports.c
===================================================================
RCS file: /cvsroot/squeak/squeak/platforms/unix/vm/osExports.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** osExports.c 13 May 2002 12:47:29 -0000 1.1
--- osExports.c 12 May 2003 07:39:08 -0000 1.2
***************
*** 1,25 ****
#include <stdio.h>
- /* duh ... this is ugly */
! #define XFN(export) {"", #export, (void*)export},
#define XFN2(plugin, export) {#plugin, #export, (void*)plugin##_##export}
! int primitivePluginBrowserReady(void);
! int primitivePluginRequestURLStream(void);
! int primitivePluginRequestURL(void);
! int primitivePluginPostURL(void);
! int primitivePluginRequestFileHandle(void);
! int primitivePluginDestroyRequest(void);
! int primitivePluginRequestState(void);
! void *os_exports[][3] = {
! XFN(primitivePluginBrowserReady)
! XFN(primitivePluginRequestURLStream)
! XFN(primitivePluginRequestURL)
! XFN(primitivePluginPostURL)
! XFN(primitivePluginRequestFileHandle)
! XFN(primitivePluginDestroyRequest)
! XFN(primitivePluginRequestState)
! {NULL, NULL, NULL}
};
-
--- 1,32 ----
#include <stdio.h>
! #define XFN(export) {"", #export, (void*)export}
#define XFN2(plugin, export) {#plugin, #export, (void*)plugin##_##export}
! #if !defined(HEADLESS)
! int primitivePluginBrowserReady(void);
! int primitivePluginRequestURLStream(void);
! int primitivePluginRequestURL(void);
! int primitivePluginPostURL(void);
! int primitivePluginRequestFileHandle(void);
! int primitivePluginDestroyRequest(void);
! int primitivePluginRequestState(void);
! void *ioGetDisplay(void);
! void *ioGetWindow(void);
! #endif
! void *os_exports[][3]=
! {
! #if !defined(HEADLESS)
! XFN(primitivePluginBrowserReady),
! XFN(primitivePluginRequestURLStream),
! XFN(primitivePluginRequestURL),
! XFN(primitivePluginPostURL),
! XFN(primitivePluginRequestFileHandle),
! XFN(primitivePluginDestroyRequest),
! XFN(primitivePluginRequestState),
! XFN(ioGetDisplay),
! XFN(ioGetWindow),
! #endif
! { 0, 0, 0 }
};
Index: sqConfig.h
===================================================================
RCS file: /cvsroot/squeak/squeak/platforms/unix/vm/sqConfig.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** sqConfig.h 24 Oct 2001 23:14:16 -0000 1.1.1.1
--- sqConfig.h 12 May 2003 07:39:08 -0000 1.2
***************
*** 1,9 ****
/* Unix sqConfig.h -- platform identification and configuration */
-
/* This file has been superseded by autoconf for Unix variants. */
! #if defined(HAVE_CONFIG_H)
! # include "sqUnixConfig.h"
! # define SQ_CONFIG_DONE
#endif
--- 1,9 ----
/* Unix sqConfig.h -- platform identification and configuration */
/* This file has been superseded by autoconf for Unix variants. */
! #include "config.h"
!
! #ifndef UNIX
! # define UNIX
#endif
Index: sqPlatformSpecific.h
===================================================================
RCS file: /cvsroot/squeak/squeak/platforms/unix/vm/sqPlatformSpecific.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** sqPlatformSpecific.h 2 Mar 2002 19:33:09 -0000 1.7
--- sqPlatformSpecific.h 12 May 2003 07:39:08 -0000 1.8
***************
*** 1,81 ****
! /* Unix sqPlatformSpecific.h -- Platform-specific prototypes and definitions */
!
! /* How to use this file:
! This file is for general platform-specific macros and declarations.
! The goal is to keep most of the other header files generic across platforms.
! To override a definition or macro from sq.h, you must first #undef it, then
! provide the new definition.
!
! */
!
!
! #ifndef SQ_PLATFORM_SPECIFIC_H
! #define SQ_PLATFORM_SPECIFIC_H
!
! #ifdef UNIX
! #include <string.h>
! #include <stdio.h>
! #include <unistd.h>
!
!
! /* off_t should be available (XXX though really, we should
! autoconf-check this, and substitute whatever fseeko is using) */
! typedef off_t squeakFileOffsetType;
!
! #undef sqFTruncate
! #undef fseek
! #undef ftell
!
!
! #define sqFTruncate(fp, offs) ftruncate(fileno(fp),offs)
! #define fseek(fp, offs,type) fseeko(fp, offs,type)
! #define ftell(fp) ftello(fp)
! /* unix-specific prototypes and definitions */
! void aioPollForIO(int microSeconds, int extraFd); /* XXX should no longer be needed -lex */
! #define SQ_FORM_FILENAME "squeak-form.ppm"
- /* undefine clock macros that are implemented as functions */
#undef ioMSecs
#undef ioMicroMSecs
#undef ioLowResMSecs
!
!
! /* use non-default heap-allocation functions; see sqUnixMemory.c */
! #undef sqAllocateMemory
! #undef sqGrowMemoryBy
! #undef sqShrinkMemoryBy
! #undef sqMemoryExtraBytesLeft
!
! void * sqAllocateMemory(int minHeapSize, int desiredHeapSize);
! int sqGrowMemoryBy(int oldLimit, int delta);
! int sqShrinkMemoryBy(int oldLimit, int delta);
! int sqMemoryExtraBytesLeft(int includingSwap);
!
!
!
!
!
! #ifdef sqImageFileOpen /* this is horrible, but is necessary because
! plugins don't include sq.h; so, we should
! redefine these macros only when all of sq.h
! is being used */
!
! /* use non-default image IO functions; see sqUnixImage.c */
! #undef sqImageFileOpen
! #undef sqImageFileStartLocation
!
! sqImageFile sqImageFileOpen(const char *fileName, const char *mode);
! int sqImageFileStartLocation(sqImageFile file, const char *fileName, int size);
! #endif
!
!
! #else
!
! #error This sqPlatformSpecific.h file is for Unix; you either have the wrong source code, or you forgot to -DUNIX
!
! #endif /* UNIX */
!
! #endif /* SQ_PLATFORM_SPECIFIC_H */
--- 1,46 ----
! /* sqPlatformSpecific.h -- platform-specific modifications to sq.h
! *
! * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
! * as listed elsewhere in this file.
! * All rights reserved.
! *
! * This file is part of Unix Squeak.
! *
! * This file is distributed in the hope that it will be useful, but WITHOUT
! * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
! * FITNESS FOR A PARTICULAR PURPOSE.
! *
! * You may use and/or distribute this file ONLY as part of Squeak, under
! * the terms of the Squeak License as described in `LICENSE' in the base of
! * this distribution, subject to the following restrictions:
! *
! * 1. The origin of this software must not be misrepresented; you must not
! * claim that you wrote the original software. If you use this software
! * in a product, an acknowledgment to the original author(s) (and any
! * other contributors mentioned herein) in the product documentation
! * would be appreciated but is not required.
! *
! * 2. This notice must not be removed or altered in any source distribution.
! *
! * Using (or modifying this file for use) in any context other than Squeak
! * changes these copyright conditions. Read the file `COPYING' in the
! * directory `platforms/unix/doc' before proceeding with any such use.
! *
! * You are not allowed to distribute a modified version of this file
! * under its original name without explicit permission to do so. If
! * you change it, rename it.
! *
! * Author: ian...@in...
! *
! * Last edited: 2002-06-08 02:34:43 by piumarta on emilia.inria.fr
! */
! /* undefine clock macros (these are implemented as functions) */
#undef ioMSecs
#undef ioMicroMSecs
#undef ioLowResMSecs
+ #include <sys/types.h>
! typedef off_t squeakFileOffsetType;
Index: sqUnixExternalPrims.c
===================================================================
RCS file: /cvsroot/squeak/squeak/platforms/unix/vm/sqUnixExternalPrims.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** sqUnixExternalPrims.c 5 May 2002 01:21:43 -0000 1.2
--- sqUnixExternalPrims.c 12 May 2003 07:39:09 -0000 1.3
***************
*** 1,6 ****
/* sqUnixExternalPrims.c -- Unix named primitives and loadable modules
*
! * Copyright (C) 1996 1997 1998 1999 2000 2001 Ian Piumarta and individual
! * authors/contributors listed elsewhere in this file.
* All rights reserved.
*
--- 1,6 ----
/* sqUnixExternalPrims.c -- Unix named primitives and loadable modules
*
! * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
! * as listed elsewhere in this file.
* All rights reserved.
*
***************
*** 21,43 ****
* would be appreciated but is not required.
*
! * 2. This notice may not be removed or altered in any source distribution.
*
! * Using or modifying this file for use in any context other than Squeak
! * changes these copyright conditions. Read the file `COPYING' in the base
! * of the distribution before proceeding with any such use.
*
! * You are STRONGLY DISCOURAGED from distributing a modified version of
! * this file under its original name without permission. If you must
! * change it, rename it first.
*/
/* Author: Ian...@IN...
*
! * Last edited: 2001-07-23 14:45:39 CEST by piumarta on emilia.inria.fr
*/
#include "sq.h" /* sqUnixConfig.h */
! #ifdef HAVE_LIBDL /* non-starter without this! */
#ifdef HAVE_DLFCN_H
--- 21,55 ----
* would be appreciated but is not required.
*
! * 2. This notice must not be removed or altered in any source distribution.
*
! * Using (or modifying this file for use) in any context other than Squeak
! * changes these copyright conditions. Read the file `COPYING' in the
! * directory `platforms/unix/doc' before proceeding with any such use.
*
! * You are not allowed to distribute a modified version of this file
! * under its original name without explicit permission to do so. If
! * you change it, rename it.
*/
/* Author: Ian...@IN...
*
! * Last edited: 2003-01-29 21:51:13 by piumarta on emilia.local.
*/
#include "sq.h" /* sqUnixConfig.h */
! #define DEBUG 0
!
! #if DEBUG
! # define dprintf(ARGS) fprintf ARGS
! #else
! # define dprintf(ARGS)
! #endif
!
! #if defined(HAVE_DYLD)
! # include "dlfcn-dyld.c"
! #endif
!
! #if defined(HAVE_LIBDL) /* non-starter without this! */
#ifdef HAVE_DLFCN_H
***************
*** 46,50 ****
extern void *dlopen (const char *filename, int flag);
extern const char *dlerror(void);
! extern void *dlsym(void *handle, char *symbol);
extern int dlclose (void *handle);
#endif
--- 58,62 ----
extern void *dlopen (const char *filename, int flag);
extern const char *dlerror(void);
! extern void *dlsym(void *handle, const char *symbol);
extern int dlclose (void *handle);
#endif
***************
*** 67,77 ****
# endif
#endif
!
! #undef DEBUG
!
! #ifdef DEBUG
! # define dprintf(ARGS) fprintf ARGS
! #else
! # define dprintf(ARGS)
#endif
--- 79,85 ----
# endif
#endif
!
! #if !defined(RTLD_GLOBAL)
! # define RTLD_GLOBAL 0
#endif
***************
*** 89,92 ****
--- 97,108 ----
+ /*** options ***/
+
+ extern char *squeakPlugins;
+
+ /*** configured variables ***/
+
+ char *vmLibDir= VM_LIBDIR;
+
/*** local functions ***/
***************
*** 96,132 ****
* library could not be loaded.
*/
! static void *tryLoading(char *prefix, char *moduleName, char *suffix)
{
! char libName[NAME_MAX + 32]; /* headroom for prefix/suffix */
! void *handle;
! sprintf(libName, "%s%s%s", prefix, moduleName, suffix);
! dprintf(("tryLoading %s\n", libName));
! handle= dlopen(libName, RTLD_NOW);
! if (handle == 0)
! {
! /* to preserve the humour of Jitter hackers: try to differentiate
! between "file not found" and a genuine load error (which would be
! difficult to diagnose out of context) when the lib is in the CWD */
! struct stat buf;
! if (/*(strcmp(prefix, "./") == 0)
! && (strcmp(suffix, ".so") == 0)
! && */ (stat(libName, &buf) == 0))
! {
! /* insist on the error message: the shared lib really _is_ broken */
! if (!(S_ISDIR(buf.st_mode)))
{
! fprintf(stderr, "ioLoadModule(%s): %s\n", libName, dlerror());
}
! }
! else
{
! dprintf(("not found\n"));
}
}
- else
- {
- dprintf((stderr, "loaded: %s\n", libName));
- }
return handle;
}
--- 112,173 ----
* library could not be loaded.
*/
! static void *tryLoading(char *dirName, char *moduleName)
{
! static char *prefixes[]= { "", "lib", 0 };
! static char *suffixes[]= { "", ".so", ".dylib", 0 };
! void *handle= 0;
! char **prefix= 0, **suffix= 0;
! for (prefix= prefixes; *prefix; ++prefix)
! for (suffix= suffixes; *suffix; ++suffix)
! {
! char libName[NAME_MAX + 32]; /* headroom for prefix/suffix */
! struct stat buf;
! int err;
! sprintf(libName, "%s%s%s%s", dirName, *prefix, moduleName, *suffix);
! if (((err= stat(libName, &buf)) == 0) && (S_ISDIR(buf.st_mode)))
! dprintf((stderr, "ignoring directory: %s\n", libName));
! else
{
! dprintf((stderr, "tryLoading %s\n", libName));
! handle= dlopen(libName, RTLD_NOW | RTLD_GLOBAL);
! if (handle == 0)
! {
! if (err == 0)
! fprintf(stderr, "ioLoadModule(%s):\n %s\n", libName, dlerror());
! }
! else
! {
! dprintf((stderr, "loaded: %s\n", libName));
! return handle;
! }
}
! }
! return 0;
! }
!
!
! static void *tryLoadingPath(char *varName, char *pluginName)
! {
! char *path= getenv(varName);
! void *handle= 0;
!
! if (path)
! {
! char pbuf[MAXPATHLEN];
! dprintf((stderr, "try %s=%s\n", varName, path));
! strncpy(pbuf, path, sizeof(pbuf));
! pbuf[sizeof(pbuf) - 1]= '\0';
! for (path= strtok(pbuf, ":");
! path != 0;
! path= strtok(0, ":"))
{
! char buf[MAXPATHLEN];
! sprintf(buf, "%s/", path);
! dprintf((stderr, " path dir = %s\n", buf));
! if ((handle= tryLoading(buf, pluginName)) != 0)
! break;
}
}
return handle;
}
***************
*** 142,190 ****
if ((pluginName == 0) || (pluginName[0] == '\0'))
{
! handle = dlopen(0, RTLD_NOW);
if (handle == 0)
fprintf(stderr, "ioLoadModule(<intrinsic>): %s\n", dlerror());
else
- dprintf((stderr, "loaded: <intrinsic>\n"));
- }
- else
- {
- (void)(/* these are ordered such that a knowledgeable user can
- override a "system" library with one in the CWD */
- ( handle= tryLoading( "./", pluginName, ".so"))
- /* these are the normal cases: when LD_LIBRARY_PATH is not
- set they search /etc/ld.so.cache, /usr/lib and /lib */
- || (handle= tryLoading( "", pluginName, ".so"))
- || (handle= tryLoading( "", pluginName, ""))
- /* this is the standard location for the plugins */
- || (handle= tryLoading(SQ_LIBDIR"/", pluginName, ".so"))
- || (handle= tryLoading( "lib", pluginName, "" ))
- || (handle= tryLoading( "lib", pluginName, ".so")));
- }
-
- if (handle == 0)
- {
- /* ld.so is broken on some platforms: try LD_LIBRARY_PATH ourselves */
- char *path= getenv("LD_LIBRARY_PATH");
- dprintf(("try LD_LIBRARY_PATH %s\n", path));
- if (path != 0)
{
! char pbuf[MAXPATHLEN];
! strncpy(pbuf, path, sizeof(pbuf));
! pbuf[sizeof(pbuf) - 1]= '\0';
! for (path= strtok(pbuf, ":");
! path != 0;
! path= strtok(0, ":"))
! {
! char buf[MAXPATHLEN];
! sprintf(buf, "%s/", path);
! dprintf(("LD_LIBRARY_PATH dir = %s\n", buf));
! if ((handle= tryLoading(buf, pluginName, ".so")) != 0)
! break;
! }
}
}
! return (int)handle;
}
--- 183,239 ----
if ((pluginName == 0) || (pluginName[0] == '\0'))
{
! handle= dlopen(0, RTLD_NOW | RTLD_GLOBAL);
if (handle == 0)
fprintf(stderr, "ioLoadModule(<intrinsic>): %s\n", dlerror());
else
{
! dprintf((stderr, "loaded: <intrinsic>\n"));
! return (int)handle;
}
}
! if (squeakPlugins)
! {
! char path[NAME_MAX];
! char c, *in= squeakPlugins, *out= path;
! while ((c= *in++))
! {
! if (c == '%' && ((*in == 'n') || (*in == 'N')))
! {
! ++in;
! strcpy(out, pluginName);
! out+= strlen(pluginName);
! }
! else
! *out++= c;
! }
! *out= '\0';
! dprintf((stderr, "ioLoadModule plugins = %s\n path = %s\n",
! squeakPlugins, path));
! if ((handle= tryLoading("", path)))
! return (int)handle;
! *out++= '/';
! *out= '\0';
! if ((handle= tryLoading(path, pluginName)))
! return (int)handle;
! }
!
! /* these are ordered such that a knowledgeable user can override a
! "system" library with one in the CWD */
!
! if (( handle= tryLoading( "./", pluginName))
! /* this is the standard location for the plugins */
! || (handle= tryLoading(VM_LIBDIR"/", pluginName))
! /* this is the default case: when LD_LIBRARY_PATH is not
! it searches /etc/ld.so.cache, /lib and /usr/lib */
! || (handle= tryLoading( "", pluginName))
! /* try SQUEAK_PLUGIN_PATH and LD_LIBRARY_PATH if set */
! || (handle= tryLoadingPath("SQUEAK_PLUGIN_PATH", pluginName))
! || (handle= tryLoadingPath("LD_LIBRARY_PATH", pluginName)))
! return (int)handle;
!
! dprintf(("ioLoadModule: could not load: %s\n", pluginName));
!
! return 0;
}
***************
*** 201,208 ****
if (fn == 0)
! {
! dprintf((stderr, "ioFindExternalFunctionIn(%s, %d):\n %s\n",
! lookupName, moduleHandle, dlerror()));
! }
return (int)fn;
--- 250,257 ----
if (fn == 0)
! dprintf((stderr, "ioFindExternalFunctionIn(%s, %d):\n %s\n",
! lookupName, moduleHandle, dlerror()));
! else
! dprintf((stderr, " => %d (0x%x)\n", (int)fn, (int)fn));
return (int)fn;
***************
*** 213,217 ****
/* Free the module with the associated handle. Answer 0 on error (do
* NOT fail the primitive!).
! */
int ioFreeModule(int moduleHandle)
{
--- 262,266 ----
/* Free the module with the associated handle. Answer 0 on error (do
* NOT fail the primitive!).
! */
int ioFreeModule(int moduleHandle)
{
Index: sqUnixMozilla.c
===================================================================
RCS file: /cvsroot/squeak/squeak/platforms/unix/vm/sqUnixMozilla.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** sqUnixMozilla.c 7 Mar 2002 23:52:49 -0000 1.5
--- sqUnixMozilla.c 12 May 2003 07:39:09 -0000 1.6
***************
*** 3,7 ****
* Author: Bert Freudenberg <be...@is...>
*
! * Last edited: Tue 05 Mar 2002 09:52:03 by bert on balloon
*
* Originally based on Andreas Raab's sqWin32PluginSupport
--- 3,7 ----
* Author: Bert Freudenberg <be...@is...>
*
! * Last edited: 2002-09-27 19:58:30 by piumarta on emilia.inria.fr
*
* Originally based on Andreas Raab's sqWin32PluginSupport
***************
*** 33,37 ****
debug= (NULL != getenv("NPSQUEAK_DEBUG"));
! if (!debug)
{
return;
--- 33,37 ----
debug= (NULL != getenv("NPSQUEAK_DEBUG"));
! if (!debug)
{
return;
***************
*** 45,49 ****
}
! {
va_list ap;
va_start(ap, format);
--- 45,49 ----
}
! if (file) {
va_list ap;
va_start(ap, format);
***************
*** 55,59 ****
}
#else
! static int DPRINT(char *, ...) { }
#endif
--- 55,59 ----
}
#else
! void DPRINT(char *, ...) { }
#endif
***************
*** 88,94 ****
--- 88,96 ----
static void browserGetURLRequest(int id, char* url, int urlSize,
char* target, int targetSize);
+ #ifdef NOT_USED
static void browserPostURLRequest(int id, char* url, int urlSize,
char* target, int targetSize,
char* postData, int postDataSize);
+ #endif
typedef struct sqStreamRequest {
***************
*** 127,132 ****
int primitivePluginBrowserReady()
{
! pop(1);
! pushBool(inBrowser);
return 1;
}
--- 129,139 ----
int primitivePluginBrowserReady()
{
! if (inBrowser)
! {
! pop(1);
! pushBool(1);
! }
! else
! primitiveFail();
return 1;
}
***************
*** 239,243 ****
sqStreamRequest *req;
int id, fileOop, openFn;
- SQFile* file;
id= stackIntegerValue(0);
--- 246,249 ----
***************
*** 254,272 ****
DPRINT("VM: Creating file handle for %s\n", req->localName);
! fileOop= instantiateClassindexableSize(classByteArray(), sizeof(SQFile));
! if (!isBytes(fileOop)) return primitiveFail();
!
! file= firstIndexableField(fileOop);
!
! /* this opens a file w/o security checks - I wonder if this is a security hole? */
! openFn= ioLoadFunctionFrom("fileOpennamesizewrite", "FilePlugin");
if (!openFn)
! {
! DPRINT("VM: Couldn't load function from FilePlugin!\n");
! return primitiveFail();
! }
!
! ((int (*) (SQFile *, int, int,int)) openFn)
! (firstIndexableField(fileOop), (int)req->localName, strlen(req->localName), 0);
if (failed())
--- 260,280 ----
DPRINT("VM: Creating file handle for %s\n", req->localName);
! openFn= ioLoadFunctionFrom("fileOpenNamesizewritesecure", "FilePlugin");
if (!openFn)
! {
! DPRINT("VM: Couldn't load fileOpenName:size:write:secure: from FilePlugin!\n");
! return primitiveFail();
! }
!
! fileOop= ((int (*) (char *, int, int, int)) openFn)
! (req->localName, strlen(req->localName), 0 /* readonly */, 0 /* insecure */);
!
! /* if file ends in a $, it was a temp link created by the plugin */
! if ('$' == req->localName[strlen(req->localName) - 1])
! {
! DPRINT("VM: unlink %s\n", req->localName);
! if (-1 == unlink(req->localName))
! DPRINT("VM: unlink failed: %s\n", strerror(errno));
! }
if (failed())
***************
*** 424,427 ****
--- 432,436 ----
Notify plugin to post data to the specified url and get result into target
*/
+ #ifdef NOT_USED
static void browserPostURLRequest(int id, char* url, int urlSize,
char* target, int targetSize,
***************
*** 449,452 ****
--- 458,462 ----
browserSend(postData, postDataSize);
}
+ #endif
***************
*** 459,463 ****
Handle commands sent by the plugin.
*/
! void browserProcessCommand()
{
static int firstTime= 1;
--- 469,473 ----
Handle commands sent by the plugin.
*/
! void browserProcessCommand(void)
{
static int firstTime= 1;
Index: sqXWindow.c
===================================================================
RCS file: /cvsroot/squeak/squeak/platforms/unix/vm/sqXWindow.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -d -r1.32 -r1.33
*** sqXWindow.c 29 Apr 2002 21:49:17 -0000 1.32
--- sqXWindow.c 12 May 2003 07:39:09 -0000 1.33
***************
*** 1,6 ****
/* sqXWindow.c -- support for Unix and the X Window System.
*
! * Copyright (C) 1996 1997 1998 1999 2000 2001 Ian Piumarta and individual
! * authors/contributors listed elsewhere in this file.
* All rights reserved.
*
--- 1,6 ----
/* sqXWindow.c -- support for Unix and the X Window System.
*
! * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
[...4223 lines suppressed...]
+ #else
+ return 0;
+ #endif
+ }
+
+
+ /* various thinks required by OSProcess when compiled headless */
+
+ #if defined(HEADLESS)
+
+ char *displayName= "";
+ int isConnectedToXServer= 0;
+
+ int openXDisplay(void) { return 0; }
+ int synchronizeXDisplay(void) { return 0; }
+ int disconnectXDisplay(void) { return 0; }
+ int forgetXDisplay(void) { return 0; }
+
+ #endif
+
Index: sunos.h
===================================================================
RCS file: /cvsroot/squeak/squeak/platforms/unix/vm/sunos.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** sunos.h 24 Oct 2001 23:14:20 -0000 1.1.1.1
--- sunos.h 12 May 2003 07:39:09 -0000 1.2
***************
*** 1,6 ****
/* It's a mystery to me why they even bothered with /usr/include on SunOS
*
! * Copyright (C) 1996 1997 1998 1999 2000 2001 Ian Piumarta and individual
! * authors/contributors listed elsewhere in this file.
* All rights reserved.
*
--- 1,6 ----
/* It's a mystery to me why they even bothered with /usr/include on SunOS
*
! * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
! * as listed elsewhere in this file.
* All rights reserved.
*
***************
*** 21,33 ****
* would be appreciated but is not required.
*
! * 2. This notice may not be removed or altered in any source distribution.
*
! * Using or modifying this file for use in any context other than Squeak
! * changes these copyright conditions. Read the file `COPYING' in the base
! * of the distribution before proceeding with any such use.
*
! * You are STRONGLY DISCOURAGED from distributing a modified version of
! * this file under its original name without permission. If you must
! * change it, rename it first.
*/
--- 21,33 ----
* would be appreciated but is not required.
*
! * 2. This notice must not be removed or altered in any source distribution.
*
! * Using (or modifying this file for use) in any context other than Squeak
! * changes these copyright conditions. Read the file `COPYING' in the
! * directory `platforms/unix/doc' before proceeding with any such use.
*
! * You are not allowed to distribute a modified version of this file
! * under its original name without explicit permission to do so. If
! * you change it, rename it.
*/
|
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:39:11
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/SoundPlugin
In directory sc8-pr-cvs1:/tmp/cvs-serv6251/plugins/SoundPlugin
Modified Files:
sqUnixSound.c
Log Message:
Ian Piumarta's release 3.4.1
Index: sqUnixSound.c
===================================================================
RCS file: /cvsroot/squeak/squeak/platforms/unix/plugins/SoundPlugin/sqUnixSound.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** sqUnixSound.c 28 Apr 2002 20:11:50 -0000 1.4
--- sqUnixSound.c 12 May 2003 07:39:07 -0000 1.5
***************
*** 1,1758 ****
/* sqUnixSound.c -- sound support for various Unix sound systems
*
! */
!
!
!
! #include "sq.h"
!
! #undef AUDIO_DRIVER_SELECTED /* will be defined as soon as one sound
! module matches. */
[...1794 lines suppressed...]
+ #include "sq.h"
+ #include "SoundPlugin.h"
! extern int snd_Stop(void);
***************
*** 1765,1768 ****
--- 58,62 ----
}
+
int soundShutdown(void)
{
***************
*** 1770,1772 ****
return 1;
}
-
--- 64,65 ----
|
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:39:10
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/SocketPlugin
In directory sc8-pr-cvs1:/tmp/cvs-serv6251/plugins/SocketPlugin
Modified Files:
sqUnixSocket.c
Log Message:
Ian Piumarta's release 3.4.1
Index: sqUnixSocket.c
===================================================================
RCS file: /cvsroot/squeak/squeak/platforms/unix/plugins/SocketPlugin/sqUnixSocket.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** sqUnixSocket.c 5 May 2002 12:29:55 -0000 1.4
--- sqUnixSocket.c 12 May 2003 07:39:04 -0000 1.5
***************
*** 1,6 ****
/* sqUnixSocket.c -- Unix socket support
*
! * Copyright (C) 1996 1997 1998 1999 2000 2001 Ian Piumarta and individual
! * authors/contributors listed elsewhere in this file.
* All rights reserved.
*
--- 1,6 ----
/* sqUnixSocket.c -- Unix socket support
*
! * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
[...1573 lines suppressed...]
severely grumpy after fixing several very unpleasant bugs that
somebody introduced into this file while i wasn't looking.) */
! *result= val;
return 0;
}
***************
*** 1370,1381 ****
}
- #if 0
- /* TPR - shouldn't be reuired now SocketPlugin is fixed */
- int ioCanCreateSocketOfType(int netType, int socketType) { return true; }
- int ioCanConnectToPort(int netAddr, int port) { return true; }
- int ioCanListenOnPort(SocketPtr s, int port) { return true; }
- int ioDisableSocketAccess(void) { return true; }
- int ioHasSocketAccess(void) { return true; }
- #endif
/*** Resolver functions ***/
--- 1302,1305 ----
|
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:27:00
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/JoystickTabletPlugin In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/JoystickTabletPlugin Added Files: sqUnixJoystickTablet.c Log Message: Ian Piumarta's release 3.4.1 |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:32
|
Update of /cvsroot/squeak/squeak/platforms/unix/vm In directory sc8-pr-cvs1:/tmp/cvs-serv30143/vm Added Files: Makefile.in aio.c aio.h dlfcn-dyld.c Log Message: Ian Piumarta's release 3.4.1 --- NEW FILE: Makefile.in --- # Makefile for core VM -*- makefile -*- # # Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors # as listed elsewhere in this file. # All rights reserved. # # This file is part of Unix Squeak. # # This file is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. # # You may use and/or distribute this file ONLY as part of Squeak, under # the terms of the Squeak License as described in `LICENSE' in the base of # this distribution, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment to the original author(s) (and any # other contributors mentioned herein) in the product documentation # would be appreciated but is not required. # # 2. This notice must not be removed or altered in any source distribution. # # Using (or modifying this file for use) in any context other than Squeak # changes these copyright conditions. Read the file `COPYING' in the # directory `platforms/unix/doc' before proceeding with any such use. # # You are not allowed to distribute a modified version of this file # under its original name without explicit permission to do so. If # you change it, rename it. # # Author: ian...@in... # # Last edited: 2002-12-01 10:20:57 by piumarta on calvin.inria.fr [make_cfg] [make_plg] TARGET = vm$a OBJS = $(INTERP)$o sqNamedPrims$o sqVirtualMachine$o \ aio$o osExports$o sqUnixExternalPrims$o sqUnixMozilla$o sqXWindow$o XINCLUDES = [includes] -I$(topdir)/platforms/Cross/plugins/FilePlugin $(TARGET) : $(OBJS) Makefile $(LINK) $(TARGET) $(OBJS) $(RANLIB) $(TARGET) # rebuild sqNamedPrims.o if sqNamedPrims.h changes sqNamedPrims$o : $(srcdir)/vm/sqNamedPrims.h # rebuild sqExtPrims (VM_LIBDIR) sqXWin (VM_VERSION) if config.h changes sqUnixExternalPrims$o sqXWindow$o : ../config.h $(topdir)/platforms/unix/vm/dlfcn-dyld.c # GNUify the interpreter if needed gnu-interp$o : gnu-interp.c $(COMPILE) $@ gnu-interp.c gnu-interp.c : $(srcdir)/vm/interp.c $(AWK) -f $(topdir)/platforms/unix/config/gnuify $(srcdir)/vm/interp.c > $@.out mv $@.out $@ [make_targets] .force : --- NEW FILE: aio.c --- /* aio.c -- asynchronous file i/o * * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors * as listed elsewhere in this file. * All rights reserved. * * This file is part of Unix Squeak. * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You may use and/or distribute this file ONLY as part of Squeak, under * the terms of the Squeak License as described in `LICENSE' in the base of * this distribution, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment to the original author(s) (and any * other contributors mentioned herein) in the product documentation * would be appreciated but is not required. * * 2. This notice must not be removed or altered in any source distribution. * * Using (or modifying this file for use) in any context other than Squeak * changes these copyright conditions. Read the file `COPYING' in the * directory `platforms/unix/doc' before proceeding with any such use. * * You are not allowed to distribute a modified version of this file * under its original name without explicit permission to do so. If * you change it, rename it. */ /* Author: Ian...@in... * * Last edited: 2003-02-06 16:36:13 by piumarta on emilia.local. */ #include "aio.h" #ifdef HAVE_CONFIG_H # include "config.h" # ifdef HAVE_UNISTD_H # include <sys/types.h> # include <unistd.h> # endif /* HAVE_UNISTD_H */ # ifdef NEED_GETHOSTNAME_P extern int gethostname(); # endif # include <stdio.h> # include <signal.h> # include <errno.h> # include <sys/ioctl.h> # ifdef HAVE_SYS_TIME_H # include <sys/time.h> # else # include <time.h> # endif # ifdef HAS_SYS_SELECT_H # include <sys/select.h> # endif # ifndef FIONBIO # ifdef HAVE_SYS_FILIO_H # include <sys/filio.h> # endif # ifndef FIONBIO # ifdef FIOSNBIO # define FIONBIO FIOSNBIO # else # error: FIONBIO is not defined # endif # endif # endif #else /* !HAVE_CONFIG_H -- assume lowest common demoninator */ # include <stdio.h> # include <stdlib.h> # include <unistd.h> # include <errno.h> # include <signal.h> # include <sys/types.h> # include <sys/time.h> # include <sys/select.h> # include <sys/ioctl.h> #endif #undef DEBUG #ifdef DEBUG # define FPRINTF(X) fprintf X static char *ticks= "-\\|/"; static char *ticker= ""; #define DO_TICK() \ { \ fprintf(stderr, "\r%c\r", *ticker); \ if (!*ticker++) ticker= ticks; \ } #else /* !DEBUG */ # define FPRINTF(X) # define DO_TICK() #endif #define _DO_FLAG_TYPE() _DO(AIO_R, rd) _DO(AIO_W, wr) _DO(AIO_X, ex) static int one= 1; static aioHandler rdHandler[FD_SETSIZE]; static aioHandler wrHandler[FD_SETSIZE]; static aioHandler exHandler[FD_SETSIZE]; static void *clientData[FD_SETSIZE]; static int maxFd; static fd_set fdMask; /* handled by aio */ static fd_set rdMask; /* handle read */ static fd_set wrMask; /* handle write */ static fd_set exMask; /* handle exception */ static fd_set xdMask; /* external descriptor */ static void undefinedHandler(int fd, void *clientData, int flags) { fprintf(stderr, "undefined handler called (fd %d, flags %x)\n", fd, flags); } #ifdef DEBUG static char *handlerName(aioHandler h) { if (h == undefinedHandler) return "undefinedHandler"; #ifdef DEBUG_SOCKETS { extern char *socketHandlerName(aioHandler); return socketHandlerName(h); } #endif return "***unknown***"; } #endif /* initialise asynchronous i/o */ void aioInit(void) { FD_ZERO(&fdMask); FD_ZERO(&rdMask); FD_ZERO(&wrMask); FD_ZERO(&exMask); FD_ZERO(&xdMask); maxFd= 0; signal(SIGPIPE, SIG_IGN); } /* disable handlers and close all handled non-exteral descriptors */ void aioFini(void) { int fd; for (fd= 0; fd < maxFd; fd++) if (FD_ISSET(fd, &fdMask) && !(FD_ISSET(fd, &xdMask))) { aioDisable(fd); close(fd); FD_CLR(fd, &fdMask); FD_CLR(fd, &rdMask); FD_CLR(fd, &wrMask); FD_CLR(fd, &exMask); } while (maxFd && !FD_ISSET(maxFd - 1, &fdMask)) --maxFd; signal(SIGPIPE, SIG_DFL); } /* poll for i/o activity, with microSeconds wait */ int aioPoll(int microSeconds) { int fd; fd_set rd, wr, ex; struct timeval tv; DO_TICK(); /* get out early if there is no pending i/o and no need to relinquish cpu */ if ((maxFd == 0) && (microSeconds == 0)) return 0; rd= rdMask; wr= wrMask; ex= exMask; tv.tv_sec= microSeconds / 1000000; tv.tv_usec= microSeconds % 1000000; { int result; do { result= select(maxFd, &rd, &wr, &ex, &tv); } while ((result < 0) && (errno == EINTR)); if (result < 0) perror("select"); else if (result > 0) { for (fd= 0; fd < maxFd; ++fd) { # define _DO(FLAG, TYPE) \ { \ if (FD_ISSET(fd, &TYPE)) \ { \ aioHandler handler= TYPE##Handler[fd]; \ FD_CLR(fd, &TYPE##Mask); \ TYPE##Handler[fd]= undefinedHandler; \ handler(fd, clientData[fd], FLAG); \ } \ } _DO_FLAG_TYPE(); # undef _DO } } } return 0; } /* enable asynchronous notification for a descriptor */ void aioEnable(int fd, void *data, int flags) { FPRINTF((stderr, "aioEnable(%d)\n", fd)); if (FD_ISSET(fd, &fdMask)) { fprintf(stderr, "aioEnable: descriptor %d already enabled\n", fd); return; } clientData[fd]= data; rdHandler[fd]= wrHandler[fd]= exHandler[fd]= undefinedHandler; FD_SET(fd, &fdMask); FD_CLR(fd, &rdMask); FD_CLR(fd, &wrMask); FD_CLR(fd, &exMask); if (fd >= maxFd) maxFd= fd + 1; if (flags & AIO_EXT) { FD_SET(fd, &xdMask); /* we should not set NBIO ourselves on external descriptors! */ } else { FD_CLR(fd, &xdMask); if (ioctl(fd, FIONBIO, (char *)&one) < 0) perror("ioctl(FIONBIO, 1)"); } } /* install/change the handler for a descriptor */ void aioHandle(int fd, aioHandler handlerFn, int mask) { FPRINTF((stderr, "aioHandle(%d, %s, %d)\n", fd, handlerName(handlerFn), mask)); # define _DO(FLAG, TYPE) \ if (mask & FLAG) { \ FD_SET(fd, &TYPE##Mask); \ TYPE##Handler[fd]= handlerFn; \ } _DO_FLAG_TYPE(); # undef _DO } /* temporarily suspend asynchronous notification for a descriptor */ void aioSuspend(int fd, int mask) { FPRINTF((stderr, "aioSuspend(%d)\n", fd)); # define _DO(FLAG, TYPE) \ { \ if (mask & FLAG) \ { \ FD_CLR(fd, &TYPE##Mask); \ TYPE##Handler[fd]= undefinedHandler; \ } \ } _DO_FLAG_TYPE(); # undef _DO } /* definitively disable asynchronous notification for a descriptor */ void aioDisable(int fd) { FPRINTF((stderr, "aioDisable(%d)\n", fd)); aioSuspend(fd, AIO_RWX); FD_CLR(fd, &xdMask); FD_CLR(fd, &fdMask); rdHandler[fd]= wrHandler[fd]= exHandler[fd]= 0; clientData[fd]= 0; /* keep maxFd accurate (drops to zero if no more sockets) */ while (maxFd && !FD_ISSET(maxFd - 1, &fdMask)) --maxFd; } --- NEW FILE: aio.h --- /* aio.h -- asynchronous file i/o * * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors * as listed elsewhere in this file. * All rights reserved. * * This file is part of Unix Squeak. * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You may use and/or distribute this file ONLY as part of Squeak, under * the terms of the Squeak License as described in `LICENSE' in the base of * this distribution, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment to the original author(s) (and any * other contributors mentioned herein) in the product documentation * would be appreciated but is not required. * * 2. This notice must not be removed or altered in any source distribution. * * Using (or modifying this file for use) in any context other than Squeak * changes these copyright conditions. Read the file `COPYING' in the * directory `platforms/unix/doc' before proceeding with any such use. * * You are not allowed to distribute a modified version of this file * under its original name without explicit permission to do so. If * you change it, rename it. */ /* author: ian...@in... * * last edited: 2003-02-06 16:34:35 by piumarta on emilia.local. */ #ifndef __aio_h #define __aio_h #define AIO_X (1<<0) /* handle for exceptions */ #define AIO_R (1<<1) /* handle for read */ #define AIO_W (1<<2) /* handle for write */ #define AIO_SEQ (1<<3) /* call handlers sequentially */ #define AIO_EXT (1<<4) /* external fd -- don't close on aio shutdown */ #define AIO_RW (AIO_R | AIO_W) #define AIO_RX (AIO_R | AIO_X) #define AIO_WX (AIO_W | AIO_X) #define AIO_RWX (AIO_R | AIO_W | AIO_X) extern void aioInit(void); extern void aioFini(void); /* Initialise `fd' for handling by AIO. `flags' can be 0 (aio takes * over the descriptor entirely and the application should not assume * anything about its subsequent behaviour) or AIO_EXT (aio will never * set NBIO on `fd' or close it on behalf of the client). */ extern void aioEnable(int fd, void *clientData, int flags); /* Declare an interest in one or more events on `fd'. `mask' can be * any combination in AIO_[R][W][X]. `handlerFn' will be called the * next time any event in `mask' arrives on `fd' and will receive * `fd', the original `clientData' (see aioEnable) and a `flag' * containing ONE of AIO_{R,W,X} indicating which event occurred. In * the event that the same handler is set for multiple events (either * by setting more than one bit in `mask', or by calling aioHandle * several times with different `mask's) and several events arrive * simultaneously for the descriptor, then `handlerFn' is called * multiple times -- once for each event in `mask'. The `handlerFn' * will NOT be called again for the same event until the client calls * aioHandle with an appropriate `mask' (the handled event is removed * implicitly from the current mask before calling `handlerFn') . * (Calls to aioHandle are cumulative: successive `mask's are ORed * with the mask currently in effect for `fd'.) */ typedef void (*aioHandler)(int fd, void *clientData, int flag); extern void aioHandle(int fd, aioHandler handlerFn, int mask); /* Suspend handling of the events in `mask' for `fd'. */ extern void aioSuspend(int fd, int mask); /* Disable further AIO handling of `fd'. The descriptor is reset to its * default state (w.r.t. NBIO, etc.) but is NOT closed. */ extern void aioDisable(int fd); /* Sleep for at most `microSeconds'. Any event(s) arriving for any * handled fd(s) will terminate the sleep, with the appropriate * handler(s) being called before returning. */ extern int aioPoll(int microSeconds); #endif /* __aio_h */ --- NEW FILE: dlfcn-dyld.c --- /* dlfcn-darwin.c -- provides dlopen() and friends as wrappers to Mach's dylib * * Author: Ian...@IN... * * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors * as listed elsewhere in this file. * All rights reserved. * * This file is part of Unix Squeak. * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You may use and/or distribute this file ONLY as part of Squeak, under * the terms of the Squeak License as described in `LICENSE' in the base of * this distribution, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment to the original author(s) (and any * other contributors mentioned herein) in the product documentation * would be appreciated but is not required. * * 2. This notice must not be removed or altered in any source distribution. * * Using (or modifying this file for use) in any context other than Squeak * changes these copyright conditions. Read the file `COPYING' in the * directory `platforms/unix/doc' before proceeding with any such use. * * You are not allowed to distribute a modified version of this file * under its original name without explicit permission to do so. If * you change it, rename it. * * Last edited: 2002-12-01 10:28:43 by piumarta on calvin.inria.fr */ #include <stdio.h> #include <stdarg.h> #include <mach-o/dyld.h> #define RTLD_NOW 0 #define RTLD_GLOBAL 0 #define DL_APP_CONTEXT ((void *)-1) static char dlErrorString[256]; static int dlErrorSet= 0; static void dlSetError(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vsnprintf(dlErrorString, sizeof(dlErrorString), fmt, ap); va_end(ap); dlErrorSet= 1; } static const char *dlerror(void) { if (dlErrorSet) { dlErrorSet= 0; return (const char *)dlErrorString; } return 0; } static void *dlopen(const char *path, int mode) { void *handle= 0; NSObjectFileImage ofi= 0; if (!path) return DL_APP_CONTEXT; switch (NSCreateObjectFileImageFromFile(path, &ofi)) { case NSObjectFileImageSuccess: handle= NSLinkModule(ofi, path, NSLINKMODULE_OPTION_RETURN_ON_ERROR); NSDestroyObjectFileImage(ofi); break; case NSObjectFileImageInappropriateFile: handle= (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); break; default: handle= 0; break; } if (!handle) dlSetError("could not load shared object: %s", path); return handle; } void *dlsym(void *handle, const char *symbol) { char _symbol[256]; NSSymbol *nsSymbol= 0; snprintf(_symbol, sizeof(_symbol), "_%s", symbol); dprintf((stderr, "dlsym: looking for %s (%s) in %d\n", symbol, _symbol, (int)handle)); if (!handle) { dprintf((stderr, "dlsym: setting app context for this handle\n")); handle= DL_APP_CONTEXT; } if (DL_APP_CONTEXT == handle) { dprintf((stderr, "dlsym: looking in app context\n")); if (NSIsSymbolNameDefined(_symbol)) nsSymbol= NSLookupAndBindSymbol(_symbol); } else { if (( (MH_MAGIC == ((struct mach_header *)handle)->magic)) /* ppc */ || (MH_CIGAM == ((struct mach_header *)handle)->magic)) /* 386 */ { if (NSIsSymbolNameDefinedInImage((struct mach_header *)handle, _symbol)) nsSymbol= NSLookupSymbolInImage ((struct mach_header *)handle, _symbol, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); dprintf((stderr, "dlsym: bundle (image) lookup returned %p\n", nsSymbol)); } else { nsSymbol= NSLookupSymbolInModule(handle, _symbol); dprintf((stderr, "dlsym: dylib (module) lookup returned %p\n", nsSymbol)); } } if (!nsSymbol) { dlSetError("symbol not found: %s", _symbol); return 0; } return NSAddressOfSymbol(nsSymbol); } int dlclose(void *handle) { if (( (MH_MAGIC == ((struct mach_header *)handle)->magic)) /* ppc */ || (MH_CIGAM == ((struct mach_header *)handle)->magic)) /* 386 */ return 0; /* can't unlink, but pretend we did */ if (!NSUnLinkModule(handle, 0)) { dlSetError("could not unlink shared object: %s", NSNameOfModule(handle)); return -1; } return 0; } /* autoconf has bugs */ #ifdef HAVE_DLFCN_H # undef HAVE_DLFCN_H #endif #ifndef HAVE_LIBDL # define HAVE_LIBDL #endif |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:32
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/SqueakFFIPrims/old
In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/SqueakFFIPrims/old
Added Files:
acinclude.m4 sqUnixFFI.c
Log Message:
Ian Piumarta's release 3.4.1
--- NEW FILE: acinclude.m4 ---
AC_CHECK_HEADER(ffi.h,
AC_CHECK_LIB(ffi, ffi_call,
AC_PLUGIN_USE_LIB(ffi),
AC_PLUGIN_DISABLE),
AC_PLUGIN_DISABLE)
--- NEW FILE: sqUnixFFI.c ---
/****************************************************************************
* PROJECT: Squeak foreign function interface
* FILE: sqUnixFFI.c
* CONTENT: Unix support for the foreign function interface
*
* AUTHOR: Andreas Raab (ar)
* ADDRESS: Walt Disney Imagineering, Glendale, CA
* EMAIL: and...@wd...
* RCSID: $Id: sqUnixFFI.c,v 1.1 2003/05/12 07:26:29 asparagi Exp $
*
* NOTES: The Unix version of the FFI support code relies on libffi from
* http://sourceware.cygnus.com/libffi/
*
*****************************************************************************/
#include "sq.h"
#include "sqFFI.h"
#ifndef NO_FFI_SUPPORT
#include <ffi.h>
#ifndef FFI_TYPE_STRUCT /* this is private in libffi-2 */
# define FFI_TYPE_STRUCT 13
#endif
extern struct VirtualMachine *interpreterProxy;
#define primitiveFail() interpreterProxy->primitiveFail()
#if 1
#define HAVE_LONGLONG
#endif
/* Check if HAVE_LONGLONG is defined (should be figured out by configure */
#ifdef HAVE_LONGLONG
#define HAS_LONGLONG 1
#define LONGLONG long long
#endif
/* Error if LONGLONG is not defined */
#if HAS_LONGLONG
#ifndef LONGLONG
#error "You must define LONGLONG if HAS_LONGLONG is defined"
#endif
#endif
/* Max number of arguments in call */
#define FFI_MAX_ARGS 32
static ffi_type* ffiTypes[FFI_MAX_ARGS];
static void* ffiArgs[FFI_MAX_ARGS];
static char ffiBytes[FFI_MAX_ARGS];
static short ffiShorts[FFI_MAX_ARGS];
static int ffiInts[FFI_MAX_ARGS];
static float ffiFloats[FFI_MAX_ARGS];
static double ffiDoubles[FFI_MAX_ARGS];
static int ffiArgIndex = 0;
static ffi_type* ffiStructTypes[FFI_MAX_ARGS];
static int ffiStructIndex = 0;
/* helpers */
#define CHECK_ARGS() if(ffiArgIndex >= FFI_MAX_ARGS) return primitiveFail();
#define PUSH_TYPE(type) { CHECK_ARGS(); ffiTypes[ffiArgIndex] = &type; }
#define PUSH(where, what, type) { \
PUSH_TYPE(type); where[ffiArgIndex] = what; \
ffiArgs[ffiArgIndex] = (void*) (where + ffiArgIndex); \
ffiArgIndex++;\
}
#define BARG_PUSH(value, type) PUSH(ffiBytes, value, type)
#define SARG_PUSH(value, type) PUSH(ffiShorts, value, type)
#define IARG_PUSH(value, type) PUSH(ffiInts, value, type)
#define FARG_PUSH(value) PUSH(ffiFloats, value, ffi_type_float)
#define DARG_PUSH(value) PUSH(ffiDoubles, value, ffi_type_double)
#if HAS_LONGLONG
static LONGLONG ffiLongLongs[FFI_MAX_ARGS];
#define LARG_PUSH(value, type) PUSH(ffiLongLongs, value, type)
#endif
/* The 64bit return value storage area - aligned by the C compiler */
static double returnValue;
/* Storage area for large structure returns */
static ffi_type* structReturnType = NULL;
static void *structReturnValue = NULL;
/* The area for temporarily allocated strings */
static char *ffiTempStrings[FFI_MAX_ARGS];
/* The number of temporarily allocated strings */
static int ffiTempStringCount = 0;
/*****************************************************************************/
/*****************************************************************************/
/* ffiInitialize:
Announce that the VM is about to do an external function call. */
int ffiInitialize(void)
{
ffiArgIndex = 0;
ffiTempStringCount = 0;
ffiStructIndex = 0;
structReturnType = NULL;
structReturnValue = NULL;
return 1;
}
/* ffiSupportsCallingConvention:
Return true if the support code supports the given calling convention */
int ffiSupportsCallingConvention(int callType)
{
if(callType == FFICallTypeCDecl) return 1;
return 0;
}
/* ffiAlloc:
Allocate space from the external heap */
int ffiAlloc(int byteSize)
{
return (int)malloc(byteSize);
}
/* ffiFree:
Free space from the external heap */
int ffiFree(int pointer)
{
if(pointer) free((void*)pointer);
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
int ffiPushSignedByte(int value)
{
BARG_PUSH((char)value, ffi_type_sint8);
return 1;
}
int ffiPushUnsignedByte(int value)
{
BARG_PUSH((char)value, ffi_type_uint8);
return 1;
}
int ffiPushSignedShort(int value)
{
SARG_PUSH((short)value, ffi_type_sint16);
return 1;
}
int ffiPushUnsignedShort(int value)
{
SARG_PUSH((short)value, ffi_type_uint16);
return 1;
}
int ffiPushSignedInt(int value)
{
IARG_PUSH(value, ffi_type_sint32);
return 1;
}
int ffiPushUnsignedInt(int value)
{
IARG_PUSH(value, ffi_type_uint32);
return 1;
}
int ffiPushSignedLongLong(int low, int high)
{
#if HAS_LONGLONG
LONGLONG value = (((LONGLONG) high) << 32) | ((LONGLONG) (unsigned) low);
LARG_PUSH(value, ffi_type_sint64);
return 1;
#else
return primitiveFail();
#endif
}
int ffiPushUnsignedLongLong(int low, int high)
{
#if HAS_LONGLONG
LONGLONG value = (((LONGLONG) high) << 32) | ((LONGLONG) (unsigned) low);
LARG_PUSH(value, ffi_type_uint64);
return 1;
#else
return primitiveFail();
#endif
}
int ffiPushSignedChar(int value)
{
BARG_PUSH(value, ffi_type_sint8);
return 1;
}
int ffiPushUnsignedChar(int value)
{
BARG_PUSH(value, ffi_type_uint8);
return 1;
}
int ffiPushBool(int value)
{
IARG_PUSH(value, ffi_type_uint8);
return 1;
}
int ffiPushSingleFloat(double value)
{
FARG_PUSH((float)value);
return 1;
}
int ffiPushDoubleFloat(double value)
{
DARG_PUSH(value);
return 1;
}
ffi_type* ffiCreateType(int *structSpec, int structSize)
{
ffi_type *structType, **newTypes;
int nTypes, i, typeSpec;
/* count the number of atomic types we need to create */
nTypes = 0;
for(i=0; i<structSize; i++) {
typeSpec = structSpec[i];
if(typeSpec & FFIFlagPointer) nTypes++;
else if(typeSpec & FFIFlagAtomic) nTypes++;
}
/* note: nTypes == 0 means an invalid structure */
if(nTypes == 0) {
printf("Warning: nTypes == 0 in ffiCreateTypes\n");
return NULL;
}
/* allocate the structure type */
structType = calloc(1, sizeof(ffi_type));
/* allocate the atomic type refs */
newTypes = calloc(nTypes+1, sizeof(ffi_type*));
/* number of elements in type */
structType->size = (*structSpec) & FFIStructSizeMask;
structType->alignment = 4;
structType->type = FFI_TYPE_STRUCT;
structType->elements = newTypes;
/* now go over the structure and fill in the fields */
nTypes = 0;
for(i=0; i<structSize; i++) {
typeSpec = structSpec[i];
if(typeSpec & FFIFlagPointer) {
newTypes[nTypes++] = &ffi_type_pointer;
continue;
}
if((typeSpec & FFIFlagAtomic) == 0) continue;
switch((typeSpec & FFIAtomicTypeMask) >> FFIAtomicTypeShift) {
case FFITypeBool:
newTypes[nTypes++] = &ffi_type_uint8; break;
case FFITypeUnsignedByte:
newTypes[nTypes++] = &ffi_type_uint8; break;
case FFITypeSignedByte:
newTypes[nTypes++] = &ffi_type_sint8; break;
case FFITypeUnsignedShort:
newTypes[nTypes++] = &ffi_type_uint16; break;
case FFITypeSignedShort:
newTypes[nTypes++] = &ffi_type_sint16; break;
case FFITypeUnsignedInt:
newTypes[nTypes++] = &ffi_type_uint32; break;
case FFITypeSignedInt:
newTypes[nTypes++] = &ffi_type_sint32; break;
case FFITypeUnsignedLongLong:
newTypes[nTypes++] = &ffi_type_uint64; break;
case FFITypeSignedLongLong:
newTypes[nTypes++] = &ffi_type_sint64; break;
case FFITypeUnsignedChar:
newTypes[nTypes++] = &ffi_type_uint8; break;
case FFITypeSignedChar:
newTypes[nTypes++] = &ffi_type_sint8; break;
case FFITypeSingleFloat:
newTypes[nTypes++] = &ffi_type_float; break;
case FFITypeDoubleFloat:
newTypes[nTypes++] = &ffi_type_double; break;
default:
printf("Warning: unknown atomic type (%x) in ffiCreateTypes\n",
typeSpec);
free(newTypes);
free(structType);
return NULL;
};
}
newTypes[nTypes++] = NULL;
return structType;
}
int ffiPushStructureOfLength(int pointer, int* structSpec, int structSize)
{
ffi_type *structType;
if(pointer == 0) return primitiveFail();
CHECK_ARGS(); /* fail early on */
structType = ffiCreateType(structSpec, structSize);
if(structType == NULL) return primitiveFail();
ffiStructTypes[ffiStructIndex++] = structType;
ffiTypes[ffiArgIndex] = structType;
ffiArgs[ffiArgIndex] = (void*) pointer;
ffiArgIndex++;
return 1;
}
int ffiPushPointer(int pointer)
{
IARG_PUSH(pointer, ffi_type_pointer);
return 1;
}
int ffiPushStringOfLength(int srcIndex, int length)
{
char *ptr;
ptr = (char*) malloc(length+1);
if(!ptr) return primitiveFail();
memcpy(ptr, (void*)srcIndex, length);
ptr[length] = 0;
ffiTempStrings[ffiTempStringCount++] = ptr;
IARG_PUSH((int)ptr, ffi_type_pointer);
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
/* ffiCanReturn:
Return true if the support code can return the given type. */
int ffiCanReturn(int *structSpec, int specSize)
{
int header = *structSpec;
if(header & FFIFlagPointer) return 1;
if(header & FFIFlagStructure) {
int structSize = header & FFIStructSizeMask;
structReturnType = ffiCreateType(structSpec, specSize);
if(!structReturnType) return 0;
if(structSize > 8) {
structReturnValue = calloc(1,structSize);
if(!structReturnValue) return 0;
return 1;
}
}
return 1;
}
/* ffiReturnFloatValue:
Return the value from a previous ffi call with float return type. */
double ffiReturnFloatValue(void)
{
return returnValue;
}
/* ffiLongLongResultLow:
Return the low 32bit from the 64bit result of a call to an external function */
int ffiLongLongResultLow(void)
{
#if HAS_LONGLONG
return (int) ( (*(LONGLONG*)&returnValue) & (LONGLONG)0xFFFFFFFFU);
#else
return 0;
#endif
}
/* ffiLongLongResultHigh:
Return the high 32bit from the 64bit result of a call to an external function */
int ffiLongLongResultHigh(void)
{
#if HAS_LONGLONG
return (int) ( (*(LONGLONG*)&returnValue) >> 32);
#else
return 0;
#endif
}
/* ffiStoreStructure:
Store the structure result of a previous ffi call into the given address*/
int ffiStoreStructure(int address, int structSize)
{
if(structReturnValue) {
memcpy((void*)address, (void*)structReturnValue, structSize);
} else {
memcpy((void*)address, (void*)&returnValue, structSize);
}
return 1;
}
/* ffiCleanup:
Cleanup after a foreign function call has completed.
The generic support code only frees the temporarily
allocated strings. */
int ffiCleanup(void)
{
int i;
for(i=0; i<ffiTempStringCount; i++)
free(ffiTempStrings[i]);
for(i=0; i<ffiStructIndex; i++) {
free(ffiStructTypes[i]->elements);
free(ffiStructTypes[i]);
ffiStructTypes[i]=NULL;
}
if(structReturnType) {
free(structReturnType->elements);
free(structReturnType);
structReturnType = NULL;
}
if(structReturnValue) {
free(structReturnValue);
structReturnValue = NULL;
}
ffiTempStringCount = 0;
ffiStructIndex = 0;
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
int ffiCallAddress(int fn, ffi_type *returnType, int atomicArgType)
{
ffi_cif cif;
ffi_status result;
int retVal;
result = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, ffiArgIndex,
returnType, ffiTypes);
if(result != FFI_OK) return primitiveFail();
if(structReturnValue) {
ffi_call(&cif, (void *)fn, (void *)structReturnValue, (void **)ffiArgs);
return (int) structReturnValue;
}
ffi_call(&cif, (void *)fn, (void *)&returnValue, (void **)ffiArgs);
retVal = *(int*)&returnValue;
#ifdef FFI_MIPS_N32
/* Note: MIPS N32 ABI returns 64bit for integer/pointer whatever.
This seems to be a bug in the fficall implementation. */
retVal = ((int*)(&returnValue))[1];
#endif
/* Promote certain return types to integral size */
switch(atomicArgType) {
case FFITypeUnsignedChar:
case FFITypeUnsignedByte: retVal = *(unsigned char*) &retVal; break;
case FFITypeSignedChar:
case FFITypeSignedByte: retVal = *(signed char*) &retVal; break;
case FFITypeUnsignedShort: retVal = *(unsigned short*) &retVal; break;
case FFITypeSignedShort: retVal = *(signed short*) &retVal; break;
case FFITypeSingleFloat: returnValue = *(float*)&returnValue; break;
}
return retVal;
}
int ffiCallAddressOfWithPointerReturn(int fn, int callType)
{
return ffiCallAddress(fn, &ffi_type_pointer,-1);
}
int ffiCallAddressOfWithStructReturn(int fn, int callType,
int *structSpec, int specSize)
{
if(!structReturnType) return primitiveFail();
return ffiCallAddress(fn, structReturnType,-1);
}
int ffiCallAddressOfWithReturnType(int fn, int callType, int typeSpec)
{
ffi_type *returnType;
int atomicType;
atomicType = (typeSpec & FFIAtomicTypeMask) >> FFIAtomicTypeShift;
switch(atomicType) {
case FFITypeVoid: returnType = &ffi_type_void; break;
case FFITypeBool: returnType = &ffi_type_uint8; break;
case FFITypeUnsignedByte: returnType = &ffi_type_uint8; break;
case FFITypeSignedByte: returnType = &ffi_type_sint8; break;
case FFITypeUnsignedShort: returnType = &ffi_type_uint16; break;
case FFITypeSignedShort: returnType = &ffi_type_sint16; break;
case FFITypeUnsignedInt: returnType = &ffi_type_uint32; break;
case FFITypeSignedInt: returnType = &ffi_type_sint32; break;
case FFITypeUnsignedLongLong: returnType = &ffi_type_uint64; break;
case FFITypeSignedLongLong: returnType = &ffi_type_sint64; break;
case FFITypeUnsignedChar: returnType = &ffi_type_uint8; break;
case FFITypeSignedChar: returnType = &ffi_type_sint8; break;
case FFITypeSingleFloat: returnType = &ffi_type_float; break;
case FFITypeDoubleFloat: returnType = &ffi_type_double; break;
default:
return primitiveFail();
}
return ffiCallAddress(fn, returnType, atomicType);
}
#endif /* NO_FFI_SUPPORT */
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/************ Test functions for the foreign function interface **************/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
#ifndef NO_FFI_TEST
typedef struct ffiTestPoint2 {
int x;
int y;
} ffiTestPoint2;
typedef struct ffiTestPoint4 {
int x;
int y;
int z;
int w;
} ffiTestPoint4;
typedef struct ffiTestPointMix {
int x;
double y;
int z;
double w;
} ffiTestPointMix;
#pragma export on
EXPORT(char) ffiTestChars(char c1, char c2, char c3, char c4);
EXPORT(short) ffiTestShorts(short c1, short c2, short c3, short c4);
EXPORT(int) ffiTestInts(int c1, int c2, int c3, int c4);
EXPORT(float) ffiTestFloats(float f1, float f2);
EXPORT(double) ffiTestDoubles(double d1, double d2);
EXPORT(char *) ffiPrintString(char *string);
EXPORT(ffiTestPoint2) ffiTestStruct64(ffiTestPoint2 pt1, ffiTestPoint2 pt2);
EXPORT(ffiTestPoint4) ffiTestStructBig(ffiTestPoint4 pt1, ffiTestPoint4 pt2);
EXPORT(ffiTestPoint4*) ffiTestPointers(ffiTestPoint4 *pt1, ffiTestPoint4 *pt2);
EXPORT(ffiTestPointMix) ffiTestStructMix(ffiTestPointMix pt1,
ffiTestPointMix pt2);
EXPORT(LONGLONG) ffiTestLongLong(LONGLONG i1, LONGLONG i2);
#pragma export off
/* test passing characters */
EXPORT(char) ffiTestChars(char c1, char c2, char c3, char c4) {
printf("4 characters came in as\nc1 = %c (%x)\nc2 = %c (%x)\nc3 = %c (%x)\nc4 = %c (%x)\n", c1, c1, c2, c2, c3, c3, c4, c4);
return 'C';
}
/* test passing shorts */
EXPORT(short) ffiTestShorts(short c1, short c2, short c3, short c4) {
printf("4 shorts came in as\ns1 = %d (%x)\ns2 = %d (%x)\ns3 = %d (%x)\ns4 = %d (%x)\n", c1, c1, c2, c2, c3, c3, c4, c4);
return -42;
}
/* test passing ints */
EXPORT(int) ffiTestInts(int c1, int c2, int c3, int c4) {
printf("4 ints came in as\ni1 = %d (%x)\ni2 = %d (%x)\ni3 = %d (%x)\ni4 = %d (%x)\n", c1, c1, c2, c2, c3, c3, c4, c4);
return 42;
}
/* test passing and returning floats */
EXPORT(float) ffiTestFloats(float f1, float f2) {
printf("The two floats are %f and %f\n", f1, f2);
return (float) (f1 + f2);
}
/* test passing and returning doubles */
EXPORT(double) ffiTestDoubles(double d1, double d2) {
printf("The two floats are %f and %f\n", (float)d1, (float)d2);
return d1+d2;
}
/* test passing and returning strings */
EXPORT(char*) ffiPrintString(char *string) {
printf("%s\n", string);
return string;
}
/* test passing and returning 64bit structures */
EXPORT(ffiTestPoint2) ffiTestStruct64(ffiTestPoint2 pt1, ffiTestPoint2 pt2) {
ffiTestPoint2 result;
printf("pt1.x = %d\npt1.y = %d\npt2.x = %d\npt2.y = %d\n",
pt1.x, pt1.y, pt2.x, pt2.y);
result.x = pt1.x + pt2.x;
result.y = pt1.y + pt2.y;
return result;
}
/* test passing and returning large structures */
EXPORT(ffiTestPoint4) ffiTestStructBig(ffiTestPoint4 pt1, ffiTestPoint4 pt2) {
ffiTestPoint4 result;
printf("pt1.x = %d\npt1.y = %d\npt1.z = %d\npt1.w = %d\n",
pt1.x, pt1.y, pt1.z, pt1.w);
printf("pt2.x = %d\npt2.y = %d\npt2.z = %d\npt2.w = %d\n",
pt2.x, pt2.y, pt2.z, pt2.w);
result.x = pt1.x + pt2.x;
result.y = pt1.y + pt2.y;
result.z = pt1.z + pt2.z;
result.w = pt1.w + pt2.w;
return result;
}
/* test passing and returning pointers */
EXPORT(ffiTestPoint4*) ffiTestPointers(ffiTestPoint4 *pt1, ffiTestPoint4 *pt2) {
ffiTestPoint4 *result;
printf("pt1.x = %d\npt1.y = %d\npt1.z = %d\npt1.w = %d\n",
pt1->x, pt1->y, pt1->z, pt1->w);
printf("pt2.x = %d\npt2.y = %d\npt2.z = %d\npt2.w = %d\n",
pt2->x, pt2->y, pt2->z, pt2->w);
result = (ffiTestPoint4*) malloc(sizeof(ffiTestPoint4));
result->x = pt1->x + pt2->x;
result->y = pt1->y + pt2->y;
result->z = pt1->z + pt2->z;
result->w = pt1->w + pt2->w;
return result;
}
/* test passing and returning longlongs */
EXPORT(LONGLONG) ffiTestLongLong(LONGLONG i1, LONGLONG i2) {
return i1 + i2;
}
#endif /* NO_FFI_TEST */
|
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:32
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/SqueakFFIPrims
In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/SqueakFFIPrims
Added Files:
00README Makefile Makefile.in acinclude.m4 any-libffi-asm.S
any-libffi.c ffi-config ffi-test-main.c ffi-test-sq.h
ffi-test.c ffi-test.h ppc-darwin-asm.S ppc-darwin.c
ppc-global.h ppc-sysv-asm.S ppc-sysv.c x86-sysv-asm.S
x86-sysv.c
Log Message:
Ian Piumarta's release 3.4.1
--- NEW FILE: 00README ---
This directory contains support code for the Squeak FFI (foreign
function interface) primitives. You should not even be here reading
this unless (i) the configure script refuses to include FFI support in
your build, or (ii) you want to try to make your FFI calls go lots
faster by avoiding the use of libffi.
About the FFI primitives
------------------------
Squeak can dynamically construct callouts to C code at runtime via one
of two mechanisms, `apicall' and `cdecl'. The `cdecl' method
constructs a `call interface description' (a data structure
representing a function's signature) which is used by libffi [1] to
construct and invoke a call to the foreign function. This method is
portable but horribly slow. The `apicall' method constructs a stack
frame on-the-fly which is used to invoke the foreign function
directly.
The `apicall' method is MUCH faster than `cdecl' (more than FOUR times
faster) but relies on horribly platform-dependent code.
Support for the `apicall' method is now available for a few platforms
on Unix:
- PowerPC and x86 using the SVr4 ABI (found on most GNU/Linux and
BSD-like systems, with the notable exception of Darwin/MacOSX)
- PowerPC using the Darwin ABI (similar to Mach)
Testing your FFI support
------------------------
First run the script `ffi-test-config' (no arguments) which will look
to see if your platform has support for the `apicall' method. If it
prints `any-libffi' then you must either install libffi [1] before you
can use the FFI primitives or implement the missing support [2]. If
it prints anything else then it has found what it thinks is suitable
support for your platform [3].
To run the test suite, just type `make' [4]. This will build a program
called `main' that tries quite hard to break the FFI support code. If
it fails using the built-in support code then you've found a bug in
either the support code or the test code [5]. If you want to try
again with libffi, then type:
make clean
make CPU=any ABI=libffi LIB=-lffi
./main
If it fails again you've found a bug either in libffi (send bug
reports to the relevant mailing list, not me) or in the test code.
To tidy up afterwards, type `make clean'.
Notes
-----
[1] libffi is now part of gcc. If you need to install it, download
just the contents of the top-level `gcc' directory and the
`libffi' subdirectory. Then `cd' to `libffi' and type:
./configure
make
sudo make install
If it breaks, you get to keep the pieces.
[2] Figure out your canonical cpu and abi (os) name. Write a bunch of
C code to create a stack frame in `${cpu}-${abi}.c' and the
assembler `trampoline' that pused it and jumps to the destination
function in the file `${cpu}-${abi}-asm.S'. This will allow the
configure script to find and use your support.
[3] If it doesn't find support code for your platform and you think it
should (based on the cpu-abi variants available) then add your
canonical host/os names to the tests in ffi-test-config. If the
resulting program works, make similar changes in `acinclude.m4' so
that the support is included in the Squeak VM. Then mail the
modified files to me [5].
[4] By default the Makefile will try to figure this out for itself
using rules similar to those in the configure script. You must be
using GNU make for this to work.
[5] Send bug reports and support code for new platforms to:
ian...@in...
--- NEW FILE: Makefile ---
### This Makefile is NOT used to build Squeak.
###
### See the file `00README' for instructions.
###
### Last edited: 2003-01-30 00:02:00 by piumarta on emilia.inria.fr
CPU= $(shell ./ffi-config -cpu)
ABI= $(shell ./ffi-config -abi)
LIB= $(shell ./ffi-config -lib)
INC= -I../../../Cross/plugins/SqueakFFIPrims
DEF= -DFFI_TEST
CFLAGS= -g -Wall -Wno-unused -O2 $(DEF) $(INC)
OBJ= ffi-test-main.o ffi-test.o $(CPU)-$(ABI).o $(CPU)-$(ABI)-asm.o
main : sq.h $(OBJ)
gcc -g -o $@ $(OBJ) $(LIB)
libffi :
$(MAKE) CPU=any ABI=libffi LIB=-lffi
sq.h :
ln -s ffi-test-sq.h sq.h
%.o : Makefile
clean :
/bin/rm -f *~ *.o main sq.h
--- NEW FILE: Makefile.in ---
# Makefile.in for FFIPlugin on Unix
#
# Author: ian...@in...
#
# Last edited: 2003-01-28 10:59:01 by piumarta on emilia.inria.fr
[make_cfg]
[make_plg]
TARGET = SqueakFFIPrims$a
OBJS = SqueakFFIPrims$o ffi-test$o $(FFI_O)
XINCLUDES = [includes]
$(TARGET) : $(OBJS) Makefile
$(LINK) $(TARGET) $(OBJS)
$(RANLIB) $(TARGET)
[make_targets]
.force :
--- NEW FILE: acinclude.m4 ---
AC_MSG_CHECKING([for FFI support])
FFI_DIR=${topdir}/platforms/unix/plugins/SqueakFFIPrims
ffi_cpu_abi=`${FFI_DIR}/ffi-config ${cfgdir} ${FFI_DIR} -cpu-abi`
if test "${ffi_cpu_abi}" != "any-libffi"; then
AC_MSG_RESULT([${ffi_cpu_abi}])
else
AC_MSG_RESULT([requires libffi])
ffi_cpu_abi=any-libffi
AC_CHECK_HEADER(ffi.h,
AC_CHECK_LIB(ffi, ffi_call,
AC_PLUGIN_USE_LIB(ffi),
AC_PLUGIN_DISABLE),
AC_PLUGIN_DISABLE)
fi
FFI_C=${ffi_cpu_abi}
FFI_S=${ffi_cpu_abi}-asm
FFI_O="${FFI_C}\$o ${FFI_S}\$o"
AC_SUBST(FFI_DIR)
AC_SUBST(FFI_C)
AC_SUBST(FFI_S)
AC_SUBST(FFI_O)
--- NEW FILE: any-libffi-asm.S ---
--- NEW FILE: any-libffi.c ---
/****************************************************************************
* PROJECT: Squeak foreign function interface
* FILE: sqUnixFFI.c
* CONTENT: Unix support for the foreign function interface
*
* AUTHOR: Andreas Raab (ar)
* ADDRESS: Walt Disney Imagineering, Glendale, CA
* EMAIL: and...@wd...
* RCSID: $Id: any-libffi.c,v 1.1 2003/05/12 07:26:28 asparagi Exp $
*
* NOTES: The Unix version of the FFI support code relies on libffi from
* http://sourceware.cygnus.com/libffi/
*
*****************************************************************************/
#include "sq.h"
#include "sqFFI.h"
#ifndef NO_FFI_SUPPORT
#include <ffi.h>
#ifndef FFI_TYPE_STRUCT /* this is private in libffi-2 */
# define FFI_TYPE_STRUCT 13
#endif
#if defined(FFI_TEST)
static int primitiveFail(void) { puts("primitive fail"); exit(1); return 0; }
#else
extern struct VirtualMachine *interpreterProxy;
# define primitiveFail() interpreterProxy->primitiveFail();
#endif
#if 1
#define HAVE_LONGLONG
#endif
/* Check if HAVE_LONGLONG is defined (should be figured out by configure */
#ifdef HAVE_LONGLONG
#define HAS_LONGLONG 1
#define LONGLONG long long
#endif
/* Error if LONGLONG is not defined */
#if HAS_LONGLONG
#ifndef LONGLONG
#error "You must define LONGLONG if HAS_LONGLONG is defined"
#endif
#endif
/* Max number of arguments in call */
#define FFI_MAX_ARGS 32
static ffi_type* ffiTypes[FFI_MAX_ARGS];
static void* ffiArgs[FFI_MAX_ARGS];
static char ffiBytes[FFI_MAX_ARGS];
static short ffiShorts[FFI_MAX_ARGS];
static int ffiInts[FFI_MAX_ARGS];
static float ffiFloats[FFI_MAX_ARGS];
static double ffiDoubles[FFI_MAX_ARGS];
static int ffiArgIndex = 0;
static ffi_type* ffiStructTypes[FFI_MAX_ARGS];
static int ffiStructIndex = 0;
/* helpers */
#define CHECK_ARGS() if(ffiArgIndex >= FFI_MAX_ARGS) return primitiveFail();
#define PUSH_TYPE(type) { CHECK_ARGS(); ffiTypes[ffiArgIndex] = &type; }
#define PUSH(where, what, type) { \
PUSH_TYPE(type); where[ffiArgIndex] = what; \
ffiArgs[ffiArgIndex] = (void*) (where + ffiArgIndex); \
ffiArgIndex++;\
}
#define BARG_PUSH(value, type) PUSH(ffiBytes, value, type)
#define SARG_PUSH(value, type) PUSH(ffiShorts, value, type)
#define IARG_PUSH(value, type) PUSH(ffiInts, value, type)
#define FARG_PUSH(value) PUSH(ffiFloats, value, ffi_type_float)
#define DARG_PUSH(value) PUSH(ffiDoubles, value, ffi_type_double)
#if HAS_LONGLONG
static LONGLONG ffiLongLongs[FFI_MAX_ARGS];
#define LARG_PUSH(value, type) PUSH(ffiLongLongs, value, type)
#endif
/* The 64bit return value storage area - aligned by the C compiler */
static double returnValue;
/* Storage area for large structure returns */
static ffi_type* structReturnType = NULL;
static void *structReturnValue = NULL;
/* The area for temporarily allocated strings */
static char *ffiTempStrings[FFI_MAX_ARGS];
/* The number of temporarily allocated strings */
static int ffiTempStringCount = 0;
/*****************************************************************************/
/*****************************************************************************/
/* ffiInitialize:
Announce that the VM is about to do an external function call. */
int ffiInitialize(void)
{
ffiArgIndex = 0;
ffiTempStringCount = 0;
ffiStructIndex = 0;
structReturnType = NULL;
structReturnValue = NULL;
return 1;
}
/* ffiSupportsCallingConvention:
Return true if the support code supports the given calling convention */
int ffiSupportsCallingConvention(int callType)
{
if(callType == FFICallTypeCDecl) return 1;
return 0;
}
/* ffiAlloc:
Allocate space from the external heap */
int ffiAlloc(int byteSize)
{
return (int)malloc(byteSize);
}
/* ffiFree:
Free space from the external heap */
int ffiFree(int pointer)
{
if(pointer) free((void*)pointer);
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
int ffiPushSignedByte(int value)
{
BARG_PUSH((char)value, ffi_type_sint8);
return 1;
}
int ffiPushUnsignedByte(int value)
{
BARG_PUSH((char)value, ffi_type_uint8);
return 1;
}
int ffiPushSignedShort(int value)
{
SARG_PUSH((short)value, ffi_type_sint16);
return 1;
}
int ffiPushUnsignedShort(int value)
{
SARG_PUSH((short)value, ffi_type_uint16);
return 1;
}
int ffiPushSignedInt(int value)
{
IARG_PUSH(value, ffi_type_sint32);
return 1;
}
int ffiPushUnsignedInt(int value)
{
IARG_PUSH(value, ffi_type_uint32);
return 1;
}
int ffiPushSignedLongLong(int low, int high)
{
#if HAS_LONGLONG
LONGLONG value = (((LONGLONG) high) << 32) | ((LONGLONG) (unsigned) low);
LARG_PUSH(value, ffi_type_sint64);
return 1;
#else
return primitiveFail();
#endif
}
int ffiPushUnsignedLongLong(int low, int high)
{
#if HAS_LONGLONG
LONGLONG value = (((LONGLONG) high) << 32) | ((LONGLONG) (unsigned) low);
LARG_PUSH(value, ffi_type_uint64);
return 1;
#else
return primitiveFail();
#endif
}
int ffiPushSignedChar(int value)
{
BARG_PUSH(value, ffi_type_sint8);
return 1;
}
int ffiPushUnsignedChar(int value)
{
BARG_PUSH(value, ffi_type_uint8);
return 1;
}
int ffiPushBool(int value)
{
IARG_PUSH(value, ffi_type_uint8);
return 1;
}
int ffiPushSingleFloat(double value)
{
FARG_PUSH((float)value);
return 1;
}
int ffiPushDoubleFloat(double value)
{
DARG_PUSH(value);
return 1;
}
ffi_type* ffiCreateType(int *structSpec, int structSize)
{
ffi_type *structType, **newTypes;
int nTypes, i, typeSpec;
/* count the number of atomic types we need to create */
nTypes = 0;
for(i=0; i<structSize; i++) {
typeSpec = structSpec[i];
if(typeSpec & FFIFlagPointer) nTypes++;
else if(typeSpec & FFIFlagAtomic) nTypes++;
}
/* note: nTypes == 0 means an invalid structure */
if(nTypes == 0) {
printf("Warning: nTypes == 0 in ffiCreateTypes\n");
return NULL;
}
/* allocate the structure type */
structType = calloc(1, sizeof(ffi_type));
/* allocate the atomic type refs */
newTypes = calloc(nTypes+1, sizeof(ffi_type*));
/* number of elements in type */
structType->size = (*structSpec) & FFIStructSizeMask;
structType->alignment = 4;
structType->type = FFI_TYPE_STRUCT;
structType->elements = newTypes;
/* now go over the structure and fill in the fields */
nTypes = 0;
for(i=0; i<structSize; i++) {
typeSpec = structSpec[i];
if(typeSpec & FFIFlagPointer) {
newTypes[nTypes++] = &ffi_type_pointer;
continue;
}
if((typeSpec & FFIFlagAtomic) == 0) continue;
switch((typeSpec & FFIAtomicTypeMask) >> FFIAtomicTypeShift) {
case FFITypeBool:
newTypes[nTypes++] = &ffi_type_uint8; break;
case FFITypeUnsignedByte:
newTypes[nTypes++] = &ffi_type_uint8; break;
case FFITypeSignedByte:
newTypes[nTypes++] = &ffi_type_sint8; break;
case FFITypeUnsignedShort:
newTypes[nTypes++] = &ffi_type_uint16; break;
case FFITypeSignedShort:
newTypes[nTypes++] = &ffi_type_sint16; break;
case FFITypeUnsignedInt:
newTypes[nTypes++] = &ffi_type_uint32; break;
case FFITypeSignedInt:
newTypes[nTypes++] = &ffi_type_sint32; break;
case FFITypeUnsignedLongLong:
newTypes[nTypes++] = &ffi_type_uint64; break;
case FFITypeSignedLongLong:
newTypes[nTypes++] = &ffi_type_sint64; break;
case FFITypeUnsignedChar:
newTypes[nTypes++] = &ffi_type_uint8; break;
case FFITypeSignedChar:
newTypes[nTypes++] = &ffi_type_sint8; break;
case FFITypeSingleFloat:
newTypes[nTypes++] = &ffi_type_float; break;
case FFITypeDoubleFloat:
newTypes[nTypes++] = &ffi_type_double; break;
default:
printf("Warning: unknown atomic type (%x) in ffiCreateTypes\n",
typeSpec);
free(newTypes);
free(structType);
return NULL;
};
}
newTypes[nTypes++] = NULL;
return structType;
}
int ffiPushStructureOfLength(int pointer, int* structSpec, int structSize)
{
ffi_type *structType;
if(pointer == 0) return primitiveFail();
CHECK_ARGS(); /* fail early on */
structType = ffiCreateType(structSpec, structSize);
if(structType == NULL) return primitiveFail();
ffiStructTypes[ffiStructIndex++] = structType;
ffiTypes[ffiArgIndex] = structType;
ffiArgs[ffiArgIndex] = (void*) pointer;
ffiArgIndex++;
return 1;
}
int ffiPushPointer(int pointer)
{
IARG_PUSH(pointer, ffi_type_pointer);
return 1;
}
int ffiPushStringOfLength(int srcIndex, int length)
{
char *ptr;
ptr = (char*) malloc(length+1);
if(!ptr) return primitiveFail();
memcpy(ptr, (void*)srcIndex, length);
ptr[length] = 0;
ffiTempStrings[ffiTempStringCount++] = ptr;
IARG_PUSH((int)ptr, ffi_type_pointer);
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
/* ffiCanReturn:
Return true if the support code can return the given type. */
int ffiCanReturn(int *structSpec, int specSize)
{
int header = *structSpec;
if(header & FFIFlagPointer) return 1;
if(header & FFIFlagStructure) {
int structSize = header & FFIStructSizeMask;
structReturnType = ffiCreateType(structSpec, specSize);
if(!structReturnType) return 0;
if(structSize > 8) {
structReturnValue = calloc(1,structSize);
if(!structReturnValue) return 0;
return 1;
}
}
return 1;
}
/* ffiReturnFloatValue:
Return the value from a previous ffi call with float return type. */
double ffiReturnFloatValue(void)
{
return returnValue;
}
/* ffiLongLongResultLow:
Return the low 32bit from the 64bit result of a call to an external function */
int ffiLongLongResultLow(void)
{
#if HAS_LONGLONG
return (int) ( (*(LONGLONG*)&returnValue) & (LONGLONG)0xFFFFFFFFU);
#else
return 0;
#endif
}
/* ffiLongLongResultHigh:
Return the high 32bit from the 64bit result of a call to an external function */
int ffiLongLongResultHigh(void)
{
#if HAS_LONGLONG
return (int) ( (*(LONGLONG*)&returnValue) >> 32);
#else
return 0;
#endif
}
/* ffiStoreStructure:
Store the structure result of a previous ffi call into the given address*/
int ffiStoreStructure(int address, int structSize)
{
if(structReturnValue) {
memcpy((void*)address, (void*)structReturnValue, structSize);
} else {
memcpy((void*)address, (void*)&returnValue, structSize);
}
return 1;
}
/* ffiCleanup:
Cleanup after a foreign function call has completed.
The generic support code only frees the temporarily
allocated strings. */
int ffiCleanup(void)
{
int i;
for(i=0; i<ffiTempStringCount; i++)
free(ffiTempStrings[i]);
for(i=0; i<ffiStructIndex; i++) {
free(ffiStructTypes[i]->elements);
free(ffiStructTypes[i]);
ffiStructTypes[i]=NULL;
}
if(structReturnType) {
free(structReturnType->elements);
free(structReturnType);
structReturnType = NULL;
}
if(structReturnValue) {
free(structReturnValue);
structReturnValue = NULL;
}
ffiTempStringCount = 0;
ffiStructIndex = 0;
return 1;
}
/*****************************************************************************/
/*****************************************************************************/
int ffiCallAddress(int fn, ffi_type *returnType, int atomicArgType)
{
ffi_cif cif;
ffi_status result;
int retVal;
result = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, ffiArgIndex,
returnType, ffiTypes);
if(result != FFI_OK) return primitiveFail();
if(structReturnValue) {
ffi_call(&cif, (void *)fn, (void *)structReturnValue, (void **)ffiArgs);
return (int) structReturnValue;
}
ffi_call(&cif, (void *)fn, (void *)&returnValue, (void **)ffiArgs);
retVal = *(int*)&returnValue;
#ifdef FFI_MIPS_N32
/* Note: MIPS N32 ABI returns 64bit for integer/pointer whatever.
This seems to be a bug in the fficall implementation. */
retVal = ((int*)(&returnValue))[1];
#endif
/* Promote certain return types to integral size */
switch(atomicArgType) {
case FFITypeUnsignedChar:
case FFITypeUnsignedByte: retVal = *(unsigned char*) &retVal; break;
case FFITypeSignedChar:
case FFITypeSignedByte: retVal = *(signed char*) &retVal; break;
case FFITypeUnsignedShort: retVal = *(unsigned short*) &retVal; break;
case FFITypeSignedShort: retVal = *(signed short*) &retVal; break;
case FFITypeSingleFloat: returnValue = *(float*)&returnValue; break;
}
return retVal;
}
int ffiCallAddressOfWithPointerReturn(int fn, int callType)
{
return ffiCallAddress(fn, &ffi_type_pointer,-1);
}
int ffiCallAddressOfWithStructReturn(int fn, int callType,
int *structSpec, int specSize)
{
if(!structReturnType) return primitiveFail();
return ffiCallAddress(fn, structReturnType,-1);
}
int ffiCallAddressOfWithReturnType(int fn, int callType, int typeSpec)
{
ffi_type *returnType;
int atomicType;
atomicType = (typeSpec & FFIAtomicTypeMask) >> FFIAtomicTypeShift;
switch(atomicType) {
case FFITypeVoid: returnType = &ffi_type_void; break;
case FFITypeBool: returnType = &ffi_type_uint8; break;
case FFITypeUnsignedByte: returnType = &ffi_type_uint8; break;
case FFITypeSignedByte: returnType = &ffi_type_sint8; break;
case FFITypeUnsignedShort: returnType = &ffi_type_uint16; break;
case FFITypeSignedShort: returnType = &ffi_type_sint16; break;
case FFITypeUnsignedInt: returnType = &ffi_type_uint32; break;
case FFITypeSignedInt: returnType = &ffi_type_sint32; break;
case FFITypeUnsignedLongLong: returnType = &ffi_type_uint64; break;
case FFITypeSignedLongLong: returnType = &ffi_type_sint64; break;
case FFITypeUnsignedChar: returnType = &ffi_type_uint8; break;
case FFITypeSignedChar: returnType = &ffi_type_sint8; break;
case FFITypeSingleFloat: returnType = &ffi_type_float; break;
case FFITypeDoubleFloat: returnType = &ffi_type_double; break;
default:
return primitiveFail();
}
return ffiCallAddress(fn, returnType, atomicType);
}
#if defined(FFI_TEST)
void ffiDoAssertions(void) {}
#endif
#endif /* NO_FFI_SUPPORT */
--- NEW FILE: ffi-config ---
#!/bin/sh
#
# ffi-config [cfgdir] [options...]
#
# -cpu print the supported cpu name or `any'
# -abi print the supported abu name or `libffi'
# -lib print nothing if supported, otherwise `-lffi'
# -query exit with status 0 if supported, 1 if libffi required
cfgdir=../../config
if [ $# -gt 0 ]; then
case $1 in
-*) ;;
*) cfgdir=$1; shift;;
esac
fi
ffidir=.
if [ $# -gt 0 ]; then
case $1 in
-*) ;;
*) ffidir=$1; shift;;
esac
fi
guess=`${cfgdir}/config.guess`
host=`${cfgdir}/config.sub ${guess}`
cpu=`echo ${host} | sed 's/-.*//'`
abi=`echo ${host} | sed 's/[^-]*-[^-]*-//;s/-.*//'`
lib=
case ${cpu} in
powerpc|ppc) cpu=ppc;;
i[3456789]86) cpu=x86;;
*) cpu=any;;
esac
case ${abi} in
linux) abi=sysv;;
darwin*) abi=darwin;;
*) abi=libffi; lib="-lffi";;
esac
if [ ! -f ${ffidir}/${cpu}-${abi}.c ] || [ ! -f ${ffidir}/${cpu}-${abi}-asm.S ]; then
cpu=any
abi=libffi
lib="-lffi"
fi
if [ ! -f ${ffidir}/${cpu}-${abi}.c ] || [ ! -f ${ffidir}/${cpu}-${abi}-asm.S ]; then
echo "Could not find ${cpu}-${abi}.c and ${cpu}-${abi}-asm.S" >&2
exit 1
fi
if [ $# -eq 0 ]; then
echo "${cpu}-${abi}" "${lib}"
else
while [ $# -gt 0 ]; do
case $1 in
-cpu) echo ${cpu};;
-abi) echo ${abi};;
-lib) echo ${lib};;
-cpu-abi) echo ${cpu}-${abi};;
-query) if [ ${abi} = "libffi" ]; then exit 1; else exit 0; fi;;
*) echo "$0: I don't understand \`$1'" >&1; exit 1;;
esac
shift
done
fi
exit 0
--- NEW FILE: ffi-test-main.c ---
/* ffi-test-main.c -- try hard to break the FFI from C
*
* Author: Ian...@IN...
*
* Based on a similar test suite in libffi, which contains the following text...
*
* Copyright (c) 1996, 1997, 1998, 2002, 2003 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* ``Software''), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include "sqFFI.h"
#if 0
# define dprintf(ARGS) printf ARGS
# define puts(ARG) puts(ARG)
#else
# define dprintf(ARGS)
# define puts(ARG)
#endif
#if 1
# define long_double double
# define Lf "f"
#else
# define long_double long double
# define Lf "Lf"
#endif
#define CHECK(x) !(x) ? fail(__FILE__, __LINE__) : 0
static int fail(char *file, int line)
{
fprintf(stderr, "%s: failed at line %d\n", file, line);
exit(EXIT_FAILURE);
return 0;
}
#define MAX_ARGS 256
static size_t my_strlen(char *s) { return strlen(s); }
static int promotion(signed char sc, signed short ss, unsigned char uc, unsigned short us)
{
int r= (int)sc + (int)ss + (int)uc + (int)us;
return r;
}
static signed char return_sc(signed char sc) { return sc; }
static unsigned char return_uc(unsigned char uc) { return uc; }
static long long return_ll(long long ll) { return ll; }
static int floating(int a, float b, double c, long_double d, int e)
{
int i;
dprintf(("%d %f %f %"Lf" %d\n", a, (double)b, c, d, e));
i= (int)((float)a/b + ((float)c/(float)d));
return i;
}
static float many(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13, float f14, float f15)
{
dprintf(("%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n",
(double)f1, (double)f2, (double)f3, (double)f4, (double)f5,
(double)f6, (double)f7, (double)f8, (double)f9, (double)f10,
(double)f11, (double)f12, (double)f13, (double)f14, (double)f15));
return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12+f13/f14) * f15);
}
static double dblit(float f) { return f/3.0; }
static long_double ldblit(float f) { return (long_double)(((long_double)f)/ (long_double)3.0); }
#define TYPE(T,S) ((FFIType##T << FFIAtomicTypeShift) | (S) | FFIFlagAtomic)
typedef struct { unsigned char uc; double d; unsigned int ui; } test_structure_1;
static int spec_structure_1[]= {
FFIFlagStructure | sizeof(test_structure_1),
TYPE(UnsignedChar,4), TYPE(DoubleFloat,8), TYPE(UnsignedInt,4)
};
static test_structure_1 struct1(test_structure_1 ts)
{
dprintf(("%d %f %d\n", ts.uc, ts.d, ts.ui));
ts.uc++; ts.d--; ts.ui++; return ts;
}
typedef struct { double d1; double d2;} test_structure_2;
static int spec_structure_2[]= {
FFIFlagStructure | sizeof(test_structure_2),
TYPE(DoubleFloat,8), TYPE(DoubleFloat,8)
};
static test_structure_2 struct2(test_structure_2 ts)
{
ts.d1--; ts.d2--; return ts;
}
typedef struct { int si; } test_structure_3;
static int spec_structure_3[]= {
FFIFlagStructure | sizeof(test_structure_3),
TYPE(SignedInt,4)
};
static test_structure_3 struct3(test_structure_3 ts)
{
ts.si= -(ts.si*2); return ts;
}
typedef struct { unsigned ui1; unsigned ui2; unsigned ui3; } test_structure_4;
static int spec_structure_4[]= {
FFIFlagStructure | sizeof(test_structure_4),
TYPE(UnsignedInt,4), TYPE(UnsignedInt,4), TYPE(UnsignedInt,4)
};
static test_structure_4 struct4(test_structure_4 ts)
{
ts.ui3= ts.ui1 * ts.ui2 * ts.ui3; return ts;
}
typedef struct { char c1; char c2; } test_structure_5;
static int spec_structure_5[]= {
FFIFlagStructure | sizeof(test_structure_5),
TYPE(SignedChar,1), TYPE(SignedChar,1)
};
static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
{
dprintf(("%d %d %d %d\n", ts1.c1, ts1.c2, ts2.c1, ts2.c2));
ts1.c1 += ts2.c1; ts1.c2 -= ts2.c2; return ts1;
}
typedef struct { float f; double d; } test_structure_6;
static int spec_structure_6[]= {
FFIFlagStructure | sizeof(test_structure_6),
TYPE(SingleFloat,4), TYPE(DoubleFloat,8)
};
static test_structure_6 struct6 (test_structure_6 ts)
{
ts.f += 1; ts.d += 1; return ts;
}
typedef struct { float f1; float f2; double d; } test_structure_7;
static int spec_structure_7[]= {
FFIFlagStructure | sizeof(test_structure_7),
TYPE(SingleFloat,4), TYPE(SingleFloat,4), TYPE(DoubleFloat,8)
};
static test_structure_7 struct7 (test_structure_7 ts)
{
ts.f1 += 1; ts.f2 += 1; ts.d += 1; return ts;
}
typedef struct { float f1; float f2; float f3; float f4; } test_structure_8;
static int spec_structure_8[]= {
FFIFlagStructure | sizeof(test_structure_8),
TYPE(SingleFloat,4), TYPE(SingleFloat,4), TYPE(SingleFloat,4), TYPE(SingleFloat,4)
};
static test_structure_8 struct8 (test_structure_8 ts)
{
ts.f1 += 1; ts.f2 += 1; ts.f3 += 1; ts.f4 += 1; return ts;
}
typedef struct { float f; int i; } test_structure_9;
static int spec_structure_9[]= {
FFIFlagStructure | sizeof(test_structure_9),
TYPE(SingleFloat,4), TYPE(SignedInt,4)
};
static test_structure_9 struct9 (test_structure_9 ts)
{
ts.f += 1; ts.i += 1; return ts;
}
#define SPEC(S) spec_##S, (sizeof(spec_##S) / sizeof(int))
#define GO(T,F) ffiCallAddressOfWithReturnType((int)(F), FFICallTypeCDecl, \
(T) << FFIAtomicTypeShift)
#define GOS(S,F) ffiCallAddressOfWithStructReturn((int)(F), FFICallTypeCDecl, SPEC(S))
void ctests(void)
{
CHECK(sizeof(char) == 1);
CHECK(sizeof(short) == 2);
CHECK(sizeof(int) == 4);
CHECK(sizeof(long) == 4);
CHECK(sizeof(long long) == 8);
CHECK(sizeof(float) == 4);
CHECK(sizeof(double) == 8);
CHECK(sizeof(long_double) == 8); //xxx BOGUS BOGUS BOGUS BOGUS BOGUS
puts("long long tests...");
{
long long ll, rll;
for (ll= 0LL; ll < 100LL; ++ll)
{
ffiInitialize();
ffiPushSignedLongLong(ll % 0x100000000, ll / 0x100000000);
GO(FFITypeSignedLongLong, return_ll);
rll= ffiLongLongResultHigh() * 0x100000000LL + ffiLongLongResultLow();
ffiCleanup();
dprintf(("%lld %lld\n", ll, rll));
CHECK(rll == ll);
}
for (ll= 55555555555000LL; ll < 55555555555100LL; ll++)
{
ffiInitialize();
ffiPushSignedLongLong(ll % 0x100000000, ll / 0x100000000);
GO(FFITypeSignedLongLong, return_ll);
rll= ffiLongLongResultHigh() * 0x100000000LL + ffiLongLongResultLow();
ffiCleanup();
CHECK(rll == ll);
}
}
puts("char tests...");
{
signed char sc;
unsigned char uc;
int rint;
for (sc= (signed char)-127; sc < (signed char)127; ++sc)
{
ffiInitialize();
ffiPushSignedChar(sc);
rint= GO(FFITypeSignedInt, return_sc);
ffiCleanup();
CHECK(rint == (int)sc);
}
for (uc= (unsigned char)'\x00'; uc < (unsigned char)'\xff'; ++uc)
{
ffiInitialize();
ffiPushUnsignedChar(uc);
rint= GO(FFITypeSignedInt, return_uc);
ffiCleanup();
CHECK(rint == (int)uc);
}
}
puts("long double tests...");
{
float f= 3.14159;
long_double ld;
dprintf(("%"Lf"\n", ldblit(f)));
ld= 666;
ffiInitialize();
ffiPushSingleFloat(f);
GO(FFITypeDoubleFloat, ldblit);
ld= ffiReturnFloatValue();
ffiCleanup();
dprintf(("%"Lf", %"Lf", %"Lf", %"Lf"\n", ld, ldblit(f), ld - ldblit(f), (long_double)LDBL_EPSILON));
/* These are not always the same!! Check for a reasonable delta */
CHECK(ld - ldblit(f) < LDBL_EPSILON);
}
puts("float arg tests...");
{
int si1= 6;
float f= 3.14159;
double d= (double)1.0/(double)3.0;
long_double ld= 2.71828182846L;
int si2= 10;
int rint;
floating(si1, f, d, ld, si2);
ffiInitialize();
ffiPushSignedInt(si1);
ffiPushSingleFloat(f);
ffiPushDoubleFloat(d);
ffiPushDoubleFloat(ld);
ffiPushSignedInt(si2);
rint= GO(FFITypeSignedInt, floating);
ffiCleanup();
dprintf(("%d vs %d\n", (int)rint, floating(si1, f, d, ld, si2)));
CHECK(rint == floating(si1, f, d, ld, si2));
}
puts("double return tests...");
{
float f= 3.14159;
double d;
ffiInitialize();
ffiPushSingleFloat(f);
GO(FFITypeDoubleFloat, dblit);
d= ffiReturnFloatValue();
ffiCleanup();
CHECK(d - dblit(f) < DBL_EPSILON);
}
puts("strlen tests...");
{
char *s= "a";
int rint;
ffiInitialize();
ffiPushPointer((int)s);
rint= GO(FFITypeSignedInt, my_strlen);
ffiCleanup();
CHECK(rint == 1);
s= "1234567";
ffiInitialize();
ffiPushPointer((int)s);
rint= GO(FFITypeSignedInt, my_strlen);
ffiCleanup();
CHECK(rint == 7);
s= "1234567890123456789012345";
ffiInitialize();
ffiPushPointer((int)s);
rint= GO(FFITypeSignedInt, my_strlen);
ffiCleanup();
CHECK(rint == 25);
}
puts("many arg tests...");
{
unsigned long ul;
float f, ff;
float fa[15];
for (ul= 0; ul < 15; ++ul)
fa[ul]= (float)ul;
ff= many(fa[0], fa[1], fa[2], fa[3], fa[4], fa[5], fa[6], fa[7], fa[8], fa[9], fa[10], fa[11], fa[12], fa[13], fa[14]);
ffiInitialize();
for (ul= 0; ul < 15; ++ul)
ffiPushSingleFloat(fa[ul]);
GO(FFITypeSingleFloat, many);
f= ffiReturnFloatValue();
ffiCleanup();
CHECK(f - ff < FLT_EPSILON);
}
puts("promotion tests...");
{
signed char sc;
unsigned char uc;
signed short ss;
unsigned short us;
int rint;
for (sc= (signed char)-127; sc <= (signed char)120; sc += 1)
for (ss= -30000; ss <= 30000; ss += 10000)
for (uc= (unsigned char)0; uc <= (unsigned char)200; uc += 20)
for (us= 0; us <= 60000; us += 10000)
{
ffiInitialize();
ffiPushSignedChar(sc);
ffiPushSignedShort(ss);
ffiPushUnsignedChar(uc);
ffiPushUnsignedShort(us);
rint= GO(FFITypeSignedInt, promotion);
ffiCleanup();
CHECK((int)rint == (signed char)sc + (signed short)ss
+ (unsigned char)uc + (unsigned short)us);
}
}
puts("struct tests...");
{
test_structure_1 ts1_arg, ts1_result;
ts1_arg.uc= '\x01';
ts1_arg.d= 3.14159;
ts1_arg.ui= 555;
ffiInitialize();
CHECK(ffiCanReturn(SPEC(structure_1)));
ffiPushStructureOfLength((int)&ts1_arg, SPEC(structure_1));
GOS(structure_1, struct1);
ffiStoreStructure((int)&ts1_result, sizeof(ts1_result));
ffiCleanup();
dprintf(("%d %g\n", ts1_result.ui, ts1_result.d));
CHECK(ts1_result.ui == 556);
CHECK(ts1_result.d == 3.14159 - 1);
}
{
test_structure_2 ts2_arg, ts2_result;
ts2_arg.d1= 5.55;
ts2_arg.d2= 6.66;
dprintf(("%g\n", ts2_result.d1)); /*xxx this is junk!*/
dprintf(("%g\n", ts2_result.d2));
ffiInitialize();
CHECK(ffiCanReturn(SPEC(structure_2)));
ffiPushStructureOfLength((int)&ts2_arg, SPEC(structure_2));
GOS(structure_2, struct2);
ffiStoreStructure((int)&ts2_result, sizeof(ts2_result));
ffiCleanup();
dprintf(("%g\n", ts2_result.d1));
dprintf(("%g\n", ts2_result.d2));
CHECK(ts2_result.d1 == 5.55 - 1);
CHECK(ts2_result.d2 == 6.66 - 1);
}
{
int compare_value;
test_structure_3 ts3_arg, ts3_result;
ts3_arg.si= -123;
compare_value= ts3_arg.si;
ffiInitialize();
CHECK(ffiCanReturn(SPEC(structure_3)));
ffiPushStructureOfLength((int)&ts3_arg, SPEC(structure_3));
GOS(structure_3, struct3);
ffiStoreStructure((int)&ts3_result, sizeof(ts3_result));
ffiCleanup();
dprintf(("%d %d\n", ts3_result.si, -(compare_value*2)));
CHECK(ts3_result.si == -(ts3_arg.si*2));
}
{
test_structure_4 ts4_arg, ts4_result;
ts4_arg.ui1= 2;
ts4_arg.ui2= 3;
ts4_arg.ui3= 4;
ffiInitialize();
CHECK(ffiCanReturn(SPEC(structure_4)));
ffiPushStructureOfLength((int)&ts4_arg, SPEC(structure_4));
GOS(structure_4, struct4);
ffiStoreStructure((int)&ts4_result, sizeof(ts4_result));
ffiCleanup();
CHECK(ts4_result.ui3 == 2U * 3U * 4U);
}
{
test_structure_5 ts5_arg1, ts5_arg2, ts5_result;
ts5_arg1.c1= 2;
ts5_arg1.c2= 6;
ts5_arg2.c1= 5;
ts5_arg2.c2= 3;
struct5(ts5_arg1, ts5_arg2);
ts5_arg1.c1= 2;
ts5_arg1.c2= 6;
ts5_arg2.c1= 5;
ts5_arg2.c2= 3;
ffiInitialize();
CHECK(ffiCanReturn(SPEC(structure_5)));
ffiPushStructureOfLength((int)&ts5_arg1, SPEC(structure_5));
ffiPushStructureOfLength((int)&ts5_arg2, SPEC(structure_5));
GOS(structure_5, struct5);
ffiStoreStructure((int)&ts5_result, sizeof(ts5_result));
ffiCleanup();
dprintf(("%d %d\n", ts5_result.c1, ts5_result.c2));
CHECK(ts5_result.c1 == 7 && ts5_result.c2 == 3);
}
{
test_structure_6 ts6_arg, ts6_result;
ts6_arg.f= 5.55f;
ts6_arg.d= 6.66;
dprintf(("%g\n", ts6_arg.f));
dprintf(("%g\n", ts6_arg.d));
ffiInitialize();
CHECK(ffiCanReturn(SPEC(structure_6)));
ffiPushStructureOfLength((int)&ts6_arg, SPEC(structure_6));
GOS(structure_6, struct6);
ffiStoreStructure((int)&ts6_result, sizeof(ts6_result));
ffiCleanup();
dprintf(("%g\n", ts6_result.f));
dprintf(("%g\n", ts6_result.d));
CHECK(ts6_result.f == 5.55f + 1);
CHECK(ts6_result.d == 6.66 + 1);
}
{
test_structure_7 ts7_arg, ts7_result;
ts7_arg.f1= 5.55f;
ts7_arg.f2= 55.5f;
ts7_arg.d= 6.66;
dprintf(("%g\n", ts7_arg.f1));
dprintf(("%g\n", ts7_arg.f2));
dprintf(("%g\n", ts7_arg.d));
ffiInitialize();
CHECK(ffiCanReturn(SPEC(structure_7)));
ffiPushStructureOfLength((int)&ts7_arg, SPEC(structure_7));
GOS(structure_7, struct7);
ffiStoreStructure((int)&ts7_result, sizeof(ts7_result));
ffiCleanup();
dprintf(("%g\n", ts7_result.f1));
dprintf(("%g\n", ts7_result.f2));
dprintf(("%g\n", ts7_result.d));
CHECK(ts7_result.f1 == 5.55f + 1);
CHECK(ts7_result.f2 == 55.5f + 1);
CHECK(ts7_result.d == 6.66 + 1);
}
{
test_structure_8 ts8_arg, ts8_result;
ts8_arg.f1= 5.55f;
ts8_arg.f2= 55.5f;
ts8_arg.f3= -5.55f;
ts8_arg.f4= -55.5f;
dprintf(("%g\n", ts8_arg.f1));
dprintf(("%g\n", ts8_arg.f2));
dprintf(("%g\n", ts8_arg.f3));
dprintf(("%g\n", ts8_arg.f4));
ffiInitialize();
CHECK(ffiCanReturn(SPEC(structure_8)));
ffiPushStructureOfLength((int)&ts8_arg, SPEC(structure_8));
GOS(structure_8, struct8);
ffiStoreStructure((int)&ts8_result, sizeof(ts8_result));
ffiCleanup();
dprintf(("%g\n", ts8_result.f1));
dprintf(("%g\n", ts8_result.f2));
dprintf(("%g\n", ts8_result.f3));
dprintf(("%g\n", ts8_result.f4));
CHECK(ts8_result.f1 == 5.55f + 1);
CHECK(ts8_result.f2 == 55.5f + 1);
CHECK(ts8_result.f3 == -5.55f + 1);
CHECK(ts8_result.f4 == -55.5f + 1);
}
{
test_structure_9 ts9_arg, ts9_result;
ts9_arg.f= 5.55f;
ts9_arg.i= 5;
dprintf(("%g\n", ts9_arg.f));
dprintf(("%d\n", ts9_arg.i));
ffiInitialize();
CHECK(ffiCanReturn(SPEC(structure_9)));
ffiPushStructureOfLength((int)&ts9_arg, SPEC(structure_9));
GOS(structure_9, struct9);
ffiStoreStructure((int)&ts9_result, sizeof(ts9_result));
ffiCleanup();
dprintf(("%g\n", ts9_result.f));
dprintf(("%d\n", ts9_result.i));
CHECK(ts9_result.f == 5.55f + 1);
CHECK(ts9_result.i == 5 + 1);
}
}
#define C(C) ffiPushSignedChar(C)
#define S(S) ffiPushSignedShort(S)
#define I(I) ffiPushSignedInt(I)
#define F(F) ffiPushSingleFloat(F)
#define D(D) ffiPushDoubleFloat(D)
#define P(P) ffiPushPointer(P)
#define GO(T,F) ffiCallAddressOfWithReturnType((int)(F), FFICallTypeCDecl, \
(T) << FFIAtomicTypeShift)
static void assert(int pred, const char *gripe)
{
if (pred) return;
fprintf(stderr, "%s\n", gripe);
exit(1);
}
#include "ffi-test.h"
void stests(void)
{
double d;
char *s;
ffiInitialize(); C('A'); C(65); C(65); C(1);
GO(FFITypeSignedInt, ffiTestChars);
ffiCleanup();
ffiInitialize(); S('A'); S(65); S(65); S(1);
GO(FFITypeSignedInt, ffiTestShorts);
ffiCleanup();
ffiInitialize(); I('A'); I(65); I(65); I(1);
GO(FFITypeSignedInt, ffiTestInts);
ffiCleanup();
ffiInitialize(); F(65); F(65.0);
GO(FFITypeSingleFloat, ffiTestFloats);
d= ffiReturnFloatValue();
ffiCleanup();
dprintf(("%f\n", d));
assert(d == 130.0, "single floats don't work");
ffiInitialize(); D(41.0L); D(1);
GO(FFITypeDoubleFloat, ffiTestDoubles);
d= ffiReturnFloatValue();
ffiCleanup();
assert(d == 42.0, "problem with doubles");
/*xxx this does not really test strings, but the corresponding call
in the image's FFITester does */
ffiInitialize();
P((int)"Hello World!");
s= (char *)ffiCallAddressOfWithPointerReturn((int)ffiPrintString, FFICallTypeCDecl);
ffiCleanup();
assert(!strcmp(s, "Hello World!"), "Problem with strings");
{
int spec[]= { FFIFlagStructure | 8,
TYPE(SignedInt,4), TYPE(SignedInt,4) };
ffiTestPoint2 pt1= { 1, 2 }, pt2= { 3, 4 }, pt3;
ffiInitialize();
assert(ffiCanReturn((int *)&spec, 3), "cannot return struct");
ffiPushStructureOfLength((int)&pt1, (int *)&spec, 3);
ffiPushStructureOfLength((int)&pt2, (int *)&spec, 3);
ffiCallAddressOfWithStructReturn((int)ffiTestStruct64, FFICallTypeCDecl, spec, 3);
ffiStoreStructure((int)&pt3, sizeof(pt3));
ffiCleanup();
assert((pt3.x == 4) && (pt3.y == 6), "Problem passing 64bit structures");
}
{
int spec[]= { FFIFlagStructure | 16,
TYPE(SignedInt,4), TYPE(SignedInt,4),
TYPE(SignedInt,4), TYPE(SignedInt,4) };
ffiTestPoint4 pt1= { 1, 2, 3, 4 }, pt2= { 5, 6, 7, 8 }, pt3= { 9, 10, 11, 12 };
ffiInitialize();
assert(ffiCanReturn((int *)&spec, 3), "cannot return struct");
ffiPushStructureOfLength((int)&pt1, (int *)&spec, 5);
ffiPushStructureOfLength((int)&pt2, (int *)&spec, 5);
ffiPushStructureOfLength((int)&pt3, (int *)&spec, 5);
ffiCallAddressOfWithStructReturn((int)ffiTestStructBig, FFICallTypeCDecl, spec, 5);
ffiStoreStructure((int)&pt3, sizeof(pt3));
ffiCleanup();
assert((pt3.x == 6) && (pt3.y == 8) && (pt3.z == 10) && (pt3.w == 12),
"Problem passing large structures");
}
{
ffiTestPoint4 pt1= { 1, 2, 3, 4 }, pt2= { 5, 6, 7, 8 }, *pt3;
ffiInitialize();
ffiPushPointer((int)&pt1);
ffiPushPointer((int)&pt2);
pt3= (ffiTestPoint4 *)
ffiCallAddressOfWithPointerReturn((int)ffiTestPointers, 0);
ffiCleanup();
assert((pt3->x == 6) && (pt3->y == 8) && (pt3->z == 10) && (pt3->w == 12),
"Problem passing pointers");
free((void *)pt3);
}
}
extern void ffiDoAssertions(void);
int main()
{
ffiDoAssertions(); printf("passed ffi assertions\n");
stests(); printf("passed FFITester support check\n");
ctests(); printf("passed C test suite\n");
return 0;
}
--- NEW FILE: ffi-test-sq.h ---
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define EXPORT(T) T
--- NEW FILE: ffi-test.c ---
/* last edited: 2003-01-29 21:48:36 by piumarta on emilia.inria.fr
*/
#if !defined(NO_FFI_TEST)
#include <stdio.h>
#include <stdlib.h>
#if !defined(LONGLONG)
# define LONGLONG long long
#endif
#if 0
# define dprintf(ARGS) printf ARGS
#else
# define dprintf(ARGS)
#endif
#include "ffi-test.h"
char ffiTestChars(char c1, char c2, char c3, char c4)
{
dprintf(("4 characters came in as\nc1 = %c (%x)\nc2 = %c (%x)\nc3 = %c (%x)\nc4 = %c (%x)\n", c1, c1, c2, c2, c3, c3, c4, c4));
return 'C';
}
short ffiTestShorts(short c1, short c2, short c3, short c4)
{
dprintf(("4 shorts came in as\ns1 = %d (%x)\ns2 = %d (%x)\ns3 = %d (%x)\ns4 = %d (%x)\n", c1, c1, c2, c2, c3, c3, c4, c4));
return -42;
}
int ffiTestInts(int c1, int c2, int c3, int c4)
{
dprintf(("4 ints came in as\ni1 = %d (%x)\ni2 = %d (%x)\ni3 = %d (%x)\ni4 = %d (%x)\n", c1, c1, c2, c2, c3, c3, c4, c4));
return 42;
}
int ffiTestInts8(int c1, int c2, int c3, int c4, int c5, int c6, int c7, int c8)
{
dprintf(("4 ints came in as\ni1 = %d (%x)\ni2 = %d (%x)\ni3 = %d (%x)\ni4 = %d (%x)\ni5 = %d (%x)\ni6 = %d (%x)\ni7 = %d (%x)\ni8 = %d (%x)\n", c1, c1, c2, c2, c3, c3, c4, c4, c5, c5, c6, c6, c7, c7, c8, c8));
return 42;
}
int ffiTestInts9(int c1, int c2, int c3, int c4, int c5, int c6, int c7, int c8, int c9)
{
dprintf(("4 ints came in as\ni1 = %d (%x)\ni2 = %d (%x)\ni3 = %d (%x)\ni4 = %d (%x)\ni5 = %d (%x)\ni6 = %d (%x)\ni7 = %d (%x)\ni8 = %d (%x)\ni9 = %d (%x)\n", c1, c1, c2, c2, c3, c3, c4, c4, c5, c5, c6, c6, c7, c7, c8, c8, c9, c9));
return 42;
}
float ffiTestFloats(float f1, float f2)
{
dprintf(("The two floats are %f and %f\n", (double)f1, (double)f2));
return (float) (f1 + f2);
}
float ffiTestFloats7(float f1, float f2, float f3, float f4, float f5, float f6, float f7)
{
dprintf(("The 7 floats are %f %f %f %f %f %f %f\n", (double)f1, (double)f2, (double)f3, (double)f4, (double)f5, (double)f6, (double)f7));
return (float) (f1 + f2 + f3 + f4 + f5 + f6 + f7);
}
float ffiTestFloats13(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13)
{
dprintf(("The 13 floats are %f %f %f %f %f %f %f %f %f %f %f %f %f\n", (double)f1, (double)f2, (double)f3, (double)f4, (double)f5, (double)f6, (double)f7, (double)f8, (double)f9, (double)f10, (double)f11, (double)f12, (double)f13));
return (float) (f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + f13);
}
float ffiTestFloats15(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13, float f14, float f15)
{
dprintf(("The 15 floats are %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n", (double)f1, (double)f2, (double)f3, (double)f4, (double)f5, (double)f6, (double)f7, (double)f8, (double)f9, (double)f10, (double)f11, (double)f12, (double)f13, (double)f14, (double)f15));
return (float) (f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + f13 + f14 + f15);
}
double ffiTestDoubles(double d1, double d2)
{
dprintf(("The two doubles are %f and %f\n", d1, d2));
return d1+d2;
}
double ffiTestDoubles15(double f1, double f2, double f3, double f4, double f5, double f6, double f7, double f8, double f9, double f10, double f11, double f12, double f13, double f14, double f15)
{
dprintf(("The 15 doubles are %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n", f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15));
return (double) (f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + f13 + f14 + f15);
}
char *ffiPrintString(char *string)
{
dprintf(("%s\n", string));
return string;
}
ffiTestPoint2 ffiTestStruct64(ffiTestPoint2 pt1, ffiTestPoint2 pt2)
{
ffiTestPoint2 result;
dprintf(("pt1.x = %d\npt1.y = %d\npt2.x = %d\npt2.y = %d\n",
pt1.x, pt1.y, pt2.x, pt2.y));
result.x = pt1.x + pt2.x;
result.y = pt1.y + pt2.y;
return result;
}
ffiTestPoint4 ffiTestStructBig(ffiTestPoint4 pt1, ffiTestPoint4 pt2)
{
ffiTestPoint4 result;
dprintf(("pt1.x = %d\npt1.y = %d\npt1.z = %d\npt1.w = %d\n",
pt1.x, pt1.y, pt1.z, pt1.w));
dprintf(("pt2.x = %d\npt2.y = %d\npt2.z = %d\npt2.w = %d\n",
pt2.x, pt2.y, pt2.z, pt2.w));
result.x = pt1.x + pt2.x;
result.y = pt1.y + pt2.y;
result.z = pt1.z + pt2.z;
result.w = pt1.w + pt2.w;
return result;
}
ffiTestPoint4 *ffiTestPointers(ffiTestPoint4 *pt1, ffiTestPoint4 *pt2)
{
ffiTestPoint4 *result;
dprintf(("pt1.x = %d\npt1.y = %d\npt1.z = %d\npt1.w = %d\n",
pt1->x, pt1->y, pt1->z, pt1->w));
dprintf(("pt2.x = %d\npt2.y = %d\npt2.z = %d\npt2.w = %d\n",
pt2->x, pt2->y, pt2->z, pt2->w));
result = (ffiTestPoint4*) malloc(sizeof(ffiTestPoint4));
result->x = pt1->x + pt2->x;
result->y = pt1->y + pt2->y;
result->z = pt1->z + pt2->z;
result->w = pt1->w + pt2->w;
return result;
}
LONGLONG ffiTestLongLong(LONGLONG i1, LONGLONG i2)
{
dprintf(("longlong %lld %lld\n", i1, i2));
return i1 + i2;
}
#endif /* !NO_FFI_TEST */
--- NEW FILE: ffi-test.h ---
typedef struct ffiTestPoint2
{
int x;
int y;
} ffiTestPoint2;
typedef struct ffiTestPoint4
{
int x;
int y;
int z;
int w;
} ffiTestPoint4;
extern char ffiTestChars(char c1, char c2, char c3, char c4);
extern short ffiTestShorts(short c1, short c2, short c3, short c4);
extern int ffiTestInts(int c1, int c2, int c3, int c4);
extern int ffiTestInts8(int c1, int c2, int c3, int c4, int c5, int c6, int c7, int c8);
extern int ffiTestInts9(int c1, int c2, int c3, int c4, int c5, int c6, int c7, int c8, int c9);
extern float ffiTestFloats(float f1, float f2);
extern float ffiTestFloats7(float f1, float f2, float f3, float f4, float f5, float f6, float f7);
extern float ffiTestFloats13(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13);
extern float ffiTestFloats15(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13, float f14, float f15);
extern double ffiTestDoubles(double d1, double d2);
extern double ffiTestDoubles15(double f1, double f2, double f3, double f4, double f5, double f6, double f7, double f8, double f9, double f10, double f11, double f12, double f13, double f14, double f15);
extern char *ffiPrintString(char *string);
extern ffiTestPoint2 ffiTestStruct64(ffiTestPoint2 pt1, ffiTestPoint2 pt2);
extern ffiTestPoint4 ffiTestStructBig(ffiTestPoint4 pt1, ffiTestPoint4 pt2);
extern ffiTestPoint4 *ffiTestPointers(ffiTestPoint4 *pt1, ffiTestPoint4 *pt2);
extern long long ffiTestLongLong(long long i1, long long i2);
--- NEW FILE: ppc-darwin-asm.S ---
/* ppc-sysv-asm.S -- PowerPC FFI trampoline for SVr4-like ABIs -*- asm -*-
*
* Author: Ian...@IN...
*
* Last edited: 2003-01-28 22:43:45 by piumarta on calvin.local.
*
* Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
* as listed elsewhere in this file.
* All rights reserved.
*
* This file is part of Unix Squeak.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You may use and/or distribute this file ONLY as part of Squeak, under
* the terms of the Squeak License as described in `LICENSE' in the base of
* this distribution, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment to the original author(s) (and any
* other contributors mentioned herein) in the product documentation
* would be appreciated but is not required.
*
* 2. This notice must not be removed or altered in any source distribution.
*
* Using (or modifying this file for use) in any context other than Squeak
* changes these copyright conditions. Read the file `COPYING' in the
* directory `platforms/unix/doc' before proceeding with any such use.
*
* You are not allowed to distribute a modified version of this file
* under its original name without explicit permission to do so. If
* you change it, rename it.
*/
/* Mach-O PPC stack frames look like this (higher addresses first):
*
* | caller's lr |
* | caller's cr |
* caller's sp->| caller's caller's sp |
* | fpr save area |
* | gpr save area |
* | [alignment pad] |
* | local variables |
* sp + 24 -> | param save area |
* sp + 20 -> | caller's toc |
* sp + 16 -> | reserved |
* sp + 12 -> | reserved |
* sp + 8 -> | (callee-save) lr |
* sp + 4 -> | (callee-save) cr |
* sp + 0 -> | caller's sp |
*/
#define GPR_MAX 8
#define FPR_MAX 13
#define ARG_MAX 512
#include "ppc-global.h"
#define sp r1
.text
.globl _ffiCallAddressOf
_ffiCallAddressOf:
stwu sp, -32(sp) // push trampoline frame
mflr r0
stw r0, 40(sp)
mfcr r0
stw r0, 36(sp) // saved ccr
mtlr r3 // destination fn address
stw r4, 28(sp) // globals
lwz r5, stackIndex(r4)
slwi r10, r5, 2 // param save area size
addi r10, r10, 32+15 // round to quad word
rlwinm r10, r10, 0,0,27
neg r10, r10
stwux sp, sp, r10 // push ffi caller frame
cmpwi r5, 0 // have params?
beq+ 2f
mtctr r5 // words to move
la r10, (stack-4)(r4) // ffi param stack - 4
addi r11, sp, 24-4 // param save area - 4
1: lwzu r0, 4(r10) // copy param save area
stwu r0, 4(r11)
bdnz 1b
2: lwz r5, fprCount(r4)
cmpwi r5, 0
beq+ 4f // no fp args
la r11, fprs(r4)
cmpwi r5, 4
ble+ 3f
lfd f5, 32(r11)
lfd f6, 40(r11)
lfd f7, 48(r11)
lfd f8, 56(r11)
# if (FPR_MAX > 8)
lfd f9, 64(r11)
lfd f10, 72(r11)
lfd f11, 80(r11)
lfd f12, 88(r11)
lfd f13, 96(r11)
# endif
3: lfd f1, 0(r11)
lfd f2, 8(r11)
lfd f3, 16(r11)
lfd f4, 24(r11)
4: lwz r5, gprCount(r4)
cmpwi r5, 0
beq- 6f // no int args
la r11, gprs(r4)
cmpwi r5, 4
ble+ 5f
lwz r7, 16(r11)
lwz r8, 20(r11)
lwz r9, 24(r11)
lwz r10, 28(r11)
5: lwz r3, 0(r11)
lwz r4, 4(r11)
lwz r5, 8(r11)
lwz r6, 12(r11)
6: blrl // callout
lwz sp, 0(sp) // pop ffi caller frame
lwz r5, 28(sp) // globals
stw r3, longReturnValue+0(r5)
stw r4, longReturnValue+4(r5)
stfd f1, floatReturnValue(r5)
lwz r0, 40(sp)
mtlr r0
lwz r0, 36(sp) // saved ccr
mtcr r0
addi sp, sp, 32 // pop trampoline frame
blr
--- NEW FILE: ppc-darwin.c ---
/* ppc-darwin.c -- FFI support for PowerPC on Mach-O (Darwin)
*
* Author: Ian...@IN...
*
* Last edited: 2003-01-29 00:02:29 by piumarta on calvin.local.
*
* Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
* as listed elsewhere in this file.
* All rights reserved.
*
* This file is part of Unix Squeak.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You may use and/or distribute this file ONLY as part of Squeak, under
* the terms of the Squeak License as described in `LICENSE' in the base of
* this distribution, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment to the original author(s) (and any
* other contributors mentioned herein) in the product documentation
* would be appreciated but is not required.
*
* 2. This notice must not be removed or altered in any source distribution.
*
* Using (or modifying this file for use) in any context other than Squeak
* changes these copyright conditions. Read the file `COPYING' in the
* directory `platforms/unix/doc' before proceeding with any such use.
*
* You are not allowed to distribute a modified version of this file
* under its original name without explicit permission to do so. If
* you change it, rename it.
*
* Notes:
*
* This is a complete rewrite of the version for MacPPC. (The latter
* is hopelessly broken when passing long longs or structs containing
* an element of alignment less strict than int.)
*
* Bugs:
*
* Because of the way strings are handled, this implementation is
* neither reentrant nor thread safe.
*
* References:
*
* Mach-O Runtime Architecture, Apple Computer Inc., July 2002.
*/
#include "sq.h"
#include "sqFFI.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef LONGLONG
# define LONGLONG long long
#endif
#if 0
# define dprintf(ARGS) printf ARGS
#else
# define dprintf(ARGS)
#endif
extern struct VirtualMachine *interpreterProxy;
#if defined(FFI_TEST)
static int primitiveFail(void) { puts("primitive fail"); exit(1); return 0; }
#else
# define primitiveFail() interpreterProxy->primitiveFail();
#endif
#define GPR_MAX 8
#define FPR_MAX 13
#define ARG_MAX 512
static char *strings[ARG_MAX];
static int stringCount= 0;
#if 0
static char structs[ARG_MAX * sizeof(int)];
static int structCount= 0;
#endif
/* the following avoids an awful lot of _very_ inefficient junk in the asm */
static struct
{
int _gprCount; // 0
int _fprCount; // 4
int _stackIndex; // 8
int *_structReturnValue; // 12 (everything below is 8-byte aligned)
LONGLONG _longReturnValue; // 16
double _floatReturnValue; // 24
int _gprs[GPR_MAX]; // 32
double _fprs[FPR_MAX]; // 32 + 4*GPR_MAX
int _stack[ARG_MAX]; // 32 + 4*GPR_MAX + 8*FPR_MAX
} global;
#define gprCount global._gprCount
#define fprCount global._fprCount
#define stackIndex global._stackIndex
#define structReturnValue global._structReturnValue
#define longReturnValue global._longReturnValue
#define floatReturnValue global._floatReturnValue
#define gprs global._gprs
#define fprs global._fprs
#define stack global._stack
extern int ffiCallAddressOf(void *addr, void *globals);
int ffiInitialize(void)
{
stackIndex= gprCount= fprCount= 0;
#if 0
structCount= 0;
#endif
floatReturnValue= 0.0;
return 1;
}
int ffiSupportsCallingConvention(int callType)
{
return (callType == FFICallTypeCDecl)
|| (callType == FFICallTypeApi);
}
int ffiAlloc(int byteSize)
{
return (int)malloc(byteSize);
}
int ffiFree(int ptr)
{
if (ptr) free((void *)ptr);
return 1;
}
#define checkStack() \
if (stackIndex >= ARG_MAX) \
return primitiveFail()
#define checkGPR() \
if ((gprCount >= GPR_MAX) && (stackIndex >= ARG_MAX)) \
return primitiveFail()
#define qalignStack() stackIndex += (stackIndex & 1)
#define pushGPR(value) \
checkGPR(); \
if (gprCount < GPR_MAX) \
gprs[gprCount++]= value; \
stack[stackIndex++]= value
#define qalignGPR() gprCount += (gprCount & 1)
int ffiPushSignedChar(int value)
{
dprintf(("ffiPushSignedChar %d\n", value));
pushGPR(value);
return 1;
}
int ffiPushUnsignedChar(int value)
{
dprintf(("ffiPushUnsignedChar %d\n", value));
pushGPR(value);
return 1;
}
int ffiPushSignedByte(int value)
{
dprintf(("ffiPushSignedByte %d\n", value));
pushGPR(value);
return 1;
}
int ffiPushUnsignedByte(int value)
{
dprintf(("ffiPushUnsignedByte %d\n", value));
pushGPR(value);
return 1;
}
int ffiPushSignedShort(int value)
{
dprintf(("ffiPushSignedShort %d\n", value));
pushGPR(value);
return 1;
}
int ffiPushUnsignedShort(int value)
{
dprintf(("ffiPushUnsignedShort %d\n", value));
pushGPR(value);
return 1;
}
int ffiPushSignedInt(int value)
{
dprintf(("ffiPushSignedInt %d\n", value));
pushGPR(value);
return 1;
}
int ffiPushUnsignedInt(int value)
{
dprintf(("ffiPushUnsignedInt %d\n", value));
pushGPR(value);
return 1;
}
int ffiPushSignedLongLong(int low, int high)
{
dprintf(("ffiPushSignedLongLong %d %d\n", low, high));
qalignGPR();
qalignStack();
pushGPR(high);
pushGPR(low);
return 1;
}
int ffiPushUnsignedLongLong(int low, int high)
{
dprintf(("ffiPushUnsignedLongLong %d %d\n", low, high));
qalignGPR();
qalignStack();
pushGPR(high);
pushGPR(low);
return 1;
}
int ffiPushPointer(int pointer)
{
dprintf(("ffiPushPointer %d\n", pointer));
pushGPR(pointer);
return 1;
}
int ffiPushSingleFloat(double value)
{
dprintf(("ffiPushSingleFloat %f\n", (float)value));
if (fprCount < FPR_MAX)
fprs[fprCount++]= value;
{
float floatValue= (float)value;
pushGPR(*(int *)&floatValue);
}
return 1;
}
int ffiPushDoubleFloat(double value)
{
dprintf(("ffiPushDoubleFloat %f\n", (float)value));
if (fprCount < FPR_MAX)
fprs[fprCount++]= value;
pushGPR(((int *)&value)[0]);
pushGPR(((int *)&value)[1]);
return 1;
}
int ffiPushStringOfLength(int srcIndex, int length)
{
char *ptr;
dprintf(("ffiPushStringOfLength %d\n", length));
checkGPR();
ptr= (char *)malloc(length + 1);
if (!ptr)
return primitiveFail();
memcpy(ptr, (void *)srcIndex, length);
ptr[length]= '\0';
strings[stringCount++]= ptr;
pushGPR((int)ptr);
return 1;
}
static inline int min(int x, int y) { return (x < y) ? x : y; }
int ffiPushStructureOfLength(int pointer, int *structSpec, int specSize)
{
int i;
char *data = (char *)pointer;
char *argp = (char *)&stack[stackIndex];
#define argl (char *)&stack[ARG_MAX]
int argSize = *structSpec & FFIStructSizeMask;
char *gprp = (char *)&gprs[gprCount];
#define gprl (char *)&gprs[GPR_MAX]
int gprSize = min(argSize, gprl - gprp);
if (gprSize < 4) gprp += (4 - gprSize);
if (argSize < 4) argp += (4 - gprSize);
if (argp + argSize > argl)
return primitiveFail();
memcpy((void *)gprp, (void *)data, gprSize);
memcpy((void *)argp, (void *)data, argSize);
gprCount += (gprSize + sizeof(int) - 1) / sizeof(int);
stackIndex += (argSize + sizeof(int) - 1) / sizeof(int);
#undef argl
#undef gprl
for (i= 0; i < specSize; ++i)
{
int typeSpec= structSpec[i];
if (typeSpec & FFIFlagPointer)
continue;
else if (typeSpec & FFIFlagStructure)
continue;
else
{
int atomicType= (typeSpec & FFIAtomicTypeMask) >> FFIAtomicTypeShift;
switch (atomicType)
{
case FFITypeSingleFloat:
if (fprCount < FPR_MAX)
fprs[fprCount++]= *(float *)data;
break;
case FFITypeDoubleFloat:
if (fprCount < FPR_MAX)
fprs[fprCount++]= *(double *)data;
break;
default:
break;
}
data += typeSpec & FFIStructSizeMask;
}
}
return 1;
}
int ffiCanReturn(int *structSpec, int specSize)
{
int header= *structSpec;
if (header & FFIFlagPointer)
return 1;
if (header & FFIFlagStructure)
{
/* structs are always returned as pointers to hidden structures */
int structSize= header & FFIStructSizeMask;
structReturnValue= malloc(structSize);
if (!structReturnValue)
return 0;
pushGPR((int)structReturnValue);
}
return 1;
}
double ffiReturnFloatValue(void) { return floatReturnValue; }
int ffiLongLongResultLow(void) { return ((int *)&longReturnValue)[1]; }
int ffiLongLongResultHigh(void) { return ((int *)&longReturnValue)[0]; }
int ffiStoreStructure(int address, int structSize)
{
memcpy((void *)address,
structReturnValue ? (void *)structReturnValue : (void *)&longReturnValue,
structSize);
return 1;
}
int ffiCleanup(void)
{
int i;
for (i= 0; i < stringCount; ++i)
free(strings[i]);
stringCount= 0;
if (structReturnValue)
{
free(structReturnValue);
structReturnValue= 0;
}
return 1;
}
int ffiCallAddress...
[truncated message content] |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:32
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/UnixOSProcessPlugin In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/UnixOSProcessPlugin Added Files: Makefile.inc Log Message: Ian Piumarta's release 3.4.1 --- NEW FILE: Makefile.inc --- XCPPFLAGS= -I$(topdir)/platforms/Cross/plugins/FilePlugin -I$(topdir)/platforms/Cross/plugins/SocketPlugin |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:31
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/PseudoTTYPlugin
In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/PseudoTTYPlugin
Added Files:
PseudoTTY.st PseudoTTYPlugin.st README acinclude.m4 openpty.h
sqUnixPseudoTTYPlugin.c
Log Message:
Ian Piumarta's release 3.4.1
--- NEW FILE: PseudoTTY.st ---
'From Squeak3.2gamma of 15 January 2002 [latest update: #4881] on 11 July 2002 at 6:06:32 am'!
AsyncFile subclass: #PseudoTTY
instanceVariableNames: 'inputBuffer outputBuffer ioError '
classVariableNames: 'AsyncFileError '
poolDictionaries: ''
category: 'Communications-Endpoints'!
!PseudoTTY commentStamp: '<historical>' prior: 0!
I am a very particular kind of AsyncFile connected to the `master' half of a pseudo TTY (pty). My purpose in life is to provide communication with a process (in the fork+exec sense) that is connected to the `slave' half of the pty. (Writing to a master pty causes the data to appear on the slave's stdin, and anything written to the slave's stdout/stderr is available for subsequent reading on the master pty.)
You create me by sending my class
command: programNameString arguments: arrayOfArgumentStrings
which will spawn a new process running the named program with the given arguments. You can subsequently send me #nextPut: (or #nextPutAll:) to send stuff to the stdin of the program, and #upToEnd to retrieve data that the program writes to its stdout or stderr. You can also send me #close which will shut down the program (by sending it SIGTERM followed shortly thereafter by SIGKILL if it's being stubborn) and both halves of the pseudo tty.
The spawned program runs in a new session, will be its own session and process group leader and will have the slave half of the pty as its controlling terminal. (In plain English this means that the program will behave exactly as if it were being run from login, in particular: shells will enable job control, screen-oriented programs like Emacs will work properly, the user's login tmode settings will be inherited, intr/quit/etc. characters will be cooked into the corresponding signals, and window geometry changes will be propagated to the program. Neat, huh? ;-)
Note that you need both the AsynchFile and PseudoTTY plugins in order for any of this to work.
Note also that I am really intended to be used by a ProcessEndpoint as part of a ProtocolStack (along with a terminal emulator and a TeletypeMorph to provide interaction with the subprocess).
!
!PseudoTTY methodsFor: 'initialize-release' stamp: 'ikp 7/10/2002 21:58'!
close
"Close the master half of the pty. The subprocess should exit (EOF on stdin) although badly written programs might start looping."
fileHandle isNil ifTrue: [^self].
self primClosePts: fileHandle.
fileHandle _ nil.
Smalltalk unregisterExternalObject: semaphore.
ioError _ AsyncFileError.
semaphore signal. "wake up waiters"
semaphore _ nil! !
!PseudoTTY methodsFor: 'initialize-release' stamp: 'ikp 7/11/2002 02:47'!
command: programName arguments: argumentArray
"Create a pseudo tty and then spawn programName with its stdin, out and err connected to the slave end of the pty."
| semaIndex |
"AsyncFile"
name _ programName.
writeable _ true.
semaphore _ Semaphore new.
semaIndex _ Smalltalk registerExternalObject: semaphore.
"PseudoTTY"
inputBuffer _ ByteArray new: 8192.
outputBuffer _ ByteArray new: 1.
ioError _ 0.
fileHandle _ self
forkAndExecWithPts: programName
arguments: (argumentArray isNil
ifTrue: [#()]
ifFalse: [argumentArray])
semaIndex: semaIndex.
fileHandle isNil ifTrue: [
Smalltalk unregisterExternalObject: semaphore.
semaphore _ nil.
ioError _ AsyncFileError.
^nil].
Processor yield.
semaphore signal.
^self! !
!PseudoTTY methodsFor: 'accessing' stamp: 'ikp 7/11/2002 01:36'!
name
"Answer the name of the program."
^name! !
!PseudoTTY methodsFor: 'input/output' stamp: 'ikp 7/7/2002 02:56'!
ioError
"Return the last error code received during read/write. If this is ever non-zero it means the subprocess has probably died."
^ioError! !
!PseudoTTY methodsFor: 'input/output' stamp: 'ikp 7/7/2002 06:22'!
isConnected
^fileHandle notNil and: [ioError == 0]! !
!PseudoTTY methodsFor: 'input/output' stamp: 'ikp 7/7/2002 06:16'!
nextPut: aCharacterOrInteger
"Send a single character to the stdin of my subprocess."
fileHandle isNil ifTrue: [^self].
outputBuffer at: 1 put: aCharacterOrInteger asInteger.
self
primWriteStart: fileHandle
fPosition: -1
fromBuffer: outputBuffer
at: 1
count: 1! !
!PseudoTTY methodsFor: 'input/output' stamp: 'ikp 7/7/2002 06:16'!
nextPutAll: aStringOrByteArray
"Send an entire string to the stdin of my subprocess."
fileHandle isNil ifTrue: [^self].
self
primWriteStart: fileHandle
fPosition: -1
fromBuffer: aStringOrByteArray
at: 1
count: aStringOrByteArray size! !
!PseudoTTY methodsFor: 'input/output' stamp: 'ikp 7/7/2002 13:28'!
noteWindowSize: aPoint
self primWindowSize: fileHandle cols: aPoint x rows: aPoint y! !
!PseudoTTY methodsFor: 'input/output' stamp: 'ikp 7/9/2002 06:15'!
peekUpToEnd
"Answer everything the subprocess has written to stdout or stderr since the last send of #upToEnd. Note that stuff written to stderr might arrive earlier than stuff written to stdout if the former is unbuffered and the latter line buffered in the subprocess's stdio library."
| n |
self isConnected ifFalse: [^nil].
n _ self
primReadResult: fileHandle
intoBuffer: inputBuffer
at: 1
count: inputBuffer size.
^(self isConnected and: [n > 0])
ifTrue: [inputBuffer copyFrom: 1 to: n]
ifFalse: [nil]! !
!PseudoTTY methodsFor: 'input/output' stamp: 'ikp 7/7/2002 21:28'!
upToEnd
"Answer everything the subprocess has written to stdout or stderr since the last send of #upToEnd. Note that stuff written to stderr might arrive earlier than stuff written to stdout if the former is unbuffered and the latter line buffered in the subprocess's stdio library."
| n |
[self isConnected and: [(n _ self startRead: inputBuffer size;
primReadResult: fileHandle
intoBuffer: inputBuffer
at: 1
count: inputBuffer size) == Busy]]
whileTrue: [self waitForCompletion].
(self isConnected and: [n > 0])
ifTrue: [^inputBuffer copyFrom: 1 to: n]
ifFalse: [ioError _ AsyncFileError. ^nil] "subprocess has died or closed stdout"! !
!PseudoTTY methodsFor: 'private' stamp: 'ikp 7/10/2002 22:57'!
forkAndExecWithPts: aCommand arguments: argArray semaIndex: semaIndex
"Run aCommand as an inferior process and connect its std{in,out,err} to the receiver through a pseudo tty."
^self primForkAndExec: aCommand arguments: argArray semaIndex: semaIndex! !
!PseudoTTY methodsFor: 'private' stamp: 'ikp 7/7/2002 03:07'!
startRead: count
"Indicate interest in receiving more data from stdout/stderr of the subprocess."
self
primReadStart: fileHandle
fPosition: -1
count: count! !
!PseudoTTY methodsFor: 'primitives' stamp: 'ikp 7/7/2002 05:11'!
primClosePts: fHandle
"Kill the process whose pts is associated with our pty."
<primitive: 'primPtyClose' module: 'PseudoTTYPlugin'>
^nil! !
!PseudoTTY methodsFor: 'primitives' stamp: 'ikp 7/10/2002 21:48'!
primForkAndExec: command arguments: arguments semaIndex: semaIndex
"Fork and exec command with the given arguments connecting the new process to a slave tty created from the receiver (which is the master half of a pseudo tty)."
<primitive: 'primPtyForkAndExec' module: 'PseudoTTYPlugin'>
^nil! !
!PseudoTTY methodsFor: 'primitives' stamp: 'ikp 7/7/2002 06:41'!
primWindowSize: fHandle cols: cols rows: rows
"Set the size of the terminal connected to the pty."
<primitive: 'primPtyWindowSize' module: 'PseudoTTYPlugin'>
^nil! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
PseudoTTY class
instanceVariableNames: ''!
!PseudoTTY class methodsFor: 'class initialization' stamp: 'ikp 7/7/2002 02:25'!
initialize
"Can't rely on Error because the compiler finds the global before the class var. Ho hum."
"PseudoTTY initialize"
AsyncFileError _ -2! !
!PseudoTTY class methodsFor: 'instance creation' stamp: 'ikp 7/7/2002 04:33'!
command: commandString arguments: argumentArray
"(PseudoTTY command: '/bin/bash' arguments: #('-c' 'pwd')) upToEnd asString"
^self new
command: commandString
arguments: argumentArray! !
!PseudoTTY class methodsFor: 'examples' stamp: 'ikp 7/10/2002 23:00'!
example
"Show the user's current tty mode settings."
"PseudoTTY example"
| pty output buf |
pty _ s
elf command: '/bin/stty' arguments: #('-a').
pty isNil ifTrue: [^self error: 'Could not create pty or process.'].
output _ WriteStream on: String new.
output nextPutAll: 'Your tty modes are: '; cr; space; cr.
[(buf _ pty upToEnd) isNil] whileFalse: [output nextPutAll: buf asString].
pty close.
self inform: output contents! !
PseudoTTY initialize!
--- NEW FILE: PseudoTTYPlugin.st ---
'From Squeak3.2gamma of 15 January 2002 [latest update: #4881] on 11 July 2002 at 12:42:23 am'!
TestInterpreterPlugin subclass: #PseudoTTYPlugin
instanceVariableNames: 'sCOAFfn '
classVariableNames: ''
poolDictionaries: ''
category: 'VMConstruction-Plugins'!
!PseudoTTYPlugin commentStamp: '<historical>' prior: 0!
Author: Ian Piumarta <ian...@in...>
Date: 2002-07-06
Version: 1.0
This plugin extends AsynchFilePlugin with support for Unix98-style pseudo ttys. Pseudo ttys (ptys) are a means for some program A (e.g., Squeak) to spawn a child process B and have B's std{in,out,err} connected to something that smells (to B) like a terminal (the `slave' tty) but which is in fact connected directly to A via another device (the `master' tty).
One example of this would be Squeak spawning an interactive shell. If we were to use pipes (or sockets) to communicate with the shell's std{in,out,err} then various screen-oriented programs (such as Emacs) would refuse to run, the shell itself would refuse to implement job control and `cooked' characters (intr, quit, suspend, etc.) would be ignored -- all because pipes (and sockets) are absolutely not the same thing as a tty. Connecting the shell to a slave tty (and talking to it indirectly through our master tty) allows such programs (and shells and interrupts, etc.) to work properly, since they believe themselves to be connected to a `real' terminal.
To use this plugin on any system that supports Unix98 pseudo ttys you would do something like this:
- open an AsyncFile on /dev/ptmx (the Pseudo Tty master MultipleXor) which returns
a handle on the master tty (and creates the slave tty device -- usually something like
/dev/ttyN or /dev/pts/N);
- prepare the slave tty for use by an inferior process by calling primGrantPt and
primUnlockPt on the master;
- call primPtsName on the master to obtain the name of the allocated slave tty device;
- open the slave tty for read (stdin), write (stdout) and again for write (stderr);
- fork;
- connect the inferior process's std{in,out,err} to the slave tty device through the three
descriptors just opened;
- exec the shell (or whatever) in the inferior process.
After all that the parent process can write (via the original AsyncFile) to the master tty (to provide data for the inferior process's stdin) and read (via the AsyncFile) from the master (to retrieve data written to std{out,err} by the inferior process). If the inferior process tests std{in,out,err} with isatty() it will be told that it is connected to a login terminal.
This plugin provides four primitives, as implied by the above, all of which apply to AsyncFiles:
primitivePtGrant - prepare the slave tty for use
primitivePtUnlock - allow connections (open) to the slave tty
primitivePtsNameLength - return the size of the slave tty's device name
primitivePtsName - read the slave tty's device name into a String
(designed to be easily useable in conjunction with OSProcess) and one more (just for my convenience) which does all of the above steps atomically (and also promotes the inferior process to a process group leader, and installs a handler to finalise the inferior process on exit and close its parent's master tty -- without the need to use OSProcess at all):
primitiveForkAndExecWithPts - create an inferior process connected to a slave tty
Note that `Unix98' does NOT imply that this will only work on Unix systems!! Unix98 is the name of a *standard* (describing one possible implementation of pseudo ttys) which can be adopted by any OS, be it Unix or something entirely different. (Unix98 ptys have been adopted by both BSD and Linux, which is why we consider it the most interesting standard to implement here. However, be warned that if [for some bizarre, masochistic reason] you have disabled Unix98 pty support in your BSD or Linux kernel then this plugin will explode in your face. [Although you should never get that far since the initial open of /dev/ptmx will fail.])
Finally note that this plugin might (should) go away in the future if (when) OSProcess implements the required support for pseudo ttys and asynchronous i/o on their master devices. Dave: are you reading this?!
!PseudoTTYPlugin methodsFor: 'initialize-release' stamp: 'ikp 7/10/2002 22:41'!
initialiseModule
self export: true.
"We have to load AsyncFile first, to get the sessionID."
interpreterProxy ioLoadFunction: 'initializeModule' From: 'AsynchFilePlugin'.
^self cCode: 'ptyInit()' inSmalltalk: [true]! !
!PseudoTTYPlugin methodsFor: 'initialize-release' stamp: 'ikp 7/7/2002 02:29'!
shutdownModule
self export: true.
^self cCode: 'ptyShutdown()' inSmalltalk: [true]! !
!PseudoTTYPlugin methodsFor: 'primitives' stamp: 'ikp 7/7/2002 05:44'!
primitivePtyClose: fHandle
| f |
self var: #f declareC: 'AsyncFile *f'.
self primitive: 'primPtyClose' parameters: #(Oop).
f _ self asyncFileValueOf: fHandle.
interpreterProxy failed ifFalse: [self cCode: 'ptyClose(f)'].! !
!PseudoTTYPlugin methodsFor: 'primitives' stamp: 'ikp 7/10/2002 22:31'!
primitivePtyForkAndExec: cmd arguments: args semaIndex: semaIndex
| f cmdLen cmdIdx argLen argIdx fOop |
self var: #f declareC: 'AsyncFile *f'.
self primitive: 'primPtyForkAndExec' parameters: #(Oop Oop SmallInteger).
interpreterProxy success: (interpreterProxy isBytes: cmd).
interpreterProxy success: (interpreterProxy isPointers: args).
interpreterProxy failed ifTrue: [^nil].
cmdIdx _ self cCoerce: (interpreterProxy firstIndexableField: cmd) to: 'int'.
cmdLen _ interpreterProxy slotSizeOf: cmd. "in bytes"
argIdx _ self cCoerce: (interpreterProxy firstIndexableField: args) to: 'int'.
argLen _ interpreterProxy slotSizeOf: args. "in fields"
fOop _ interpreterProxy
instantiateClass: interpreterProxy classByteArray
indexableSize: (self cCode: 'sizeof(AsyncFile)').
f _ self asyncFileValueOf: fOop.
interpreterProxy failed
ifFalse: [self cCode: 'ptyForkAndExec(f, semaIndex, cmdIdx, cmdLen, argIdx, argLen)'].
^fOop! !
!PseudoTTYPlugin methodsFor: 'primitives' stamp: 'ikp 7/7/2002 06:38'!
primitivePtyWindowSize: fHandle cols: cols rows: rows
| f |
self var: #f declareC: 'AsyncFile *f'.
self primitive: 'primPtyWindowSize' parameters: #(Oop SmallInteger SmallInteger).
f _ self asyncFileValueOf: fHandle.
interpreterProxy failed ifFalse: [self cCode: 'ptyWindowSize(f, cols, rows)'].! !
!PseudoTTYPlugin methodsFor: 'private' stamp: 'ikp 7/6/2002 19:08'!
asyncFileValueOf: oop
"Return a pointer to the first byte of the async file record within the given Smalltalk bytes object, or nil if oop is not an async file record."
self returnTypeC: 'AsyncFile *'.
interpreterProxy success:
((interpreterProxy isIntegerObject: oop) not
and: [(interpreterProxy isBytes: oop)
and: [(interpreterProxy slotSizeOf: oop) = (self cCode: 'sizeof(AsyncFile)')]]).
interpreterProxy failed ifTrue: [^ nil].
^ self cCode: '(AsyncFile *) (oop + 4)'
! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
PseudoTTYPlugin class
instanceVariableNames: ''!
!PseudoTTYPlugin class methodsFor: 'translation' stamp: 'ikp 7/6/2002 21:18'!
hasHeaderFile
^true! !
!PseudoTTYPlugin class methodsFor: 'translation' stamp: 'ikp 7/6/2002 21:12'!
requiresPlatformFiles
^true! !
--- NEW FILE: README ---
/* This directory contains the PseudoTTYPlugin, a means for Squeak to
* fork an interactive program that believes itself to be running on a
* login terminal when, in fact, Squeak is providing it with data for
* its stdin and recovering the output it writes to its stdout/stderr.
*
* The Squeak plugin source code is in `PseudoTTYPlugin.st'.
* The Squeak class needed to use the plugin is in `PseudoTTY.st'.
*
* The plugin has been built and tested on the following architecures:
*
* GNU/Linux (libc2.3)
* NetBSD 1.5ZC
* Solaris 2.8
*
* The remainder of this file is a C program designed to ease the
* process of porting this plugin to unsupported architectures.
*
* ----------------------------------------------------------------
*
* This program forks a child process to run /bin/stty and then
* collects and prints its output. If the child is not connected to a
* login terminal then stty will complain (printing something like
* "stdin: not a tty") and you have a problem somewhere in "opentty.h"
* which you must FIND AND FIX before the plugin will work. OTOH, if
* it prints a bunch (about ten lines) of tty mode information then
* all is well and the plugin should work just fine.
*
* (Do I really need to mention that you have to rename this file to
* "pty.c" or somesuch before trying to compile it? ;)
*/
/* For the plugin the HAVE_* macros are set in config.h by acinclude.m4.
* In this test file you need to set them manually for your architecture.
* If you invent new HAVE_* macros then you'll need to modify acinclude.m4
* and regenerate configure (run `make' in ../../config) before building
* the VM.
*
* If it is available then we use openpty() in preference to Unix98 ptys:
*
* HAVE_OPENPTY -- defined if you have openpty() and login_tty()
* HAVE_UTIL_H -- defined if you have /usr/include/util.h
* HAVE_PTY_H -- defined if you have /usr/include/pty.h
*
* If you don't have openpty() then we fake it from /dev/ptmx:
*
* HAVE_UNIX98_PTY -- defined if you have /dev/ptmx and grantpt() et al.
* HAVE_STROPTS_H -- defined if you have /usr/include/stropts.h
*
* We assume you have /usr/include/utmp.h; if you don't then you need to
* buy a real computer before trying to compile this plugin.
*
* Suggested compile command is shown with each architecture.
* If you have to add new libraries then you'll need to modify acinclude.m4
* and regenerate configure (run `make' in ../../config) before building the
* VM.
*/
#if defined(__NetBSD__) /* cc -o pty pty.c -lutil */
# define HAVE_OPENPTY
# define HAVE_UTIL_H
#elif defined(__OpenBSD__) /* cc -o pty pty.c -lutil */
# define HAVE_OPENPTY
# define HAVE_UTIL_H
#elif defined(__linux__) /* cc -o pty pty.c -lutil */
# define HAVE_UNIX98_PTY
# define HAVE_OPENPTY
# define HAVE_PTY_H
#elif defined(__sun__) /* cc -o pty pty.c */
# define HAVE_UNIX98_PTY
# define HAVE_STROPTS_H
#else
# error: defines for your architecture go here
#endif
/* Absolutely everybody has these. */
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>
/* This gets the obscure (interesting ;) stuff. */
#include "openpty.h"
/* Here we go! ... */
static char *prog= "/bin/stty";
static char *argv[]= { "stty", "-a", 0 };
extern char **environ;
static int ptm= -1, pts= -1;
static void sigchld(int signum)
{
close(pts); /* force i/o error or EOF on ptm */
}
int main()
{
char tty[32];
pid_t pid= 0;
if (openpty(&ptm, &pts, tty, 0, 0) == -1)
{
perror("openpty");
exit(1);
}
printf("using %s (ptm %d pts %d)\n", tty, ptm, pts);
signal(SIGCHLD, sigchld);
pid= fork();
switch (pid)
{
case -1:
perror("fork");
exit(1);
break;
case 0: /* child */
close(ptm);
if (login_tty(pts) == -1)
{
perror("login_tty");
exit(1);
}
execve(prog, argv, environ);
perror(argv[0]);
exit(1);
break;
default: /* parent */
{
char buf[128];
int n, status;
printf("---------------- from child:\n");
while (((n= read(ptm, buf, sizeof(buf) - 1)) > 0)
|| ((n == -1) && (errno == EINTR)))
if (n > 0)
{
buf[n]= '\0';
printf("%s", buf);
}
printf("----------------\n");
if (n < 0)
perror("read");
else
printf("EOF\n");
close(ptm);
pid= wait(&status);
printf("child exited with status %d\n", status);
}
break;
}
return 0;
}
--- NEW FILE: acinclude.m4 ---
AC_HAVE_HEADERS(util.h libutil.h pty.h stropts.h)
AC_SEARCH_LIBS(openpty, util,
AC_DEFINE(HAVE_OPENPTY, 1),[
if test -r /dev/ptmx; then
AC_CHECK_FUNC(grantpt, AC_DEFINE(HAVE_UNIX98_PTYS, 1))
fi])
--- NEW FILE: openpty.h ---
/* openpty.h -- provides openpty() and login_tty()
*
* Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
* as listed elsewhere in this file.
* All rights reserved.
*
* This file is part of Unix Squeak.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You may use and/or distribute this file ONLY as part of Squeak, under
* the terms of the Squeak License as described in `LICENSE' in the base of
* this distribution, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment to the original author(s) (and any
* other contributors mentioned herein) in the product documentation
* would be appreciated but is not required.
*
* 2. This notice must not be removed or altered in any source distribution.
*
* Using (or modifying this file for use) in any context other than Squeak
* changes these copyright conditions. Read the file `COPYING' in the
* directory `platforms/unix/doc' before proceeding with any such use.
*
* You are not allowed to distribute a modified version of this file
* under its original name without explicit permission to do so. If
* you change it, rename it.
*
* Author: Ian...@in...
*
* Last edited: 2002-07-11 21:07:37 by piumarta on emilia.inria.fr
*/
#if defined(HAVE_OPENPTY)
# include <utmp.h> /* login_tty() */
# if defined(HAVE_PTY_H)
# include <pty.h> /* openpty() */
# elif defined(HAVE_UTIL_H)
# include <util.h> /* openpty() */
# elif defined(HAVE_LIBUTIL_H)
# include <libutil.h> /* openpty() on FreeBSD */
# else
# error: cannot find headers for openpty()
# endif
#else /* !HAVE_OPENPTY */
# if defined(HAVE_UNIX98_PTYS)
/* we'll just roll our own, it ain't hard */
# include <stdlib.h> /* ptsname(), grantpt(), unlockpt() */
# include <unistd.h>
# include <string.h>
# include <fcntl.h>
# if defined(HAVE_STROPTS_H)
# include <stropts.h>
# include <sys/ioctl.h>
# endif
static int openpty(int *ptmp, int *ptsp, char *ttyp, void *termiosp, void *winp)
{
int ptm= -1, pts= -1;
char *tty= 0;
if ((ptm= open("/dev/ptmx", O_RDWR, 0)) == -1) return -1;
tty= ptsname(ptm);
if (grantpt(ptm) == -1) return -1;
if (unlockpt(ptm) == -1) return -1;
if ((pts= open(tty, O_RDWR, 0)) == -1) return -1;
*ptmp= ptm;
*ptsp= pts;
strcpy(ttyp, tty);
return 0;
}
static int login_tty(int pts)
{
#if defined(HAVE_STROPTS_H)
/* push a terminal onto stream head */
if (ioctl(pts, I_PUSH, "ptem") == -1) return -1;
if (ioctl(pts, I_PUSH, "ldterm") == -1) return -1;
#endif
setsid();
#if defined(TIOCSCTTY)
ioctl(pts, TIOCSCTTY, 0);
#endif
dup2(pts, 0);
dup2(pts, 1);
dup2(pts, 2);
if (pts > 2) close(pts);
return 0;
}
# else /* !HAVE_UNIX98_PTYS */
# error: cannot open a pty -- this plugin will not work
# endif
#endif /* !HAVE_OPENPTY */
--- NEW FILE: sqUnixPseudoTTYPlugin.c ---
/* PseudoTTYPlugin.c -- support for Unix98-style pseudo ttys -*- C -*-
*
* Author: Ian Piumarta <ian...@in...>
* Version: 1.1
* Last edited: 2002-07-12 10:37:47 by piumarta on emilia.inria.fr
*
* This plugin extends AsynchFilePlugin with support for Unix98-style
* pseudo ttys. See the PseudoTTY and PseudoTTYPlugin class comments
* for details.
*
* Note that `Unix98' does NOT imply that this will only work on Unix
* systems! Unix98 is the name of a *standard* describing (amonst
* many other things) one possible implementation of pseudo ttys that
* could be adopted by any OS, be it Unix or something entirely
* different. (Unix98 ptys have been adopted by both BSD and Linux,
* which is why we consider it the most interesting standard to
* implement here. However, be warned that if [for some bizarre,
* masochistic reason] you have disabled Unix98 pty support in your
* BSD or Linux kernel then this plugin will explode in your face.
* [Although you should never get that far since the initial open of
* /dev/ptmx will fail.])
*
* Finally note that this plugin might (should) go away in the future
* if (when) OSProcess implements the required support for pseudo ttys
* and asynchronous i/o on their master devices. (Dave: are you
* reading this?)
*
* Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
* as listed elsewhere in this file.
* All rights reserved.
*
* This file is part of Unix Squeak.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You may use and/or distribute this file ONLY as part of Squeak, under
* the terms of the Squeak License as described in `LICENSE' in the base of
* this distribution, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment to the original author(s) (and any
* other contributors mentioned herein) in the product documentation
* would be appreciated but is not required.
*
* 2. This notice must not be removed or altered in any source distribution.
*
* Using (or modifying this file for use) in any context other than Squeak
* changes these copyright conditions. Read the file `COPYING' in the
* directory `platforms/unix/doc' before proceeding with any such use.
*
* You are not allowed to distribute a modified version of this file
* under its original name without explicit permission to do so. If
* you change it, rename it.
*/
#include "sq.h"
#include "PseudoTTYPlugin.h"
/* Ian says: never EVER #include things in the Unix Squeak sources
using relative paths. Never. Ever. Period. Write a Makefile.inc
with the right XCPPFLAGS instead. Having said that... */
#include "../AsynchFilePlugin/sqUnixAsynchFile.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <termios.h>
#include <sys/ioctl.h>
#include "openpty.h" /* hide the gory details ;) */
#if 0
# define dprintf(ARGS) printf ARGS
#else
# define dprintf(ARGS)
#endif
typedef struct Slave
{
pid_t pid; /* process */
int status; /* exit status */
int pts; /* pts (child pty) */
FilePtr pty; /* ptm (parent pty) */
struct Slave *next; /* list */
} SlaveRec, *SlavePtr;
static SlavePtr slaves= 0;
typedef void (*sighandler_t)(int);
static sighandler_t prevchld= 0;
static int reaping= 0;
#define isValid(f) (f->sessionID == sqUnixAsyncFileSessionID)
#define validate(f) if ((!isValid(f)) || (!(f->state))) return vm->primitiveFail()
/*** initialise-release ***/
#include "sqVirtualMachine.h"
static struct VirtualMachine *vm= 0;
static void sigchld(int signum)
{
int status= 0;
SlavePtr zombie= 0;
pid_t pid= wait(&status);
if (!slaves)
fprintf(stderr, "unexpected SIGCHLD for pid %d\n", pid);
else
for (zombie= slaves; zombie; zombie= zombie->next)
if (zombie->pid == pid)
break;
if (!zombie)
fprintf(stderr, "failed to clean up for pid %d\n", pid);
else
{
/* force any image server loop to exit */
/* close(zombie->pty->fd); */
zombie->pty->rd.status= -2;
signalSemaphoreWithIndex(zombie->pty->sema);
dprintf(("closed pty for pid %d\n", pid));
}
}
int ptyInit(void)
{
dprintf(("ptyInit: AsyncFileSession is %d\n", sqUnixAsyncFileSessionID));
vm= sqGetInterpreterProxy();
slaves= 0;
prevchld= signal(SIGCHLD, sigchld);
if ((prevchld != SIG_DFL) && (prevchld != SIG_IGN))
{
fprintf(stderr, "declining responsibility for child processes!\n");
signal(SIGCHLD, prevchld);
reaping= 0;
}
else
reaping= 1;
return 1;
}
int ptyShutdown(void)
{
if (reaping)
{
SlavePtr slave= 0;
for (slave= slaves; slave; slave= slave->next)
kill(slave->pid, SIGTERM);
usleep(200*1000);
for (slave= slaves; slave; slave= slave->next)
kill(slave->pid, SIGKILL);
usleep(200*1000);
signal(SIGCHLD, prevchld);
while (slaves)
{
slave= slaves->next;
fprintf(stderr, "child process %d refused to die\n", slaves->pid);
free(slaves);
slaves= slave;
}
}
slaves= 0;
return 1;
}
/*** primitives ***/
#include <fcntl.h>
#include <time.h>
int ptyForkAndExec(AsyncFile *f, int semaIndex,
int cmdIndex, int cmdLen, int argIndex, int argLen)
{
int ptm= -1, pts= -1;
char tty[32];
FilePtr fp= 0;
/* Module init must succeed in loading the AsyncFile plugin */
if (sqUnixAsyncFileSessionID == 0)
{
vm->primitiveFail();
return 0;
}
dprintf(("AsyncFileSession is %d\n", sqUnixAsyncFileSessionID));
if (openpty(&ptm, &pts, tty, 0, 0) == -1)
{
perror("pty: openpty");
goto failDetached;
}
dprintf(("pty: using %s (ptm %d pts %d)\n", tty, ptm, pts));
if ((fp= asyncFileAttach(f, ptm, semaIndex)) == 0)
goto failDetached;
/* fork the child on the new pts (from now on we must detach on fail) */
{
extern char **environ;
char *cmd= (char *)alloca(cmdLen + 1);
char **argv= (char **)alloca(sizeof(char *) * (argLen + 2));
int i= 0;
SlavePtr slave= 0;
memcpy((void *)cmd, (void *)cmdIndex, cmdLen);
cmd[cmdLen]= '\0';
dprintf(("pty: command: %s\n", cmd));
argv[0]= cmd;
for (i= 1; i <= argLen; ++i)
{
int argOop= ((int *)argIndex)[i - 1];
char *arg= 0;
int len= 0;
if (!vm->isBytes(argOop)) goto fail;
len= vm->stSizeOf(argOop);
dprintf(("pty: arg %d len %d\n", i, len));
arg= (char *)alloca(len + 1);
memcpy((void *)arg, (void *)vm->firstIndexableField(argOop), len);
arg[len]= '\0';
argv[i]= arg;
dprintf(("pty: argv[%d]: %s\n", i, argv[i]));
}
argv[argLen+1]= 0; /* argv terminator */
/* put slave on list in case of immediate exit in child */
slave= (SlavePtr)malloc(sizeof(SlaveRec));
slave->next= slaves;
slaves= slave;
slave->pts= pts;
slave->pty= fp;
slave->pid= fork();
switch (slave->pid)
{
case -1: /* error */
slaves= slaves->next;
free(slave);
perror("pty: fork");
goto fail;
break;
case 0: /* child */
close(ptm);
login_tty(pts);
execve(cmd, argv, environ);
fprintf(stderr, "pty: ");
perror(cmd);
exit(1);
break;
default: /* parent */
close(pts);
break;
}
return 0;
}
fail:
asyncFileClose(f);
ptm= -1;
failDetached:
if (ptm >= 0) close(ptm);
if (pts >= 0) close(pts);
vm->primitiveFail();
return 0;
}
int ptyClose(AsyncFile *f)
{
SlavePtr slave= 0, prev= 0;
FilePtr pty= (FilePtr)f->state;
validate(f);
dprintf(("pty: close %d\n", pty->fd));
if (pty->fd >= 0)
{
for (prev= 0, slave= slaves; slave; prev= slave, slave= slave->next)
if (slave->pty == pty)
{
int pid= slave->pid;
dprintf(("killing pid %d connected to pts %d\n", pid, slave->pts));
/* terminate with increasing degrees of violence... */
kill(pid, SIGTERM);
usleep(200*1000);
kill(pid, SIGKILL);
/* delete from list */
if (prev)
prev->next= slave->next;
else
slaves= slave->next;
break;
}
if (slave)
free(slave);
else
fprintf(stderr, "pty %d not in active process list\n", pty->fd);
}
asyncFileClose(f);
return 0;
}
ptyWindowSize(AsyncFile *f, int cols, int rows)
{
#if defined(TIOCSWINSZ)
struct winsize sz;
FilePtr pty= (FilePtr)f->state;
validate(f);
dprintf(("pty %d size %d %d\n", pty->fd, cols, rows));
sz.ws_col= cols;
sz.ws_row= rows;
sz.ws_xpixel= sz.ws_ypixel= 0;
if (ioctl(pty->fd, TIOCSWINSZ, &sz) == -1)
perror("pty: TIOCSWINSZ");
#endif
return 0;
}
|
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:31
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/SoundPlugin
In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/SoundPlugin
Added Files:
sqUnixSoundNAS.c sqUnixSoundNone.c sqUnixSoundOSS.c
sqUnixSoundSun.c
Log Message:
Ian Piumarta's release 3.4.1
--- NEW FILE: sqUnixSoundNAS.c ---
/* sqUnixSoundNAS.c -- sound support for the Network Audio System
*
* Author: Lex Spoon <le...@cc...>
*
* Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
* as listed elsewhere in this file.
* All rights reserved.
*
* This file is part of Unix Squeak.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You may use and/or distribute this file ONLY as part of Squeak, under
* the terms of the Squeak License as described in `LICENSE' in the base of
* this distribution, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment to the original author(s) (and any
* other contributors mentioned herein) in the product documentation
* would be appreciated but is not required.
*
* 2. This notice must not be removed or altered in any source distribution.
*
* Using (or modifying this file for use) in any context other than Squeak
* changes these copyright conditions. Read the file `COPYING' in the
* directory `platforms/unix/doc' before proceeding with any such use.
*
* You are not allowed to distribute a modified version of this file
* under its original name without explicit permission to do so. If
* you change it, rename it.
*/
#include "sq.h"
#ifdef USE_AUDIO_NAS
#include "SoundPlugin.h"
#include "aio.h"
#include <audio/audiolib.h>
#include <assert.h>
#ifdef DEBUG
# define dprintf printf
#else
static void dprintf(char *fmt, ...) {}
#endif
#ifdef WORDS_BIGENDIAN
# define AU_FORMAT AuFormatLinearSigned16MSB
#else
# define AU_FORMAT AuFormatLinearSigned16LSB
#endif
int snd_Stop(void);
/** routines for converting samples to different formats **/
/* XXX actually, I don't think NAS will need conversion. However,
SunOS could use it... */
#define BYTES_PER_SAMPLE 2 /* Squeak always uses 16-bit samples */
#ifdef HAS_MSB_FIRST
# define IS_BIGENDIAN 1
#else
# define IS_BIGENDIAN 0
#endif
/* specification of the output format. (Squeak's format is fixed:
stereo, 16-bit, host-endian, signed) */
static int fmtBytes= 2; /* bytes per sample the device is using */
static int fmtSigned= 1; /* whether the device uses signed samples */
static int fmtStereo= 0; /* whether the device is in stereo */
static int fmtIsBigendian= 0; /* whether the device is big-endion */
/* whether the device is differently-ended than Squeak */
#define auSwapBytes (fmtIsBigendian != IS_BIGENDIAN)
/* calculate number of bytes per frame, given the current mode */
static int bytesPerPlayFrame(void)
{
#if 1 /* ikp doesn't understand why this ... */
int bytes= 1;
bytes *= fmtBytes;
if (fmtStereo)
bytes *= 2;
return bytes;
#else /* ... doesn't look like this */
return fmtBytes * (fmtStereo ? 2 : 1);
#endif
}
#define FAIL(X) { success(false); return X; }
static AuServer *server = NULL; /* the audio server to write to */
static int recording=0; /* whether this module is recording
or playing. Only valid if
server!= NULL . */
static AuFlowID flow; /* the NAS flow being used */
static int semaIndex; /* the semaphore to signal Squeak with */
static int stereo; /* whether Squeak sees stereo or not */
static int bytesAvail; /* current number of bytes that may be written
or read from the server */
static int sampleRate; /* the sample rate of the device.
Currently not accurate. */
int snd_AvailableSpace(void)
{
if(server == NULL)
return 0;
return bytesAvail;
}
int snd_InsertSamplesFromLeadTime(int frameCount, int srcBufPtr,
int samplesOfLeadTime)
{
/* not possible, I don't think using NAS */
success(false);
return 0;
}
int snd_Stop(void)
{
if(server != NULL) {
aioDisable(AuServerConnectionNumber(server));
AuCloseServer(server);
server = NULL;
}
return 0;
}
int snd_PlaySamplesFromAtLength(int frameCount, int arrayIndex, int startIndex)
{
int bytesToPlay;
int framesToPlay;
char *buf; /* buffer to play from; it may not be arrayIndex if a
conversion is necessary */
dprintf("PlaySamples(frameCount=%d, arrayIndex=%d, startIndex=%d\n",
frameCount, arrayIndex, startIndex);
/* figure out how much to play */
bytesToPlay = frameCount * bytesPerPlayFrame();
if (bytesToPlay > bytesAvail)
bytesToPlay = bytesAvail;
framesToPlay = bytesToPlay / bytesPerPlayFrame();
/* convert the buffer when not in stereo; when playing back, Squeak
will send mono data as stereo, where the right channel is to be
ignored */
if(stereo)
{
buf= (char *) (arrayIndex + 4*startIndex);
}
else
{
int i;
short *sbuf; /* the buffer, as short's instead of char's */
dprintf("converting\n");
buf= malloc(2 * frameCount);
if(buf == NULL)
{
fprintf(stderr, "out of memory\n");
return 0;
}
sbuf= (short *) buf;
for(i=0; i<frameCount; i++)
{
sbuf[i]= ((short *) (arrayIndex + 4*startIndex)) [2*i];
}
}
dprintf("writing %d bytes (%d frames)\n", bytesToPlay, framesToPlay);
AuWriteElement(server, flow, 0,
bytesToPlay,
buf,
AuFalse,
NULL);
AuFlush(server);
bytesAvail -= bytesToPlay;
if(!stereo)
{
free(buf);
}
return framesToPlay;
}
/* Process audio events from the NAS server. The same routine is used
whether we are recording or playing back */
static void handleAudioEvents(int fd, void *data, int flags)
{
if(!server) {
dprintf( "handleAudioEvents called while unconnected!\n");
return;
}
/* read events once */
AuEventsQueued(server, AuEventsQueuedAfterReading);
/* then loop through the read queue */
while(AuEventsQueued(server, AuEventsQueuedAlready)) {
AuEvent event;
AuNextEvent(server, AuTrue, &event);
dprintf("event of type %d\n", event.type);
switch(event.type) {
case 0:
{
AuErrorEvent *errEvent = (AuErrorEvent *) &event;
char errdesc[1000];
AuGetErrorText(server, errEvent->error_code, errdesc, sizeof(errdesc));
fprintf(stderr, "audio error: %s\n", errdesc);
snd_Stop();
return; /* return, not break, so that we don't
process the now-closed server any longer! */
}
case AuEventTypeElementNotify:
{
AuElementNotifyEvent *enEvent = (AuElementNotifyEvent *)&event;
switch(enEvent->kind) {
case AuElementNotifyKindLowWater:
dprintf("low water event\n");
bytesAvail += enEvent->num_bytes;
break;
case AuElementNotifyKindHighWater:
dprintf("high water event\n");
bytesAvail += enEvent->num_bytes;
break;
case AuElementNotifyKindState:
dprintf("state change (%d->%d)\n",
enEvent->prev_state,
enEvent->cur_state);
bytesAvail += enEvent->num_bytes;
if(enEvent->cur_state == AuStatePause) {
/* if the flow has stopped, then arrange for it to get started again */
/* XXX there is probably a more intelligent place to do
this, in case there is a real reason it has paused */
dprintf("unpausing\n");
AuStartFlow(server, flow, NULL);
AuFlush(server);
}
break;
}
}
}
}
if(bytesAvail > 0) {
dprintf("bytesAvail: %d\n", bytesAvail);
signalSemaphoreWithIndex(semaIndex);
}
aioHandle(fd, handleAudioEvents, flags & AIO_RW);
}
int snd_PlaySilence(void)
{
return 0;
}
static AuDeviceID choose_nas_device(AuServer *server, int samplesPerSec, int stereo, int recording)
{
int desiredDeviceKind=
recording ?
AuComponentKindPhysicalInput :
AuComponentKindPhysicalOutput;
int desired_channels= stereo ? 2 : 1;
int i;
/* look for a physical device of the proper kind, with the proper number of channels */
for (i = 0; i < AuServerNumDevices(server); i++) {
if((AuDeviceKind(AuServerDevice(server, i))
== desiredDeviceKind)
&& (AuDeviceNumTracks(AuServerDevice(server, i))
== desired_channels))
return AuDeviceIdentifier(AuServerDevice(server, i));
}
/* look for a physical device of the proper kind; ignore number of channels */
for (i = 0; i < AuServerNumDevices(server); i++) {
if(AuDeviceKind(AuServerDevice(server, i))
== desiredDeviceKind)
return AuDeviceIdentifier(AuServerDevice(server, i));
}
return AuNone;
}
int snd_Start(int frameCount, int samplesPerSec, int stereo0, int semaIndex0)
{
AuElement elements[2]; /* first is a client element, second is
a device output element */
AuDeviceID device; /* ID of the device to play to */
/* open the server */
dprintf("opening server\n");
server = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL);
if(server == NULL) {
dprintf("failed to open audio server\n");
return false;
}
/* XXX should check the protocol version! */
/* record requested info */
semaIndex = semaIndex0;
stereo = stereo0;
sampleRate= samplesPerSec;
/* pick a device to play to */
device = choose_nas_device(server, samplesPerSec, stereo, 0);
if(device == AuNone) {
dprintf("no available device on the server!\n");
AuCloseServer(server);
server = NULL;
return false;
}
/* set up output parameters */
fmtBytes=2;
fmtSigned=1;
fmtStereo=stereo;
fmtIsBigendian=0;
recording=0;
/* create a flow to write on */
dprintf("creating flow\n");
flow = AuCreateFlow(server, NULL);
/* create client and device elements to play with */
dprintf("creating elements(%d,%d)\n",
frameCount, frameCount / 4);
AuMakeElementImportClient(&elements[0],
samplesPerSec,
AuFormatLinearSigned16LSB, /* XXX this should be chosen based on the platform */
stereo ? 2 : 1,
AuTrue,
2*frameCount, /* max: 2 buffers */
frameCount, /* low */
0, NULL);
AuMakeElementExportDevice(&elements[1],
0,
device,
samplesPerSec,
AuUnlimitedSamples,
0, NULL);
/* set up the flow with these elements */
AuSetElements(server, flow,
AuTrue,
2, elements,
NULL);
/* start her up */
dprintf("starting flow\n");
AuStartFlow(server, flow, NULL);
AuFlush(server);
/* initialize the space indication */
bytesAvail = 0;
/* arrange to be informed when events come in from the server */
aioEnable(AuServerConnectionNumber(server), 0, AIO_EXT);
aioHandle(AuServerConnectionNumber(server), handleAudioEvents, AIO_R);
return true;
}
/* StartRecording: open the device for recording.
XXX this routine is almost identical to snd_Start(). The two should
be factored into a single function!
*/
int snd_StartRecording(int desiredSamplesPerSec, int stereo0, int semaIndex0)
{
AuElement elements[2]; /* elements for the NAS flow to assemble:
element 0 = physical input
element 1 = client export */
AuDeviceID device; /* physical device ID to use */
dprintf("StartRecording\n");
snd_Stop();
dprintf("opening server\n");
server = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL);
if(server == NULL) {
dprintf("failed to open audio server\n");
return false;
}
/* XXX check protocol version of the server */
semaIndex= semaIndex0;
stereo= stereo0;
sampleRate= desiredSamplesPerSec;
device= choose_nas_device(server, desiredSamplesPerSec, stereo, 1);
if(device == AuNone) {
dprintf("no available device on the server!\n");
AuCloseServer(server);
server = NULL;
return false;
}
/* record format info */
fmtBytes=2;
fmtSigned=1;
fmtStereo=stereo;
fmtIsBigendian=0;
recording=1;
/* create a flow to read from */
dprintf("creating flow\n");
flow = AuCreateFlow(server, NULL);
/* create client and device elements to record with */
dprintf("creating elements\n");
AuMakeElementImportDevice(&elements[0],
desiredSamplesPerSec, /* XXX should use the actual sampling rate of device */
device,
AuUnlimitedSamples,
0, NULL);
AuMakeElementExportClient(&elements[1],
0,
desiredSamplesPerSec,
AuFormatLinearSigned16LSB, /* XXX this should be chosen based on the platform */
stereo ? 2 : 1,
AuTrue,
1000000, /* was AuUnlimitedSamples */
1000, /* water mark: go ahead and send frequently! */
0, NULL);
/* set up the flow with these elements */
AuSetElements(server, flow,
AuTrue,
2, elements,
NULL);
/* start her up */
dprintf("starting flow\n");
AuStartFlow(server, flow, NULL);
AuFlush(server);
/* initialize the space indication */
bytesAvail = 0;
/* arrange to be informed when events come in from the server */
aioEnable(AuServerConnectionNumber(server), NULL, AIO_EXT);
aioHandle(AuServerConnectionNumber(server), handleAudioEvents, AIO_W);
return true;
}
int snd_StopRecording(void)
{
return snd_Stop();
}
double snd_GetRecordingSampleRate(void)
{
return sampleRate;
}
int snd_RecordSamplesIntoAtLength(int buf, int startSliceIndex,
int bufferSizeInBytes)
{
int bytesToRead;
int sliceSize= (stereo ? 4 : 2); /* a "slice" seems to be a "frame": one sample from each channel */
dprintf("RecordSamplesIntoAtLength(buf=%d, startSliceIndex=%d, bufferSizeInBytes=%d\n",
buf, startSliceIndex, bufferSizeInBytes);
/* sanity checks */
if(server==NULL || !recording) {
success(false);
return 0;
}
if(bytesAvail <= 0)
return 0;
/* figure out how much to read */
bytesToRead= bufferSizeInBytes - (startSliceIndex * sliceSize);
if(bytesToRead > bytesAvail)
bytesToRead= bytesAvail;
dprintf("reading %d bytes\n", bytesToRead);
/* read it */
AuReadElement(server,
flow,
1, /* element 1 is the client export */
bytesToRead,
(char *) (buf + startSliceIndex*sliceSize),
NULL);
bytesAvail -= bytesToRead;
return bytesToRead/sliceSize; /* return number of samples read (or slices?!) */
}
/* mixer settings */
int snd_SetRecordLevel(int level)
{
return level;
}
void snd_Volume(double *left, double *right)
{
return;
}
void snd_SetVolume(double left, double right)
{
return;
}
#endif /* USE_AUDIO_NAS */
--- NEW FILE: sqUnixSoundNone.c ---
/* sqUnixSoundNone.c -- stubs for dummy (unimplemented) sound support
*
* Author: Ian...@in...
*
* Last edited: 2002-10-26 14:40:54 by piumarta on emilia.inria.fr
*
* Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
* as listed elsewhere in this file.
* All rights reserved.
*
* This file is part of Unix Squeak.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You may use and/or distribute this file ONLY as part of Squeak, under
* the terms of the Squeak License as described in `LICENSE' in the base of
* this distribution, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment to the original author(s) (and any
* other contributors mentioned herein) in the product documentation
* would be appreciated but is not required.
*
* 2. This notice must not be removed or altered in any source distribution.
*
* Using (or modifying this file for use) in any context other than Squeak
* changes these copyright conditions. Read the file `COPYING' in the
* directory `platforms/unix/doc' before proceeding with any such use.
*
* You are not allowed to distribute a modified version of this file
* under its original name without explicit permission to do so. If
* you change it, rename it.
*/
#include "sq.h"
#ifdef USE_AUDIO_NONE
#include "SoundPlugin.h"
#define FAIL(X) { success(false); return X; }
/* sound output */
int snd_AvailableSpace(void)
FAIL(8192)
int snd_InsertSamplesFromLeadTime(int frameCount, int srcBufPtr,
int samplesOfLeadTime)
FAIL(frameCount)
int snd_PlaySamplesFromAtLength(int frameCount, int arrayIndex, int startIndex)
FAIL(8192)
int snd_PlaySilence(void)
FAIL(8192)
int snd_Start(int frameCount, int samplesPerSec, int stereo, int semaIndex)
FAIL(1)
int snd_Stop(void)
FAIL(0)
/* sound input */
int snd_SetRecordLevel(int level)
FAIL(0)
int snd_StartRecording(int desiredSamplesPerSec, int stereo, int semaIndex)
FAIL(0)
int snd_StopRecording(void)
FAIL(0)
double snd_GetRecordingSampleRate(void)
FAIL(0)
int snd_RecordSamplesIntoAtLength(int buf, int startSliceIndex,
int bufferSizeInBytes)
FAIL(0)
void snd_Volume(double *left, double *right)
{
return;
}
void snd_SetVolume(double left, double right)
{
return;
}
#endif /* USE_AUDIO_NONE */
--- NEW FILE: sqUnixSoundOSS.c ---
#include "sq.h"
#ifdef USE_AUDIO_OSS
/* The SoundPlayer playLoop does not attempt to play sounds unless at
* least 100 frames of output space are available. select() says
* output space is available when one byte can be written. Net
* result: Squeak sits at 100% CPU thrashing between playSema wait and
* select() signaling the playSema. OSS does not provide any means to
* increase the output low water mark from one byte (to 100 frames, or
* even an entire fragment) either. Disabling the Semaphore entirely
* increases audio performace noticably and Squeak idles for almost
* all of the time (consuming < 1% CPU) when only playing sound.
*
* If you turn the play Semaphore back on then you should at least
* consider also turning on `soundStopWhenDone' in the image
* preferences, otherwise Squeak WILL eat ALL of your CPU from the
* moment you play the first sound.
*/
[...1073 lines suppressed...]
if (wr == wrMS8_U) return "MS8_U";
if (wr == wrSM___) return "SM___";
if (wr == wrSM__U) return "SM__U";
if (wr == wrSM_E_) return "SM_E_";
if (wr == wrSM_EU) return "SM_EU";
if (wr == wrSM8__) return "SM8__";
if (wr == wrSM8_U) return "SM8_U";
if (wr == wrSS__U) return "SS__U";
if (wr == wrSS_E_) return "SS_E_";
if (wr == wrSS_EU) return "SS_EU";
if (wr == wrSS8__) return "SS8__";
if (wr == wrSS8_U) return "SS8_U";
if (wr == 0) return "*** NULL ***";
return "*** ILLEGAL ***";
}
#endif /* DEBUG */
#endif /* USE_AUDIO_OSS */
--- NEW FILE: sqUnixSoundSun.c ---
/* sqUnixSoundSun.c -- sound support for SunOS and Solaris
*
* Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
* as listed elsewhere in this file.
* All rights reserved.
*
* This file is part of Unix Squeak.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You may use and/or distribute this file ONLY as part of Squeak, under
* the terms of the Squeak License as described in `LICENSE' in the base of
* this distribution, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment to the original author(s) (and any
* other contributors mentioned herein) in the product documentation
* would be appreciated but is not required.
*
* 2. This notice must not be removed or altered in any source distribution.
*
* Using (or modifying this file for use) in any context other than Squeak
* changes these copyright conditions. Read the file `COPYING' in the
* directory `platforms/unix/doc' before proceeding with any such use.
*
* You are not allowed to distribute a modified version of this file
* under its original name without explicit permission to do so. If
* you change it, rename it.
*
* Authors: Ian...@in... and Lex Spoon <le...@cc...>
*
* This support is rudimentary and is implemented largely by reading
* header files and guessing what to do.
*/
#include "sq.h"
#ifdef USE_AUDIO_SUN
#undef DEBUG
#include "SoundPlugin.h"
#include "aio.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#ifdef HAVE_SYS_AUDIOIO_H
# include <sys/audioio.h>
#else
# include <sun/audioio.h>
#endif
#include <errno.h>
#ifdef DEBUG
# define PRINTF(ARGS) printf ARGS
# define TRACE 1
#elsen
# define PRINTF(ARGS)
#endif
int snd_Stop(void);
static int auFd= -1; /* open on /dev/dsp */
static int fmtStereo= 0; /* whether we are playing in stereo or not */
static int auPlaySemaIndex= 0; /* an index to signal when new data may be played */
static int auBufBytes= 0; /* buffer size to use for playback.
unfortunately, this bears no relationship to
whatever the kernel and soundcard are using */
static int auBuffersPlayed= 0;
static void auHandle(int fd, void *data, int flags)
{
if (auFd < 0) return;
if (snd_AvailableSpace() > 0)
signalSemaphoreWithIndex(auPlaySemaIndex);
aioHandle(fd, auHandle, flags);
}
/*** exported sound output functions ***/
int snd_Stop(void)
{
if (auFd == -1) return;
aioDisable(auFd);
close(auFd);
auFd= -1;
return 0;
}
int snd_Start(int frameCount, int samplesPerSec, int stereo, int semaIndex)
{
int bytesPerFrame= (stereo ? 4 : 2);
int bufferBytes= ((frameCount * bytesPerFrame) / 8) * 8;
struct audio_info info;
int err;
if (auFd != -1) snd_Stop();
auPlaySemaIndex= semaIndex;
fmtStereo= stereo;
auBufBytes= bytesPerFrame * frameCount;
if ((auFd= open("/dev/audio", O_WRONLY)) == -1)
{
perror("/dev/audio");
return false;
}
/* set up device */
if (ioctl(auFd, AUDIO_GETINFO, &info))
{
perror("AUDIO_GETINFO");
goto closeAndFail;
}
info.play.gain= 100;
info.play.precision= 16;
info.play.encoding= AUDIO_ENCODING_LINEAR;
info.play.channels= fmtStereo ? 2 : 1;
info.play.sample_rate= samplesPerSec;
auBuffersPlayed= info.play.eof;
while ((err= ioctl(auFd, AUDIO_SETINFO, &info)) && errno == EINTR)
;
if (err)
{
perror("AUDIO_SETINFO");
goto closeAndFail;
}
aioEnable(auFd, 0, 0);
aioHandle(auFd, auHandle, AIO_RX);
return true;
closeAndFail:
close(auFd);
auFd= -1;
return false;
}
int snd_AvailableSpace(void)
{
struct audio_info info;
if (auFd < 0) return 0;
if (ioctl(auFd, AUDIO_GETINFO, &info))
{
perror("AUDIO_GETINFO");
snd_Stop();
}
return (auBufBytes * (info.play.eof - auBuffersPlayed + 2));
}
int snd_PlaySamplesFromAtLength(int frameCount, int arrayIndex, int startIndex)
{
short *src= (short *) (arrayIndex + 4*startIndex);
short buf[2*frameCount];
int i;
int bytes;
if (auFd < 0) return -1;
if (fmtStereo)
{
bytes= 4 * frameCount;
for (i= 0; i < 2 * frameCount; i++)
buf[i]= src[i];
}
else
{
bytes= 2 * frameCount;
for (i= 0; i < frameCount; i++)
buf[i]= src[2*i];
}
/* write data to device from auBuf to dst */
while (bytes > 0)
{
int len;
char *pos= (char *) buf;
len= write(auFd, pos, bytes);
if (len < 0)
{
perror("/dev/audio");
return 0;
}
bytes -= len;
pos += len;
}
/* add an eof marker */
write(auFd, buf, 0);
auBuffersPlayed += 1;
return frameCount;
}
int snd_InsertSamplesFromLeadTime(int frameCount, int srcBufPtr,
int samplesOfLeadTime)
{
return 0;
}
int snd_PlaySilence(void)
{
return 0;
}
/** recording not supported **/
int snd_SetRecordLevel(int level)
{
success(false);
return;
}
int snd_StartRecording(int desiredSamplesPerSec, int stereo, int semaIndex)
{
success(false);
return;
}
int snd_StopRecording(void)
{
return;
}
double snd_GetRecordingSampleRate(void)
{
success(false);
return 0.0;
}
int snd_RecordSamplesIntoAtLength(int buf, int startSliceIndex,
int bufferSizeInBytes)
{
success(false);
return 0;
}
void snd_Volume(double *left, double *right)
{
success(false);
return;
}
void snd_SetVolume(double left, double right)
{
success(false);
return;
}
#endif /* USE_AUDIO_SUN */
|
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:30
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/MIDIPlugin In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/MIDIPlugin Added Files: sqUnixMIDI.c Log Message: Ian Piumarta's release 3.4.1 --- NEW FILE: sqUnixMIDI.c --- /* sqUnixMIDI.c -- Unix MIDI support * * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors * as listed elsewhere in this file. * All rights reserved. * * This file is part of Unix Squeak. * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You may use and/or distribute this file ONLY as part of Squeak, under * the terms of the Squeak License as described in `LICENSE' in the base of * this distribution, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment to the original author(s) (and any * other contributors mentioned herein) in the product documentation * would be appreciated but is not required. * * 2. This notice must not be removed or altered in any source distribution. * * Using (or modifying this file for use) in any context other than Squeak * changes these copyright conditions. Read the file `COPYING' in the * directory `platforms/unix/doc' before proceeding with any such use. * * You are not allowed to distribute a modified version of this file * under its original name without explicit permission to do so. If * you change it, rename it. */ /* Author: Ian...@IN... * * Last edited: 2002-10-26 14:34:46 by piumarta on emilia.inria.fr */ #include "sq.h" #include "MIDIPlugin.h" /* Put the given port into MIDI mode, which uses a clock supplied by an external MIDI interface adaptor to determine the data rate. Possible external clock rates: 31.25 KHz, 0.5 MHz, 1 MHz, or 2 MHz. */ int serialPortMidiClockRate(int portNum, int interfaceClockRate) { success(false); return 0; } /* Close the given MIDI port. Do nothing if the port is not open. Fail if there is no port of the given number.*/ int sqMIDIClosePort(int portNum) { success(false); return 0; } /* Return the current value of the clock used to schedule MIDI events. The MIDI clock is assumed to wrap at or before half the maximum positive SmallInteger value. This allows events to be scheduled into the future without overflowing into LargePositiveIntegers. This implementation does not support event scheduling, so it just returns the value of the Squeak millisecond clock. */ int sqMIDIGetClock(void) { success(false); return 0; } /* Return the number of available MIDI interfaces, including both hardware ports and software entities that act like ports. Ports are numbered from 0 to N-1, where N is the number returned by this primitive. */ int sqMIDIGetPortCount(void) { success(false); return 0; } /* Return an integer indicating the directionality of the given port where: 1 = input, 2 = output, 3 = bidirectional. Fail if there is no port of the given number. */ int sqMIDIGetPortDirectionality(int portNum) { success(false); return 0; } /* Copy the name of the given MIDI port into the string at the given address. Copy at most length characters, and return the number of characters copied. Fail if there is no port of the given number.*/ int sqMIDIGetPortName(int portNum, int namePtr, int length) { success(false); return 0; } /* Open the given port, if possible. If non-zero, readSemaphoreIndex specifies the index in the external objects array of a semaphore to be signalled when incoming MIDI data is available. Note that not all implementations support read semaphores (this one does not); see sqMIDICanUseSemaphore. The interfaceClockRate parameter specifies the clock speed for an external MIDI interface adaptor on platforms that use such adaptors (e.g., Macintosh). Fail if there is no port of the given number.*/ int sqMIDIOpenPort(int portNum, int readSemaIndex, int interfaceClockRate) { success(false); return 0; } /* Read or write the given MIDI driver parameter. If modify is 0, then newValue is ignored and the current value of the specified parameter is returned. If modify is non-zero, then the specified parameter is set to newValue. Note that many MIDI driver parameters are read-only; attempting to set one of these parameters fails. For boolean parameters, true = 1, false = 0. */ int sqMIDIParameter(int whichParameter, int modify, int newValue) { success(false); return 0; } /* bufferPtr is the address of the first byte of a Smalltalk ByteArray of the given length. Copy up to (length - 4) bytes of incoming MIDI data into that buffer, preceded by a 4-byte timestamp in the units of the MIDI clock, most significant byte first. Implementations that do not support timestamping of incoming data as it arrives (see sqMIDIHasInputClock) simply set the timestamp to the value of the MIDI clock when this function is called. Return the total number of bytes read, including the timestamp bytes. Return zero if no data is available. Fail if the buffer is shorter than five bytes, since there must be enough room for the timestamp plus at least one data byte. */ int sqMIDIPortReadInto(int portNum, int count, int bufferPtr) { success(false); return 0; } /* bufferPtr is the address of the first byte of a Smalltalk ByteArray of the given length. Send its contents to the given port when the MIDI clock reaches the given time. If time equals zero, then send the data immediately. Implementations that do not support a timestamped output queue, such as this one, always send the data immediately; see sqMIDIHasBuffer. */ int sqMIDIPortWriteFromAt(int portNum, int count, int bufferPtr, int time) { success(false); return 0; } int midiInit(void) { success(false); return 0; } int sqMIDIParameterGet(int which) { success(false); return 0; } int sqMIDIParameterSet(int which, int value) { success(false); return 0; } int midiShutdown(void) { success(false); return 0; } |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:30
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/Mpeg3Plugin In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/Mpeg3Plugin Added Files: Makefile.in acinclude.m4 mkmf.subdirs Log Message: Ian Piumarta's release 3.4.1 --- NEW FILE: Makefile.in --- # Makefile.in for Mpeg3Plugin on Unix # # Author: ian...@in... # # Last edited: 2002-07-10 23:52:17 by piumarta on emilia.inria.fr [make_cfg] [make_plg] TARGET = Mpeg3Plugin$a PLUGIN = Mpeg3Plugin$o VIDEO = getpicture$o headers$o idct$o macroblocks$o mmxtest$o motion$o \ mpeg3video$o output$o reconstruct$o seek$o slice$o vlc$o AUDIO = dct$o header$o layer1$o layer2$o layer3$o mpeg3audio$o pcm$o \ synthesizers$o tables$o LIBMPEG = bitstream$o changesForSqueak$o libmpeg3$o mpeg3atrack$o \ mpeg3demux$o mpeg3io$o mpeg3title$o mpeg3vtrack$o OBJS = $(PLUGIN) $(VIDEO) $(AUDIO) $(LIBMPEG) XINCLUDES = [includes] XDEFS = [xdefs] $(TARGET) : $(OBJS) Makefile $(LINK) $(TARGET) $(OBJS) $(RANLIB) $(TARGET) [make_targets] .force : --- NEW FILE: acinclude.m4 --- # Add `--enable-mpg-[mmx,pthreads]' switches AC_ARG_ENABLE(mpg-mmx, [ --enable-mpg-mmx enable MMX support in Mpeg3Plugin [default=no]], XDEFS="-DUSE_MMX", XDEFS="") AC_ARG_ENABLE(mpg-pthreads, [ --enable-mpg-pthreads enable pthread support in Mpeg3Plugin [default=no]], , XDEFS="$XDEFS -DNOPTHREADS") # Define `[xdefs]' in Makefile.in AC_PLUGIN_DEFINE_UNQUOTED([xdefs], $XDEFS) --- NEW FILE: mkmf.subdirs --- platforms/Cross/plugins/Mpeg3Plugin/libmpeg platforms/Cross/plugins/Mpeg3Plugin/libmpeg/audio platforms/Cross/plugins/Mpeg3Plugin/libmpeg/video |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:29
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/JPEGReadWriter2Plugin In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/JPEGReadWriter2Plugin Added Files: Makefile.inc Log Message: Ian Piumarta's release 3.4.1 --- NEW FILE: Makefile.inc --- # this Makefile.inc intentionally left blank # # (to persuade VMMaker to generate the plugin) |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:29
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/FileCopyPlugin In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/FileCopyPlugin Added Files: sqUnixFileCopyPlugin.c Log Message: Ian Piumarta's release 3.4.1 --- NEW FILE: sqUnixFileCopyPlugin.c --- /* sqUnixFileCopyPlugin.c -- fast file copy, preserving permissions * * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors * as listed elsewhere in this file. * All rights reserved. * * This file is part of Unix Squeak. * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You may use and/or distribute this file ONLY as part of Squeak, under * the terms of the Squeak License as described in `LICENSE' in the base of * this distribution, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment to the original author(s) (and any * other contributors mentioned herein) in the product documentation * would be appreciated but is not required. * * 2. This notice must not be removed or altered in any source distribution. * * Using (or modifying this file for use) in any context other than Squeak * changes these copyright conditions. Read the file `COPYING' in the * directory `platforms/unix/doc' before proceeding with any such use. * * You are not allowed to distribute a modified version of this file * under its original name without explicit permission to do so. If * you change it, rename it. * * Author: ian...@in... * * Last edited: 2002-10-26 14:33:09 by piumarta on emilia.inria.fr * * NOTE: * This plugin is kind of ridiculous. Nevertheless, after seeing what * somebody (and I honestly have no idea who) decided would be a good * implementation of this (it might still be on SourceForge if you're * perverse wough to want to look at it) I was dumbfounded into writing * a version that didn't open pipes to forked processes. (Now I bet * you can't possibly resist having a peek for the original. ;^p) * (Besides, the original version had BUGS -- in a one page program. 8^o) * * CAVEATS: * - we should use mmap() only if the file is "large" (define that as * you will), preferring a few block-sized read()/write()s otherwise * - we should fall back onto the loop if mmap fails (we might simply * have a file larger than available memory) * * BUGS: * - some of the system calls should handle EAGAIN and/or EINTR (this * will cause problems on Solaris) * (the following could be fixed if we had a real "config.h":) * - we assume <unistd.h> but not everyone has this * - we assume alloca() but not everyone has this (ANSI does not define it) * - use of stat.st_blksize is extremely non-portable * * COMPILE: * gcc -Wall -W -pedantic -o copy copy.c */ #include "sq.h" #include "FileCopyPlugin.h" #include "config.h" #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #ifdef HAVE_MMAP # include <sys/mman.h> #endif static int copy(char *from, char *to) { int status= 1; /* exit status: assume failure */ int in; struct stat stat; if (((in= open(from, O_RDONLY)) < 0) || (fstat(in, &stat) != 0)) return -1; { int out; if ((out= open(to, O_WRONLY | O_CREAT | O_TRUNC, stat.st_mode)) < 0) return -1; { # ifdef HAVE_MMAP static const char *_dev_zero= "/dev/zero"; int zero; if ((zero= open(_dev_zero, O_RDWR)) >= 0) { void *mem; if (MAP_FAILED != (mem= mmap(0, stat.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero, 0))) { if (( (read(in, mem, stat.st_size) != stat.st_size) >= 0) && (write(out, mem, stat.st_size) != stat.st_size) >= 0) { status= 0; /* success */ } munmap(mem, stat.st_size); } close(zero); } # else /* !HAVE_MMAP */ char *buf= (char *)alloca(stat.st_blksize); int n; while (( ((n= read(in, buf, stat.st_blksize)) > 0)) && (n == write(out, buf, n))) ; if (n == 0) status= 0; /* success */ # endif /* !HAVE_MMAP */ close(out); } close(in); } return status; } int sqCopyFilesizetosize(char *srcName, int srcNameSize, char *dstName, int dstNameSize) { int status= 0; char *from= (char *)alloca(srcNameSize + 1); char *to= (char *)alloca(dstNameSize + 1); sqFilenameFromString(from, srcName, srcNameSize); sqFilenameFromString(to, dstName, dstNameSize); return copy(from, to); } |
Update of /cvsroot/squeak/squeak/platforms/unix/doc
In directory sc8-pr-cvs1:/tmp/cvs-serv30143/doc
Added Files:
3.2-1.RELEASE_NOTES 3.2-2.RELEASE_NOTES 3.2-3.RELEASE_NOTES
3.2-4.RELEASE_NOTES 3.2-5.RELEASE_NOTES 3.2-6.RELEASE_NOTES
3.4-1.RELEASE_NOTES 3.4-gamma1.RELEASE_NOTES COPYING COPYRIGHT
HowToBuildFromSource.pdf HowToBuildFromSource.ps
HowToBuildFromSource.txt LICENSE Makefile README.Contributing
README.Keyboard README.Sound squeak.1
Log Message:
Ian Piumarta's release 3.4.1
--- NEW FILE: 3.2-1.RELEASE_NOTES ---
This VM should work with any 3.3 or earlier image.
The major changes since 3.1-pre2 are as follows:
- Lots of changes based on patches applied to the SF tree.
(See the ChangeLog file in the source distribution for a
comprehensive list of these changes and the authors of
the SF patches, where relevant.)
- The VM version number (3.2-1) is now decoupled from the image
version (3.3alpha-4857) used produced the generated files, as
seems to be the case with Mac and Win32 VMs. For bug reporting
purposes, `squeak -version' reports both these version numbers.
- Build process completely rewritten to accommodate VMMaker. (Lots
of documentation in the source distrib under platforms/unix/doc.
Plugin developers who want their code to run on Unix absolutely
must read this stuff.)
- New option: `-plugins <path>' (env: SQUEAK_PLUGINS='<path>') appends
<path> to the list of places the VM seaches for plugins. Each
occurrence of `%n' in <path> is replaced by the name of the plugin
being loaded.
To run a newly-compiled VM without first installing it, use:
.../blddir/squeak -plugins .../blddir/%n/.libs
- Modifier keys are handled more intelligently. The default is the
"traditional" Unix behaviour: mod1 is mapped to Command, Ctrl+mod1
is mapped to Option, and other modifiers are ignored. (This is
usually what GNU/Linux systems with PC hardware [mod1=Alt] want.)
- For the rest of us, two new options: `-cmdmod <n>' and `-optmod <n>'
(env: SQUEAK_CMDMOD=n and SQUEAK_OPTMOD=n). If one or both of these
are set then the X11 modifier `mod<n>' is mapped to Squeak's Command
and/or Option, respectively.
For example, to map a Sun keyboard so that the physical locations of
the modifier keys ("Alt" = mod1 and "<>" [meta] = mod4) correspond
precisely to their homologues on an Apple keyboard ("Option" and
"Command") use:
-cmdmod 4 -optmod 1
(or set `export SQUEAK_CMDMOD=4; export SQUEAK_OPTMOD=1' in your
.profile to make the change permanent). (Note that setting a modifier
for just one of these keys will entirely disable the other.)
- New option: `-swapbtn' (env: SQUEAK_SWAPBTN=1) reverses the "yellow" and
"blue" buttons which might be useful for people having two-button mice
(or who have 3-button mice and no respect for historical precedents).
- Various manual page updates (mainly for new/missing options).
- New Netscape plugin code from Bert Freudenberg. (Not tested because
my Netscape's dynamic loading is broken.)
- OSS sound rewritten from scratch. (Full-duplex is supported but the
image contains bugs which might prevent it from ever being attempted.)
Both input and output have been tested extensively on Linux 2.4.18 with
ALSA 0.9rc1 drivers (www.alsa-project.org) and the the OSS compatibility
modules (snd-pcm-oss/mixer) that come with them. (This is the only
[non-commercial] OSS implementation I've found that respects the
published OSS API sufficiently to permit any kind of serious development
work.)
With the new implementation, playing and recording should only comsume
a fraction of 1% of the CPU. Your kilometrage may vary depending on
the (quite possibly lamentable) state of your OSS drivers.
- New option: `-nomixer' (env: SQUEAK_NOMIXER=1). For people who prefer
that Squeak not arbitrarily set the input gain to 50% every time
recording is started, this turns off the mixer primitives. With this
option your external mixer program retains control of the settings
(as it should).
- Changes to gnuification should make this thing 5-10% faster on Intel.
- Major overhaul of socket code should prevent lockups. (There are
still outstanding issues but they concern very obscure situations.)
- Lots and lots of smallish changes to the X11 code. Plus some biggish
ones: responsiveness should be better and occasional crashes (or
freezes) observed when resizing the window should no longer occur.
(`-xshm -xasync' not yet extensively tested with the new code.)
- Copy/Paste problems encountered between Squeak and some applications
(probably mainly KDE and anything that uses Qt or gtk) are fixed.
- The default image name is now `squeak.image' (for compatibility with
other platforms).
- Default heap size increased to 48MB to cope with recent images.
Still to do:
- mmap()-based memory allocator (when I have time to think about
portability).
- Revisit the socket code to make a few minor tweaks for the obscure
cases and to pull connection reset detection forward into the
getSockState primitive (cf the Mac implementation).
- Add sources and support for building the VM as a Netscape plugin.
- Arrange for -USE_MMX in MpegPlugin on 386.
Don't Panic!
- Just send me mail if something is broken: ian...@in...
--- NEW FILE: 3.2-2.RELEASE_NOTES ---
Since 3.2-1:
- RPMs for ppc and i386 binaries, and noarch .image/.changes and
.sources, are available (with prefix /usr)
- fixes serious problem in selection handling (many thanks to Ned
Konz for spotting the missing "break" :o)
- sysAttr #0 is now full pathname to VM (as per method comment in the
image)
- control key behaviour is inverted as per Ned's insistence: mouse
wheel to scroll pane, ctrl+wheel to scroll selection
- images are now in version-independent libdir and are installed
compressed to save space. inisqueak uncompresses them to
squeak.{image,changes} in the cwd
- lots of subtle changes to cope with automated builds of tarballs and
RPMs from cron jobs
- slight version numbering shuffle to allow tarballs and RPMs to have
exactly the same version numbers for corresponding files
--- NEW FILE: 3.2-3.RELEASE_NOTES ---
Since 3.2-2:
Build
* Make problems fixed. OpenBSD should now work: $< no longer used
anywhere and ranlib run on all static libs. (Craig, you should
submit a PR to OpenBSD about the $< thing: it's a bug in make.)
VM
* Socket options processing improved.
* Everything compiles cleanly (and has been tested and is known to
work) with -DHEADLESS. (Many thanks to Colin Putney who submitted
some of the necessary changes. I added a bunch more to make it
work with OSProcess too.)
* Small change to browser support code to bring it into line with what
the image expects (fail primBrowserReady if not running in a
browser). FWIW: this cures (and was hunted down because of) an
infuriating three-second pause on return from snapshot.
Plugins
* B3DAccelerator fixes (many thanks to Joshua Gargus). However it
doesn't want to work for me (either internal or external):
X Error of failed request: GLXBadDrawable
Major opcode of failed request: 143 (GLX)
Minor opcode of failed request: 11 (X_GLXSwapBuffers)
but that doesn't necessarily mean it won't work for other people.
I'll look into this sometime (but I don't consider it urgent, and it
might just be my Xserver is broken or maybe libGL hasn't been tested
very much on bigendian processors...).
* AsynchFilePlugin support has been implemented (and tested).
* UnixOSProcessPlugin now bundled with the sources (and built as
external plugin in the precompiled VMs).
* New plugin: PseudoTTYPlugin (extends AsynchFilePlugin) adding
support for pseudo ttys (necessary if processes spawned from Squeak
are to believe themselves connected to a real terminal). The
changesets for PseudoTTY and PseudoTTYPlugin are in the platform
plugin dir (unix/plugins/PseudoTTYPlugin/*.cs). Maybe Dave will
take a look at this and pull the functionality into OSProcess (which
is probably where it belongs).
Enjoy!
Ian
--- NEW FILE: 3.2-4.RELEASE_NOTES ---
This release is mainly for the BSD folks. It fixes some portability
issues in the PTY plugin (I've now built and tested it on GNU/Linux,
NetBSD and Solaris and I'm hopeful that it will compile out of the box
and work on almost any Unix now) and ties up the last of the loose
ends in BSD build.
Since 3.2-3:
* PtyPlugin rewritten to use either /dev/ptmx or openpty(), as
availablility permits.
* Minor tweaks to build process (thanks to Steve Elkins for spotting
the problems).
* A couple of buglets fixed in AsynchFilePlugin (the *class*, not the
support code) to prevent core dumps when AsyncFiles are left open
across snapshot. (The changes have been sent to John Mc who was, I
believe, the original author. Apologies if this isn't so. In any
case the changes file is in the unix/plugins/AsynchFilePlugin
directory and they're in the Unix VM source/binaries [since I've
had core dumps from these bugs recently].)
That's it.
Ian
--- NEW FILE: 3.2-5.RELEASE_NOTES ---
3.2-5 released on 2002-10-16.
Major changes since 3.2-4:
VM:
Option `-fullscreen' should work better.
New option: `-iconic' which does the obvious thing.
New option: `-notimer' disables use of itimers and reverts to
gettimeofday() for low-res clock.
Selection handling support for compatibility with latest Qt (based
on code from Ned Konz -- thanks!).
Delicious new browser support code from Bert Freudenberg. (Tested
under Mozilla on GNU/Linux PPC, but YKMV.)
Minor tweaks to closing the X connection via OSProcPlug. (Thanks to
Dave Lewis for spotting the problem.)
Minor tweak in sound output to cope with incomplete writes (which
shouldn't happen, but some ALSA drivers just don't want to respect
the rules). (Thanks to Lex for this one.)
Broken versions of Solaris that lack snprintf() should no longer
cause compile/link errors.
As a failsafe, sqGnu.h now defines (empty) all xx_REG symbols on
platforms it doesn't recognise. (Thanks to Tommy Thorn for spotting
the problem.)
aio can now manage fd 0 (stdin).
Plugins:
RePlugin is now bundled with the VM.
Minor tweaks to PseudoTTYPlugin to avoid potential SEGV from stale
AsyncFile handles.
PTYPlugin is now external by default, to ease the task of compiling
on systems that have broken (or no) pty support. (There might still
be problems on old [pre-2.8] Solaris, Irix and HP/UX. Not having
accounts on such machines I cannot really test it all.)
SqueakFFIPrims is now enabled and bundled with the VM as an external
plugin (and various patches for PPC have been submitted to the
libffi folks as a result ;). Hopefully this will allow Unix
Squeakers to drink tea on the croquet lawn along with everyone else.
Build:
Build process now uses a configure script generated from the VERY
LATEST autoconf (2.53) and libtool (1.4.2) that I downloaded
_direct_ from gnu.org and lovingly installed by hand (rather than
using the broken ones that were in pkgsrc and which created
practically unusable configure scripts in 3.2-4). Many associated
diverse changes in the *.{ac,in} files due to incompatibilities in
the new autoconf. (Obviously this only applies to `configure' as
shipped from our factory. If you regenerate `configure' for
yourself then everything depends on your autoconf [not mine] and
your [fictitious] warranty is immediately void. ;)
configure now recognises `--with-gnu-awk[=gawk]' to force gawk even
on systems where mawk is the default. PLEASE use this flag if you
have problems rather than complaining to me about gnuify not
working.
configure now recognises `--without-npsqueak' to exclude browser
support (npsqueak) in the build. (Browser support is experimental
and not [yet] quite the final thing that Bert and I are aiming for.
Use at your own risk.)
SqueakFFIPrims is enabled conditionally on ffi.h and libffi.so (the
latter becomes a library dependency of the plugin). The header and
library must be in your compiler's default search paths.
Support:
inisqueak now looks first for `squeak.{image,changes}' in the libdir,
to let sysadmins link to the preferred VM. If more than one VM is in
libdir then inisqueak presents a list and lets you choose. It also
has some options:
-b avoid all interaction (exit status => success)
-l list available VM versions
-n install but don't start up
Manual page updated to include the new options, etc.
Prebuilt distributions:
I can't be bothered rebooting my powerbook to make a NetBSD/macppc
distribution. (In the whole time that I have been making BSD
binaries available, only two people ever downloaded them.) If I'm
wrong (maybe hundreds of BSD fans are secretly downloading them from
uiuc?) then tell me and I'll get off my rear end and build one.
--- NEW FILE: 3.2-6.RELEASE_NOTES ---
3.2-6 released on 2002-11-27.
This release consolidates the VM support required by Croquet (which is
missing in 3.2) and that required by several 3.2 plugins (that are
missing in Croquet). It should work just fine with 3.2, 3.4 and
Croquet images.
Major changes since 3.2-5:
VM:
New VM sources generated (for Croquet compatibility). The core is
now generated out of a 3.4a-5125 image and runs Croquet fine on the
build machine.
Various small changes in several places for Darwin compatibility.
The `-secure' option has been removed.
Plugins:
Updated OpenGL code for B3DAcceleratorPlugin. _Many_ thanks to Bert
Freudenberg for this.
OSProcessPlugin updated to 3.0.2.
Build:
Updated to autoconf-2.54.
Builds out of the box on Darwin, either headless or with X11 support
(tested with XDarwin 4.2.1.1 on darwin6.2). NOTE: there are still
bugs in autoconf (more precisely, in aclocal and libtool) concerning
darwin. If you rebuild the configure script (by running `autoconf'
or `make' in the config dir) then the resulting configure script may
not work (the build will fail when trying to create shared libs for
external plugins). If you are affected by this then I can send you
my patched versions of ltcf-c.sh and aclocal.m4. You have been
warned!
Problems with libGLs that depend on libpthread should be fixed.
Link errors in sqUnixMozilla on BSD should no longer occur.
Removed the majority of the ridiculous dependencies in the RPM.
--- NEW FILE: 3.4-1.RELEASE_NOTES ---
Folks,
I've just put fresh 3.4 "final" Unix VMs in the usual place [1] with
source and binary tarballs/.rpms/.debs for i386 and ppc.
(I'd appreciate someone letting me know if the .debs work at all; it's
my first incursion into this particular territory and if they're
broken I'd like to know ASAP. Thanks.)
Enjoy!
Ian
[1] http://www-sor.inria.fr/~piumarta/squeak
3.4-1 RELEASE NOTES
Major changes since 3.2-5:
INSTALL:
The INSTALL script (present only in the binary tarballs) will no
longer remove symlinks to dirs, replacing them with newly-created
dirs. (Thanks to L. Peter Deutsch for spotting this.)
VM:
The core VM is generated out of a 3.4-5170 ("3.4 final") image.
Subtle directory deletion bug eliminated. (Thanks to Ned Konz.)
The peer address is filled in correctly after reception of a UDP
packet. (Thanks to Stefan Kersten.)
The `-secure' option has been removed.
On PowerPC machines (only) mod2 (the Option key) is mapped to Option
and mod3 (the Command key) is mapped to Command. (On other
architectures the mapping remains as before: mod1 and mod2 mapped to
Option and Command.)
Plugins:
Updated OpenGL code for B3DAcceleratorPlugin. _Many_ thanks to Bert
Freudenberg for this.
OSProcessPlugin updated to 3.0.5. Thanks to Dave Lewis for keeping
me up to date with his progress.
The FFIPlugin now comes with built-in support for SVr4-like APIs
(GNU/Linux, BSD, etc.) on PowerPC and Intel x86, and for the Mach-O
(Darwin) API on PowerPC. There is no longer any dependency on
libffi on these platforms. Fallback to using libffi is retained for
other platforms.
DragDrop changes for Darwin/Quartz. (Note that the Quartz window
code that uses it will bundled starting with version 3.5-1, so don't
go looking for it in 3.4.)
Build:
The build is using autoconf-2.52 for the moment, since there are
severe problems with 2.54-generated configure scripts (which refuse
to create a working libtool on Darwin).
Builds out of the box on Darwin, either headless or with X11 support
(tested with XDarwin 4.2.1.1 on darwin6.2). NOTE: there are still
bugs in autoconf (more precisely, in aclocal and libtool) concerning
darwin. If you rebuild the configure script (by running `autoconf'
or `make' in the config dir) then the resulting configure script may
not work (the build will fail when trying to create shared libs for
external plugins). If you are affected by this then I can send you
my patched versions of ltcf-c.sh and aclocal.m4. You have been
warned! (On the other hand, the autoconf supplied with Darwin works
perfectly on all the systems that I've tested it on.)
Numerous small changes in several places in the sources for Darwin
compatibility.
Problems with libGLs that depend on libpthread should be fixed.
MAXHOSTNAMELEN defaults to 256 when necessary (for ancient Solaris
systems that fail to define it anywhere).
Type of sizeIfFile corrected to squeakFileOffsetType. (Many thanks
to Alain Fischer for spotting this.)
Link errors in sqUnixMozilla on BSD should no longer occur.
Removed the majority of the ridiculous dependencies in the RPM.
--- NEW FILE: 3.4-gamma1.RELEASE_NOTES ---
3.4-gamma1 released on 2003-02-09.
Note that this will be the last release of the VM in its current form.
A major overhaul has been underway to add support for MacOSX and to
modularise large parts of the support code. Active development has
ceased in 3.4 and moved to the 3.5 VM, although bug-fix releases of
3.4 will continue to be made as necessary in the short term until 3.5
is considered stable.
Major changes since 3.2-5:
VM:
The core VM was generated out of a 3.4a-5169 (3.4gammeOne) image.
IMPORTANT NOTE for Croquet users: binary releases of this VM will
NOT run the latest version of Croquet. The 3.4 image is missing
some BitBlt and Float support required by Croquet. The support code
is entirely compatible, though, so regenerating the VM core from
within a Croquet image and then recompiling WILL yield a VM capable
of running Croquet just fine.
Subtle directory deletion bug eliminated. (Thanks to Ned Konz.)
The peer address is filled in correctly after reception of a UDP
packet. (Thanks to Stefan Kersten.)
Numerous small changes in several places for Darwin compatibility.
Type of sizeIfFile corrected to squeakFileOffsetType. (Many thanks
to Alain Fischer for finding this.)
The `-secure' option has been removed.
MAXHOSTNAMELEN defaults to 256 (for ancient Solaris systems that
fail to define it anywhere).
On PowerPC machines (only) mod2 (the Option key) is mapped to Option
and mod3 (the Command key) is mapped to Command. (On other
architectures the mapping remains as before: mod1 and mod2 mapped to
Option and Command. If anyone else is having problems with
modifiers, blame it on the peecee crowd whose keyboards are broken.
It just seemed ridiculous that the image wasn't behaving the way it
should on Apple keyboards, which is after all what it was originally
designed for.)
Plugins:
Updated OpenGL code for B3DAcceleratorPlugin. _Many_ thanks to Bert
Freudenberg for this.
OSProcessPlugin updated to 3.0.5. Thanks to Dave Lewis for keeping
me up to date with his progress.
The FFIPlugin now comes with built-in support for SVr4-like APIs
(GNU/Linux, BSD, etc.) on PowerPC and Intel x86, and for the Mach-O
(Darwin) API on PowerPC. There is no longer any dependency on
libffi on these platforms. Fallback to using libffi is retained for
other platforms.
DragDrop changes for Darwin/Quartz. (Note that the Quartz window
code that uses it will bundled starting with version 3.5-1, so don't
go looking for it in 3.4.)
Build:
The build is using autoconf-2.52 for the moment, since there are
severe problems with 2.54-generated configure scripts (which refuse
to create a working libtool on Darwin).
Builds out of the box on Darwin, either headless or with X11 support
(tested with XDarwin 4.2.1.1 on darwin6.2). NOTE: there are still
bugs in autoconf (more precisely, in aclocal and libtool) concerning
darwin. If you rebuild the configure script (by running `autoconf'
or `make' in the config dir) then the resulting configure script may
not work (the build will fail when trying to create shared libs for
external plugins). If you are affected by this then I can send you
my patched versions of ltcf-c.sh and aclocal.m4. You have been
warned! (On the other hand, the autoconf supplied with Darwin works
perfectly on all the systems that I've tested it on.)
Problems with libGLs that depend on libpthread should be fixed.
Link errors in sqUnixMozilla on BSD should no longer occur.
Removed the majority of the ridiculous dependencies in the RPM.
--- NEW FILE: COPYING ---
Many of the files in this distribution are subject to the following
copyright conditions:
Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors
as listed elsewhere in this file.
All rights reserved.
This file is part of Unix Squeak.
This file is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.
You may use and/or distribute this file ONLY as part of Squeak, under
the terms of the Squeak License as described in `LICENSE' in the base of
this distribution, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment to the original author(s) (and any
other contributors mentioned herein) in the product documentation
would be appreciated but is not required.
2. This notice must not be removed or altered in any source distribution.
Using (or modifying this file for use) in any context other than Squeak
changes these copyright conditions. Read the file `COPYING' in the
directory `platforms/unix/doc' before proceeding with any such use.
You are not allowed to distribute a modified version of this file
under its original name without explicit permission to do so. If
you change it, rename it.
NOTE: Files that do not contain the above notice are subject to the
conditions contained in the individual files themselves. In the
absence of explicit copyright conditions they are subject to the
conditions described in the file `LICENSE'.
NOTE: Significant source contributions from other people are always
acknowledged in the individual source files. Unless explicitly
indicated otherwise, the above copyright notice applies to such code
(without prejudice and strictly to protect the interests of the
individual contributors) but makes NO REPRESENTATION about the
authorship or the ownership of the contributed code.
You are allowed to use (or modify for use) in a non-Squeak context, or to
create derivative works unrelated to Squeak based on, any files that
contain the above copyright notice, subject to the following restrictions:
1. You must make a copy of the file under a different name and then use
only your renamed copy.
2. You must not change the first three lines of the copyright notice in
your copy.
3. In your copy you must replace the portion of the copyright notice that
commences:
This file is part of Unix Squeak
with the following notice:
This program is free software. You can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranties of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
See the file COPYRIGHT for more details.
4. You MUST NOT remove any acknowledgements for code contributed by other
authors from your copy of the file.
5. You must include the file `COPYRIGHT' in any source or binary
distribution that includes or is based on one or more files modified in
the above manner.
6. You can now use your copy in any way that you like, subject to its new
copyright conditions, provided that you do not re-introduce the file
into any distribution of Squeak.
---
I'm sorry if the above seems draconian, but I'm trying simply to ensure
that both the Squeak and non-Squeak communities obtain the maximum benefit
from the software in this distribution.
--- NEW FILE: COPYRIGHT ---
(If you received this file as part of a Squeak distribution then
please stop here and refer instead to the copyright notices in
the individual files and to those in the file `LICENSE'.)
This software is distributed under the terms of the GNU General Public
License (GPL), a copy of which is included below. In brief: you can
(and are encouraged to) redistribute and reuse the software according
to the terms of the GPL. You can not use any part of the software for
commercial purposes (other than charging a fee for its distribution
according to the terms of the GPL), nor create a derivative work based
on the software except when such work is itself distributed under the
terms of the GPL. All other use of the software is strictly
prohibited except when explicit written permission for such use has
first been obtained from the copyright holder.
----------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
--- NEW FILE: HowToBuildFromSource.pdf ---
%PDF-1.2
%Çì¢
6 0 obj
<</Length 7 0 R/Filter /FlateDecode>>
stream
xµXxÕ[Jx$åbÁþLk!éÎGDImIefÔÖu[4´±Bºw¿8Æ9ÜØÅmTÙı
ç&Ú¦¶i70¶¹óü·ôÿÒ6->ëÓ'ósÞó}ï÷~ßÚ(ZþÓ>[M[Me·³Ô¦ i+
)ý£±rÔÊVSªm2é+lòÄ1vâ|¯m5Y¦\157'oZþô<÷æÜîm3¯$9æY³¯;§pêüy]½xQñ5K¨¥µ-&$1ìUë5Y>{mÉu¥×»º-Öe¶å¥vymº^¦Î_fÃÌ<yÂXF¢X²Zdó9D´bå
«n¼nv¬.ç3Ç$§XÝRYá\ã¬Z{«ùL
ë¶âU®©^g»½fMqme
«ªfÝd¾ôÖºdýQe5Ç#
ó²úcB½Çí¾³á®õu¼Öçmðm¢=-þsþÝ-þÍùw¯lñoA-å[ëÑ áov4kcÓZÊÑÖà¶¶íÞÆ÷vÖ{v4´×ßw¯wÛúº¨qÇÆúÀÇÕX^[׸c·uWScXÁ´~Æý]
l,ß!IüsW{½gwÈí.ÙÓQï!¸ë664ÝÛ¦,æ$ÍvbÑþ@P=ôÑèÀýjÃfµáOv¢=á4¨M4|*зþ´ÿÐnïúû¶>ãjv´8È]Õ°I&aCñg?ÿ¹Â/~±æKÉï_
h¡ÕîÝ÷ëWGö-ô¨ëëÑkûæ7Bï·ô~«à±oï÷?\ýàw£»ºÊFÐ}ô=5ú
=|2öCÇSôáÿHxÚy~â§]?9Úù³>óó}OF;k¶æ¹Ö#ôaá©Ç÷+6Á_X¹×Ò/üñ )/ìûeÁ±c48 @9àø³«;q¤æ°SËÜêWêV!§mõbôdä¥Å/ßtEOyáîØ+%=æ^gÒß¿êì+êËï·vG_õ²vEêRÁÁ¡D¸ßÛýëü^èäoÒßã
Ìè ^SAдAXÉK1Eºåoc§åZªHí¬ª¬]¤0by;/R,bx;-Êòâ¨2UÝFmßÖ¶ÑTVG!SS~s¬+'U·PSLUÊN">,Ȳø¼;8ëûp®ü±±dg'QEd
H Ôý8°3^î@çÀÁÐ`U8×hÅr²©%}x$eJÍ)]>Å7MkxSÖnpq×= 9µ-Ì]Ñx$éè9>Ëe¥Á
1Øék¤»sÞùÐÉRØ'×Ý~H
WË£p~QIíõ¥I,¯Yl´$,Ò]ÕÌ
Äm=fQßÀP'iÜ'9Øô.!2d,µÇ'.#êĽ~\ÞBÖ¤Ö·ø¤¤ÛGt.Üe\1=ÎUÂݾ?böcô#i¸ÒË4!u?PÍÌäѨ¤G)XÖ¸@Â3Ƚ4SÚÓɬtÖePÞN¤]¾x<Ð
aØ÷¡Xõ%#ȲÅÚôÚèÚ´¼0éèÆÕç`®V¤Ê PÝ>àùg¬\ÇDüþO¾=âLû!m½~¾§;$ÓjÀt@RÙ@ö3kìhÆN9Q#j÷*y2ý<UÓ}n§Ëà-2ú/HûB¹¬Y`2J
v^rg0¡×0CÎÒ¿dÄb)j*g7É*H¿ÐPý=³'ÞJAÏF3Ìê»0
O¼Ùä£vÖ£ôÕ@ö±¨ï¾×¹Wñé
h
Kâ05.ªMï
endobj
7 0 obj
2212
[...10417 lines suppressed...]
0000155143 00000 n
0000155209 00000 n
0000155482 00000 n
0000155744 00000 n
0000156029 00000 n
0000156251 00000 n
0000040036 00000 n
0000157063 00000 n
0000156559 00000 n
0000044669 00000 n
0000040146 00000 n
0000042835 00000 n
0000156789 00000 n
0000042857 00000 n
trailer
<< /Size 582 /Root 1 0 R /Info 2 0 R
>>
startxref
169112
%%EOF
--- NEW FILE: HowToBuildFromSource.ps ---
%!PS-Adobe-2.0
%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software
%%Title: HowToBuildFromSource.dvi
%%Pages: 12
%%PageOrder: Ascend
%%BoundingBox: 0 0 596 842
%%EndComments
%DVIPSWebPage: (www.radicaleye.com)
%DVIPSCommandLine: dvips -o HowToBuildFromSource.ps
%+ HowToBuildFromSource.dvi
%DVIPSParameters: dpi=600, compressed
%DVIPSSource: TeX output 2002.06.05:0522
%%BeginProcSet: texc.pro
%!
/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72
mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0
0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{
landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize
[...2107 lines suppressed...]
Fg(,)g(8)2258 1411 y Fh([targets])p Fg(,)f(7)2092 1511
y Fh(Makefile.in)p Fg(,)f(9)2258 1610 y(example,)k(10)2092
1710 y Fh(Makefile.inc)p Fg(,)c(9)2258 1810 y(example,)k(10)2258
1909 y(k)n(eyw)n(ord)f(substitution,)i(9)2092 2009 y
Fh(mkmf)p Fg(,)e(6)2258 2109 y(additional)h(source)g(directories,)f(9)
2258 2208 y(default)i(header)f(directories,)f(7)2258
2308 y(default)i(source)f(directories,)f(7)2092 2407
y Fh(mkmf.subdirs)p Fg(,)d(9)2258 2507 y(example,)k(10)2092
2690 y(plugin)2258 2789 y Fh(Makefile)p Fg(,)e(6)2258
2889 y Fh(Makefile)g Fg(anatom)n(y)-7 b(,)26 b(6)2258
2989 y(adding)h(y)n(our)g(o)n(wn,)g(4)2258 3088 y(con\014guring,)f(5)
2258 3188 y(target)h(rules,)g(8)2258 3287 y(Unix-sp)r(eci\014c)h
(directory)-7 b(,)26 b(5)2092 3470 y(Unix-sp)r(eci\014c)i(\014les,)f(4)
2092 3653 y(VMMak)n(er)2258 3752 y(con\014guration)f(\014le,)i(3)2258
3852 y(missing)f(platform)h(supp)r(ort,)f(11)2258 3952
y(reference,)g(3)p Black 1905 5255 a(12)p Black eop
%%Trailer
end
userdict /end-hook known{end-hook}if
%%EOF
--- NEW FILE: HowToBuildFromSource.txt ---
****** Building Unix Squeak (>= 3.2) from source ******
Ian Piumarta
<ian...@in...>
Last edited: 2002-06-05 05:22:02 by piumarta on emilia.inria.fr
Translated to .ps/.pdf/.html/.txt: June 5, 2002
***** Contents *****
* 1_configure_-_build_-_install
* 2_Generating_your_own_VM_and_plugin_sources
* 3_Adding_your_own_plugins
o 3.1_Plugin-specific_configuration
o 3.2_Plugin-specific_Makefile_declarations_and_rules
o 3.3_Examples_taken_from_existing_plugins
o 3.4_Coping_with_VMMaker_quirks
o 3.5_If_all_else_fails
* Index
1 configure - build - install
Unix Squeak is built using the (almost) universal ``configure; make; make
install''. If you haven't come across this before, read on...
Create a build directory (which we will call `blddir' from now on) and then
`cd' to it:
$ mkdir blddir
$ cd blddir
A convenient place is just next to the platforms directory, like this:
$ cd squeak
$ ls
platforms src ...
$ mkdir bld
$ cd bld
Create the build environment by running the script configure which lives in the
platforms/unix/config directory.
Note: The configure script accepts lots of options. To see a list of
them, run: `configure --help'
Assuming you've created the blddir next to platforms, this would be:
$ ../platforms/unix/config/configure
Note: This assumes that the VMMaker sources are in `../src'. However,
since the Unix Squeak support code is independent of the image
version from which VMMaker generated the interpreter/plugin sources,
it is possible that your source distribution comes with more than one
src directory (corresponding to more than one image version used to
generate the sources). In such cases you will have to tell configure
which source version to use, via the `--with-src' option. For
example, if there are two source directories called src-3.2gamma-4857
and src-3.3.alpha-4881 then you would use one of the following
commands:
$ .../configure --with-src=src-3.2gamma-4857
or
$ .../configure --with-src=src-3.3alpha-4881
Build the VM and plugins by running make:
$ make
Note: If you want to build just the VM (without external plugins) or
just the external plugins (without the VM) then you can use: `make
squeak' or `make plugins' respectively.
Finally install the VM, plugins and manual pages:
$ su root
$ make install
****** 2 Generating your own VM and plugin sources ******
Generating your own VM/plugin sources might be necessary for various reasons:
* you want to change the mix of internal vs. external plugins
* you want to remove some plugins from the VM that you will never use
* you've pulled in some updates that modify the Interpreter or plugins
* you've filed-in (or written) a whole new plugin
* etc...
Version 3.2 (and later) of Unix Squeak use VMMaker to generate the core
interpreter and plugin sources.
Start Squeak in the top-level directory (the one containing the platforms
directory); for example:
$ ls
src platforms ...
$ squeak MyCoolPlugin.image
Open a VMMakerTool and modify the setup to your liking.
Note: The VMMaker configuration used to build the distributions of
Unix Squeak is available in platforms/unix/config/VMMaker.config.
Then click on the relevant ``generate ...'' button. You can now `configure;
make; make install' in your blddir (as described above).
Note: You only need to run configure once for a given blddir (on the
same host). If you modify the choice of plugins (or change whether
they're internal/external) then you can update the build environment
by running the config.status script in the bldddir, like this:
$ squeak MyCoolPlugin.image
... generate new sources ...
$ cd blddir
$ ./config.status
$ make
This is much faster than running configure all over again. (In fact,
make should detect any changes to the plugin configuration and re-run
config.status for you automatically.)
Note: `configure' doesn't actually create any files. The last thing
it does is run `config.status' to create the configured files in
blddir from the corresponding file.ins in the unix/config directory.
So in the remainder of this document the phrase `during
configuration' means either when running `configure' for the first
time or running `config.status' to update an already configured build
environment.
****** 3 Adding your own plugins ******
Note: This section is intended primarily for plugin developers.
If your plugin requires no platform-specific tweaks then there's nothing for
you to do. configure (and config.status) will provide a default Makefile for it
that should work. If your plugin requires only platform-independent tweaks
(and/or additional hand-written code) then these go in platforms/Cross/plugins,
and there's nothing for you to do (in Unixland).
On the other hand, if you require special configure tests or additional
declarations/rules in your plugin's Makefile then you need to specify them
explicitly.
Note: Unix Squeak subscribes to the following philopsophy:
Absolutely everything that is specific to Unix (sources, headers,
configure and Makefile extensions, etc.) lives under platforms/unix.
In other words: there is not (nor aught there be) any Unix-related
information under the platforms/Cross directory. (Unix Squeak is
entirely encapsulated under platforms/unix and is utterly immune to
``random junk'' elsewhere in the platforms tree.)
First you must create a new directory under platforms/unix/plugins named after
your plugin. This directory will hold the files describing the additional
configuration checks and/or Makefile contents. For example, if your plugin is
called ``MyCoolPlugin'' then
$ mkdir platforms/unix/plugins/MyCoolPlugin
would be the thing to do. (The following sections will refer to this directory
as platdep since the full path is quite a mouthful of typing for my lazy
fingers.)
***** 3.1 Plugin-specific configuration *****
Your plugin can ask configure to run additional tests (and to set additional
variables in its output files) simply by including a file called acinclude.m4
in it's platdep directory.
Note: The configure script is `compiled' from several other files. If
you create a `platdep./acinclude.m4' file then you must `recompile'
configure. You can do this by `cd'ing to unix/config and running
`make', or (if you have GNU make) from the blddir like this:
$ make -C ../platforms/unix/config
In addition to the usual autoconf macros, the following macros are available
specifically for Squeak plugins to use:
3.1.1 AC_PLUGIN_CHECK_LIB(lib,func)
This is similar to the autoconf `AC_CHECK_LIB' macro.
func is the name of a function required by the plugin, defined in the external
(system) library lib. The macro checks that the library is available (via `-
llib') and then adds it to the list of libraries required by the plugin (see
the explanation of [plibs] in Section 3.2.1 for a description of how library
dependencies for plugins are handled).
If func cannot be found in lib then the plugin will be disabled and a message
to that effect printed during configuration. (The VM can still be built,
without rerunning VMMaker or reconfiguring, and the plugin will simply be
ommitted from it.)
3.1.2 AC_PLUGIN_DEFINE_UNQUOTED(keyword,text)
This is similar to the autoconf `AC_DEFINE_UNQUOTED' macro.
keyword is a Makefile keyword (usually of the form `[name]') and text is
arbitrary text to be associated with it. Calling this macro causes mkmf to
substitute text for all occurrences of keyword in the Makefile generated for
the plugin.
**** 3.1.3 Plugin-specific variables ****
The following variables are also set during the execution of a plugin-specific
acinclude.m4:
${plugin} is the name of the plugin;
${topdir} is the path to the top-level directory (containing platforms);
${vmmdir} is the path to the VMMaker `src' directory.
3.2 Plugin-specific Makefile declarations and rules
Three mechanisms are avilable for this:
1. scanning additional dirrectories for sources and headers;
2.
including a few additional lines into the default Makefile; and
3.
replacing entirely the default Makefile with a hand-written one.
(The last option isn't as scary as it might sound: read on...)
3.2.1 The anatomy of a plugin's Makefile
Before proceeding, let's take a minute to understand how Unix Squeak compiles
and links files in its default Makefile for plugins. The default Makefile looks
like this:
# default Makefile for Unix Squeak plugins
[make_cfg]
[make_plg]
XINCLUDES = [includes]
OBJS = [targets]
TARGET = [target]
PLIBS = [plibs]
[make_inc]
$(TARGET) : $(OBJS) Makefile
$(LINK) $(TARGET) $(OBJS) $(PLIBS)
[make_targets]
.force :
Note: The keywords appearing between `[ square brackets ]' are
substituted during configuration by a preprocessor called `mkmf'
according to the kind of plugin (internal/external) being built.
[make_cfg] is the configured variable section. It contains the platform-
specific information gleaned by configure while it was figuring out which
compiler you have, what flags your linker needs, where to install stuff, and so
on.
[make_plg] contains a handful of definitions which depend on whether the
plugin is being compiled as internal or external:
o the extension for object files
a the extension for plugins
COMPILE the command to compile a source file into an object file
LINK the command to link one or more object files into a
plugin
For internal plugins: $o is `.o' and $a is `.a'. $(COMPILE) is the C compiler
(`$(CC) ... -o', so the first thing after the command must be the output
filename) and $(LINK) is archiver (`ar -rc', again requiring the output file to
follow immediately). Note that internal plugins are built as `ar' archives
before being linked into the final binary.
For external plugins: $o is `.lo', $a is `.la', and $(COMPILE) and $(LINK) are
invocations of `libtool' to create position-independent objects and shared
libraries (with a `-o' appearing right at the end, so the first thing after the
command must be the output filename).
[includes] is a list of `-Idir' compiler flags, one for each of the
directories
src/plugins/name
src/vm/intplugins/name
platforms/Cross/plugins/name
platforms/unix/plugins/name
in which at least one header file is present.
[targets] is a list of object files corresponding to the source (.c) files
found in the directories:
src/plugins/name/*.c
src/vm/intplugins/name/*.c
platforms/Cross/plugins/name/*.c
platforms/unix/plugins/name/*.c
where each source file has been stripped of the directory name and had the `.c'
converted into `$o'.
[target] is the name of the plugin, including the $a extension.
[plibs] is a list of zero or more libraries on which the plugin depends (as
detected using the macro AC_PLUGIN_CHECK_LIB in the plugin-specific
acinclude.m4). If the plugin is being built internally then this list is empty
and the required libraries are included in the final link command. If the
plugin is being built externally then the plugin itself (a shared object) is
linked against these libraries (via [plist]) rather than with the main VM
binary.
(This is to ensure that a missing shared object needed by an external plugin
will only affect the operation of that plugin and not prevent the rest of the
VM from running, which would be the case if the entire VM were linked against
it.)
[make_inc] is the contents of the Makefile.inc file in your plugin's platdep
directory (or empty if this file doesn't exist).
[make_targets] is a list of rules for building the files listed i...
[truncated message content] |
Update of /cvsroot/squeak/squeak/platforms/unix/config In directory sc8-pr-cvs1:/tmp/cvs-serv30143/config Added Files: Makefile Makefile.in Makefile.install Makefile.plg.in Squeak.spec.in VMMaker.config acinclude.m4 aclocal.m4 build config.guess config.h.in config.sub configure configure.ac gnuify inisqueak.in install-sh ltcf-c.sh ltconfig ltmain.sh make.cfg.in make.ext.in make.int.in make.prg.in mkacinc mkconfig.in mkinstalldirs mkman mkmf mktargets relpath uninstall version version.stamp verstamp vmm.config Log Message: Ian Piumarta's release 3.4.1 --- NEW FILE: Makefile --- configure : .force ./mkacinc > acplugins.m4 aclocal autoconf rm acplugins.m4 .force : --- NEW FILE: Makefile.in --- # Makefile.in for Unix Squeak using VMMaker -*- makefile -*- # # Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors # as listed elsewhere in this file. # All rights reserved. # # This file is part of Unix Squeak. # # This file is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. # # You may use and/or distribute this file ONLY as part of Squeak, under # the terms of the Squeak License as described in `LICENSE' in the base of # this distribution, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment to the original author(s) (and any # other contributors mentioned herein) in the product documentation # would be appreciated but is not required. # # 2. This notice must not be removed or altered in any source distribution. # # Using (or modifying this file for use) in any context other than Squeak # changes these copyright conditions. Read the file `COPYING' in the # directory `platforms/unix/doc' before proceeding with any such use. # # You are not allowed to distribute a modified version of this file # under its original name without explicit permission to do so. If # you change it, rename it. # # Author: ian...@in... # # Last edited: 2003-03-04 06:44:45 by piumarta on emilia.inria.fr @make_cfg@ @make_prg@ la = .la SQLIBS = [targets] PLUGINS_LA = [plugins] squeak = squeak$(NOX) all : $(squeak) plugins squeak.1 $(npsqueak) # VM $(squeak) : config.sh $(SQLIBS) version.o $(LINK) $(squeak) $(SQLIBS) version.o $(LIBS) [plibs] size $(squeak) @echo @./$(squeak) -version @echo version.o : version.c $(COMPILE) version.o version.c version.c : $(SQLIBS) ${cfgdir}/verstamp version.c $(CC) plugins : config.sh $(PLUGINS_LA) # npsqueak npsqueak : nps/npsqueak.so nps : mkdir nps $(SHELL) -ec 'cd nps; ln -s $(topdir)/platforms/unix/npsqueak/* .' nps/npsqueak.so : nps $(SHELL) -ec 'cd nps; $(MAKE) VM_VERSION=$(VM_VERSION) SQ_DIR=$(imgdir)' # manual page squeak.1 : $(topdir)/platforms/unix/doc/squeak.1 $(cfgdir)/mkman $(SQ_MAJOR) $(SQ_VERSION) \ $(bindir) $(imgdir) $(plgdir) $(mandir) $(docdir) \ < $(topdir)/platforms/unix/doc/squeak.1 > $@ # install/distrib (these just get in the way -- suck 'em in from elsewhere) @Makefile_install@ @Makefile_dist@ @Makefile_rpm@ @Makefile_deb@ # VMM configuration changes config.sh : $(srcdir)/plugins.int $(srcdir)/plugins.ext $(srcdir)/vm/sqNamedPrims.h ./config.status @echo @echo "configuration changed: please run make again" @echo @exit 1 [make_targets] .force : --- NEW FILE: Makefile.install --- # Makefile.install for Unix Squeak using VMMaker -*- makefile -*- # # Author: ian...@in... # # Last edited: Wed Nov 27 19:13:56 2002 by piumarta (Ian Piumarta) on xombul DOCFILES = COPYING COPYRIGHT LICENSE \ README.Contributing README.Keyboard README.Sound install : install-squeak install-plugins install-doc $(install_nps) uninstall : uninstall-squeak uninstall-plugins uninstall-doc $(uninstall_nps) # squeak install-squeak : $(squeak) $(MKINSTALLDIRS) $(ROOT)$(plgdir) $(INSTALL_PROG) -s $(squeak) $(ROOT)$(plgdir) $(MKINSTALLDIRS) $(ROOT)$(bindir) ( path=`$(cfgdir)/relpath $(bindir) $(plgdir)`; \ cd $(ROOT)$(bindir); \ rm -f $(squeak); \ $(LN_S) $$path/$(squeak) .; ) uninstall-squeak : .force @$(UNINSTALL) $(ROOT)$(plgdir) $(squeak) @$(UNINSTALL) $(ROOT)$(bindir) $(squeak) # plugins install-plugins : plugins $(MKINSTALLDIRS) $(ROOT)$(plgdir) @list='$(PLUGINS_LA)'; for p in $$list; do \ if test -f */$$p; then \ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(ROOT)$(plgdir)/$$p"; \ $(LIBTOOL) --mode=install $(INSTALL) */$$p $(ROOT)$(plgdir)/$$p; \ else :; fi; \ done uninstall-plugins : .force @list='$(PLUGINS_LA)'; for p in $$list; do \ if test -f $(ROOT)/$(plgdir)/$$p; then \ echo "$(LIBTOOL) --mode=uninstall rm -f $(ROOT)$(plgdir)/$$p"; \ $(LIBTOOL) --mode=uninstall rm -f $(ROOT)$(plgdir)/$$p; \ else :; fi; \ done @$(UNINSTALL) $(ROOT)$(plgdir) # doc install-doc : squeak.1 $(MKINSTALLDIRS) $(ROOT)$(docdir) @list='$(DOCFILES)'; for f in $$list; do \ echo $(INSTALL_DATA) $(topdir)/platforms/unix/doc/$$f $(ROOT)$(docdir); \ $(INSTALL_DATA) $(topdir)/platforms/unix/doc/$$f $(ROOT)$(docdir); \ done $(MKINSTALLDIRS) $(ROOT)$(mandir)/man1 $(INSTALL_DATA) squeak.1 $(ROOT)$(mandir)/man1 rm -f $(ROOT)$(mandir)/man1/inisqueak.1 $(LN_S) squeak.1 $(ROOT)$(mandir)/man1/inisqueak.1 uninstall-doc : @$(UNINSTALL) $(ROOT)$(docdir) $(DOCFILES) @$(UNINSTALL) $(ROOT)$(mandir)/man1 squeak.1 inisqueak.1 # image install-image : inisqueak $(topdir)/Squeak$(SQ_VERSION).image.gz $(topdir)/Squeak$(SQ_VERSION).changes.gz $(MKINSTALLDIRS) $(ROOT)$(imgdir) $(INSTALL_DATA) $(topdir)/Squeak$(SQ_VERSION).image.gz $(ROOT)$(imgdir) $(INSTALL_DATA) $(topdir)/Squeak$(SQ_VERSION).changes.gz $(ROOT)$(imgdir) $(INSTALL_PROG) inisqueak $(ROOT)$(imgdir) $(MKINSTALLDIRS) $(ROOT)$(bindir) ( path=`$(cfgdir)/relpath $(bindir) $(imgdir)`; \ cd $(ROOT)$(bindir); \ rm -f inisqueak; \ $(LN_S) $$path/inisqueak .; ) uninstall-image : @$(UNINSTALL) $(ROOT)$(plgdir) Squeak$(SQ_VERSION).image.gz @$(UNINSTALL) $(ROOT)$(plgdir) Squeak$(SQ_VERSION).changes.gz @$(UNINSTALL) $(ROOT)$(plgdir) inisqueak # sources install-sources : $(MKINSTALLDIRS) $(ROOT)$(imgdir) $(INSTALL_DATA) $(topdir)/SqueakV$(SQ_MAJOR).sources $(ROOT)$(imgdir) uninstall-sources : @$(UNINSTALL) $(ROOT)$(imgdir) SqueakV$(SQ_MAJOR).sources # npsqueak install-npsqueak : npsqueak .force $(SHELL) -ec 'cd nps; $(MAKE) install VM_VERSION=$(VM_VERSION) SQ_DIR=$(ROOT)$(imgdir) imgdir=$(imgdir)' uninstall-npsqueak : npsqueak .force $(SHELL) -ec 'cd nps; $(MAKE) uninstall VM_VERSION=$(VM_VERSION) SQ_DIR=$(ROOT)$(imgdir) imgdir=$(imgdir)' --- NEW FILE: Makefile.plg.in --- # Makefile.plg.in -- default rules for plugins -*- makefile -*- # # Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors # as listed elsewhere in this file. # All rights reserved. # # This file is part of Unix Squeak. # # This file is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. # # You may use and/or distribute this file ONLY as part of Squeak, under # the terms of the Squeak License as described in `LICENSE' in the base of # this distribution, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment to the original author(s) (and any # other contributors mentioned herein) in the product documentation # would be appreciated but is not required. # # 2. This notice must not be removed or altered in any source distribution. # # Using (or modifying this file for use) in any context other than Squeak # changes these copyright conditions. Read the file `COPYING' in the # directory `platforms/unix/doc' before proceeding with any such use. # # You are not allowed to distribute a modified version of this file # under its original name without explicit permission to do so. If # you change it, rename it. # # Author: ian...@in... # # Last edited: 2002-07-08 20:23:48 by piumarta on emilia.inria.fr [make_cfg] [make_plg] XINCLUDES = [includes] OBJS = [targets] TARGET = [target] PLIBS = [plibs] [make_inc] $(TARGET) : $(OBJS) Makefile $(LINK) $(TARGET) $(OBJS) $(PLIBS) $(RANLIB) $(TARGET) [make_targets] .force : --- NEW FILE: Squeak.spec.in --- Name: Squeak Version: [version] Release: [release] Requires: Summary: A portable implementation of the Smalltalk programming system. Vendor: Squeak.org Source: [source] Copyright: Squeak Software License Group: Development/Languages BuildRoot: /var/tmp/%{name}-root %description Squeak is a full-featured implementation of the Smalltalk programming language and environment based on (and largely compatible with) the original Smalltalk-80 system. Squeak has very powerful 2- and 3-D graphics, sound, video, MIDI, animation and other multimedia capabilities -- and one of the most impressive development environments ever created. It also includes a customisable framework for creating dynamic HTTP servers and interactively extensible Web sites. The entire Squeak system is open source software, distributed freely with a liberal license. See <http://Squeak.org> for further information. This package contains the binaries, libraries and data files needed to run version [version] of Squeak. %prep %setup -q %build mkdir bld-rpm cd bld-rpm ../platforms/unix/config/configure --prefix=/usr make %install rm -rf $RPM_BUILD_ROOT cd bld-rpm make install-bin install-image install-sources ROOT=$RPM_BUILD_ROOT cd .. # # package file lists # find $RPM_BUILD_ROOT \( -type f -o -type l \) -print | sed "s,$RPM_BUILD_ROOT,,;s,^//,/," > sq-files %clean echo "rm -rf $RPM_BUILD_ROOT" echo "rm -rf bld-rpm" %files -f sq-files %files -f ffi-files ffi --- NEW FILE: VMMaker.config --- 'From Squeak3.2 of 15 January 2002 [latest update: #4881] on 20 October 2002 at 6:43:10 pm'! !ObjectScanner new initialize! !self smartRefStream! Dictionary firstIndex lastIndex Collection FilePluginFloatArrayPluginGeniePluginIntegerPokerPluginJPEGReadWriter2PluginJPEGReaderPluginJoystickTabletPluginKlattSynthesizerPluginLargeIntegersPlugin MIDIPluginMatrix2x3PluginMiscPrimitivePluginMpeg3PluginRePluginSecurityPluginSerialPluginSocketPluginSoundCodecPluginSoundGenerationPluginSoundPluginStarSqueakPlugin SurfacePlugin B3DAcceleratorPlugin FFIPluginPseudoTTYPlugin)UnixOSProcessPluginNoThisSessionAvailable unix/home/piumarta/squeak/devel/src%/home/piumarta/squeak/devel/platforms! --- NEW FILE: acinclude.m4 --- # Local autoconf macros for configuring Unix Squeak -*- sh -*- # # Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors # as listed elsewhere in this file. # All rights reserved. # # This file is part of Unix Squeak. # # This file is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. # # You may use and/or distribute this file ONLY as part of Squeak, under # the terms of the Squeak License as described in `LICENSE' in the base of # this distribution, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment to the original author(s) (and any # other contributors mentioned herein) in the product documentation # would be appreciated but is not required. # # 2. This notice must not be removed or altered in any source distribution. # # Using (or modifying this file for use) in any context other than Squeak # changes these copyright conditions. Read the file `COPYING' in the # directory `platforms/unix/doc' before proceeding with any such use. # # You are not allowed to distribute a modified version of this file # under its original name without explicit permission to do so. If # you change it, rename it. # # Author: Ian...@IN... # # Last edited: 2003-02-09 02:40:58 by piumarta on emilia.inria.fr AC_DEFUN(AC_CHECK_VMM_DIR,[ AC_MSG_CHECKING([sanity of VMMaker src directory]) vmmcheck () { if test ! ${2} ${3}; then AC_MSG_RESULT(bad) echo "missing ${1}: ${3}" exit 1 fi } vmmcheck dir -d ${vmmdir} vmmcheck file -f ${vmmdir}/plugins.int vmmcheck file -f ${vmmdir}/plugins.ext vmmcheck dir -d ${vmmdir}/plugins vmmcheck dir -d ${vmmdir}/vm vmmcheck file -f ${vmmdir}/vm/interp.c vmmcheck file -f ${vmmdir}/vm/sqNamedPrims.h vmmcheck dir -d ${vmmdir}/plugins AC_MSG_RESULT(okay)]) AC_DEFUN(AC_VM_VERSION,[ VM_MAJOR=$1 VM_MINOR=$2 VM_RELEASE=$3 SQ_MAJOR=$4 SQ_MINOR=$5 SQ_UPDATE=$6 ]) AC_DEFUN(AC_CHECK_VERSION,[ gendir="${vmmdir}/vm" version=`${cfgdir}/version ${gendir}/interp.c` SQ_MAJOR=`echo ${version} | cut -d ' ' -f 1` SQ_MINOR=`echo ${version} | cut -d ' ' -f 2` SQ_UPDATE=`echo ${version} | cut -d ' ' -f 3` ]) AC_SUBST(NM) AC_SUBST(LD) AC_DEFUN(AC_REQUIRE_SIZEOF,[ AC_MSG_CHECKING("size of $1") AC_TRY_RUN([#include <sys/types.h> int main(){return(sizeof($1) == $2)?0:1;}], AC_MSG_RESULT("okay"), AC_MSG_RESULT("bad") AC_MSG_ERROR("one or more basic data types has an incompatible size: giving up"))]) # Try to find a 64-bit integer data type. # NOTE: `long long' is 64 bits in ANSI C99 [ISO/IEC 9899:1999 (E)]. AC_DEFUN(AC_CHECK_INT64_T,[ AC_CACHE_CHECK([for 64-bit integer type],ac_cv_int64_t, AC_TRY_RUN([int main(){return(sizeof(long) == 8)?0:1;}], ac_cv_int64_t="long", AC_TRY_RUN([int main(){return(sizeof(long long) == 8)?0:1;}], ac_cv_int64_t="long long", ac_cv_int64_t="no"))) if test "$ac_cv_int64_t" = ""; then AC_MSG_ERROR([could not find a 64-bit integer type]) fi SQUEAK_INT64_T="$ac_cv_int64_t" AC_DEFINE_UNQUOTED(squeakInt64, $ac_cv_int64_t)]) AC_DEFUN(AC_NEED_SUNOS_H, [case "$host" in *-sunos*) AC_DEFINE(NEED_SUNOS_H, 1) esac]) AC_DEFUN(AC_PROG_CC_WALL, [AC_PROG_CC test "$GCC" = yes && WFLAGS="-Wall" AC_SUBST(WFLAGS)]) AC_DEFUN(AC_GNU_OPT, [AC_MSG_CHECKING("for optimization flags") ac_optflags="no" if test "$GCC" = yes; then case $host in i?86-*) ac_optflags="-fomit-frame-pointer" ;; esac fi if test "$ac_optflags" = "no"; then AC_MSG_RESULT([(none)]) else CFLAGS="$CFLAGS $ac_optflags" AC_MSG_RESULT("$ac_optflags") fi]) AC_DEFUN(AC_GNU_INTERP, [INTERP="interp" AC_SUBST(INTERP) AC_PROG_AWK AC_MSG_CHECKING(whether we can gnuify interp.c) if test "$GCC" = "yes"; then case "$GAWK" in no) ;; yes) AWK=awk; GAWK=yes ;; gawk) AWK=gawk; GAWK=yes ;; *) if test -x /usr/bin/gawk; then GAWK=yes AWK=gawk else if $AWK --version /dev/null </dev/null 2>&1 | fgrep -i gnu >/dev/null then GAWK=yes else GAWK=no fi fi ;; esac if test "$GAWK" = "yes" then INTERP="gnu-$INTERP"; AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi else AC_MSG_RESULT(no) fi]) AC_DEFUN(AC_PROG_AS_GNU, [AC_CHECK_PROG(AS,as,as) AC_MSG_CHECKING(for GNU as) case "$GAS" in yes|no) ;; *) if test "$AS" = "as" && as -v /dev/null </dev/null 2>&1 | fgrep -i gnu >/dev/null then GAS=yes else GAS=no fi ;; esac AC_MSG_RESULT($GAS)]) AC_DEFUN(AC_CHECK_ATEXIT, [AC_CACHE_CHECK([for atexit or on_exit], ac_cv_atexit, AC_TRY_COMPILE([#include <stdlib.h>],[atexit(0);], ac_cv_atexit="atexit", AC_TRY_COMPILE([#include <stdlib.h>],[on_exit(0);], ac_cv_atexit="on_exit", ac_cv_atexit="no"))) if test "$ac_cv_atexit" != "no"; then AC_DEFINE_UNQUOTED(AT_EXIT, $ac_cv_atexit) fi]) AC_DEFUN(AC_CHECK_SOCKLEN_T, [AC_CACHE_CHECK([for socklen_t in sys/socket.h], ac_cv_socklen_t, AC_TRY_COMPILE([#include <sys/socket.h>],[sizeof(socklen_t);], ac_cv_socklen_t="yes", ac_cv_socklen_t="no")) test "$ac_cv_socklen_t" != "yes" && AC_DEFINE(socklen_t, int)]) AC_DEFUN(AC_CHECK_TZSET, [AC_CACHE_CHECK([for tzset], ac_cv_tzset, AC_TRY_COMPILE([#include <time.h>],[tzet();], ac_cv_tzset="yes", ac_cv_tzset="no")) test "$ac_cv_tzset" != "no" && AC_DEFINE(HAVE_TZSET)]) AC_DEFUN(AC_CHECK_GMTOFF, [AC_CACHE_CHECK([for gmtoff in struct tm], ac_cv_tm_gmtoff, AC_TRY_COMPILE([#include <time.h>],[struct tm tm; tm.tm_gmtoff;], ac_cv_tm_gmtoff="yes", ac_cv_tm_gmtoff="no")) test "$ac_cv_tm_gmtoff" != "no" && AC_DEFINE(HAVE_TM_GMTOFF)]) AC_DEFUN(AC_CHECK_TIMEZONE, [AC_CACHE_CHECK([for timezone and daylight variables], ac_cv_timezone, AC_TRY_COMPILE([extern long timezone; extern int daylight;],[timezone;daylight;], ac_cv_timezone="yes", ac_cv_timezone="no")) test "$ac_cv_timezone" != "no" && AC_DEFINE(HAVE_TIMEZONE)]) AC_DEFUN(AC_CHECK_GETHOSTNAME, [AC_CACHE_CHECK([for gethostname in unistd.h], ac_cv_gethostname_p, AC_TRY_COMPILE([#include <unistd.h>],[return (int)gethostname;], ac_cv_gethostname_p="yes", ac_cv_gethostname_p="no")) test "$ac_cv_gethostname_p" = "no" && AC_DEFINE(NEED_GETHOSTNAME_P)]) if test -x /bin/test; then test=/bin/test else if test -x /usr/bin/test; then test=/usr/bin/test else test=test fi fi AC_DEFUN(AC_HAVE_NAS,[AC_MSG_CHECKING([for Network Audio System]) AC_TRY_COMPILE([#include <audio/audio.h>],[AuElementNotifyKindLowWater;], ac_cv_nas="yes", ac_cv_nas="no") AC_MSG_RESULT($ac_cv_nas)]) AC_DEFUN(AC_HAVE_OSS,[AC_MSG_CHECKING([for Open Sound System]) AC_TRY_COMPILE([#include <sys/soundcard.h>],[OPEN_SOUND_SYSTEM;], ac_cv_oss="yes", ac_cv_oss="no") AC_MSG_RESULT($ac_cv_oss)]) AC_DEFUN(AC_HAVE_SUN,[AC_MSG_CHECKING([for SunOS/Solaris audio]) AC_TRY_COMPILE([#include <sys/audioio.h>],[AUDIO_SUNVTS;], ac_cv_sun="yes" AC_DEFINE_UNQUOTED(HAVE_SYS_AUDIOIO_H,1), AC_TRY_COMPILE([#include <sun/audioio.h>],[AUDIO_SUNVTS;], ac_cv_sun="yes" AC_DEFINE_UNQUOTED(HAVE_SUN_AUDIOIO_H,1), ac_cv_sun="no")) AC_MSG_RESULT($ac_cv_sun)]) AC_DEFUN(AC_CHECK_SOUND,[ use_audio="" AC_MSG_CHECKING([for audio support]) AC_MSG_RESULT($with_audio) if test "$with_audio" = "auto" -o "$with_audio" = "oss"; then AC_HAVE_OSS if test "$ac_cv_oss" = "yes"; then use_audio=oss; with_audio=oss; fi fi if test "$with_audio" = "auto" -o "$with_audio" = "sun"; then AC_HAVE_SUN if test "$ac_cv_sun" = "yes"; then use_audio=sun; with_audio=sun; fi fi if test "$with_audio" = "auto" -o "$with_audio" = "nas"; then AC_HAVE_NAS if test "$ac_cv_nas" = "yes"; then use_audio=nas; with_audio=nas; fi fi if test "$with_audio" = "none"; then use_audio=none; fi if test "$use_audio" = ""; then AC_MSG_RESULT([******** AUDIO DISABLED (no support found for: $with_audio)]) use_audio=none fi case $use_audio in nas) AC_DEFINE(USE_AUDIO_NAS,1) LIBS="$LIBS -laudio -lXt" ;; oss) AC_DEFINE(USE_AUDIO_OSS,1) ;; sun) AC_DEFINE(USE_AUDIO_SUN,1) AC_HAVE_HEADERS(sys/audioio.h) ;; none) AC_DEFINE(USE_AUDIO_NONE,1) ;; *) echo; echo "this cannot happen"; echo; exit 1 ;; esac ]) AC_DEFUN(AC_C_BYTEORDER, [AC_C_BIGENDIAN if test $ac_cv_c_bigendian != yes then CFLAGS="$CFLAGS -DLSB_FIRST=1" fi]) AC_DEFUN(AC_C_DOUBLE_ALIGNMENT, [AC_CACHE_CHECK([whether misaligned access to doubles is ok], ac_cv_double_align, AC_TRY_RUN([f(int i){*(double *)i=*(double *)(i+4);} int main(){char b[[12]];f(b);return 0;}], ac_cv_double_align="yes", ac_cv_double_align="no")) test "$ac_cv_double_align" = "no" && AC_DEFINE(DOUBLE_WORD_ALIGNMENT)]) AC_DEFUN(AC_C_DOUBLE_ORDER, [AC_CACHE_CHECK([whether doubles are stored in Squeak order], ac_cv_double_order, AC_TRY_RUN([main(){ double d= 1.0; return *(int *)&d == 0;}], ac_cv_double_order="yes", ac_cv_double_order="no")) test "$ac_cv_double_order" = "no" && AC_DEFINE(DOUBLE_WORD_ORDER)]) # this assumes that libtool has already been configured and built -- # if not then err on the side of conservatism. AC_DEFUN(AC_MODULE_LIB_PREFIX, [AC_CACHE_CHECK([for prefix to use for loadable modules], ac_cv_module_prefix, if test -x ./libtool && test "`./libtool --config | fgrep need_lib_prefix`" = "need_lib_prefix=no" then ac_cv_module_prefix="(none)"; else ac_cv_module_prefix="lib" fi) AC_DEFINE_UNQUOTED(VM_MODULE_PREFIX,"$mkfrags_lib_prefix") test "$ac_cv_module_prefix" = lib && mkfrags_lib_prefix=lib]) AC_DEFUN(AC_64BIT_ARCH, [AC_MSG_CHECKING(for compiler flags to force 32-bit addresses) case $host in alpha*) CFLAGS_32="-taso" test "$GCC" = "yes" && CC="\$(utldir)/decgcc" ;; esac AC_MSG_RESULT($CFLAGS_32)]) ### plugin support # AC_PLUGIN_SUBST(varname,value) AC_DEFUN(AC_PLUGIN_DISABLE_PLUGIN,[ AC_MSG_RESULT([******** disabling $1]) disabled_plugins="${disabled_plugins} $1"]) AC_DEFUN(AC_PLUGIN_DISABLE,[ AC_PLUGIN_DISABLE_PLUGIN(${plugin})]) AC_DEFUN(AC_PLUGIN_USE_LIB,[ plibs="${plibs} $1"]) AC_DEFUN(AC_PLUGIN_DEFINE_UNQUOTED,[ echo 's%[\['$1'\]]%'$2'%g' >> ${plugin}.sub]) # AC_PLUGIN_SEARCH_LIBS(function,libs...) AC_DEFUN(AC_PLUGIN_SEARCH_LIBS,[ AC_SEARCH_LIBS($1,$2,, AC_MSG_RESULT([******** disabling ${plugin} due to missing libraries]) disabled_plugins="${disabled_plugins} ${plugin}")]) # AC_PLUGIN_CHECK_LIB(lib,func,ok,bad) AC_DEFUN(AC_PLUGIN_CHECK_LIB,[ AC_CHECK_LIB($1,$2, plibs="${plibs} $1", AC_MSG_RESULT([******** disabling ${plugin} due to missing libraries]) disabled_plugins="${disabled_plugins} ${plugin}")]) --- NEW FILE: aclocal.m4 --- # aclocal.m4 generated automatically by aclocal 1.6.1 -*- Autoconf -*- # Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 # Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. # Local autoconf macros for configuring Unix Squeak -*- sh -*- # # Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors # as listed elsewhere in this file. # All rights reserved. # [...3817 lines suppressed...] INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) else ac_configure_args="$ac_configure_args --enable-ltdl-install=no" LIBLTDL="-lltdl" INCLTDL= fi ]) # old names AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) # This is just to silence aclocal about the macro not being used ifelse([AC_DISABLE_FAST_INSTALL]) --- NEW FILE: build --- #!/bin/bash # This script is really intended for "batch-mode" nightly builds of # Squeak binary distributions. It is therefore intended mainly for # the VM maintainer (who runs it from cron) rather than VM hackers in # general (who would probably prefer to run it from the command line). # Nevertheless it does attempt to be interactive (and even makes some # concessions towards user-friendliness ;) for those who cannot be # bothered to type `mkdir bld; cd bld; ../.../configure; make') -- but # your kilometrage may vary (enormously). # # Run `build -h' for a list of options (without much explanation). # Last edited: 2002-06-07 06:12:13 by piumarta on emilia.inria.fr UTS_SYS=`(uname -s) 2>/dev/null` if [ -x /usr/5bin/echo ]; then # SunOS SysV echo echo=/usr/5bin/echo elif [ -z "`(echo -e a) 2>/dev/null | fgrep e`" ]; then # GNU bash, etc. echo="echo -e" else # generic SysV echo=echo fi if [ "${UTS_SYS}" = QNX ]; then echo=echo fi ouch () { $echo $echo 'Ouch! That hurts!!' exit 1 } trap ouch 2 srcdir="" blddir="" batch="" doConfig=yes doMake=tes getYN() { if [ "${batch}" ]; then YN="y" else YN="" while [ ! "${YN}" ]; do read YN case ${YN} in y|Y|n|N) ;; *) $echo "Did you mean Y or N ? \c" >&2; YN="" ;; esac done fi $echo ${YN} } getN () { N=0 while [ ${N} -eq 0 ]; do read n let n="${n}" if [ "${n}" -a \( ${n} -gt 0 \) -a \( ${n} -le ${1} \) ]; then N=${n} else $echo "Please answer a number in the range [1-${1}]: \c" fi done $echo ${N} } usage () { $echo "usage: ${0} [-c] [-h] [-m] [-y] [-s srcdir] [-b blddir]" >&2 } help () { usage cat >&2 <<\EOF -b dir build in `dir' -c run `configure' only (don't make) -h show this help message -m run `make' only (don't configure) -s dir VMMaker sources are in `dir' -y assume `y' to all questions and work silently (`batch' mode) EOF exit 0 } notFound () { $echo "VMMaker src directory not found" >&2 exit 1 } while [ $# -gt 0 ]; do case $1 in -b) shift; blddir="${1}"; shift;; -c) shift; doMake="";; -h) help;; -m) shift; doConfig="";; -s) shift; srcdir="${1}"; shift;; -y) shift; batch=yes;; *) usage; exit 1;; esac done [ $# -gt 0 ] && usage && exit 1 if [ "${srcdir}" ]; then srcdirs="${srcdir}" else srcdirs=`$echo src*` fi [ ! "${srcdirs}" ] && notFound count=0; for d in ${srcdirs}; do [ -d ${d} ] && let count="${count}+1" done chooseDir () { $echo "We found the following source directories:" i=0 for d in ${srcdirs}; do let i="${i}+1" list="${list} [${i}] ${d} " done $echo $echo "${list}" if [ "${batch}" ]; then $echo "batch mode failed!" >&2 exit 1 fi $echo "Which would you like to use [1-${i}]? \c" n=`getN ${count}` srcdir=`$echo "${list}" | fgrep "[$n]" | sed "s,^\[.*\] ,,"` [ "${srcdir}" ] || notFound } case ${count} in 0) notFound ;; 1) srcdir=${srcdirs} ;; *) chooseDir ;; esac $echo "Using source directory: ${srcdir}" if [ ! "${blddir}" ]; then vers=`$echo ${srcdir} | sed 's,^src,,'` mach=`uname -m | sed 's,i.86,i386,;s,sun4.,sparc,'` blddir="bld${vers}-${mach}" fi $echo "Using build directory: ${blddir}" if [ ! "${batch}" ]; then $echo "Is this okay [y/n]? \c" case `getYN` in y|Y) ;; n|N) $echo "Goodybye" >&2; exit 1 ;; *) $echo "Huh?" >&2; exit 1 ;; esac fi [ -d ${blddir} ] || mkdir ${blddir} cd ${blddir} if [ "${doConfig}" ]; then $echo $echo '-------------------------------------------------------------------------------' $echo "Configuring in ${PWD}" $echo '-------------------------------------------------------------------------------' $echo ../platforms/unix/config/configure --with-src=${srcdir} || exit 1 fi if [ "${doMake}" ]; then $echo $echo '-------------------------------------------------------------------------------' $echo "Building in ${PWD}" $echo '-------------------------------------------------------------------------------' $echo make || exit 1 fi $echo $echo '-------------------------------------------------------------------------------' if [ ! -x squeak ]; then $echo "The build appears to have failed. We can't really continue." >&2 $echo "Goodbye." >&2 exit 1 fi $echo "The build appears to have succeeded." [ "${batch}" ] && exit 0 if [ "`whoami`" != "root" ]; then $echo "We cannot install Squeak because you are not root" >&2 exit 0 fi $echo "Would you like me to install Squeak in the default location [y/n]? \c" case `getYN` in y|Y) ;; n|N) $echo "Less work for us that way."; exit 0 ;; *) $echo "Huh?"; exit 1 ;; esac $echo make install $echo $echo "We're done. Happy Squeaking!" --- NEW FILE: config.guess --- #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002 Free Software Foundation, Inc. timestamp='2002-10-21' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software [...1324 lines suppressed...] /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: --- NEW FILE: config.h.in --- /* config.h.in -- template for config.h -*- C -*- * * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors * as listed elsewhere in this file. * All rights reserved. * * This file is part of Unix Squeak. * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You may use and/or distribute this file ONLY as part of Squeak, under * the terms of the Squeak License as described in `LICENSE' in the base of * this distribution, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment to the original author(s) (and any * other contributors mentioned herein) in the product documentation * would be appreciated but is not required. * * 2. This notice must not be removed or altered in any source distribution. * * Using (or modifying this file for use) in any context other than Squeak * changes these copyright conditions. Read the file `COPYING' in the * directory `platforms/unix/doc' before proceeding with any such use. * * You are not allowed to distribute a modified version of this file * under its original name without explicit permission to do so. If * you change it, rename it. */ /* Author: Ian...@IN... * * Last edited: 2002-11-30 16:00:59 by piumarta on calvin.inria.fr */ /* package options */ #undef USE_X11 #undef USE_RFB /* libraries */ #undef HAVE_LIBX11 #undef HAVE_LIBXEXT #undef HAVE_LIBDL #undef HAVE_LIBFFI #undef USE_AUDIO_NONE #undef USE_AUDIO_SUN #undef USE_AUDIO_NAS #undef USE_AUDIO_OSS #undef OSS_DEVICE /* header files */ #undef HAVE_UNISTD_H #undef NEED_GETHOSTNAME_P #undef HAVE_DIRENT_H #undef HAVE_SYS_NDIR_H #undef HAVE_SYS_DIR_H #undef HAVE_NDIR_H #undef HAVE_DLFCN_H #undef HAVE_SYS_TIME_H #undef TIME_WITH_SYS_TIME #undef HAVE_SYS_FILIO_H #undef HAVE_SYS_AUDIOIO_H #undef HAVE_SUN_AUDIOIO_H #undef HAVE_PTY_H #undef HAVE_UTIL_H #undef HAVE_STROPTS_H #undef NEED_SUNOS_H /* system calls/library functions */ #undef AT_EXIT #undef HAVE_TZSET #undef HAVE_OPENPTY #undef HAVE_UNIX98_PTYS #undef HAVE_SNPRINTF #undef HAVE___SNPRINTF #undef HAVE_DYLD /* structures */ #undef HAVE_TM_GMTOFF #undef HAVE_TIMEZONE /* typedefs */ #undef size_t #undef socklen_t #undef squeakInt64 /* architecture */ #undef OS_TYPE #undef VM_HOST #undef VM_HOST_CPU #undef VM_HOST_VENDOR #undef VM_HOST_OS #undef WORDS_BIGENDIAN #undef DOUBLE_WORD_ALIGNMENT #undef DOUBLE_WORD_ORDER /* damage containment */ #undef DARWIN #ifdef NEED_SUNOS_H # include "sunos.h" #endif /* other configured variables */ #undef SQ_VERSION #undef VM_VERSION #undef VM_LIBDIR #undef VM_MODULE_PREFIX #undef VM_DLSYM_PREFIX --- NEW FILE: config.sub --- #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002 Free Software Foundation, Inc. timestamp='2002-09-05' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the [...1431 lines suppressed...] -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: --- NEW FILE: configure --- #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by Autoconf 2.52. # # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 # Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Find the correct PATH separator. Usually this is `:', but # DJGPP uses `;' like DOS. if test "X${PATH_SEPARATOR+set}" != Xset; then UNAME=${UNAME-`uname 2>/dev/null`} case X$UNAME in *-DOS) lt_cv_sys_path_separator=';' ;; *) lt_cv_sys_path_separator=':' ;; esac PATH_SEPARATOR=$lt_cv_sys_path_separator fi [...11427 lines suppressed...] ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: exec 5>/dev/null $SHELL $CONFIG_STATUS || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi --- NEW FILE: configure.ac --- # configure.in (version 4) for Unix Squeak -*- sh -*- # # Process this file with autoconf to produce a configure script # Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors # as listed elsewhere in this file. # All rights reserved. # # This file is part of Unix Squeak. # # This file is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. # # You may use and/or distribute this file ONLY as part of Squeak, under # the terms of the Squeak License as described in `LICENSE' in the base of # this distribution, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment to the original author(s) (and any # other contributors mentioned herein) in the product documentation # would be appreciated but is not required. # # 2. This notice must not be removed or altered in any source distribution. # # Using (or modifying this file for use) in any context other than Squeak # changes these copyright conditions. Read the file `COPYING' in the # directory `platforms/unix/doc' before proceeding with any such use. # # You are not allowed to distribute a modified version of this file # under its original name without explicit permission to do so. If # you change it, rename it. # # Author: Ian...@IN... # # Last edited: 2003-03-04 06:48:40 by piumarta on emilia.inria.fr AC_INIT([config.h.in]) AC_VM_VERSION(3,4,1, 3,4,5170) topdir=`cd ${srcdir}/../../..; pwd` cfgdir=`cd ${srcdir}; pwd` AC_ARG_WITH(src, [ --with-src=dir VMMaker src directory [default=src]], [ vmmdir="${topdir}/${with_src}"], [ vmmdir="${topdir}/src"]) # Check the VMMaker src dir looks sane AC_CHECK_VMM_DIR blddir=`pwd` AC_SUBST(topdir) AC_SUBST(cfgdir) AC_SUBST(vmmdir) AC_SUBST(blddir) SQ_VERSION=${SQ_MAJOR}.${SQ_MINOR}-${SQ_UPDATE} AC_DEFINE_UNQUOTED(SQ_VERSION, "${SQ_VERSION}") AC_SUBST(SQ_MAJOR) AC_SUBST(SQ_MINOR) AC_SUBST(SQ_UPDATE) AC_SUBST(SQ_VERSION) VM_VERSION=${VM_MAJOR}.${VM_MINOR}-${VM_RELEASE} AC_DEFINE_UNQUOTED(VM_VERSION, "${VM_VERSION}") AC_SUBST(VM_MAJOR) AC_SUBST(VM_MINOR) AC_SUBST(VM_RELEASE) AC_SUBST(VM_VERSION) # libdir contains ${exec_prefix}, so we have to default and expand early test "x$prefix" = xNONE && prefix=$ac_default_prefix test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' imgdir=`eval echo ${libdir}/squeak` plgdir=`eval echo ${imgdir}/${VM_VERSION}` AC_SUBST(imgdir) AC_SUBST(plgdir) AC_DEFINE(OS_TYPE, "unix") AC_CANONICAL_HOST host_cpu=`echo $host | sed 's,-.*,,'` host=`echo $host | sed 's,-unknown,,'` AC_SUBST(host) AC_SUBST(host_cpu) AC_SUBST(host_vendor) AC_SUBST(host_os) AC_DEFINE_UNQUOTED(VM_HOST, "$host") AC_DEFINE_UNQUOTED(VM_HOST_OS, "$host_os") AC_DEFINE_UNQUOTED(VM_HOST_CPU, "$host_cpu") echo echo "Configuring Squeak ${VM_VERSION} (${SQ_VERSION}) for ${host}" echo # Checks for programs. AC_ARG_WITH(gnu-awk, [ --with-gnu-awk assume that awk is GNU gawk [default=no]], [GAWK="$withval"], [case $host_os in darwin*) GAWK="yes";; *) GAWK="unknown";; esac]) AC_ARG_WITH(gnu-as, [ --with-gnu-as assume that as is the GNU assembler [default=no]], [GAS="$withval"], [GAS="unknown"]) AC_PROG_MAKE_SET AC_PROG_CC_WALL AC_PROG_AS_GNU AC_PROG_RANLIB AC_PROG_INSTALL AC_PROG_NM AC_CHECK_PROG(LN, ln, ln) # Check size assumptions of basic data types AC_REQUIRE_SIZEOF(int, 4) AC_REQUIRE_SIZEOF(time_t, 4) AC_REQUIRE_SIZEOF(double, 8) AC_CHECK_INT64_T # libtool configuration AC_DISABLE_STATIC AC_PROG_LIBTOOL # Configured headers (pretty much everybody needs blddir and vm) INCLUDES="-I${blddir} -I${topdir}/platforms/unix/vm -I${topdir}/platforms/Cross/vm" AC_SUBST(INCLUDES) # Checks for X11 AC_ARG_WITH(x, [ --without-x disable X Window System support [default=enabled]], [ if test "$withval" = "no"; then have_x="no"; else have_x="yes"; fi ], [ have_x="yes"] ) if test "$have_x" = "yes"; then AC_DEFINE(USE_X11,[1]) NOX="" AC_PATH_XTRA LIBS="$X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS $LIBS" CFLAGS="$X_CFLAGS $CFLAGS" if test "$x_includes" != ""; then INCLUDES="${INCLUDES} -I${x_includes}" fi else NOX="-nox" CFLAGS="$CFLAGS -DHEADLESS" with_npsqueak=no fi AC_SUBST(NOX) # Checks for header files. AC_NEED_SUNOS_H AC_STDC_HEADERS AC_HAVE_HEADERS(unistd.h string.h fcntl.h sys/file.h sys/param.h) AC_HAVE_HEADERS(sys/time.h sys/filio.h sys/select.h) AC_HEADER_TIME AC_HEADER_DIRENT AC_STRUCT_TIMEZONE AC_CHECK_SOCKLEN_T AC_CHECK_ATEXIT AC_CHECK_TZSET AC_CHECK_GMTOFF AC_CHECK_TIMEZONE AC_CHECK_GETHOSTNAME # Display options. AC_ARG_WITH(rfb, [ --without-rfb disable Remote FrameBuffer support [default=enabled]], [[have_rfb=no]], [[have_rfb=yes]]) test $have_rfb = "yes" && AC_DEFINE(USE_RFB,[1]) # Checks for libraries. AC_CHECK_LIB(nsl, yp_bind) AC_CHECK_LIB(socket, socket) AC_HAVE_HEADERS(dlfcn.h) AC_CHECK_FUNC(dlopen, [AC_DEFINE(HAVE_LIBDL,[1])], [AC_CHECK_LIB(dl, dlopen, [LIBS="-ldl $LIBS" AC_DEFINE(HAVE_LIBDL,[1])], [AC_CHECK_FUNC(_dyld_present,[AC_DEFINE(HAVE_DYLD,[1])])])]) AC_CHECK_LIB(m, sin) if test "$have_x" = "yes"; then AC_CHECK_LIB(X11, XOpenDisplay) AC_CHECK_LIB(Xext, XShmAttach) fi AC_CHECK_FUNCS(snprintf __snprintf,[break]) #AC_ARG_ENABLE(jit, #[ --enable-jit enable J4 support [default=no]], #JIT="yes", JIT="no") # #test $JIT = "yes" && J_CFLAGS="-DJ_ENABLED" #AC_SUBST(J_CFLAGS) # Checks for sound support. AC_ARG_WITH(audio, [ --with-audio=choice choose audio device [default=auto] available devices: auto none oss sun nas], [[]], [[with_audio=auto]]) AC_CHECK_SOUND # Checks for platform characteristics. AC_GNU_OPT AC_GNU_INTERP AC_MODULE_LIB_PREFIX AC_64BIT_ARCH CFLAGS="$CFLAGS_32 $CFLAGS" AC_C_BYTEORDER AC_C_DOUBLE_ALIGNMENT AC_C_DOUBLE_ORDER case $host_os in darwin*) AC_DEFINE(DARWIN,[1]) CFLAGS="-no-cpp-precomp $CFLAGS" with_npsqueak=no ;; *) ;; esac # Checks for browser support AC_SUBST(npsqueak) AC_SUBST(install_nps) AC_SUBST(uninstall_nps) AC_ARG_WITH(npsqueak, [ --without-npsqueak disable browser plugin support [default=enabled]], [[with_npsqueak=no]], [[with_npsqueak=yes]]) if test "$with_npsqueak" = "no"; then npsqueak="" install_nps="" uninstall_nps="" else npsqueak=npsqueak install_nps=install-npsqueak uninstall_nps=uninstall-npsqueak fi # Install locations if test "x${prefix}" = xNONE; then SQ_LIBDIR=${ac_default_prefix}/lib/squeak/${SQ_VERSION} else SQ_LIBDIR=${prefix}/lib/squeak/${SQ_VERSION} fi AC_SUBST(SQ_LIBDIR) AC_DEFINE_UNQUOTED(SQ_LIBDIR,["${SQ_LIBDIR}"]) AC_DEFINE_UNQUOTED(VM_LIBDIR,["${plgdir}"]) # Configure files make_cfg=${blddir}/make.cfg make_int=${blddir}/make.int make_ext=${blddir}/make.ext make_prg=${blddir}/make.prg AC_SUBST_FILE(make_cfg) AC_SUBST_FILE(make_int) AC_SUBST_FILE(make_ext) AC_SUBST_FILE(make_prg) Makefile_install=${cfgdir}/Makefile.install Makefile_dist=${topdir}/util/Makefile.dist Makefile_rpm=${topdir}/util/Makefile.rpm Makefile_deb=${topdir}/util/Makefile.deb AC_SUBST_FILE(Makefile_install) AC_SUBST_FILE(Makefile_dist) AC_SUBST_FILE(Makefile_rpm) AC_SUBST_FILE(Makefile_deb) # Configure plugins disabled_plugins="" rm -f plugins.exc sinclude(acplugins.m4) if test "$have_x" = "no"; then AC_PLUGIN_DISABLE_PLUGIN(UnixOSProcessPlugin) fi if test "${disabled_plugins}" != ""; then echo ${disabled_plugins} | tr ' ' '\012' > plugins.exc fi # for some reason configure leaves an empty a.out lying around test -f a.out && rm a.out # Create the build environment AC_CONFIG_HEADER(config.h) AC_CONFIG_FILES(mkconfig make.cfg make.int make.ext make.prg inisqueak Makefile) AC_CONFIG_COMMANDS([default],[ chmod +x mkconfig inisqueak ${SHELL} -ec "./mkconfig; ${cfgdir}/mktargets; ${cfgdir}/mkmf"],[ cfgdir=${cfgdir} ]) AC_OUTPUT --- NEW FILE: gnuify --- #!/usr/bin/gawk -f # # Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors # as listed elsewhere in this file. # All rights reserved. # # This file is part of Unix Squeak. # # This file is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. # # You may use and/or distribute this file ONLY as part of Squeak, under # the terms of the Squeak License as described in `LICENSE' in the base of # this distribution, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment to the original author(s) (and any # other contributors mentioned herein) in the product documentation # would be appreciated but is not required. # # 2. This notice must not be removed or altered in any source distribution. # # Using (or modifying this file for use) in any context other than Squeak # changes these copyright conditions. Read the file `COPYING' in the # directory `platforms/unix/doc' before proceeding with any such use. # # You are not allowed to distribute a modified version of this file # under its original name without explicit permission to do so. If # you change it, rename it. # Author: Ian...@IN... # # Last edited: 2002-09-07 03:28:53 by piumarta on emilia.inria.fr # Rewrite the interpreter source in $1 to use GNU C extensions, writing the # modified file to stdout. Author: Ian...@in... BEGIN { print "/* This file has been post-processed for GNU C */\n\ \n\ "; print "copying first section of file" > "/dev/stderr"; stage= 0; } /#include "sq.h"/ { print "#include \"sqGnu.h\"\n"; next; } # An inlining comment means the interpreter was not inlined /inline\: true/ { print NR, $0 > "/dev/stderr"; print "" > "/dev/stderr"; print "*** interpreter was not inlined: bailing out! ***" > "/dev/stderr"; print "" > "/dev/stderr"; exit 1; } (stage == 0) && /^int interpret\(void\) \{/ { print "interpret: adding static register assignments" > "/dev/stderr"; stage= 1; print; next; } (stage == 1) && /^ char\* localIP;/ { print " register char* localIP IP_REG;"; next; } (stage == 1) && /^ char\* localSP;/ { print " register char* localSP SP_REG;"; next; } (stage == 1) && /^ int currentBytecode;/ { print " register int currentBytecode CB_REG;"; next; } (stage == 1) && /^$/ { print "interpret: adding bytecode dispatch table" > "/dev/stderr"; print " JUMP_TABLE;\n"; print " register void **jumpTablePtr JP_REG= jumpTable;"; print "interpret: rewriting case labels and outer breaks" > "/dev/stderr"; stage= 2; FS="[ :]+"; next; } (stage == 2) && /^ case / { print " CASE(" $3 ")"; next; } (stage == 2) && /^ break;/ { print " BREAK;"; next; } (stage == 2) && /^\}/ { stage= 3; print; next; } (stage == 3) && /^int primitiveResponse\(/ { print; print "primitiveResponse: adding primitive dispatch table" > "/dev/stderr"; print " PRIM_TABLE;\n"; print "primitiveResponse: rewriting case labels" > "/dev/stderr"; stage= 4; FS="[ :]+"; next; } (stage == 4) && /^ switch \(primitiveIndex\) {/ { print "primitiveResponse: adding primitive dispatch" > "/dev/stderr"; print " PRIM_DISPATCH;"; print; next; } (stage == 4) && /^ case / { print " CASE(" $3 ")"; next; } (stage == 4) && /^\}/ { print "copying last section of file" > "/dev/stderr"; stage= 5; FS=" "; print; next; } # default { print; next; } --- NEW FILE: inisqueak.in --- #!/bin/sh # # inisqueak -- setup a directory for use with Squeak # # Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors # as listed elsewhere in this file. # All rights reserved. # # This file is part of Unix Squeak. # # This file is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. # # You may use and/or distribute this file ONLY as part of Squeak, under # the terms of the Squeak License as described in `LICENSE' in the base of # this distribution, subject to the following restrictions: # # 1. The origin of this software must not be misrepresented; you must not # claim that you wrote the original software. If you use this software # in a product, an acknowledgment to the original author(s) (and any # other contributors mentioned herein) in the product documentation # would be appreciated but is not required. # # 2. This notice must not be removed or altered in any source distribution. # # Using (or modifying this file for use) in any context other than Squeak # changes these copyright conditions. Read the file `COPYING' in the # directory `platforms/unix/doc' before proceeding with any such use. # # You are not allowed to distribute a modified version of this file # under its original name without explicit permission to do so. If # you change it, rename it. # # Author: Ian...@IN... # # Last edited: 2002-09-29 05:14:34 by piumarta on emilia.inria.fr MAJOR=@SQ_MAJOR@ VERSION=@SQ_VERSION@ prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ imgdir=@imgdir@ plgdir=@plgdir@ if test ! -w .; then echo "You don't have write permission in this directory." >&2 exit 1 fi # Sun's /bin/sh does not understand "test -e", but [/usr]/bin/test does test="`which test`" list=false startup=true batch=false while true; do case "$1" in -l) list=true; shift;; -n) startup=false; shift;; -b) batch=true; shift;; -h|-help|--help) echo "`basename $0` [-option...] [rootdir]" echo ' -b batch (avoid interaction, exit status reflects success)' echo ' -h you already know about' echo ' -help same as -h' echo ' -l always present a list of alternative images (overrides -b)' echo ' -n do not run Squeak after installing the files' echo ' --help same as -help' exit 0;; *) break;; esac done if test "$1" != ""; then bindir=${1}/${bindir} imgdir=${1}/${imgdir} plgdir=${1}/${plgdir} fi SQUEAK=${bindir}/squeak SOURCES=SqueakV${MAJOR}.sources IMAGE=squeak.image.gz CHANGES=squeak.changes.gz # local install function missing() { echo "The file ${1} is missing." >&2 echo "Please check your Squeak installation." >&2 exit 1 } install() { cpy="${1}" src="${2}" red="${3}" dst="${4}" if ${test} ! -e ${dst}; then if ${test} -e ${src}; then echo "+ ${cpy} ${src} ${red} ${dst}" eval ${cpy} ${src} ${red} ${dst} else missing "${src}" fi else echo "${dst} is already present -- leaving it alone" startup=false fi } # choose an image to install if ${list}; then :; else if ${test} \( ! -e ${imgdir}/${IMAGE} \) \ -o \( ! -e ${imgdir}/${CHANGES} \) ; then if ${batch}; then echo "Could not find default image to install -- giving up." >&2 exit 1; fi list=true echo "No default image, looking for alternatives..." echo fi fi if ${list}; then images=`ls -1 ${imgdir}/*.image.gz 2>/dev/null | \ sed "s.${imgdir}/..;s/.image.gz//"` if test "$images" = ""; then echo "I could not find an image to install." >&2 echo "Please check your Squeak installation." >&2 exit 1 fi nimg=`echo ${images} | tr ' ' '\012' | wc -l` nimg=`echo ${nimg}` more=true while ${more}; do echo "I found the following images:" echo ${images} | tr ' ' '\012' | cat -n if echo ${images} | fgrep "Squeak${VERSION}" >/dev/null; then echo "(of which I might recommend Squeak${VERSION}, unless you know better)." fi echo -n "Which one should I install [1-${nimg}]? " read reply case ${reply} in [1-9]) ;; [1-9][0-9]) ;; *) echo echo "Let's try that again, with a NUMBER between 1 and ${nimg}." echo continue;; esac if test \( ${reply} -ge 1 \) -a \( ${reply} -le ${nimg} \); then more=false fi if ${more}; then echo echo "Ha ha, very clever. Now give me a number between 1 and ${nimg}" echo "(or hit your interrupt key [^C or whatever] if you don't like" echo "the look of any of them)." echo fi done IMAGE=`echo ${images} | tr ' ' '\012' | tail +${reply} | head -1` CHANGES=${IMAGE}.changes.gz IMAGE=${IMAGE}.image.gz fi echo "Installing ${IMAGE} in `pwd`" install "ln -s" "${imgdir}/${SOURCES}" " " "${SOURCES}" install "gunzip -dc" "${imgdir}/${IMAGE}" ">" "squeak.image" install "gunzip -dc" "${imgdir}/${CHANGES}" ">" "squeak.changes" if ${startup}; then if test ! -x ${SQUEAK}; then missing "${SQUEAK}" fi echo "Running ${SQUEAK}" exec ${SQUEAK} fi --- NEW FILE: install-sh --- #!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" # CYGNUS LOCAL: exeext variable exeext="" # END CYGNUS LOCAL while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; # CYGNUS LOCAL: -x option -x=*) exeext=`echo $1 | sed 's/-x=//'` shift continue;; -x) exeext=".exe" shift continue;; # END CYGNUS LOCAL *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # CYGNUS LOCAL noer # Win32-based gcc automatically appends .exe to produced executables, # whether asked for or not. This breaks installs. The following # changes the value of $src to $src.exe if $src is missing if [ -f $src ] then true elif [ -f $src.exe ] then echo "install: $src does not exist, trying with .exe appended" src="$src".exe fi # end CYGNUS LOCAL noer # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi # CYGNUS LOCAL: Use exeext case "`basename $dst`" in *.*) ;; *) dst="$dst$exeext" ;; esac # END CYGNUS LOCAL fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 --- NEW FILE: ltcf-c.sh --- #### This script is meant to be sourced by ltconfig. # ltcf-c.sh - Create a C compiler specific configuration # # Copyright (C) 1996-2000, 2001 Free Software Foundation, Inc. # Originally by Gordon Matzigkeit <go...@gn...>, 1996 # # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o # Code to be used in simple compile tests lt_simple_compile_test_code="int some_var... [truncated message content] |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:27
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/B3DAcceleratorPlugin
In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/B3DAcceleratorPlugin
Added Files:
acinclude.m4
Log Message:
Ian Piumarta's release 3.4.1
--- NEW FILE: acinclude.m4 ---
# Require OpenGL
# (Note: some broken distribs [mandrake] require explicit -lpthread)
AC_CHECK_LIB(GL,glIsEnabled,
[AC_PLUGIN_USE_LIB(GL)],
[unset ac_cv_lib_GL_glIsEnabled # stupid moronic pathetic autoconf
AC_CHECK_LIB(GL,glIsEnabled,
[AC_PLUGIN_USE_LIB(GL)],
[unset ac_cv_lib_GL_glIsEnabled # stupid moronic pathetic autoconf
AC_CHECK_LIB(GL,glIsEnabled,
[AC_PLUGIN_USE_LIB(GL)
AC_PLUGIN_USE_LIB(pthread)],
[AC_PLUGIN_DISABLE],
[-lpthread])])])
|
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:27
|
Update of /cvsroot/squeak/squeak/platforms/unix/plugins/AsynchFilePlugin In directory sc8-pr-cvs1:/tmp/cvs-serv30143/plugins/AsynchFilePlugin Added Files: sqUnixAsynchFile.c sqUnixAsynchFile.h Log Message: Ian Piumarta's release 3.4.1 --- NEW FILE: sqUnixAsynchFile.c --- /* sqUnixAsynchFile.c -- non-blocking file i/o * * Copyright (C) 1996-2002 Ian Piumarta and other authors/contributors * as listed elsewhere in this file. * All rights reserved. * * This file is part of Unix Squeak. * * This file is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You may use and/or distribute this file ONLY as part of Squeak, under * the terms of the Squeak License as described in `LICENSE' in the base of * this distribution, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment to the original author(s) (and any * other contributors mentioned herein) in the product documentation * would be appreciated but is not required. * * 2. This notice must not be removed or altered in any source distribution. * * Using (or modifying this file for use) in any context other than Squeak * changes these copyright conditions. Read the file `COPYING' in the * directory `platforms/unix/doc' before proceeding with any such use. * * You are not allowed to distribute a modified version of this file * under its original name without explicit permission to do so. If * you change it, rename it. * * Author: Ian...@IN... * * Last edited: 2002-07-12 10:36:51 by piumarta on emilia.inria.fr */ /* Experimental support for asynchronous file reading and writing. When a read or write operation is initiated, control is returned to Squeak immediately. A semaphore is signaled when the operation completes, at which time the client can find out how many bytes were actually read or written and copy the results of the read operation from the file buffer into a Squeak buffer. Only one operation may be in progress on a given file at a given time, but operations on different files may be done in parallel. The semaphore is signalled once for each transfer operation that is successfully started, even if that operation later fails. Write operations always write their entire buffer if they succeed, but read operations may transfer less than their buffer size if they are started less than a buffer's size from the end of the file. The state of a file is kept in the following structure, which is stored directly in a Squeak ByteArray object: typedef struct { int sessionID; void *state; // private to the implementation } AsyncFile; The session ID is used to detect stale files--files that were open when the image was saved. The state pointer of such files is meaningless. Async file handles use the same session ID as ordinary file handles. Note: These primitives are experimental! They need not be implemented on every platform, and they may be withdrawn or replaced in a future release. */ #include "sq.h" #include "AsynchFilePlugin.h" #include "sqUnixAsynchFile.h" /*** module initialisation ***/ #include "sqVirtualMachine.h" #include "aio.h" #include <sys/types.h> #include <unistd.h> #include <time.h> int sqUnixAsyncFileSessionID= 0; static struct VirtualMachine *vm= 0; static fd_set fds; static int nfd= 0; #define isValid(f) (f->sessionID == sqUnixAsyncFileSessionID) #define validate(f) if ((!isValid(f)) || (!(f->state))) return vm->primitiveFail() int asyncFileInit(void) { vm= sqGetInterpreterProxy(); sqUnixAsyncFileSessionID= clock() + time(0); FD_ZERO(&fds); nfd= 0; return 1; } int asyncFileShutdown(void) { /* protect against calling stale aio handlers */ int i; for (i= 0; i < nfd; ++i) if (FD_ISSET(i, &fds)) aioDisable(i); nfd= 0; FD_ZERO(&fds); sqUnixAsyncFileSessionID= 0; return 1; } /*** module ***/ #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <errno.h> #ifdef __GNUC__ # define INLINE inline #else # define INLINE #endif #define min(a,b) ((a) < (b) ? (a) : (b)) #define max(a,b) ((a) > (b) ? (a) : (b)) static void readHandler(int fd, void *data, int flags); static void writeHandler(int fd, void *data, int flags); INLINE static FilePtr newFileRec(int fd, int sema) { FilePtr fp= (FilePtr)calloc(1, sizeof(FileRec)); if (fp) { fp->fd= fd; fp->sema= sema; fp->rd.status= Busy; /* read not ready */ fp->wr.status= Busy; /* write not complete */ } return fp; } INLINE static allocateBuffer(struct FileBuf *buf, int size) { if (buf->capacity >= size) return 1; if (buf->capacity > 0) { free(buf->bytes); buf->capacity= 0; } buf->bytes= (char *)malloc(size); if (!buf->bytes) { fprintf(stderr, "out of memory\n"); return 0; } buf->capacity= size; return 1; } FilePtr asyncFileAttach(AsyncFile *f, int fd, int semaIndex) { FilePtr fp= newFileRec(fd, semaIndex); if (fp) { f->sessionID= sqUnixAsyncFileSessionID; f->state= (void *)fp; aioEnable(fd, (void *)fp, 0); FD_SET(fd, &fds); nfd= max(nfd, fd + 1); return fp; /* success */ } fprintf(stderr, "out of memory\n"); f->sessionID= 0; f->state= 0; return 0; } /*** public functions ***/ int asyncFileOpen(AsyncFile *f, int fileNamePtr, int fileNameSize, int writeFlag, int semaIndex) { int fd= 0; char *name= alloca(fileNameSize + 1); memcpy((void *)name, (void *)fileNamePtr, fileNameSize); name[fileNameSize]= '\0'; /* if opening for wr then open for rw so that we can use these primitives to read bidirectional files (e.g., master ptys for interactive child processes) */ fd= (writeFlag ? open(name, O_RDWR | O_CREAT, 0644) : open(name, O_RDONLY)); if (fd >= 0) { if (asyncFileAttach(f, fd, semaIndex)) return 0; /* success */ close(fd); } vm->primitiveFail(); return 0; /* failure */ } int asyncFileClose(AsyncFile *f) { FilePtr fp= 0; validate(f); if ((fp= (FilePtr)f->state)) { if (fp->fd >= 0) { aioDisable(fp->fd); FD_CLR(fp->fd, &fds); close(fp->fd); } if (fp->buf.bytes) free((void *)fp->buf.bytes); free((void *)fp); f->state= 0; } return 0; /* success */ } /* this no longer appears to be used */ int asyncFileRecordSize(void) { fprintf(stderr, "asyncFileRecordSize() called -- why?\n"); vm->primitiveFail(); return 0; } int asyncFileReadResult(AsyncFile *f, int bufferPtr, int bufferSize) { FilePtr fp= 0; int n= 0; validate(f); fp= (FilePtr)f->state; n= read(fp->fd, (void *)bufferPtr, bufferSize); if ((n < 0) && (errno == EWOULDBLOCK)) return fp->rd.status= Busy; else if (n <= 0) return fp->rd.status= Error; else /* (n > 0) */ fp->rd.pos += n; return fp->rd.status= n; } static void readHandler(int fd, void *data, int flags) { signalSemaphoreWithIndex(((FilePtr)data)->sema); } int asyncFileReadStart(AsyncFile *f, int fPosition, int count) { FilePtr fp= 0; validate(f); fp= (FilePtr)f->state; if (( (fPosition >= 0)) /* (fPos < 0) => current position */ && (fp->rd.pos != fPosition)) /* avoid EPIPE on pty */ { if (lseek(fp->fd, fPosition, SEEK_SET) < 0) { perror("lseek"); goto fail; } fp->rd.pos= fPosition; } fp->rd.status= Busy; aioHandle(fp->fd, readHandler, AIO_R); return 0; fail: fp->rd.status= Error; vm->primitiveFail(); return 0; } int asyncFileWriteResult(AsyncFile *f) { int n= 0; FilePtr fp= 0; validate(f); fp= (FilePtr)f->state; n= fp->wr.status; fp->wr.status= Busy; return n; } static void writeBuffer(FilePtr fp) { int n= 0; while ((n= fp->buf.size - fp->buf.pos) > 0) { n= write(fp->fd, (void *)(fp->buf.bytes + fp->buf.pos), n); if (n < 0) switch (errno) { case EWOULDBLOCK: aioHandle(fp->fd, writeHandler, AIO_W); return; default: fp->wr.status= Error; return; } fp->buf.pos += n; fp->wr.pos += n; } /* completed */ fp->wr.status= fp->buf.size; signalSemaphoreWithIndex(fp->sema); } static void writeHandler(int fd, void *data, int flags) { writeBuffer((FilePtr)data); } int asyncFileWriteStart(AsyncFile *f, int fPosition, int bufferPtr, int count) { FilePtr fp= 0; validate(f); fp= (FilePtr)f->state; if (( (fPosition >= 0)) /* (fPos < 0) => current position */ && (fp->wr.pos != fPosition)) /* avoid EPIPE on tty */ { if (lseek(fp->fd, fPosition, SEEK_SET) < 0) { perror("lseek"); goto fail; } fp->wr.pos= fPosition; } if (count < 1) { fp->wr.status= 0; signalSemaphoreWithIndex(fp->sema); return 0; } if (!allocateBuffer(&fp->buf, count)) { fprintf(stderr, "out of memory\n"); goto fail; } memcpy((void *)fp->buf.bytes, (void *)bufferPtr, count); fp->buf.pos= 0; /* current output pointer */ fp->buf.size= count; /* bytes to transfer */ fp->wr.status= Busy; /* transfer in progress */ writeBuffer(fp); /* begin transfer */ return 0; fail: fp->wr.status= Error; vm->primitiveFail(); return 0; } --- NEW FILE: sqUnixAsynchFile.h --- /* private file data */ typedef struct { int fd; /* descriptor */ int sema; /* completion semaphore */ struct { int pos; /* file position */ int status; /* number of bytes transferred, or: */ # define Busy -1 /* operation in progress */ # define Error -2 /* operation aborted */ } rd, wr; /* one each for read and write */ struct FileBuf { char *bytes; /* write buffer */ int capacity; /* capacity */ int size; /* contents size */ int pos; /* position */ } buf; } FileRec, *FilePtr; extern int sqUnixAsyncFileSessionID; extern FilePtr asyncFileAttach(AsyncFile *f, int fd, int semaIndex); |
|
From: Brenda L. <asp...@us...> - 2003-05-12 07:26:27
|
Update of /cvsroot/squeak/squeak/platforms/unix/npsqueak
In directory sc8-pr-cvs1:/tmp/cvs-serv30143/npsqueak
Added Files:
Makefile README.npsqueak npsqueak.c npsqueakregister.in
npsqueakrun.in npunix.c
Log Message:
Ian Piumarta's release 3.4.1
--- NEW FILE: Makefile ---
# Netscape Plugin for Squeak on Unix platforms
# Author: Bert Freudenberg <be...@is...>
############ Customize flags here #######################
INC = -I./include
CC = gcc
CFLAGS = $(INC) -O2 -fPIC -Wall
LD = gcc
LDFLAGS = -shared
# usually overridden from top level makefile
imgdir= /usr/local/lib/squeak
SQ_DIR= /usr/local/lib/squeak
VM_VERSION= 3.2-5devel
libdir= $(imgdir)/$(VM_VERSION)
VM_LIBDIR= $(SQ_DIR)/$(VM_VERSION)
############ compile and link ###########################
npsqueak.so : npsqueak.o npunix.o
$(LD) $(LDFLAGS) npsqueak.o npunix.o -o npsqueak.so
npsqueak.o: npsqueak.c
$(CC) -c $(CFLAGS) -DVM_LIBDIR=\"$(VM_LIBDIR)\" $<
npunix.o: npunix.c
$(CC) -c $(CFLAGS) $<
clean:
-rm -f *.o *.so *~ .*~ */*~ */.*~
############ install ####################################
$(SQ_DIR):
@if [ -d $@ ] ; then \
touch $@ ; \
else \
echo "Error: $@ not found" ; \
echo "You have to install squeak first!" ; \
false ; \
fi
$(VM_LIBDIR): $(SQ_DIR)
@if [ -d $@ ] ; then \
touch $@ ; \
else \
echo "Error: $@ not found" ; \
echo "Is there a version mismatch? Install squeak first!" ; \
false ; \
fi
$(VM_LIBDIR)/npsqueak.so: npsqueak.so $(VM_LIBDIR)
cp $< $@
strip $@
$(VM_LIBDIR)/npsqueakrun: npsqueakrun.in $(SQ_DIR)
sed "s|@SQ_DIR@|$(imgdir)|;s|@VM_VERSION@|$(VM_VERSION)|" \
$< > $@
chmod +x $@
$(SQ_DIR)/npsqueakregister: npsqueakregister.in $(SQ_DIR)
sed "s|@NPSQUEAK_SO@|$(libdir)/npsqueak.so|" \
$< > $@
chmod +x $@
### Go! ###
NPSQUEAK_TARGETS= \
$(VM_LIBDIR)/npsqueak.so \
$(VM_LIBDIR)/npsqueakrun \
$(SQ_DIR)/npsqueakregister
install: $(NPSQUEAK_TARGETS)
# $(SQ_DIR)/npsqueakregister
uninstall: $(SQ_DIR)/npsqueakregister
$(SQ_DIR)/npsqueakregister -u
rm -rf $(NPSQUEAK_TARGETS)
--- NEW FILE: README.npsqueak ---
=================================================================
Netscape Plugin for Squeak on Unix platforms
Author: Bert Freudenberg <be...@is...>
Version: @VM_VERSION@
Last edited: Wed 02 Oct 2002 15:52:35 by bert on balloon
=================================================================
Files:
Makefile
README.npsqueak
npsqueak.c
npunix.c (modified copy from Netscape Plugin SDK)
include/* (unmodified headers from Netscape Plugin SDK)
test/*
=================================================================
To compile and install the Squeak plugin
0a. You have to compile and install the main VM first.
mkdir build
cd build
../platforms/unix/config/configure
make
make install
This installs squeak into (probably)
SQ_DIR=/usr/local/lib/squeak
0b. You will need an image. Copy it to
${SQ_DIR}/npsqueak.image
A good place to look for an image suited as plugin is
http://squeakland.org/plugin/installers/files.html
1. Change into the plugin source directory:
cd npsqueak
2a. If necessary, edit the Makefile (compiler options):
emacs Makefile
2b. Make the plugin:
make
"npsqueak.so" will be the output of a successful compile process.
3. Install the plugin as superuser (root):
su
make install
This creates the following files and directories
${SQ_DIR}/@VM_VERSION@/npsqueakrun
(executed from plugin)
${SQ_DIR}/@VM_VERSION@/npsqueak.so
(the plugin itself)
${SQ_DIR}/npsqueakregister
(a shell script to register)
It also runs npsqueakregister which looks for various browsers
in various directories and creates links to the plugin. If
your browser is not found, hack the npsqueakregister script or
symlink the plugin manually:
ln -s ${SQ_DIR}/@VM_VERSION@/npsqueak.so \
/usr/lib/mybrowser/plugins/
Finally, log out of the super user account:
exit
4. Exit and restart the browser. Check if the Squeak plugin
was recognized by selecting the Help>>About Plugins menu item.
5. Open the html file in the test/ directory. This should
activate the Squeak plugin. Since this is the first time the
plugin is executed, a .npsqueak folder will be created in your
home directory and the plugin image is installed into it.
=================================================================
NOTE: If you are not the super user of your machine you can install
everything into your home directory. Put npsqueak.so somewhere your
browser will find it. Make a .npsqueak dir in your home directory
with subdirectories and files like shown below. Also create a
.npsqueak/npsqueakvm file which points to a Squeak VM.
=================================================================
DOCUMENTATION
* On the first run for each user, the npsqueakrun will create a directory
structure like this:
$(HOME)/
|
+--- .npsqueak/
|
+--- SqueakPlugin.image
|
+--- secure/
|
+--- untrusted/
* Environment Variables:
NPSQUEAK_DEBUG
logs debug info to /tmp/npsqueak.log
Default: don't log
* Mimetypes:
application/x-squeak-source:sts:Squeak source
application/x-squeak-object:sqo:Squeak object
application/x-squeak-project:pr:Squeak project
* Parameters:
parameters in EMBED tag used by Squeak:
SRC=...
MEMORY=... (not by unix npsqueak)
* Communication with VM is via Pipes
=================================================================
TODO
* loop on read() and write() until all data is sent and received.
* make sure Squeak really gets killed
* fix crashing the browser when closing plugin page
* make plugin not wait for browser when the url is loaded into a target.
* use autoconf
=================================================================
Change log
Oct 2002:
* modified install from home directory to system-wide
Sep 2002:
* hack to work with Mozilla >= 1.0 which deletes the delivered
file immediately. We just create a hard link before and
delete that after opening the file.
Mar 2002:
* uses aio now for command pipe
* moved stuff from ~/.netscape/squeak to ~/.npsqueak directory
* implemented SecurityPlugin
May 2001:
* updated for squeakland.org image.
* TODO: SecurityManager
Feb 2001:
* updated for Squeak 3.0
Nov 2000:
* introduced -browserPipes command line
* this fixed the bug of plugins in tables
* cleaned up a lot of hacks
* this fixed crashing Mozilla 0.6
* made widget destroy work more often than not
* Problems: crashes when closing Netscape window
* pipe is polled for now - should use select in sqXWindow
Apr 2000:
* url requests through browser
Nov 1999
* report attributes to vm
Aug 1999
* initial version
--- NEW FILE: npsqueak.c ---
/* -*- Mode: C; tab-width: 8; -*-
*
* Browser Plugin for Squeak on Unix platforms
*
* Author: Bert Freudenberg <be...@is...>
*
* Last edited: Wed 02 Oct 2002 14:43:26 by bert on balloon
*
* History:
* Oct 2002 - system-wide install
* Sep 2002 - create hard links for streamed files
* Mar 2002 - moved to ~/.npsqueak dir
* Nov 2000 - browserPipes interface replaces X events
* Apr 2000 - url requests through browser
* Nov 1999 - report attributes to vm
* Aug 99 - initial version
*/
#define XP_UNIX
#include <npapi.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
/* VM install directory is passed via "cc -D..." or through autoconf */
/* config.h is in the top build dir of the VM */
#ifndef VM_LIBDIR
# include "config.h"
#endif
#undef DEBUG
#ifdef DEBUG
static void DPRINT(char *format, ...)
{
static int debug= 42;
if (42 == debug)
debug= (NULL != getenv("NPSQUEAK_DEBUG"));
if (!debug)
{
return;
}
else
{
static FILE *file= 0;
if (!file)
{
file= fopen("/tmp/npsqueak.log", "a+");
fprintf(file, "=== START PLUGIN ===\n");
}
{
va_list ap;
va_start(ap, format);
vfprintf(file, format, ap);
va_end(ap);
fflush(file);
}
}
}
#else
static void DPRINT(char *format, ...) { }
#endif
/***********************************************************************
* Plugin instance data
***********************************************************************/
#define CMD_BROWSER_WINDOW 1
#define CMD_GET_URL 2
#define CMD_POST_URL 3
#define CMD_RECEIVE_DATA 4
#define MAX_STREAMS 128
#define SQUEAK_READ 0
#define PLUGIN_WRITE 1
#define PLUGIN_READ 2
#define SQUEAK_WRITE 3
/* plugin state */
typedef struct SqueakPlugin {
NPP instance; /* plugin instance */
pid_t pid; /* the child process pid */
Display *display;
Window nswindow; /* the netscape window */
Window sqwindow; /* the Squeak window */
XtInputId input; /* handler for command pipe */
Bool embedded; /* false if we have the whole window */
char **argv; /* the commandline for Squeak vm */
int argc;
char vmName[PATH_MAX];
char imageName[PATH_MAX];
int pipes[4]; /* 4 ends of 2 pipes */
char* srcUrl; /* set by browser in first NewStream */
char* srcFilename;
int srcId; /* if requested */
} SqueakPlugin;
/* URL notify data */
typedef struct SqueakStream {
int id; /* request id (0 if finished) */
} SqueakStream;
/***********************************************************************
* Prototypes
***********************************************************************/
static void DeliverFile(SqueakPlugin *, int id, const char* fname);
static void SetWindow(SqueakPlugin*, Window window, int width, int height);
static void SetUpWindow(SqueakPlugin*);
static void SetUpSqueakWindow(SqueakPlugin*);
static void Run(SqueakPlugin*);
static void GetUrl(SqueakPlugin*);
static void PostUrl(SqueakPlugin*);
static void DestroyCallback(Widget widget, SqueakPlugin *, XtPointer calldata);
static void InputCallback(SqueakPlugin *, int *source, XtInputId*);
static char* NPN_StrDup(const char* s)
{
return strcpy(NPN_MemAlloc(strlen(s)+1), s);
}
/***********************************************************************
* Plugin registration
***********************************************************************/
char*
NPP_GetMIMEDescription(void)
{
return("application/x-squeak-source:sts:Squeak source"
";application/x-squeak-object:sqo:Squeak object"
";application/x-squeak-project:pr:Squeak project");
}
NPError
NPP_GetValue(void *instance, NPPVariable variable, void *value)
{
switch (variable) {
case NPPVpluginNameString:
*((char **)value)= "Squeak";
break;
case NPPVpluginDescriptionString:
*((char **)value) =
"<a href=\"http://squeak.org/\">Squeak</a> is a modern open source"
" Smalltalk environment. The Squeak Plugin handles Squeaklets.<P>"
"The Squeak Plugin for Unix was developed by"
" <a href=\"mailto:be...@fr...\">Bert Freudenberg</a>,"
" it uses the Squeak VM developed by"
" <a href=\"mailto:Ian...@in...\">Ian Piumarta</a>"
" and many others.";
break;
default:
return NPERR_GENERIC_ERROR;
}
return NPERR_NO_ERROR;
}
/***********************************************************************
* Plugin loading and termination
***********************************************************************/
NPError
NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc,
char* argn[], char* argv[], NPSavedData* saved)
{
SqueakPlugin *plugin;
char basedir[PATH_MAX];
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
plugin= (SqueakPlugin*) NPN_MemAlloc(sizeof(SqueakPlugin));
if (!plugin)
return NPERR_OUT_OF_MEMORY_ERROR;
plugin->argv= (char**) NPN_MemAlloc(sizeof(char*) * (16+2*argc));
if (!plugin->argv)
return NPERR_OUT_OF_MEMORY_ERROR;
{
char* ev= getenv("HOME");
if (ev) {
strcpy(basedir, ev);
strcat(basedir, "/.npsqueak/");
} else {
basedir[0]= '\0';
fprintf(stderr, "Squeak Plugin: No home directory?!\n");
return NPERR_GENERIC_ERROR;
}
}
/* Default settings */
plugin->instance= instance;
plugin->pid= 0;
plugin->nswindow= 0;
plugin->sqwindow= 0;
plugin->display= NULL;
plugin->input= 0;
plugin->embedded= (mode == NP_EMBED);
plugin->srcUrl= NULL;
plugin->srcFilename= NULL;
plugin->srcId= -1;
strcpy(plugin->vmName, basedir);
strcat(plugin->vmName, "npsqueakvm");
strcpy(plugin->imageName, basedir);
strcat(plugin->imageName, "SqueakPlugin.image");
plugin->argv[0]= NPN_StrDup(plugin->vmName);
plugin->argv[1]= NPN_StrDup("-display");
plugin->argv[2]= NULL; /* inserted later */
plugin->argv[3]= NPN_StrDup("-browserPipes");
plugin->argv[4]= NULL; /* inserted later */
plugin->argv[5]= NULL; /* inserted later */
plugin->argv[6]= NPN_StrDup(plugin->imageName);
plugin->argv[7]= NPN_StrDup(""); /* empty document file on cmdline! */
plugin->argc= 8;
if (plugin->embedded) {
int i;
for (i= 0; i < argc; i++) {
plugin->argv[plugin->argc++]= NPN_StrDup(argn[i]);
plugin->argv[plugin->argc++]= NPN_StrDup(argv[i] ? argv[i] : "");
if (strcasecmp("SRC", argn[i]) == 0)
plugin->srcUrl= NPN_StrDup(argv[i]);
}
if (!plugin->srcUrl)
plugin->srcUrl= NPN_StrDup(""); /* we were embedded without a SRC */
} else {
/* if not embedded srcUrl will be set in NewStream */
plugin->srcUrl= NULL;
}
plugin->argv[plugin->argc]= 0;
if (pipe(&plugin->pipes[SQUEAK_READ])
|| pipe(&plugin->pipes[PLUGIN_READ])) {
perror("Squeak Plugin: Creating pipes failed");
return NPERR_GENERIC_ERROR;
}
DPRINT("NP: Created pipes (VM read: %d <- %d, NP read: %d <- %d)\n",
plugin->pipes[SQUEAK_READ],
plugin->pipes[PLUGIN_WRITE],
plugin->pipes[PLUGIN_READ],
plugin->pipes[SQUEAK_WRITE]);
instance->pdata= (void*) plugin;
return NPERR_NO_ERROR;
}
NPError
NPP_Destroy(NPP instance, NPSavedData** save)
{
SqueakPlugin *plugin;
if (!instance)
return NPERR_INVALID_INSTANCE_ERROR;
plugin= (SqueakPlugin*) instance->pdata;
if (plugin) {
int i;
if (plugin->pid) {
kill(plugin->pid, SIGTERM);
plugin->pid= 0;
}
if (plugin->input) {
XtRemoveInput(plugin->input);
}
for (i=0; i<4; i++)
if (plugin->pipes[i]) {
close(plugin->pipes[i]);
plugin->pipes[i]= 0;
}
if (plugin->srcUrl) {
NPN_MemFree(plugin->srcUrl);
plugin->srcUrl= NULL;
}
if (plugin->srcFilename) {
NPN_MemFree(plugin->srcFilename);
plugin->srcFilename= NULL;
}
if (plugin->argv) {
for (i=0; i<plugin->argc; i++) {
if (plugin->argv[i])
NPN_MemFree(plugin->argv[i]);
}
plugin->argc= 0;
NPN_MemFree(plugin->argv);
plugin->argv= NULL;
}
NPN_MemFree(plugin);
}
instance->pdata= NULL;
return NPERR_NO_ERROR;
}
/***********************************************************************
* Plugin events we need to handle
***********************************************************************/
NPError
NPP_SetWindow(NPP instance, NPWindow *pNPWindow)
{
SqueakPlugin *plugin;
if (!instance)
return NPERR_INVALID_INSTANCE_ERROR;
plugin= (SqueakPlugin*) instance->pdata;
if (!plugin)
return NPERR_GENERIC_ERROR;
if (pNPWindow == NULL)
return NPERR_NO_ERROR;
if (!plugin->display) {
/* first time only */
plugin->display= ((NPSetWindowCallbackStruct *)pNPWindow->ws_info)->display;
}
SetWindow(plugin, (Window) pNPWindow->window,
pNPWindow->width, pNPWindow->height);
if (!plugin->pid)
Run(plugin);
return NPERR_NO_ERROR;
}
NPError
NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, NPBool seekable, uint16 *stype)
{
SqueakPlugin *plugin= (SqueakPlugin*) instance->pdata;
DPRINT("NP: NewStream(%s, id=%i)\n", stream->url,
stream->notifyData ? ((SqueakStream*) stream->notifyData)->id : -1);
if (!stream->notifyData && !plugin->srcUrl) {
/* We did not request this stream, so it is our SRC file. */
plugin->srcUrl= NPN_StrDup(stream->url);
plugin->argv[plugin->argc++]= NPN_StrDup("SRC");
plugin->argv[plugin->argc++]= NPN_StrDup(plugin->srcUrl);
DPRINT("NP: got srcUrl=%s\n", plugin->srcUrl);
Run(plugin);
}
*stype= NP_ASFILEONLY; /* We want the file after download */
return NPERR_NO_ERROR;
}
NPError
NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason)
{
/* We'll clean up in URLNotify */
DPRINT("NP: DestroyStream(%s, id=%i)\n", stream->url,
stream->notifyData ? ((SqueakStream*) stream->notifyData)->id : -1);
return NPERR_NO_ERROR;
}
void
NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
{
int id= stream->notifyData ? ((SqueakStream*) stream->notifyData)->id : -1;
char lname[PATH_MAX];
SqueakPlugin *plugin= (SqueakPlugin*) instance->pdata;
DPRINT("NP: StreamAsFile(%s, id=%i)\n", stream->url, id);
DPRINT("NP: fname=%s\n", fname ? fname : "<NULL>");
if (!plugin || !fname) return;
/* need to copy file because it might be deleted after return */
strncpy(lname, fname, PATH_MAX);
strcat(lname, "$");
DPRINT("NP: lname=%s\n", lname);
if (-1 == link(fname, lname))
DPRINT("NP: Link failed: %s\n", strerror(errno));
fname= lname;
if (!stream->notifyData && !plugin->srcFilename) {
/* We did not request this stream, so it is our SRC file. */
plugin->srcFilename= NPN_StrDup(fname);
DPRINT("NP: got srcFilename=%s\n", plugin->srcFilename);
if (plugin->srcId >= 0) {
/* plugin wanted it already */
DeliverFile(plugin, plugin->srcId, plugin->srcFilename);
plugin->srcId= -1;
}
return;
}
DeliverFile(plugin, id, fname);
/* signal URLNotify that we're done */
((SqueakStream*) stream->notifyData)->id= -1;
}
void
NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
{
int id= notifyData ? ((SqueakStream*) notifyData)->id : -1;
int ok= reason == NPRES_DONE;
SqueakPlugin *plugin= (SqueakPlugin*) instance->pdata;
DPRINT("NP: URLNotify(%s, id=%i, ok=%i)\n", url, id, ok);
if (notifyData) NPN_MemFree(notifyData);
if (!plugin || -1 == id) return;
DeliverFile(plugin, id, NULL);
}
/***********************************************************************
* Plugin stubs
***********************************************************************/
NPError
NPP_Initialize(void)
{
return NPERR_NO_ERROR;
}
void
NPP_Shutdown(void)
{
}
/* We don't have an associated java class */
jref
NPP_GetJavaClass()
{
return NULL;
}
/* We don't really stream */
int32
NPP_WriteReady(NPP instance, NPStream *stream)
{
return 0X0FFFFFFF;
}
int32
NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
{
return len;
}
/* We don't print */
void
NPP_Print(NPP instance, NPPrint* printInfo)
{
}
/***********************************************************************
* Our functions
***********************************************************************/
/* Read from command pipe. */
static void
Receive(SqueakPlugin *plugin, void *buf, size_t count)
{
ssize_t n;
do {
n= read(plugin->pipes[PLUGIN_READ], buf, count);
} while (n == -1 && errno == EINTR);
if (n == -1)
perror("Squeak plugin pipe read failed:");
if (n < count)
fprintf(stderr, "Squeak plugin read too few data from pipe\n");
}
/* Write to command pipe. */
static void
Send(SqueakPlugin *plugin, const void *buf, size_t count)
{
ssize_t n;
do {
n= write(plugin->pipes[PLUGIN_WRITE], buf, count);
} while (n == -1 && errno == EINTR);
if (n == -1)
perror("Squeak plugin write failed:");
if (n < count)
fprintf(stderr, "Squeak plugin wrote too few data to pipe\n");
}
static void
SendInt(SqueakPlugin *plugin, int value)
{
Send(plugin, &value, 4);
}
static void
DeliverFile(SqueakPlugin *plugin, int id, const char* fname)
{
int ok= fname != NULL;
DPRINT("NP: Send RECEIVE_DATA id=%i state=%i\n", id, ok);
errno= 0;
SendInt(plugin, CMD_RECEIVE_DATA);
SendInt(plugin, id);
SendInt(plugin, ok);
if (ok) {
int length= strlen(fname);
SendInt(plugin, length);
Send(plugin, fname, length);
}
if (errno)
perror("Squeak Plugin (StreamAsFile)");
}
static void
Run(SqueakPlugin *plugin)
{
if (plugin->pid || !plugin->nswindow || !plugin->srcUrl)
return;
plugin->pid= fork();
if (plugin->pid == -1) {
perror("Squeak fork() failed");
plugin->pid= 0;
return;
}
DPRINT("NP: fork() -> %i\n", plugin->pid);
if (plugin->pid == 0) {
char tmp1[16], tmp2[16];
plugin->argv[2]= NPN_StrDup(DisplayString(plugin->display));
sprintf(tmp1, "%i", plugin->pipes[SQUEAK_READ]);
plugin->argv[4]= NPN_StrDup(tmp1);
sprintf(tmp2, "%i", plugin->pipes[SQUEAK_WRITE]);
plugin->argv[5]= NPN_StrDup(tmp2);
DPRINT("NP(child): Running Squeak VM with arguments\n");
{
int i;
for (i= 1; i<plugin->argc; i++)
DPRINT(" %s\n", plugin->argv[i]);
}
/* this is from the XLib manual ... */
if ((fcntl(ConnectionNumber(plugin->display), F_SETFD, FD_CLOEXEC)) == -1)
DPRINT("NP: Cannot disinherit X connection fd\n");
DPRINT("NP(child): trying %s\n", plugin->vmName);
execv(plugin->vmName, plugin->argv);
/* ~/.npsqueak/npsqueakvm could not be executed */
strcpy(plugin->vmName, VM_LIBDIR "/npsqueakrun");
NPN_MemFree(plugin->argv[0]);
plugin->argv[0]= NPN_StrDup(plugin->vmName);
DPRINT("NP(child): trying %s\n", plugin->vmName);
execv(plugin->vmName, plugin->argv);
/* npsqueakrun could not be executed either */
fprintf(stderr, "Squeak Plugin: running \"%s\"\n", plugin->vmName);
perror("Squeak execv() failed");
_exit(1);
}
/* establish communication via command pipes */
{
XtAppContext app= XtDisplayToApplicationContext(plugin->display);
plugin->input= XtAppAddInput(app,
plugin->pipes[PLUGIN_READ],
(XtPointer) XtInputReadMask,
(XtInputCallbackProc) InputCallback,
plugin);
}
/* send browser window */
DPRINT("NP: Sending browser window=0x%X\n", plugin->nswindow);
SendInt(plugin, plugin->nswindow);
}
static void
SetWindow(SqueakPlugin *plugin, Window window, int width, int height)
{
DPRINT("NP: SetWindow(0x%X, %i@%i)\n", window, width, height);
if (plugin->nswindow == window) {
XResizeWindow(plugin->display, plugin->nswindow, width, height);
} else {
/* New window */
plugin->nswindow= window;
SetUpWindow(plugin);
if (plugin->sqwindow) {
DPRINT("NP: Reparenting to plugin window 0x%X\n", plugin->nswindow);
XReparentWindow(plugin->display, plugin->sqwindow, plugin->nswindow, 0, 0);
XMapWindow(plugin->display, plugin->sqwindow);
/* notify Squeak */
SendInt(plugin, CMD_BROWSER_WINDOW);
SendInt(plugin, plugin->nswindow);
}
}
if (plugin->sqwindow)
XResizeWindow(plugin->display, plugin->sqwindow, width, height);
}
static void
SetUpWindow(SqueakPlugin *plugin)
{
Widget w= XtWindowToWidget(plugin->display, plugin->nswindow);
DPRINT("NP: SetUpWindow(0x%X)\n", plugin->nswindow);
XSelectInput(plugin->display, plugin->nswindow, 0);
if (plugin->embedded) {
/* need to capture destroys when page is re-layouted */
XtAddCallback(w, XtNdestroyCallback,
(XtCallbackProc) DestroyCallback, plugin);
}
}
static void
SetUpSqueakWindow(SqueakPlugin *plugin)
{
Receive(plugin, &plugin->sqwindow, 4);
DPRINT("NP: got squeak window=0x%X\n", plugin->sqwindow);
DPRINT("NP: resizing squeak window\n");
{
XWindowAttributes attr;
XGetWindowAttributes(plugin->display, plugin->nswindow, &attr);
XResizeWindow(plugin->display, plugin->sqwindow, attr.width, attr.height);
}
DPRINT("NP: mapping squeak window\n");
XMapWindow(plugin->display, plugin->sqwindow);
}
static int
IgnoreErrors(Display *display, XErrorEvent *evt)
{
DPRINT("NP: X Error ignored.\n");
return 1;
}
static void
DestroyCallback(Widget widget, SqueakPlugin *plugin, XtPointer data)
{
int (*previous)(Display *, XErrorEvent *);
DPRINT("NP: DestroyCallback()\n");
/* Ignore errors due to the window being closed */
XSync(plugin->display, False);
previous= XSetErrorHandler(IgnoreErrors);
/* Save Squeak window from being destroyed by page re-layout */
DPRINT("NP: Reparenting to root window\n");
XUnmapWindow(plugin->display, plugin->sqwindow);
XReparentWindow(plugin->display, plugin->sqwindow,
DefaultRootWindow(plugin->display), 0, 0);
/* Report errors */
XSync(plugin->display, False);
XSetErrorHandler(previous);
}
static void
InputCallback(SqueakPlugin *plugin, int *source, XtInputId* id)
{
int cmd;
DPRINT("NP: InputCallback()\n");
if (!plugin->sqwindow)
{
/* read sqwindow */
SetUpSqueakWindow(plugin);
return;
}
Receive(plugin, &cmd, 4);
switch (cmd) {
case CMD_GET_URL:
GetUrl(plugin);
break;
case CMD_POST_URL:
PostUrl(plugin);
break;
default:
fprintf(stderr, "Unknown command from Squeak: %i\n", cmd);
}
}
static void
GetUrl(SqueakPlugin *plugin)
{
char *url, *target;
int id, urlSize, targetSize;
errno= 0;
Receive(plugin, &id, 4);
/* Read URL from pipe */
Receive(plugin, &urlSize, 4);
if (urlSize > 0) {
url= NPN_MemAlloc(urlSize+1);
Receive(plugin, url, urlSize);
url[urlSize]= 0;
} else url= NULL;
/* Read target from pipe */
Receive(plugin, &targetSize, 4);
if (targetSize > 0) {
target= NPN_MemAlloc(targetSize+1);
Receive(plugin, target, targetSize);
target[targetSize]= 0;
} else target= NULL;
if (errno) {
perror("Squeak Plugin (GetUrl)");
} else {
DPRINT("NP: GetUrl(%s, %s)\n", url, target ? target : "NULL");
if (strcmp(url, plugin->srcUrl)==0) {
if (plugin->srcFilename)
DeliverFile(plugin, id, plugin->srcFilename);
else
plugin->srcId= id;
} else {
SqueakStream* notifyData= (SqueakStream*) NPN_MemAlloc(sizeof(SqueakStream));
if (!notifyData) {
fprintf(stderr, "Squeak Plugin (GetUrl): alloc failed\n");
} else {
DPRINT("NP: GetURLNotify(%s, id=%i)\n", url, id);
notifyData->id= id;
NPN_GetURLNotify(plugin->instance, url, target, notifyData);
}
}
}
if (url) NPN_MemFree(url);
if (target) NPN_MemFree(target);
}
static void
PostUrl(SqueakPlugin *plugin)
{
char *url, *target, *data;
int id, urlSize, targetSize, dataSize;
errno= 0;
Receive(plugin, &id, 4);
/* Read URL from pipe */
Receive(plugin, &urlSize, 4);
if (urlSize > 0) {
url= NPN_MemAlloc(urlSize+1);
Receive(plugin, url, urlSize);
url[urlSize]= 0;
} else url= NULL;
/* Read target from pipe */
Receive(plugin, &targetSize, 4);
if (targetSize > 0) {
target= NPN_MemAlloc(targetSize+1);
Receive(plugin, target, targetSize);
target[targetSize]= 0;
} else target= NULL;
/* Read post data from pipe */
Receive(plugin, &dataSize, 4);
if (dataSize > 0) {
data= NPN_MemAlloc(dataSize);
Receive(plugin, data, dataSize);
} else data= NULL;
if (errno) {
perror("Squeak Plugin (PostUrl)");
} else {
SqueakStream* notifyData= (SqueakStream*) NPN_MemAlloc(sizeof(SqueakStream));
if (!notifyData) {
fprintf(stderr, "Squeak Plugin (PostUrl): alloc failed\n");
} else {
DPRINT("NP: PostURLNotify(%s, id=%i)\n", url, id);
notifyData->id= id;
NPN_PostURLNotify(plugin->instance, url, target,
dataSize, data, FALSE, notifyData);
}
}
if (url) NPN_MemFree(url);
if (target) NPN_MemFree(target);
if (data) NPN_MemFree(data);
}
--- NEW FILE: npsqueakregister.in ---
#! /bin/sh
# File: npsqueakregister
# Author: Bert Freudenberg <be...@is...>
# Description: Script to register the npsqueak plugin with
# various browsers.
# Rerun after you installed a new browser!
# Parameters: -u unregister
NPSQUEAK_SO=@NPSQUEAK_SO@
BROWSERS="netscape mozilla opera"
BROWSER_DIRS="/usr/local/lib /usr/lib"
ACTION=register
usage() {
echo "Usage: $0 [-u] [PLUGIN]"
echo "Registers the Squeak browser plugin for known browsers"
echo " -u unregister plugin"
echo " PLUGIN absolute path to npsqueak.so"
echo " (default is @NPSQUEAK_SO@)"
exit
}
register() {
echo Registering ${1}
rm -f ${1}
ln -sv $NPSQUEAK_SO ${1}
}
unregister() {
echo Unregistering ${1}
rm -f ${1}
}
case "$1" in
-u)
ACTION=unregister
;;
"")
ACTION=register
;;
/*.so)
NPSQUEAK_SO="$1"
;;
*) usage
exit 1
;;
esac
if [ ! -x "$NPSQUEAK_SO" ] ; then
echo File not found: $NPSQUEAK_SO
echo Aborting.
exit 1
fi
for browser in $BROWSERS
do
for bdir in $BROWSER_DIRS
do
dirs=`ls -d ${bdir}/${browser}* 2>/dev/null`
for dir in $dirs
do
pdirs=`find $dir -name plugins -print`
for pdir in $pdirs
do
$ACTION ${pdir}/npsqueak.so
done
done
done
done
--- NEW FILE: npsqueakrun.in ---
#! /bin/sh
# File: @SQ_DIR@/@VM_VERSION@/npsqueakrun
# Author: Bert Freudenberg <be...@is...>
# Description: Script to start the Squeak VM binary
# from the Browser Plugin (npsqueak.so)
# If necessary, sets up $HOME/.npsqueak/* first.
SQ_DIR=@SQ_DIR@
VM_VERSION=@VM_VERSION@
IMAGE=${SQ_DIR}/npsqueak.image
VM=${SQ_DIR}/${VM_VERSION}/squeak
VMOPTIONS="-memory 64m -xshm"
ensuredir()
{
if [ ! -d "${1}" ] ; then
if mkdir "${1}" ; then
echo npsqueak: Created ${1}
if [ -n "${2}" ] ; then
chmod "${2}" "${1}"
fi
else
echo npsqueak: Could not create ${1}!
fi
fi
}
ensurefile()
{
if [ ! -e "${1}" ] ; then
if cp "${2}" "${1}" ; then
echo npsqueak: Created ${1}
else
echo npsqueak: Could not create ${1}
if [ ! -r "${2}" ] ; then
echo npsqueak: because ${2} is missing
fi
fi
fi
}
ensuredir "${HOME}/.npsqueak"
ensuredir "${HOME}/.npsqueak/secure" 700
ensuredir "${HOME}/.npsqueak/untrusted"
ensurefile "${HOME}/.npsqueak/SqueakPlugin.image" "${IMAGE}"
exec $VM $OPT "$@"
--- NEW FILE: npunix.c ---
/*
* npunix.c
*
* Netscape Client Plugin API
* - Wrapper function to interface with the Netscape Navigator
*
* dp Suresh <dp...@ne...>
*
*----------------------------------------------------------------------
* PLUGIN DEVELOPERS:
* YOU WILL NOT NEED TO EDIT THIS FILE.
*----------------------------------------------------------------------
*
* At the official Netscape site there's only the PluginSDK30b5 for unix:
*
* !!! I had to add the missing URLNotify stuff here. If you find an official
* !!! version of this file which has it, use it instead.
* !!! April 2000, Bert Freudenberg <be...@is...>
*
*/
#define XP_UNIX 1
#include <stdio.h>
#include "npapi.h"
#include "npupp.h"
/*
* Define PLUGIN_TRACE to have the wrapper functions print
* messages to stderr whenever they are called.
*/
#ifdef PLUGIN_TRACE
#include <stdio.h>
#define PLUGINDEBUGSTR(msg) fprintf(stderr, "%s\n", msg)
#else
#define PLUGINDEBUGSTR(msg)
#endif
/***********************************************************************
*
* Globals
*
***********************************************************************/
static NPNetscapeFuncs gNetscapeFuncs; /* Netscape Function table */
/***********************************************************************
*
* Wrapper functions : plugin calling Netscape Navigator
*
* These functions let the plugin developer just call the APIs
* as documented and defined in npapi.h, without needing to know
* about the function table and call macros in npupp.h.
*
***********************************************************************/
void
NPN_Version(int* plugin_major, int* plugin_minor,
int* netscape_major, int* netscape_minor)
{
*plugin_major = NP_VERSION_MAJOR;
*plugin_minor = NP_VERSION_MINOR;
/* Major version is in high byte */
*netscape_major = gNetscapeFuncs.version >> 8;
/* Minor version is in low byte */
*netscape_minor = gNetscapeFuncs.version & 0xFF;
}
NPError
NPN_GetValue(NPP instance, NPNVariable variable, void *r_value)
{
return CallNPN_GetValueProc(gNetscapeFuncs.getvalue,
instance, variable, r_value);
}
NPError
NPN_GetURL(NPP instance, const char* url, const char* window)
{
return CallNPN_GetURLProc(gNetscapeFuncs.geturl, instance, url, window);
}
NPError
NPN_GetURLNotify(NPP instance, const char* url, const char* window, void* notifyData)
{
int navMinorVers = gNetscapeFuncs.version & 0xFF;
if (navMinorVers < NPVERS_HAS_NOTIFICATION)
return NPERR_INCOMPATIBLE_VERSION_ERROR;
return CallNPN_GetURLNotifyProc(gNetscapeFuncs.geturlnotify, instance, url, window, notifyData);
}
NPError
NPN_PostURL(NPP instance, const char* url, const char* window,
uint32 len, const char* buf, NPBool file)
{
return CallNPN_PostURLProc(gNetscapeFuncs.posturl, instance,
url, window, len, buf, file);
}
NPError
NPN_PostURLNotify(NPP instance, const char* url, const char* window,
uint32 len, const char* buf, NPBool file, void* notifyData)
{
int navMinorVers = gNetscapeFuncs.version & 0xFF;
if (navMinorVers < NPVERS_HAS_NOTIFICATION)
return NPERR_INCOMPATIBLE_VERSION_ERROR;
return CallNPN_PostURLNotifyProc(gNetscapeFuncs.posturlnotify, instance,
url, window, len, buf, file, notifyData);
}
NPError
NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
{
return CallNPN_RequestReadProc(gNetscapeFuncs.requestread,
stream, rangeList);
}
NPError
NPN_NewStream(NPP instance, NPMIMEType type, const char *window,
NPStream** stream_ptr)
{
return CallNPN_NewStreamProc(gNetscapeFuncs.newstream, instance,
type, window, stream_ptr);
}
int32
NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer)
{
return CallNPN_WriteProc(gNetscapeFuncs.write, instance,
stream, len, buffer);
}
NPError
NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
{
return CallNPN_DestroyStreamProc(gNetscapeFuncs.destroystream,
instance, stream, reason);
}
void
NPN_Status(NPP instance, const char* message)
{
CallNPN_StatusProc(gNetscapeFuncs.status, instance, message);
}
const char*
NPN_UserAgent(NPP instance)
{
return CallNPN_UserAgentProc(gNetscapeFuncs.uagent, instance);
}
void*
NPN_MemAlloc(uint32 size)
{
return CallNPN_MemAllocProc(gNetscapeFuncs.memalloc, size);
}
void NPN_MemFree(void* ptr)
{
CallNPN_MemFreeProc(gNetscapeFuncs.memfree, ptr);
}
uint32 NPN_MemFlush(uint32 size)
{
return CallNPN_MemFlushProc(gNetscapeFuncs.memflush, size);
}
void NPN_ReloadPlugins(NPBool reloadPages)
{
CallNPN_ReloadPluginsProc(gNetscapeFuncs.reloadplugins, reloadPages);
}
JRIEnv* NPN_GetJavaEnv()
{
return CallNPN_GetJavaEnvProc(gNetscapeFuncs.getJavaEnv);
}
jref NPN_GetJavaPeer(NPP instance)
{
return CallNPN_GetJavaPeerProc(gNetscapeFuncs.getJavaPeer,
instance);
}
/***********************************************************************
*
* Wrapper functions : Netscape Navigator -> plugin
*
* These functions let the plugin developer just create the APIs
* as documented and defined in npapi.h, without needing to
* install those functions in the function table or worry about
* setting up globals for 68K plugins.
*
***********************************************************************/
NPError
Private_New(NPMIMEType pluginType, NPP instance, uint16 mode,
int16 argc, char* argn[], char* argv[], NPSavedData* saved)
{
NPError ret;
PLUGINDEBUGSTR("New");
ret = NPP_New(pluginType, instance, mode, argc, argn, argv, saved);
return ret;
}
NPError
Private_Destroy(NPP instance, NPSavedData** save)
{
PLUGINDEBUGSTR("Destroy");
return NPP_Destroy(instance, save);
}
NPError
Private_SetWindow(NPP instance, NPWindow* window)
{
NPError err;
PLUGINDEBUGSTR("SetWindow");
err = NPP_SetWindow(instance, window);
return err;
}
NPError
Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
NPBool seekable, uint16* stype)
{
NPError err;
PLUGINDEBUGSTR("NewStream");
err = NPP_NewStream(instance, type, stream, seekable, stype);
return err;
}
int32
Private_WriteReady(NPP instance, NPStream* stream)
{
unsigned int result;
PLUGINDEBUGSTR("WriteReady");
result = NPP_WriteReady(instance, stream);
return result;
}
int32
Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len,
void* buffer)
{
unsigned int result;
PLUGINDEBUGSTR("Write");
result = NPP_Write(instance, stream, offset, len, buffer);
return result;
}
void
Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
{
PLUGINDEBUGSTR("StreamAsFile");
NPP_StreamAsFile(instance, stream, fname);
}
void
Private_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
{
PLUGINDEBUGSTR("URLNotify");
NPP_URLNotify(instance, url, reason, notifyData);
}
NPError
Private_DestroyStream(NPP instance, NPStream* stream, NPError reason)
{
NPError err;
PLUGINDEBUGSTR("DestroyStream");
err = NPP_DestroyStream(instance, stream, reason);
return err;
}
void
Private_Print(NPP instance, NPPrint* platformPrint)
{
PLUGINDEBUGSTR("Print");
NPP_Print(instance, platformPrint);
}
JRIGlobalRef
Private_GetJavaClass(void)
{
jref clazz = NPP_GetJavaClass();
if (clazz) {
JRIEnv* env = NPN_GetJavaEnv();
return JRI_NewGlobalRef(env, clazz);
}
return NULL;
}
/***********************************************************************
*
* These functions are located automagically by netscape.
*
***********************************************************************/
/*
* NP_GetMIMEDescription
* - Netscape needs to know about this symbol
* - Netscape uses the return value to identify when an object instance
* of this plugin should be created.
*/
char *
NP_GetMIMEDescription(void)
{
return NPP_GetMIMEDescription();
}
/*
* NP_GetValue [optional]
* - Netscape needs to know about this symbol.
* - Interfaces with plugin to get values for predefined variables
* that the navigator needs.
*/
NPError
NP_GetValue(void *future, NPPVariable variable, void *value)
{
return NPP_GetValue(future, variable, value);
}
/*
* NP_Initialize
* - Netscape needs to know about this symbol.
* - It calls this function after looking up its symbol before it
* is about to create the first ever object of this kind.
*
* PARAMETERS
* nsTable - The netscape function table. If developers just use these
* wrappers, they dont need to worry about all these function
* tables.
* RETURN
* pluginFuncs
* - This functions needs to fill the plugin function table
* pluginFuncs and return it. Netscape Navigator plugin
* library will use this function table to call the plugin.
*
*/
NPError
NP_Initialize(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs)
{
NPError err = NPERR_NO_ERROR;
PLUGINDEBUGSTR("NP_Initialize");
/* validate input parameters */
if ((nsTable == NULL) || (pluginFuncs == NULL))
err = NPERR_INVALID_FUNCTABLE_ERROR;
/*
* Check the major version passed in Netscape's function table.
* We won't load if the major version is newer than what we expect.
* Also check that the function tables passed in are big enough for
* all the functions we need (they could be bigger, if Netscape added
* new APIs, but that's OK with us -- we'll just ignore them).
*
*/
if (err == NPERR_NO_ERROR) {
if ((nsTable->version >> 8) > NP_VERSION_MAJOR)
err = NPERR_INCOMPATIBLE_VERSION_ERROR;
if (nsTable->size < sizeof(NPNetscapeFuncs))
err = NPERR_INVALID_FUNCTABLE_ERROR;
if (pluginFuncs->size < sizeof(NPPluginFuncs))
err = NPERR_INVALID_FUNCTABLE_ERROR;
}
if (err == NPERR_NO_ERROR) {
/*
* Copy all the fields of Netscape function table into our
* copy so we can call back into Netscape later. Note that
* we need to copy the fields one by one, rather than assigning
* the whole structure, because the Netscape function table
* could actually be bigger than what we expect.
*/
gNetscapeFuncs.version = nsTable->version;
gNetscapeFuncs.size = nsTable->size;
gNetscapeFuncs.posturl = nsTable->posturl;
gNetscapeFuncs.geturl = nsTable->geturl;
gNetscapeFuncs.requestread = nsTable->requestread;
gNetscapeFuncs.newstream = nsTable->newstream;
gNetscapeFuncs.write = nsTable->write;
gNetscapeFuncs.destroystream = nsTable->destroystream;
gNetscapeFuncs.status = nsTable->status;
gNetscapeFuncs.uagent = nsTable->uagent;
gNetscapeFuncs.memalloc = nsTable->memalloc;
gNetscapeFuncs.memfree = nsTable->memfree;
gNetscapeFuncs.memflush = nsTable->memflush;
gNetscapeFuncs.reloadplugins = nsTable->reloadplugins;
gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv;
gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer;
gNetscapeFuncs.getvalue = nsTable->getvalue;
if ((nsTable->version & 0xFF) >= NPVERS_HAS_NOTIFICATION) {
gNetscapeFuncs.posturlnotify = nsTable->posturlnotify;
gNetscapeFuncs.geturlnotify = nsTable->geturlnotify;
}
/*
* Set up the plugin function table that Netscape will use to
* call us. Netscape needs to know about our version and size
* and have a UniversalProcPointer for every function we
* implement.
*/
pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
pluginFuncs->size = sizeof(NPPluginFuncs);
pluginFuncs->newp = NewNPP_NewProc(Private_New);
pluginFuncs->destroy = NewNPP_DestroyProc(Private_Destroy);
pluginFuncs->setwindow = NewNPP_SetWindowProc(Private_SetWindow);
pluginFuncs->newstream = NewNPP_NewStreamProc(Private_NewStream);
pluginFuncs->destroystream = NewNPP_DestroyStreamProc(Private_DestroyStream);
pluginFuncs->asfile = NewNPP_StreamAsFileProc(Private_StreamAsFile);
pluginFuncs->urlnotify = NewNPP_URLNotifyProc(Private_URLNotify);
pluginFuncs->writeready = NewNPP_WriteReadyProc(Private_WriteReady);
pluginFuncs->write = NewNPP_WriteProc(Private_Write);
pluginFuncs->print = NewNPP_PrintProc(Private_Print);
pluginFuncs->event = NULL;
pluginFuncs->javaClass = Private_GetJavaClass();
err = NPP_Initialize();
}
return err;
}
/*
* NP_Shutdown [optional]
* - Netscape needs to know about this symbol.
* - It calls this function after looking up its symbol after
* the last object of this kind has been destroyed.
*
*/
NPError
NP_Shutdown(void)
{
PLUGINDEBUGSTR("NP_Shutdown");
NPP_Shutdown();
return NPERR_NO_ERROR;
}
|
Update of /cvsroot/squeak/squeak/platforms/unix/doc/HowToBuildFromSource.html In directory sc8-pr-cvs1:/tmp/cvs-serv30143/doc/HowToBuildFromSource.html Added Files: HowToBuildFromSource-img1.png HowToBuildFromSource-node1.html HowToBuildFromSource-node2.html HowToBuildFromSource-node3.html HowToBuildFromSource-node4.html HowToBuildFromSource-node5.html HowToBuildFromSource-node6.html HowToBuildFromSource.css HowToBuildFromSource.html contents.png index.html index.png next.png next_g.png prev.png prev_g.png up.png up_g.png Log Message: Ian Piumarta's release 3.4.1 --- NEW FILE: HowToBuildFromSource-img1.png --- PNG Pä --- NEW FILE: HowToBuildFromSource-node1.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <!--Converted with LaTeX2HTML 2002 (1.67) original version by: Nikos Drakos, CBLU, University of Leeds * revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan * with significant contributions from: Jens Lippmann, Marek Rouchal, Martin Wilck and others --> <HTML> <HEAD> <TITLE>Contents</TITLE> <META NAME="description" CONTENT="Contents"> <META NAME="keywords" CONTENT="HowToBuildFromSource"> <META NAME="resource-type" CONTENT="document"> <META NAME="distribution" CONTENT="global"> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <META NAME="Generator" CONTENT="LaTeX2HTML v2002"> <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css"> <LINK REL="STYLESHEET" HREF="HowToBuildFromSource.css"> <LINK REL="next" HREF="HowToBuildFromSource-node2.html"> <LINK REL="previous" HREF="HowToBuildFromSource.html"> <LINK REL="up" HREF="HowToBuildFromSource.html"> <LINK REL="next" HREF="HowToBuildFromSource-node2.html"> </HEAD> <BODY > <!--Navigation Panel--> <A NAME="tex2html41" HREF="HowToBuildFromSource-node2.html"> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> <A NAME="tex2html37" HREF="HowToBuildFromSource.html"> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> <A NAME="tex2html31" HREF="HowToBuildFromSource.html"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> <A NAME="tex2html39" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> <BR> <B> Next:</B> <A NAME="tex2html42" HREF="HowToBuildFromSource-node2.html">1 configure - build</A> <B> Up:</B> <A NAME="tex2html38" HREF="HowToBuildFromSource.html">Building Unix Squeak (</A> <B> Previous:</B> <A NAME="tex2html32" HREF="HowToBuildFromSource.html">Building Unix Squeak (</A>   <B> <A NAME="tex2html40" HREF="HowToBuildFromSource-node5.html">Index</A></B> <BR> <BR> <!--End of Navigation Panel--> <BR> <H2><A NAME="SECTION00010000000000000000"> Contents</A> </H2> <!--Table of Contents--> <UL> <LI><A NAME="tex2html43" HREF="HowToBuildFromSource-node2.html">1 configure - build - install</A> <LI><A NAME="tex2html44" HREF="HowToBuildFromSource-node3.html">2 Generating your own VM and plugin sources</A> <LI><A NAME="tex2html45" HREF="HowToBuildFromSource-node4.html">3 Adding your own plugins</A> <UL> <LI><A NAME="tex2html46" HREF="HowToBuildFromSource-node4.html#SECTION00041000000000000000">3.1 Plugin-specific configuration</A> <LI><A NAME="tex2html47" HREF="HowToBuildFromSource-node4.html#SECTION00042000000000000000">3.2 Plugin-specific Makefile declarations and rules</A> <LI><A NAME="tex2html48" HREF="HowToBuildFromSource-node4.html#SECTION00043000000000000000">3.3 Examples taken from existing plugins</A> <LI><A NAME="tex2html49" HREF="HowToBuildFromSource-node4.html#SECTION00044000000000000000">3.4 Coping with VMMaker quirks</A> <LI><A NAME="tex2html50" HREF="HowToBuildFromSource-node4.html#SECTION00045000000000000000">3.5 If all else fails</A> </UL> <BR> <LI><A NAME="tex2html51" HREF="HowToBuildFromSource-node5.html">Index</A> </UL> <!--End of Table of Contents--> <P> <BR><HR> <ADDRESS> Ian Piumarta 2002-06-05 </ADDRESS> </BODY> </HTML> --- NEW FILE: HowToBuildFromSource-node2.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <!--Converted with LaTeX2HTML 2002 (1.67) original version by: Nikos Drakos, CBLU, University of Leeds * revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan * with significant contributions from: Jens Lippmann, Marek Rouchal, Martin Wilck and others --> <HTML> <HEAD> <TITLE>1 configure - build - install</TITLE> <META NAME="description" CONTENT="1 configure - build - install"> <META NAME="keywords" CONTENT="HowToBuildFromSource"> <META NAME="resource-type" CONTENT="document"> <META NAME="distribution" CONTENT="global"> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <META NAME="Generator" CONTENT="LaTeX2HTML v2002"> <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css"> <LINK REL="STYLESHEET" HREF="HowToBuildFromSource.css"> <LINK REL="next" HREF="HowToBuildFromSource-node3.html"> <LINK REL="previous" HREF="HowToBuildFromSource-node1.html"> <LINK REL="up" HREF="HowToBuildFromSource.html"> <LINK REL="next" HREF="HowToBuildFromSource-node3.html"> </HEAD> <BODY > <!--Navigation Panel--> <A NAME="tex2html64" HREF="HowToBuildFromSource-node3.html"> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> <A NAME="tex2html58" HREF="HowToBuildFromSource.html"> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> <A NAME="tex2html52" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> <A NAME="tex2html60" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> <A NAME="tex2html62" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> <BR> <B> Next:</B> <A NAME="tex2html65" HREF="HowToBuildFromSource-node3.html">2 Generating your own</A> <B> Up:</B> <A NAME="tex2html59" HREF="HowToBuildFromSource.html">Building Unix Squeak (</A> <B> Previous:</B> <A NAME="tex2html53" HREF="HowToBuildFromSource-node1.html">Contents</A>   <B> <A NAME="tex2html61" HREF="HowToBuildFromSource-node1.html">Contents</A></B>   <B> <A NAME="tex2html63" HREF="HowToBuildFromSource-node5.html">Index</A></B> <BR> <BR> <!--End of Navigation Panel--> <H1><A NAME="SECTION00020000000000000000"> 1 <TT>configure</TT> - <TT>build</TT> - <TT>install</TT></A> </H1> <P> Unix Squeak is built using the (almost) universal ``<TT>configure; make; make install</TT>''. If you haven't come across this before, read on... <P> Create a build<A NAME="43"></A> directory (which we will call `<TT>blddir</TT>' from now on) and then `<TT>cd</TT>' to it: <FONT COLOR="#0000ff"> <DIV ALIGN="LEFT"> <TT> <FONT COLOR="#0000ff"> <BR> $ mkdir blddir <BR> $ cd blddir <BR></FONT></TT> </DIV> </FONT> <P> A convenient place is just next to the <TT>platforms</TT> directory, like this: <FONT COLOR="#0000ff"> <DIV ALIGN="LEFT"> <TT> <FONT COLOR="#0000ff"> <BR> $ cd squeak <BR> $ ls <BR> platforms src ... <BR> $ mkdir bld <BR> $ cd bld <BR></FONT></TT> </DIV> </FONT> <P> Create the build<A NAME="55"></A> environment by running the script <TT>configure</TT> which lives in the <TT>platforms/unix/config</TT> directory. <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: The <TT>configure</TT> script accepts lots of options. To see a list of them, run: `<code>configure --help</code>' </FONT></BLOCKQUOTE> <P> Assuming you've created the <TT>blddir</TT> next to <TT>platforms</TT>, this would be: <FONT COLOR="#0000ff"> <DIV ALIGN="LEFT"> <TT> <FONT COLOR="#0000ff"> <BR> $ ../platforms/unix/config/configure <BR></FONT></TT> </DIV> </FONT> <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: This assumes that the VMMaker sources are in `<TT>../src</TT>'. However, since the Unix Squeak support code is independent of the image version from which VMMaker generated the interpreter/plugin sources, it is possible that your source distribution comes with more than one <TT>src</TT> directory (corresponding to more than one image version used to generate the sources). In such cases you will have to tell <TT>configure</TT> which source version to use, via the `-<TT>-with-src</TT>' option. For example, if there are two source directories called <TT>src-3.2gamma-4857</TT> and <TT>src-3.3.alpha-4881</TT> then you would use <I>one</I> of the following commands: <FONT COLOR="#ff0000"> <DIV ALIGN="LEFT"> <TT> <FONT COLOR="#ff0000"> <BR> $ .../configure --with-src=src-3.2gamma-4857 <BR> <I>or</I> <BR> $ .../configure --with-src=src-3.3alpha-4881 <BR></FONT></TT> </DIV> </FONT> </FONT></BLOCKQUOTE> <P> Build the VM and plugins by running <TT>make</TT>: <FONT COLOR="#0000ff"> <DIV ALIGN="LEFT"> <TT> <FONT COLOR="#0000ff"> <BR> $ make <BR></FONT></TT> </DIV> </FONT> <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: If you want to build just the VM (without external plugins) or just the external plugins (without the VM) then you can use: `<code>make squeak</code>' or `<code>make plugins</code>' respectively. </FONT></BLOCKQUOTE> <P> Finally install the VM, plugins and manual pages: <FONT COLOR="#0000ff"> <DIV ALIGN="LEFT"> <TT> <FONT COLOR="#0000ff"> <BR> $ su root <BR> $ make install <BR></FONT></TT> </DIV> </FONT> <P> <HR> <!--Navigation Panel--> <A NAME="tex2html64" HREF="HowToBuildFromSource-node3.html"> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> <A NAME="tex2html58" HREF="HowToBuildFromSource.html"> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> <A NAME="tex2html52" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> <A NAME="tex2html60" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> <A NAME="tex2html62" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> <BR> <B> Next:</B> <A NAME="tex2html65" HREF="HowToBuildFromSource-node3.html">2 Generating your own</A> <B> Up:</B> <A NAME="tex2html59" HREF="HowToBuildFromSource.html">Building Unix Squeak (</A> <B> Previous:</B> <A NAME="tex2html53" HREF="HowToBuildFromSource-node1.html">Contents</A>   <B> <A NAME="tex2html61" HREF="HowToBuildFromSource-node1.html">Contents</A></B>   <B> <A NAME="tex2html63" HREF="HowToBuildFromSource-node5.html">Index</A></B> <!--End of Navigation Panel--> <ADDRESS> Ian Piumarta 2002-06-05 </ADDRESS> </BODY> </HTML> --- NEW FILE: HowToBuildFromSource-node3.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <!--Converted with LaTeX2HTML 2002 (1.67) original version by: Nikos Drakos, CBLU, University of Leeds * revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan * with significant contributions from: Jens Lippmann, Marek Rouchal, Martin Wilck and others --> <HTML> <HEAD> <TITLE>2 Generating your own VM and plugin sources</TITLE> <META NAME="description" CONTENT="2 Generating your own VM and plugin sources"> <META NAME="keywords" CONTENT="HowToBuildFromSource"> <META NAME="resource-type" CONTENT="document"> <META NAME="distribution" CONTENT="global"> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <META NAME="Generator" CONTENT="LaTeX2HTML v2002"> <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css"> <LINK REL="STYLESHEET" HREF="HowToBuildFromSource.css"> <LINK REL="next" HREF="HowToBuildFromSource-node4.html"> <LINK REL="previous" HREF="HowToBuildFromSource-node2.html"> <LINK REL="up" HREF="HowToBuildFromSource.html"> <LINK REL="next" HREF="HowToBuildFromSource-node4.html"> </HEAD> <BODY > <!--Navigation Panel--> <A NAME="tex2html78" HREF="HowToBuildFromSource-node4.html"> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> <A NAME="tex2html72" HREF="HowToBuildFromSource.html"> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> <A NAME="tex2html66" HREF="HowToBuildFromSource-node2.html"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> <A NAME="tex2html74" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> <A NAME="tex2html76" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> <BR> <B> Next:</B> <A NAME="tex2html79" HREF="HowToBuildFromSource-node4.html">3 Adding your own</A> <B> Up:</B> <A NAME="tex2html73" HREF="HowToBuildFromSource.html">Building Unix Squeak (</A> <B> Previous:</B> <A NAME="tex2html67" HREF="HowToBuildFromSource-node2.html">1 configure - build</A>   <B> <A NAME="tex2html75" HREF="HowToBuildFromSource-node1.html">Contents</A></B>   <B> <A NAME="tex2html77" HREF="HowToBuildFromSource-node5.html">Index</A></B> <BR> <BR> <!--End of Navigation Panel--> <H1><A NAME="SECTION00030000000000000000"> 2 Generating your own VM and plugin sources</A> </H1> <P> Generating your own VM/plugin sources might be necessary for various reasons: <UL> <LI>you want to change the mix of internal vs. external plugins </LI> <LI>you want to remove some plugins from the VM that you will never use </LI> <LI>you've pulled in some updates that modify the Interpreter or plugins </LI> <LI>you've filed-in (or written) a whole new plugin </LI> <LI>etc... </LI> </UL> <P> Version 3.2 (and later) of Unix Squeak use <A NAME="tex2html2" HREF="http://minnow.cc.gatech.edu/squeak/2105">VMMaker</A><A NAME="100"></A> to generate the core interpreter and plugin sources. <P> Start Squeak in the top-level directory (the one containing the <TT>platforms</TT> directory); for example: <FONT COLOR="#0000ff"> <DIV ALIGN="LEFT"> <TT> <FONT COLOR="#0000ff"> <BR> $ ls <BR> src platforms ... <BR> $ squeak MyCoolPlugin.image <BR></FONT></TT> </DIV> </FONT> <P> Open a VMMakerTool and modify the setup to your liking. <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: The VMMaker configuration used to build the distributions of Unix Squeak is available in <TT>platforms/unix/config/VMMaker.config</TT>.<A NAME="108"></A> </FONT></BLOCKQUOTE> <P> Then click on the relevant ``<I>generate ...</I>'' button. You can now `<TT>configure; make; make install</TT>' in your <TT>blddir</TT> (as described above). <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: You only need to run <TT>configure</TT><A NAME="515"></A> <B><U>once</U></B> for a given <TT>blddir</TT> (on the same host). If you modify the choice of plugins (or change whether they're internal/external) then you can update the build environment by running the <TT>config.status</TT><A NAME="517"></A> script in the <TT>bldddir</TT>, like this: <FONT COLOR="#ff0000"> <DIV ALIGN="LEFT"> <TT> $ squeak MyCoolPlugin.image <BR> ... generate new sources ... <BR> $ cd blddir <BR> $ ./config.status <BR> $ make <BR></TT> </DIV> </FONT>This is <I>much</I> faster than running <TT>configure</TT> all over again. (In fact, <TT>make</TT> should detect any changes to the plugin configuration and re-run <TT>config.status</TT> for you automatically.) </FONT></BLOCKQUOTE> <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: `<TT>configure</TT>' doesn't actually create any files. The last thing it does is run `<TT>config.status</TT>' to create the configured <I>file</I>s in <TT>blddir</TT> from the corresponding <I>file.in</I>s in the <TT>unix/config</TT> directory. So in the remainder of this document the phrase `during configuration' means <I>either</I> when running `<TT>configure</TT>' for the first time <I>or</I> running `<TT>config.status</TT>' to update an already <TT>configure</TT>d build environment. </FONT></BLOCKQUOTE> <P> <HR> <!--Navigation Panel--> <A NAME="tex2html78" HREF="HowToBuildFromSource-node4.html"> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> <A NAME="tex2html72" HREF="HowToBuildFromSource.html"> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> <A NAME="tex2html66" HREF="HowToBuildFromSource-node2.html"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> <A NAME="tex2html74" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> <A NAME="tex2html76" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> <BR> <B> Next:</B> <A NAME="tex2html79" HREF="HowToBuildFromSource-node4.html">3 Adding your own</A> <B> Up:</B> <A NAME="tex2html73" HREF="HowToBuildFromSource.html">Building Unix Squeak (</A> <B> Previous:</B> <A NAME="tex2html67" HREF="HowToBuildFromSource-node2.html">1 configure - build</A>   <B> <A NAME="tex2html75" HREF="HowToBuildFromSource-node1.html">Contents</A></B>   <B> <A NAME="tex2html77" HREF="HowToBuildFromSource-node5.html">Index</A></B> <!--End of Navigation Panel--> <ADDRESS> Ian Piumarta 2002-06-05 </ADDRESS> </BODY> </HTML> --- NEW FILE: HowToBuildFromSource-node4.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <!--Converted with LaTeX2HTML 2002 (1.67) original version by: Nikos Drakos, CBLU, University of Leeds * revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan * with significant contributions from: Jens Lippmann, Marek Rouchal, Martin Wilck and others --> <HTML> <HEAD> <TITLE>3 Adding your own plugins</TITLE> <META NAME="description" CONTENT="3 Adding your own plugins"> <META NAME="keywords" CONTENT="HowToBuildFromSource"> <META NAME="resource-type" CONTENT="document"> <META NAME="distribution" CONTENT="global"> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <META NAME="Generator" CONTENT="LaTeX2HTML v2002"> <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css"> <LINK REL="STYLESHEET" HREF="HowToBuildFromSource.css"> <LINK REL="next" HREF="HowToBuildFromSource-node5.html"> <LINK REL="previous" HREF="HowToBuildFromSource-node3.html"> <LINK REL="up" HREF="HowToBuildFromSource.html"> <LINK REL="next" HREF="HowToBuildFromSource-node5.html"> </HEAD> <BODY > <!--Navigation Panel--> <A NAME="tex2html92" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> <A NAME="tex2html86" HREF="HowToBuildFromSource.html"> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> <A NAME="tex2html80" HREF="HowToBuildFromSource-node3.html"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> <A NAME="tex2html88" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> <A NAME="tex2html90" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> <BR> <B> Next:</B> <A NAME="tex2html93" HREF="HowToBuildFromSource-node5.html">Index</A> <B> Up:</B> <A NAME="tex2html87" HREF="HowToBuildFromSource.html">Building Unix Squeak (</A> <B> Previous:</B> <A NAME="tex2html81" HREF="HowToBuildFromSource-node3.html">2 Generating your own</A>   <B> <A NAME="tex2html89" HREF="HowToBuildFromSource-node1.html">Contents</A></B>   <B> <A NAME="tex2html91" HREF="HowToBuildFromSource-node5.html">Index</A></B> <BR> <BR> <!--End of Navigation Panel--> <!--Table of Child-Links--> <A NAME="CHILD_LINKS"><STRONG>Subsections</STRONG></A> <UL> <LI><A NAME="tex2html94" HREF="HowToBuildFromSource-node4.html#SECTION00041000000000000000">3.1 Plugin-specific configuration</A> <UL> <LI><A NAME="tex2html95" HREF="HowToBuildFromSource-node4.html#SECTION00041100000000000000">3.1.1 <TT>AC_PLUGIN_CHECK_LIB(<I>lib</I>,<I>func</I>)</TT></A> <LI><A NAME="tex2html96" HREF="HowToBuildFromSource-node4.html#SECTION00041200000000000000">3.1.2 <TT>AC_PLUGIN_DEFINE_UNQUOTED(<I>keyword</I>,<I>text</I>)</TT></A> <LI><A NAME="tex2html97" HREF="HowToBuildFromSource-node4.html#SECTION00041300000000000000">3.1.3 Plugin-specific variables</A> </UL> <BR> <LI><A NAME="tex2html98" HREF="HowToBuildFromSource-node4.html#SECTION00042000000000000000">3.2 Plugin-specific <TT>Makefile</TT> declarations and rules</A> <UL> <LI><A NAME="tex2html99" HREF="HowToBuildFromSource-node4.html#SECTION00042100000000000000">3.2.1 The anatomy of a plugin's <TT>Makefile</TT></A> <LI><A NAME="tex2html100" HREF="HowToBuildFromSource-node4.html#SECTION00042200000000000000">3.2.2 A note about <TT>$(COMPILE)</TT> and <TT>$(LINK)</TT> commands</A> <LI><A NAME="tex2html101" HREF="HowToBuildFromSource-node4.html#SECTION00042300000000000000">3.2.3 Specifying additional source directories</A> <LI><A NAME="tex2html102" HREF="HowToBuildFromSource-node4.html#SECTION00042400000000000000">3.2.4 Including additional material in the default <TT>Makefile</TT></A> <LI><A NAME="tex2html103" HREF="HowToBuildFromSource-node4.html#SECTION00042500000000000000">3.2.5 Replacing the default <TT>Makefile</TT> entirely</A> </UL> <BR> <LI><A NAME="tex2html104" HREF="HowToBuildFromSource-node4.html#SECTION00043000000000000000">3.3 Examples taken from existing plugins</A> <UL> <LI><A NAME="tex2html105" HREF="HowToBuildFromSource-node4.html#SECTION00043100000000000000">3.3.1 Configuration</A> <LI><A NAME="tex2html106" HREF="HowToBuildFromSource-node4.html#SECTION00043200000000000000">3.3.2 Customising the <TT>Makefile</TT></A> </UL> <BR> <LI><A NAME="tex2html107" HREF="HowToBuildFromSource-node4.html#SECTION00044000000000000000">3.4 Coping with VMMaker quirks</A> <LI><A NAME="tex2html108" HREF="HowToBuildFromSource-node4.html#SECTION00045000000000000000">3.5 If all else fails</A> </UL> <!--End of Table of Child-Links--> <HR> <H1><A NAME="SECTION00040000000000000000"> 3 Adding your own plugins</A> </H1> <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: This section is intended primarily for plugin developers. </FONT></BLOCKQUOTE> <P> If your plugin<A NAME="146"></A> requires no platform-specific tweaks then there's nothing for you to do. <TT>configure</TT> (and <TT>config.status</TT>) will provide a default <TT>Makefile</TT> for it that should work. If your plugin requires only platform-independent tweaks (and/or additional hand-written code) then these go in <TT>platforms/Cross/plugins</TT>, and there's nothing for you to do (in Unixland). <P> On the other hand, if you require special <TT>configure</TT> tests or additional declarations/rules in your plugin's <TT>Makefile</TT> then you need to specify them explicitly. <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: Unix Squeak subscribes to the following philopsophy: </FONT></BLOCKQUOTE> <P> <BLOCKQUOTE><FONT COLOR="#ff0000"><I>Absolutely everything that is specific<A NAME="154"></A> to Unix (sources, headers, <TT>configure</TT> and <TT>Makefile</TT> extensions, etc.) lives under <TT>platforms/unix</TT>.</I> </FONT></BLOCKQUOTE> <P> <BLOCKQUOTE><FONT COLOR="#ff0000">In other words: there is not (nor aught there be) <I>any</I> Unix-related information under the <TT>platforms/Cross</TT> directory. (Unix Squeak is entirely encapsulated under <TT>platforms/unix</TT> and is utterly immune to ``random junk'' elsewhere in the <TT>platforms</TT> tree.) </FONT></BLOCKQUOTE> <P> First you must create a new directory<A NAME="163"></A> under <TT>platforms/unix/plugins</TT> named after your plugin. This directory will hold the files describing the additional configuration checks and/or <TT>Makefile</TT> contents. For example, if your plugin is called ``MyCoolPlugin'' then <FONT COLOR="#0000ff"> <DIV ALIGN="LEFT"> <TT> <FONT COLOR="#0000ff"> <BR> $ mkdir platforms/unix/plugins/MyCoolPlugin <BR></FONT></TT> </DIV> </FONT> <P> would be the thing to do. (The following sections will refer to this directory as <TT>platdep</TT> since the full path is quite a mouthful of typing for my lazy fingers.) <P> <H2><A NAME="SECTION00041000000000000000"> 3.1 Plugin-specific configuration</A> </H2> <P> Your plugin can ask <TT>configure</TT><A NAME="173"></A> to run additional tests (and to set additional variables in its output files) simply by including a file called <TT>acinclude.m4</TT><A NAME="522"></A> in it's <TT>platdep</TT> directory. <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: The <TT>configure</TT><A NAME="523"></A> script is `compiled' from several other files. If you create a `<TT>platdep./acinclude.m4</TT>' file then you <I>must</I> `recompile'<A NAME="524"></A> <TT>configure</TT>. You can do this by `<TT>cd</TT>'ing to <TT>unix/config</TT> and running `<TT>make</TT>', or (if you have GNU <TT>make</TT>) from the <TT>blddir</TT> like this: <FONT COLOR="#ff0000"> <DIV ALIGN="LEFT"> <TT> <FONT COLOR="#ff0000"> <BR> $ make -C ../platforms/unix/config <BR></FONT></TT> </DIV> </FONT> </FONT></BLOCKQUOTE> <P> In addition to the usual <TT>autoconf</TT> macros, the following macros<A NAME="527"></A> are available specifically for Squeak plugins to use: <P> <H3><A NAME="SECTION00041100000000000000"> 3.1.1 <TT>AC_PLUGIN_CHECK_LIB(<I>lib</I>,<I>func</I>)</TT></A> </H3> <A NAME="529"></A> <P> This is similar to the <TT>autoconf</TT> `<TT>AC_CHECK_LIB</TT>' macro. <P> <I>func</I> is the name of a function required by the plugin, defined in the external (system) library <I>lib</I>. The macro checks that the library is available (via `<TT>-l<I>lib</I></TT>') and then adds it to the list of libraries required by the plugin (see the explanation of <TT>[plibs]</TT> in Section <A HREF="HowToBuildFromSource-node4.html#sec:plibs">3.2.1</A> for a description of how library dependencies for plugins are handled). <P> If <I>func</I> cannot be found in <I>lib</I> then the plugin will be disabled and a message to that effect printed during configuration. (The VM can still be built, <I>without</I> rerunning VMMaker or reconfiguring, and the plugin will simply be ommitted from it.) <P> <H3><A NAME="SECTION00041200000000000000"> 3.1.2 <TT>AC_PLUGIN_DEFINE_UNQUOTED(<I>keyword</I>,<I>text</I>)</TT></A> </H3> <P> This<A NAME="532"></A> is similar to the <TT>autoconf</TT> `<TT>AC_DEFINE_UNQUOTED</TT>' macro. <P> <I>keyword</I> is a <TT>Makefile</TT> keyword (usually of the form `[<I>name</I>]') and <I>text</I> is arbitrary text to be associated with it. Calling this macro causes <TT>mkmf</TT> to substitute <I>text</I> for all occurrences of <I>keyword</I> in the <TT>Makefile</TT> generated for the plugin. <P> <H3><A NAME="SECTION00041300000000000000"> 3.1.3 Plugin-specific variables</A> </H3> <P> The following variables are also set during the execution of a plugin-specific <TT>acinclude.m4</TT>: <P> <DL COMPACT> <DT></DT> <DD><TT>${plugin}</TT> is the name of the plugin; </DD> <DT></DT> <DD><TT>${topdir}</TT> is the path to the top-level directory (containing <TT>platforms</TT>); </DD> <DT></DT> <DD><TT>${vmmdir}</TT> is the path to the VMMaker `<TT>src</TT>' directory. </DD> </DL> <P> <H2><A NAME="SECTION00042000000000000000"> 3.2 Plugin-specific <TT>Makefile</TT> declarations and rules</A> </H2> <P> Three<A NAME="534"></A> mechanisms are avilable for this: <OL> <LI>scanning additional dirrectories for sources and headers; </LI> <LI>including a few additional lines into the default <TT>Makefile</TT>; and </LI> <LI>replacing entirely the default <TT>Makefile</TT> with a hand-written one. </LI> </OL> (The last option isn't as scary as it might sound: read on...) <P> <H3><A NAME="SECTION00042100000000000000"> 3.2.1 The anatomy of a plugin's <TT>Makefile</TT></A> </H3> <P> Before proceeding, let's take a minute to understand how Unix Squeak compiles and links files in its default <TT>Makefile</TT> for plugins. The default <TT>Makefile</TT><A NAME="536"></A><A NAME="537"></A> looks like this: <P> <BLOCKQUOTE> <BLOCKQUOTE> <FONT COLOR="#000000"> <DIV ALIGN="LEFT"> <TT> # default Makefile for Unix Squeak plugins <BR> <BR>[make_cfg] <BR>[make_plg] <BR> <BR> XINCLUDES = [includes] <BR> OBJS = [targets] <BR> TARGET = [target] <BR> PLIBS = [plibs] <BR> <BR>[make_inc] <BR> <BR>$(TARGET) : $(OBJS) Makefile <BR> $(LINK) $(TARGET) $(OBJS) $(PLIBS) <BR> <BR>[make_targets] <BR> <BR>.force : <BR></TT> </DIV> </FONT> </BLOCKQUOTE> </BLOCKQUOTE> <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: The keywords<A NAME="541"></A> appearing between `<TT>[</TT> square brackets <TT>]</TT>' are substituted during configuration by a preprocessor called `<TT>mkmf</TT>'<A NAME="542"></A> according to the kind of plugin (internal/external) being built. </FONT></BLOCKQUOTE> <P> <TT><B>[make_cfg]</B></TT><A NAME="544"></A> <A NAME="545"></A> is the configured variable section. It contains the platform-specific information gleaned by <TT>configure</TT> while it was figuring out which compiler you have, what flags your linker needs, where to install stuff, and so on. <P> <TT><B>[make_plg]</B></TT><A NAME="547"></A> <A NAME="548"></A> contains a handful of definitions which depend on whether the plugin is being compiled as internal or external: <BLOCKQUOTE> <TABLE CELLPADDING=3> <TR><TD ALIGN="LEFT"><TT></TD><TD ALIGN="LEFT">o </TT></TD> <TD ALIGN="LEFT"> </TD><TD ALIGN="LEFT">the extension for object files</TD> </TR> <TR><TD ALIGN="LEFT"><TT></TD><TD ALIGN="LEFT">a </TT></TD> <TD ALIGN="LEFT"> </TD><TD ALIGN="LEFT">the extension for plugins</TD> </TR> <TR><TD ALIGN="LEFT"><TT></TD><TD ALIGN="LEFT">COMPILE </TT></TD> <TD ALIGN="LEFT"> </TD><TD ALIGN="LEFT">the command to compile a source file into an object file</TD> </TR> <TR><TD ALIGN="LEFT"><TT></TD><TD ALIGN="LEFT">LINK </TT></TD> <TD ALIGN="LEFT"> </TD><TD ALIGN="LEFT">the command to link one or more object files into a plugin</TD> </TR> </TABLE> </BLOCKQUOTE> <P> For internal plugins: <TT>$o</TT> is `<TT>.o</TT>' and <TT>$a</TT> is `<TT>.a</TT>'. <TT>$(COMPILE)</TT> is the C compiler (`<TT>$(CC) ... -o</TT>', so the first thing after the command <I>must</I> be the output filename) and <TT>$(LINK)</TT> is archiver (`<TT>ar -rc</TT>', again requiring the output file to follow immediately). Note that internal plugins are built as `<TT>ar</TT>' archives before being linked into the final binary. <P> For external plugins: <TT>$o</TT> is `<TT>.lo</TT>', <TT>$a</TT> is `<TT>.la</TT>', and <TT>$(COMPILE)</TT> and <TT>$(LINK)</TT> are invocations of `<TT>libtool</TT>' to create position-independent objects and shared libraries (with a `<TT>-o</TT>' appearing right at the end, so the first thing after the command <I>must</I> be the output filename). <P> <TT><B>[includes]</B></TT><A NAME="551"></A> <A NAME="552"></A> is a list of `<TT>-I<I>dir</I></TT>' compiler flags, one for each of the directories<A NAME="554"></A> <FONT COLOR="#000000"> <DIV ALIGN="LEFT"> <TT> src/plugins/<I>name</I> <BR> src/vm/intplugins/<I>name</I> <BR> platforms/Cross/plugins/<I>name</I> <BR> platforms/unix/plugins/<I>name</I> <BR></TT> </DIV> </FONT>in which at least one header file is present. <P> <TT><B>[targets]</B></TT><A NAME="557"></A> <A NAME="558"></A> is a list of object files corresponding to the source (<TT>.c</TT>) files found in the directories:<A NAME="559"></A> <FONT COLOR="#000000"> <DIV ALIGN="LEFT"> <TT> src/plugins/<I>name</I>/*.c <BR> src/vm/intplugins/<I>name</I>/*.c <BR> platforms/Cross/plugins/<I>name</I>/*.c <BR> platforms/unix/plugins/<I>name</I>/*.c <BR></TT> </DIV> </FONT>where each source file has been stripped of the directory name and had the `<TT>.c</TT>' converted into `<TT>$o</TT>'. <P> <TT><B>[target]</B></TT><A NAME="562"></A> <A NAME="563"></A> is the name of the plugin, including the <TT>$a</TT> extension. <P> <TT><B>[plibs]</B></TT><A NAME="565"></A> <A NAME="566"></A> <A NAME="sec:plibs"></A>is a list of zero or more libraries on which the plugin depends (as detected using the macro <TT>AC_PLUGIN_CHECK_LIB</TT> in the plugin-specific <TT>acinclude.m4</TT>). If the plugin is being built internally then this list is empty and the required libraries are included in the final link command. If the plugin is being built externally then the plugin itself (a shared object) is linked against these libraries (via <TT>[plist]</TT>) rather than with the main VM binary. <P> (This is to ensure that a missing shared object needed by an external plugin will only affect the operation of that plugin and not prevent the rest of the VM from running, which would be the case if the entire VM were linked against it.) <P> <TT><B>[make_inc]</B></TT><A NAME="568"></A> <A NAME="569"></A> is the contents of the <TT>Makefile.inc</TT> file in your plugin's <TT>platdep</TT> directory (or empty if this file doesn't exist). <P> <TT><B>[make_targets]</B></TT><A NAME="571"></A> <A NAME="572"></A> is a list of rules<A NAME="573"></A> for building the files listed in <TT>[targets]</TT>. Each rule<A NAME="345"></A> looks like this: <P> <DIV ALIGN="LEFT"> <TT> name$o : <I>original/source/dir/</I>name.c <BR> $(COMPILE) name$o <I>original/source/dir/</I>name.c <BR></TT> </DIV> <P> <H3><A NAME="SECTION00042200000000000000"> 3.2.2 A note about <TT>$(COMPILE)</TT> and <TT>$(LINK)</TT> commands</A> </H3> <P> You should <I>never</I> pass additional flags to these commands<A NAME="575"></A><A NAME="576"></A><A NAME="577"></A> explicitly. This is because you cannot know how they are defined. (Their definitions depend on whether the plugin is being built internally or externally -- and might even change radically in future releases of Unix Squeak.) <P> Instead you should pass additional compiler/linker flags<A NAME="578"></A> to these commands by setting the following variables in `<TT>Makefile.inc</TT>' or `<TT>Makefile.in</TT>': <BLOCKQUOTE> <A NAME="579"></A> <A NAME="580"></A> <A NAME="581"></A> <A NAME="582"></A> <TABLE CELLPADDING=3> <TR><TD ALIGN="LEFT"><TT></TD><TD ALIGN="LEFT">XCPPFLAGS </TT></TD> <TD ALIGN="LEFT"> </TD><TD ALIGN="LEFT">`<TT>-I</TT>' flags for <TT>cpp</TT></TD> </TR> <TR><TD ALIGN="LEFT"><TT></TD><TD ALIGN="LEFT">XDEFS </TT></TD> <TD ALIGN="LEFT"> </TD><TD ALIGN="LEFT">`<TT>-D</TT>' flags for <TT>cpp</TT></TD> </TR> <TR><TD ALIGN="LEFT"><TT></TD><TD ALIGN="LEFT">XCFLAGS </TT></TD> <TD ALIGN="LEFT"> </TD><TD ALIGN="LEFT">anything to be passed to the compiler</TD> </TR> <TR><TD ALIGN="LEFT"><TT></TD><TD ALIGN="LEFT">XLDFLAGS </TT></TD> <TD ALIGN="LEFT"> </TD><TD ALIGN="LEFT">anything to be passed to the linker</TD> </TR> </TABLE> </BLOCKQUOTE> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: `<TT>mkmf</TT>' already uses `<TT>XINCLUDES</TT>'<A NAME="584"></A> <A NAME="585"></A> to pass the list of directories containing plugin header files to <TT>cpp</TT>. You can redefine it if you like, but make sure that `<TT>[includes]</TT>' appears in its definition (or in the definition of `<TT>XCPPFLAGS</TT>'). </FONT></BLOCKQUOTE> <P> <H3><A NAME="SECTION00042300000000000000"> 3.2.3 Specifying additional source directories</A> </H3> <P> <TT>mkmf</TT><A NAME="586"></A> looks for a file in your plugin's <TT>platdep</TT> directory called `<TT>mkmf.subdirs</TT>'.<A NAME="587"></A> If this file exists then it should contain a list of directory names relative to the top-level directory (the one containing the <TT>src</TT> and <TT>platform</TT> directories). These directories<A NAME="391"></A> will be added to the list of locations searched for `<TT>.c</TT>' and `<TT>.h</TT>' files while constructing the substitutions for `<TT>[includes]</TT>', `<TT>[targets]</TT>' and `<TT>[make_targets]</TT>'. <P> <H3><A NAME="SECTION00042400000000000000"> 3.2.4 Including additional material in the default <TT>Makefile</TT></A> </H3> <P> If the file <TT>platdep/Makefile.inc</TT><A NAME="589"></A> exists then <TT>mkmf</TT> will substitute its contents into the <TT>Makefile</TT> in place of the <TT>[make_inc]</TT> keyword. <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: <TT>Makefile.inc</TT><A NAME="590"></A> is read into the <TT>Makefile</TT> under construction <I>before</I> <TT>mkmf</TT> performs substitutions on the `<TT>[keyword]</TT>'s. In other words, your <TT>Makefile.inc</TT> can use the above keywords to include relevant declarations and rules without worrying about whether the plugin is internal or external. </FONT></BLOCKQUOTE> <P> <H3><A NAME="SECTION00042500000000000000"> 3.2.5 Replacing the default <TT>Makefile</TT> entirely</A> </H3> <P> If neither of the above are sufficient then you can create a complete <TT>Makefile</TT><A NAME="592"></A> template called <TT>platdep/Makefile.in</TT>.<A NAME="593"></A> <TT>mkmf</TT> will use this template instead of the default <TT>Makefile</TT> template shown earlier, and will perform keyword substitutions on it as described above to create the final <TT>Makefile</TT>. (In other words, simply copying the default template shown earlier will result in a <TT>Makefile</TT> identical to the one that <TT>mkmf</TT> would have produced by default. <P> <H2><A NAME="SECTION00043000000000000000"> 3.3 Examples taken from existing plugins</A> </H2> <P> By way of example we'll look at how two existing plugins specialise their configuration and <TT>Makefile</TT>s. <P> <H3><A NAME="SECTION00043100000000000000"> 3.3.1 Configuration</A> </H3> <P> The <TT>B3DAcceleratorPlugin</TT> requires OpenGL in order to compile. The file <TT>unix/plugins/B3DAcceleratorPlugin/acinclude.m4</TT><A NAME="594"></A> contains a single call to an <TT>autoconf</TT>-style macro: <P> <DIV ALIGN="LEFT"> <TT> AC_PLUGIN_SEARCH_LIBS(glIsEnabled, GL) <BR></TT> </DIV> <P> This works similarly to the <TT>autoconf</TT> `<TT>AC_SEARCH_LIBS</TT>' macro: If a library <TT>libGL.{a,so}</TT> (OpenGL) exists and exports the function <TT>glIsEnabled()</TT> then `<TT>-lGL</TT>' is added to the final VM link command. Otherwise the plugin is disabled (and a message warning of the fact is printed). <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: There's a bug here. This should also check for `<TT>GL_VERSION_1_1</TT>' in headers. </FONT></BLOCKQUOTE> <P> <H3><A NAME="SECTION00043200000000000000"> 3.3.2 Customising the <TT>Makefile</TT></A> </H3> <P> The <TT>Mpeg3Plugin</TT> requires a (modified) <TT>libmpeg</TT> to be compiled along with it. The sources for this library are in (several) subdirectories of <TT>Cross/Meg3Plugin</TT> and they require additional <TT>cpp</TT> definitions in order to compile correctly. <P> To cope with the additional directories, <TT>unix/plugins/Mpeg3Plugin/mkmf.subdirs</TT><A NAME="596"></A> simply lists them: <P> <DIV ALIGN="LEFT"> <TT> platforms/Cross/plugins/Mpeg3Plugin/libmpeg <BR> platforms/Cross/plugins/Mpeg3Plugin/libmpeg/audio <BR> platforms/Cross/plugins/Mpeg3Plugin/libmpeg/video <BR></TT> </DIV> <P> To cope with the additional <TT>cpp</TT> definitions, we could have written a tiny <TT>Makefile.inc</TT><A NAME="597"></A> containing: <P> <DIV ALIGN="LEFT"> <TT> XDEFS = -DNOPTHREADS <BR></TT> </DIV> <P> Unfortunately the additional source directories contain various utility and test programs (which <I>must not</I> be built) so we cannot rely on <TT>mkmf</TT> generating the correct <TT>[targets]</TT> list. <P> Instead we just copy the default <TT>Makefile</TT> ``template'' (shown above) as <TT>Mpeg3Plugin/Makefile.in</TT> and insert the required list of targets (and <TT>cpp</TT> definition) manually. The end result<A NAME="598"></A> looks like this: <BLOCKQUOTE> <BLOCKQUOTE> <FONT COLOR="#000000"> <DIV ALIGN="LEFT"> <TT> # Makefile.in for Mpeg3Plugin in Unix Squeak <BR> <BR>[make_cfg] <BR>[make_plg] <BR> <BR> TARGET = Mpeg3Plugin$a <BR> <BR> PLUGIN = Mpeg3Plugin$o <BR> VIDEO = getpicture$o headers$o idct$o macroblocks$o <I>etc...</I> <BR> AUDIO = dct$o header$o layer1$o layer2$o layer3$o <I>etc...</I> <BR> LIBMPEG = bitstream$o changesForSqueak$o libmpeg3$o <I>etc...</I> <BR> <BR> OBJS = $(PLUGIN) $(VIDEO) $(AUDIO) $(LIBMPEG) <BR> <BR> XINCLUDES = [includes] <BR> XDEFS = -DNOPTHREADS <BR> <BR>$(TARGET) : $(OBJS) Makefile <BR> $(LINK) $(TARGET) $(OBJS) <BR> <BR>[make_targets] <BR> <BR>.force : <BR></TT> </DIV> </FONT> </BLOCKQUOTE> </BLOCKQUOTE> <P> <BLOCKQUOTE> <FONT COLOR="#ff0000"> Note: The default `<TT>[make_targets]</TT>' will contain additional rules for the objects that we're trying to avoid building (because it's built from an exhaustive list of `<TT>.c</TT>' files in the source directories). This does no harm since the offending rules can never be triggered (their targets are not listed in `<TT>OBJS</TT>'). </FONT></BLOCKQUOTE> <P> <H2><A NAME="SECTION00044000000000000000"> 3.4 Coping with VMMaker quirks</A> </H2> <P> VMMaker<A NAME="478"></A> will refuse to compile a plugin if it thinks the plugin requires platform support. This is ``all-or-nothing'': if platform support is required on <I>one</I> platform then it is required on <I>all</I> platforms (even if the plugin compiles quite happily without platform support in Unix). <P> The easiest way to add ``null'' platform support is to place an empty `<TT>Makefile.inc</TT>' in the plugin's <TT>platdep</TT> directory. (To see this in action, look in <TT>unix/plugins/JPEGReadWriter2Plugin</TT>.) <P> <H2><A NAME="SECTION00045000000000000000"> 3.5 If all else fails</A> </H2> <P> (Where<A NAME="485"></A> ``all else failing'' is defined as: ``after trying for 20 minutes and still getting nowhere''.) <P> If you're writing a plugin that needs platform support (beyond dumb inclusion of a few additional `<TT>.c</TT>' files) and this document has been of no help at all (or if you understood it but you're still suffering from ``all else failing'') then send me <A NAME="tex2html3" HREF="mailto:ian...@in...">mail</A> and I'll be happy to help you with the various platdep files. <P> <P> <HR> <!--Navigation Panel--> <A NAME="tex2html92" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> <A NAME="tex2html86" HREF="HowToBuildFromSource.html"> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> <A NAME="tex2html80" HREF="HowToBuildFromSource-node3.html"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> <A NAME="tex2html88" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> <A NAME="tex2html90" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> <BR> <B> Next:</B> <A NAME="tex2html93" HREF="HowToBuildFromSource-node5.html">Index</A> <B> Up:</B> <A NAME="tex2html87" HREF="HowToBuildFromSource.html">Building Unix Squeak (</A> <B> Previous:</B> <A NAME="tex2html81" HREF="HowToBuildFromSource-node3.html">2 Generating your own</A>   <B> <A NAME="tex2html89" HREF="HowToBuildFromSource-node1.html">Contents</A></B>   <B> <A NAME="tex2html91" HREF="HowToBuildFromSource-node5.html">Index</A></B> <!--End of Navigation Panel--> <ADDRESS> Ian Piumarta 2002-06-05 </ADDRESS> </BODY> </HTML> --- NEW FILE: HowToBuildFromSource-node5.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <!--Converted with LaTeX2HTML 2002 (1.67) original version by: Nikos Drakos, CBLU, University of Leeds * revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan * with significant contributions from: Jens Lippmann, Marek Rouchal, Martin Wilck and others --> <HTML> <HEAD> <TITLE>Index</TITLE> <META NAME="description" CONTENT="Index"> <META NAME="keywords" CONTENT="HowToBuildFromSource"> <META NAME="resource-type" CONTENT="document"> <META NAME="distribution" CONTENT="global"> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <META NAME="Generator" CONTENT="LaTeX2HTML v2002"> <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css"> <LINK REL="STYLESHEET" HREF="HowToBuildFromSource.css"> <LINK REL="next" HREF="HowToBuildFromSource-node6.html"> <LINK REL="previous" HREF="HowToBuildFromSource-node4.html"> <LINK REL="up" HREF="HowToBuildFromSource.html"> <LINK REL="next" HREF="HowToBuildFromSource-node6.html"> </HEAD> <BODY > <!--Navigation Panel--> <A NAME="tex2html119" HREF="HowToBuildFromSource-node6.html"> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> <A NAME="tex2html115" HREF="HowToBuildFromSource.html"> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> <A NAME="tex2html109" HREF="HowToBuildFromSource-node4.html"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> <A NAME="tex2html117" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> <BR> <B> Next:</B> <A NAME="tex2html120" HREF="HowToBuildFromSource-node6.html">About this document ...</A> <B> Up:</B> <A NAME="tex2html116" HREF="HowToBuildFromSource.html">Building Unix Squeak (</A> <B> Previous:</B> <A NAME="tex2html110" HREF="HowToBuildFromSource-node4.html">3 Adding your own</A>   <B> <A NAME="tex2html118" HREF="HowToBuildFromSource-node1.html">Contents</A></B> <BR> <BR> <!--End of Navigation Panel--> <BR> <H2><A NAME="SECTION00050000000000000000"> Index</A> </H2><DL COMPACT> <DT><STRONG><TT>$(COMPILE)</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#575">3.2.2</A> <DT><STRONG><TT>$(LINK)</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#576">3.2.2</A> <DT><STRONG><TT>$(XCFLAGS)</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#581">3.2.2</A> <DT><STRONG><TT>$(XCPPFLAGS)</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#579">3.2.2</A> <DT><STRONG><TT>$(XDEFS)</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#580">3.2.2</A> <DT><STRONG><TT>$(XINCLUDES)</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#584">3.2.2</A> <DT><STRONG><TT>$(XLDFLAGS)</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#582">3.2.2</A> <DT><STRONG><TT>[includes]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#551">3.2.1</A> <DT><STRONG><TT>[make_cfg]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#544">3.2.1</A> <DT><STRONG><TT>[make_inc]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#568">3.2.1</A> <DT><STRONG><TT>[make_plg]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#547">3.2.1</A> <DT><STRONG><TT>[make_targets]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#571">3.2.1</A> <DT><STRONG><TT>[plibs]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#565">3.2.1</A> <DT><STRONG><TT>[target]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#562">3.2.1</A> <DT><STRONG><TT>[targets]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#557">3.2.1</A> <DT><STRONG><TT>AC_PLUGIN_CHECK_LIB</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#529">3.1.1</A> <DT><STRONG><TT>AC_PLUGIN_DEFINE_UNQUOTED</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#532">3.1.2</A> <DT><STRONG><TT>acinclude.m4</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#522">3.1</A> <DL COMPACT> <DT><STRONG>example</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#594">3.3.1</A> </DL> <DT><STRONG>additional plugin source directories</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#391">3.2.3</A> <DT><STRONG>build directory</STRONG> <DD><DL COMPACT> <DT><STRONG>configuring</STRONG> <DD><A HREF="HowToBuildFromSource-node2.html#55">1</A> <DT><STRONG>creating</STRONG> <DD><A HREF="HowToBuildFromSource-node2.html#43">1</A> </DL> <DT><STRONG><TT>config.status</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node3.html#517">2</A> <DL COMPACT> <DT><STRONG>versus <TT>configure</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node3.html#515">2</A> </DL> <DT><STRONG><TT>configure</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#523">3.1</A> <DL COMPACT> <DT><STRONG>macros for plugins</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#527">3.1</A> <DT><STRONG>recreating</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#524">3.1</A> </DL> <DT><STRONG>emergency services</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#485">3.5</A> <DT><STRONG><TT>Makefile</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#536">3.2.1</A> <DL COMPACT> <DT><STRONG>avoiding <TT>$(XINCLUDES)</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#585">3.2.2</A> <DT><STRONG>compile/link commands</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#577">3.2.2</A> <DT><STRONG>keyword substitution</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#541">3.2.1</A> <DT><STRONG>passing extra flags</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#578">3.2.2</A> <DT><STRONG>replacing</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#592">3.2.5</A> <DT><STRONG>target rules</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#573">3.2.1</A> </DL> <DT><STRONG><TT>Makefile</TT> keywords</STRONG> <DD><DL COMPACT> <DT><STRONG><TT>[includes]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#552">3.2.1</A> <DT><STRONG><TT>[make_cfg]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#545">3.2.1</A> <DT><STRONG><TT>[make_inc]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#569">3.2.1</A> <DT><STRONG><TT>[make_plg]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#548">3.2.1</A> <DT><STRONG><TT>[make_targets]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#572">3.2.1</A> <DT><STRONG><TT>[plibs]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#566">3.2.1</A> <DT><STRONG><TT>[target]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#563">3.2.1</A> <DT><STRONG><TT>[targets]</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#558">3.2.1</A> </DL> <DT><STRONG><TT>Makefile.in</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#593">3.2.5</A> <DL COMPACT> <DT><STRONG>example</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#598">3.3.2</A> </DL> <DT><STRONG><TT>Makefile.inc</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#589">3.2.4</A> <DL COMPACT> <DT><STRONG>example</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#597">3.3.2</A> <DT><STRONG>keyword substitution</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#590">3.2.4</A> </DL> <DT><STRONG><TT>mkmf</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#542">3.2.1</A> <DL COMPACT> <DT><STRONG>additional source directories</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#586">3.2.3</A> <DT><STRONG>default header directories</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#554">3.2.1</A> <DT><STRONG>default source directories</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#559">3.2.1</A> </DL> <DT><STRONG><TT>mkmf.subdirs</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#587">3.2.3</A> <DL COMPACT> <DT><STRONG>example</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#596">3.3.2</A> </DL> <DT><STRONG>plugin</STRONG> <DD><DL COMPACT> <DT><STRONG><TT>Makefile</TT></STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#534">3.2</A> <DT><STRONG><TT>Makefile</TT> anatomy</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#537">3.2.1</A> <DT><STRONG>adding your own</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#146">3</A> <DT><STRONG>configuring</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#173">3.1</A> <DT><STRONG>target rules</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#345">3.2.1</A> <DT><STRONG>Unix-specific directory</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#163">3</A> </DL> <DT><STRONG>Unix-specific files</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#154">3</A> <DT><STRONG>VMMaker</STRONG> <DD><DL COMPACT> <DT><STRONG>configuration file</STRONG> <DD><A HREF="HowToBuildFromSource-node3.html#108">2</A> <DT><STRONG>missing platform support</STRONG> <DD><A HREF="HowToBuildFromSource-node4.html#478">3.4</A> <DT><STRONG>reference</STRONG> <DD><A HREF="HowToBuildFromSource-node3.html#100">2</A> </DL> </DL> <P> <BR><HR> <ADDRESS> Ian Piumarta 2002-06-05 </ADDRESS> </BODY> </HTML> --- NEW FILE: HowToBuildFromSource-node6.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <!--Converted with LaTeX2HTML 2002 (1.67) original version by: Nikos Drakos, CBLU, University of Leeds * revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan * with significant contributions from: Jens Lippmann, Marek Rouchal, Martin Wilck and others --> <HTML> <HEAD> <TITLE>About this document ...</TITLE> <META NAME="description" CONTENT="About this document ..."> <META NAME="keywords" CONTENT="HowToBuildFromSource"> <META NAME="resource-type" CONTENT="document"> <META NAME="distribution" CONTENT="global"> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <META NAME="Generator" CONTENT="LaTeX2HTML v2002"> <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css"> <LINK REL="STYLESHEET" HREF="HowToBuildFromSource.css"> <LINK REL="previous" HREF="HowToBuildFromSource-node5.html"> <LINK REL="up" HREF="HowToBuildFromSource.html"> </HEAD> <BODY > <!--Navigation Panel--> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next_g.png"> <A NAME="tex2html125" HREF="HowToBuildFromSource.html"> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up.png"></A> <A NAME="tex2html121" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev.png"></A> <A NAME="tex2html127" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> <A NAME="tex2html129" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> <BR> <B> Up:</B> <A NAME="tex2html126" HREF="HowToBuildFromSource.html">Building Unix Squeak (</A> <B> Previous:</B> <A NAME="tex2html122" HREF="HowToBuildFromSource-node5.html">Index</A>   <B> <A NAME="tex2html128" HREF="HowToBuildFromSource-node1.html">Contents</A></B>   <B> <A NAME="tex2html130" HREF="HowToBuildFromSource-node5.html">Index</A></B> <BR> <BR> <!--End of Navigation Panel--> <H1><A NAME="SECTION00060000000000000000"> About this document ...</A> </H1> <STRONG>Building Unix Squeak (>= 3.2) from source</STRONG><P> This document was generated using the <A HREF="http://www.latex2html.org/"><STRONG>LaTeX</STRONG>2<tt>HTML</tt></A> translator Version 2002 (1.67) <P> Copyright © 1993, 1994, 1995, 1996, <A HREF="http://cbl.leeds.ac.uk/nikos/personal.html">Nikos Drakos</A>, Computer Based Learning Unit, University of Leeds. <BR> Copyright © 1997, 1998, 1999, <A HREF="http://www.maths.mq.edu.au/~ross/">Ross Moore</A>, Mathematics Department, Macquarie University, Sydney. <P> The command line arguments were: <BR> <STRONG>latex2html</STRONG> <TT>-dir tmp -local_icons -auto_prefix -show_section_numbers -split 4 HowToBuildFromSource.tex</TT> <P> The translation was initiated by Ian Piumarta on 2002-06-05 <BR><HR> <ADDRESS> Ian Piumarta 2002-06-05 </ADDRESS> </BODY> </HTML> --- NEW FILE: HowToBuildFromSource.css --- /* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ .MATH { font-family: "Century Schoolbook", serif; } .MATH I { font-family: "Century Schoolbook", serif; font-style: italic } .BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold } /* implement both fixed-size and relative sizes */ SMALL.XTINY { font-size : xx-small } SMALL.TINY { font-size : x-small } SMALL.SCRIPTSIZE { font-size : smaller } SMALL.FOOTNOTESIZE { font-size : small } SMALL.SMALL { } BIG.LARGE { } BIG.XLARGE { font-size : large } BIG.XXLARGE { font-size : x-large } BIG.HUGE { font-size : larger } BIG.XHUGE { font-size : xx-large } /* heading styles */ H1 { } H2 { } H3 { } H4 { } H5 { } /* mathematics styles */ DIV.displaymath { } /* math displays */ TD.eqno { } /* equation-number cells */ /* document-specific styles come next */ --- NEW FILE: HowToBuildFromSource.html --- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <!--Converted with LaTeX2HTML 2002 (1.67) original version by: Nikos Drakos, CBLU, University of Leeds * revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan * with significant contributions from: Jens Lippmann, Marek Rouchal, Martin Wilck and others --> <HTML> <HEAD> <TITLE>Building Unix Squeak ( 3.2) from source</TITLE> <META NAME="description" CONTENT="Building Unix Squeak ( 3.2) from source"> <META NAME="keywords" CONTENT="HowToBuildFromSource"> <META NAME="resource-type" CONTENT="document"> <META NAME="distribution" CONTENT="global"> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <META NAME="Generator" CONTENT="LaTeX2HTML v2002"> <META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css"> <LINK REL="STYLESHEET" HREF="HowToBuildFromSource.css"> <LINK REL="next" HREF="HowToBuildFromSource-node1.html"> </HEAD> <BODY > <!--Navigation Panel--> <A NAME="tex2html8" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="37" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="next" SRC="next.png"></A> <IMG WIDTH="26" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="up" SRC="up_g.png"> <IMG WIDTH="63" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="previous" SRC="prev_g.png"> <A NAME="tex2html4" HREF="HowToBuildFromSource-node1.html"> <IMG WIDTH="65" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="contents" SRC="contents.png"></A> <A NAME="tex2html6" HREF="HowToBuildFromSource-node5.html"> <IMG WIDTH="43" HEIGHT="24" ALIGN="BOTTOM" BORDER="0" ALT="index" SRC="index.png"></A> <BR> <B> Next:</B> <A NAME="tex2html9" HREF="HowToBuildFromSource-node1.html">Contents</A>   <B> <A NAME="tex2html5" HREF="HowToBuildFromSource-node1.html">Contents</A></B>   <B> <A NAME="tex2html7" HREF="HowToBuildFromSource-node5.html">Index</A></B> <BR> <BR> <!--End of Navigation Panel--> <H1 ALIGN="CENTER">Building Unix Squeak (>= 3.2) from source</H1> <P ALIGN="CENTER"><STRONG>Ian Piumarta <BR><A NAME="tex2html1" HREF="mailto:ian...@in..."><TT><ian...@in...></TT></A></STRONG></P> <P ALIGN="CENTER"><STRONG><FONT SIZE="-1">Last edited: 2002-06-05 05:22:02 by piumarta on emilia.inria.fr <BR> Translated to .ps/.pdf/.html/.txt: June 5, 2002</FONT></STRONG></P> <BR><HR> <!--Table of Child-Links--> <A NAME="CHILD_LINKS"></A> <UL> <LI><A NAME="tex2html10" HREF="HowToBuildFromSource-node1.html">Contents</A> <LI><A NAME="tex2html11" HREF="HowToBuildFromSource-node2.html">1 <TT>configure</TT> - <TT>build</TT> - <TT>install</TT></A> <LI><A NAME="tex2html12" HREF="HowToBuildFromSource-node3.html">2 Generating your own VM and plugin sources</A> <LI><A NAME="tex2html13" HREF="HowToBuildFromSource-node4.html">3 Adding your own plugins</A> <UL> <LI><A NAME="tex2html14" HREF="HowToBuildFromSource-node4.html#SECTION00041000000000000000">3.1 Plugin-specific configuration</A> <UL> <LI... [truncated message content] |