summaryrefslogtreecommitdiff
path: root/PC
diff options
context:
space:
mode:
authorAndrew MacIntyre <andymac@bullseye.apana.org.au>2002-02-17 05:23:30 +0000
committerAndrew MacIntyre <andymac@bullseye.apana.org.au>2002-02-17 05:23:30 +0000
commit41d97d677761032a12b1efdf1f61bec6b0b37235 (patch)
tree9f13f36d9945cfb4736fa62a88946a763e7e2238 /PC
parent18e6778bcdffc68c5b954cb41a6031698e67082e (diff)
downloadcpython-git-41d97d677761032a12b1efdf1f61bec6b0b37235.tar.gz
Create and populate OS/2 EMX port build directory:
PC/os2emx/ Makefile README.os2emx config.c dlfcn.c // libdl emulation code for loadable extensions dlfcn.h dllentry.c // DLL initialisation routine for Python DLL getpath.c pyconfig.h python23.def // Python DLL symbol export definitions pythonpm.c // console-less PM interpreter wrapper
Diffstat (limited to 'PC')
-rw-r--r--PC/os2emx/Makefile622
-rw-r--r--PC/os2emx/README.os2emx570
-rw-r--r--PC/os2emx/config.c160
-rw-r--r--PC/os2emx/dlfcn.c224
-rw-r--r--PC/os2emx/dlfcn.h50
-rw-r--r--PC/os2emx/dllentry.c54
-rw-r--r--PC/os2emx/getpathp.c383
-rw-r--r--PC/os2emx/pyconfig.h306
-rw-r--r--PC/os2emx/python23.def931
-rw-r--r--PC/os2emx/pythonpm.c124
10 files changed, 3424 insertions, 0 deletions
diff --git a/PC/os2emx/Makefile b/PC/os2emx/Makefile
new file mode 100644
index 0000000000..88120baac6
--- /dev/null
+++ b/PC/os2emx/Makefile
@@ -0,0 +1,622 @@
+#####################==================----------------תתתתתתתתתתתתת
+#
+# Top-Level Makefile for Building Python 2.3 for OS/2 using GCC/EMX
+# Originally written by Andrew Zabolotny, <bit@eltech.ru> for Python 1.5.2
+# Modified by Andrew MacIntyre, <andymac@pcug.org.au> for Python 2.3
+#
+# This makefile was developed for use with [P]GCC/EMX compiler any
+# version and GNU Make.
+#
+# The output of the build is a largish Python23.DLL containing the
+# essential modules of Python and a small Python.exe program to start
+# the interpreter. When embedding Python within another program, only
+# Python23.DLL is needed. We also build python_s.a static library (which
+# can be converted into OMF (.lib) format using emxomf tool) and both
+# python.a and python.lib import libraries. Then the optional
+# extension modules, which are OS/2 DLLs renamed with a PYD file extension.
+#
+# Recommended build order:
+# make depend (if you have makedep)
+# make all
+# make lx (if you have lxlite)
+# make test (optional)
+#
+#####################==================----------------תתתתתתתתתתתתת
+
+# === Compilation mode: debug or release ===
+MODE= optimize
+#MODE= debug
+# === Assert() enabled ===
+#ASSERTIONS=no
+ASSERTIONS=yes
+
+# === Optional modules ===
+# Do you have the InfoZip compression library installed?
+ZLIB= no
+# Do you have the Ultra Fast Crypt (UFC) library installed?
+UFC= no
+# Do you have the Tcl/Tk library installed?
+TCLTK= no
+# Do you have the GNU multiprecision library installed?
+GMPZ= no
+# Do you have the GNU readline library installed?
+# NOTE: I'm using a modified version of Kai Uwe Rommel's port that
+# - is compiled with multithreading enabled
+# - is linked statically
+# I have had no success trying to use a DLL version, even with
+# the multithreading switch.
+GREADLINE= no
+# Do you have the BSD DB library (v1.85) as included in the EMXBSD package?
+# NOTE: this library needs to be recompiled with a structure member
+# renamed to avoid problems with the multithreaded errno support
+# (there is a structure member called errno, used for shadowing the
+# real errno, which conflicts with the errno redefinition of -Zmt)
+BSDDB= no
+# Do you have the ncurses library installed? EMX's BSD curses aren't enough!
+CURSES= no
+# Do you have the expat XML parsing library installed?
+EXPAT= no
+# Do you have the GDBM library installed?
+GDBM= no
+
+# === The Tools ===
+CC= gcc
+CFLAGS= -Zmt -Wall $(INCLUDE)
+CFLAGS.LIB= $(CFLAGS)
+LD= gcc
+LDFLAGS= -Zmt -Zcrtdll -L. -lgcc
+LDFLAGS.EXE= $(LDFLAGS)
+LDFLAGS.DLL= $(LDFLAGS) -Zdll
+LDFLAGS.A= $(LDFLAGS) $(LIBS)
+ARFLAGS= crs
+IMPLIB= emximp
+EXPLIB= emxexp
+
+# adjust C compiler settings based on build options
+ifeq ($(MODE),debug)
+ CFLAGS+= -g -O
+ LDFLAGS+= -g
+else
+ CFLAGS+= -s -O2
+ LDFLAGS+= -s
+endif
+ifeq ($(ASSERTIONS),no)
+ CFLAGS+= -DNDEBUG
+endif
+
+# We're using the OMF format since EMX's ld has a obscure bug
+# because of which it sometimes fails to build relocations
+# in .data segment that point to another .data locations
+# (except for the final linking if the .EXEs)
+OMF= yes
+
+# if fork() support is required, the main executable must be linked with ld
+EXEOMF= no
+
+# File extensions
+MODULE.EXT= .pyd
+ifeq ($(OMF),yes)
+ O= .obj
+ A= .lib
+ AR= emxomfar
+ CFLAGS+= -Zomf
+ LDFLAGS+= -Zomf
+ ifeq ($(MODE),debug)
+ ARFLAGS= -p64 crs
+ else
+ ARFLAGS= -p32 crs
+ endif
+else
+ O= .o
+ A= .a
+ AR= ar
+endif
+
+# Source file paths
+SRCPATH=.;../../Python;../../Parser;../../Objects;../../Include;../../Modules
+# Python contains the central core, containing the builtins and interpreter.
+# Parser contains Python's Internal Parser and
+# Standalone Parser Generator Program (Shares Some of Python's Modules)
+# Objects contains Python Object Types
+# Modules contains extension Modules (Built-In or as Separate DLLs)
+
+# Unix shells tend to use "$" as delimiter for variable names.
+# Test for this behaviour and set $(BUCK) variable correspondigly ...
+__TMP__:=$(shell echo $$$$)
+ifeq ($(__TMP__),$$$$)
+ BUCK= $$
+ BRO= (
+ BRC= )
+else
+ BUCK= \$$
+ BRO= \(
+ BRC= \)
+endif
+# Compute the "double quote" variable
+__TMP__:=$(shell echo "")
+ifeq ($(__TMP__),"")
+ DQUOTE= "
+else
+ DQUOTE= \"
+endif
+
+# Include paths
+#INCLUDE= -I$(subst ;, -I, $(SRCPATH))
+INCLUDE= -I. -I../../Include
+
+# Path to search for .c files
+vpath %.c .;..;$(SRCPATH)
+
+# Top of the package tree
+TOP= ../../
+
+# Directory for output files
+OUTBASE= out/
+OUT= $(OUTBASE)$(MODE)/
+
+# Additional libraries
+LIBS= -lsocket
+
+# Utility macro: replacement for $^
+^^= $(filter-out %$A,$^)
+# Use $(L^) to link with all libraries specified as dependencies
+L^= $(addprefix -l,$(basename $(notdir $(filter %$A,$+))))
+
+# Build rules
+$(OUT)%$O: %.c
+ $(CC) $(CFLAGS.LIB) -c $< -o $@
+
+%.a:
+ $(LD) $(LDFLAGS.A) -o $@ $(^^) $(L^)
+
+%.dll:
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+%.pyd: $(OUT)%module$O $(OUT)%_m.def
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(PYTHON.IMPLIB) $(LIBS)
+
+%.exe:
+ $(LD) $(LDFLAGS.EXE) -o $@ $(^^) $(L^)
+
+%_m.def:
+ @echo Creating .DEF file: $@
+ @echo LIBRARY $(notdir $*) INITINSTANCE TERMINSTANCE >$@
+ ifeq ($(DESCRIPTION.$(notdir $*)$(MODULE.EXT)),)
+ @echo DESCRIPTION $(DQUOTE)Python standard module $(notdir $*)$(DQUOTE) >>$@
+ else
+ @echo DESCRIPTION $(DQUOTE)$(DESCRIPTION.$(notdir $*)$(MODULE.EXT))$(DQUOTE) >>$@
+ endif
+ @echo DATA MULTIPLE NONSHARED >>$@
+ @echo EXPORTS >>$@
+ @echo init$(notdir $*) >>$@
+
+%.def:
+ @echo Creating .DEF file: $@
+ @echo NAME $(notdir $*) $(EXETYPE.$(notdir $*).exe) >$@
+ @echo DESCRIPTION $(DQUOTE)$(DESCRIPTION.$(notdir $*).exe)$(DQUOTE) >>$@
+ @echo STACKSIZE 1048576 >>$@
+
+# Output file names
+PYTHON_VER= 2.3
+PYTHON_LIB= python23
+PYTHON.LIB= $(PYTHON_LIB)_s$A
+PYTHON.IMPLIB= $(PYTHON_LIB)$A
+ifeq ($(EXEOMF),yes)
+ PYTHON.EXEIMP= $(PYTHON.IMPLIB)
+ LDMODE.EXE= -Zomf
+else
+ PYTHON.EXEIMP= $(PYTHON_LIB).a
+ LDMODE.EXE =
+endif
+PYTHON.DLL= $(PYTHON_LIB).dll
+PYTHON.DEF= $(PYTHON_LIB).def
+PYTHON.EXE= python.exe
+PYTHONPM.EXE= pythonpm.exe
+PGEN.EXE= pgen.exe
+LIBRARY= $(PYTHON.LIB)
+LD_LIBRARY= $(PYTHON.IMPLIB)
+
+# Additional executable parameters
+EXETYPE.$(PYTHON.EXE)= WINDOWCOMPAT
+EXETYPE.$(PYTHONPM.EXE)= WINDOWAPI
+EXETYPE.$(PGEN.EXE)= WINDOWCOMPAT
+DESCRIPTION.$(PYTHON.EXE)= Python object-oriented programming language interpreter for OS/2
+DESCRIPTION.$(PYTHONPM.EXE)= $(DESCRIPTION.$(PYTHON.EXE))
+DESCRIPTION.$(PGEN.EXE)= Python object-oriented programming language parser generator for OS/2
+
+# Module descriptions
+DESCRIPTION.zlib$(MODULE.EXT)= Python Extension DLL for accessing the InfoZip compression library
+DESCRIPTION.crypt$(MODULE.EXT)= Python Extension DLL implementing the crypt$(BRO)$(BRC) function
+DESCRIPTION._tkinter$(MODULE.EXT)= Python Extension DLL for access to Tcl/Tk Environment
+DESCRIPTION.mpz$(MODULE.EXT)= Python Extension DLL for access to GNU multi-precision library
+DESCRIPTION.readline$(MODULE.EXT)= Python Extension DLL for access to GNU ReadLine library
+DESCRIPTION.bsddb$(MODULE.EXT)= Python Extension DLL for access to BSD DB (v1.85) library
+DESCRIPTION._curses$(MODULE.EXT)= Python Extension DLL for access to ncurses library
+DESCRIPTION.pyexpat$(MODULE.EXT)= Python Extension DLL for access to expat library
+
+# Source files
+SRC.PGEN= $(addprefix ../../Parser/, \
+ pgenmain.c \
+ pgen.c \
+ printgrammar.c \
+ grammar.c \
+ bitset.c \
+ firstsets.c)
+OBJ.PGEN= $(addprefix $(OUT),$(notdir $(SRC.PGEN:.c=$O)))
+
+SRC.OS2EMX= config.c dlfcn.c getpathp.c
+SRC.MAIN= $(addprefix $(TOP), \
+ Modules/getbuildinfo.c \
+ Modules/main.c)
+SRC.MODULES= $(addprefix $(TOP), \
+ Modules/gcmodule.c \
+ Modules/signalmodule.c \
+ Modules/posixmodule.c \
+ Modules/threadmodule.c \
+ Modules/_sre.c)
+SRC.PARSER= $(addprefix $(TOP), \
+ Parser/acceler.c \
+ Parser/grammar1.c \
+ Parser/listnode.c \
+ Parser/node.c \
+ Parser/parser.c \
+ Parser/parsetok.c \
+ Parser/tokenizer.c \
+ Parser/bitset.c \
+ Parser/metagrammar.c \
+ Parser/myreadline.c)
+SRC.PYTHON= $(addprefix $(TOP), \
+ Python/bltinmodule.c \
+ Python/exceptions.c \
+ Python/ceval.c \
+ Python/compile.c \
+ Python/codecs.c \
+ Python/errors.c \
+ Python/frozen.c \
+ Python/frozenmain.c \
+ Python/future.c \
+ Python/getargs.c \
+ Python/getcompiler.c \
+ Python/getcopyright.c \
+ Python/getmtime.c \
+ Python/getplatform.c \
+ Python/getversion.c \
+ Python/graminit.c \
+ Python/import.c \
+ Python/importdl.c \
+ Python/marshal.c \
+ Python/modsupport.c \
+ Python/mysnprintf.c \
+ Python/mystrtoul.c \
+ Python/pyfpe.c \
+ Python/pystate.c \
+ Python/pythonrun.c \
+ Python/structmember.c \
+ Python/symtable.c \
+ Python/sysmodule.c \
+ Python/traceback.c \
+ Python/getopt.c \
+ Python/dynload_shlib.c \
+ Python/thread.c)
+SRC.OBJECT= $(addprefix $(TOP), \
+ Objects/abstract.c \
+ Objects/bufferobject.c \
+ Objects/cellobject.c \
+ Objects/classobject.c \
+ Objects/cobject.c \
+ Objects/complexobject.c \
+ Objects/descrobject.c \
+ Objects/dictobject.c \
+ Objects/fileobject.c \
+ Objects/floatobject.c \
+ Objects/frameobject.c \
+ Objects/funcobject.c \
+ Objects/intobject.c \
+ Objects/iterobject.c \
+ Objects/listobject.c \
+ Objects/longobject.c \
+ Objects/methodobject.c \
+ Objects/moduleobject.c \
+ Objects/object.c \
+ Objects/rangeobject.c \
+ Objects/sliceobject.c \
+ Objects/stringobject.c \
+ Objects/structseq.c \
+ Objects/tupleobject.c \
+ Objects/typeobject.c \
+ Objects/unicodeobject.c \
+ Objects/unicodectype.c \
+ Objects/weakrefobject.c)
+
+SRC.LIB= $(SRC.OS2EMX) \
+ $(SRC.MAIN) \
+ $(SRC.PARSER) \
+ $(SRC.OBJECT) \
+ $(SRC.PYTHON) \
+ $(SRC.MODULES)
+OBJ.LIB= $(addprefix $(OUT),$(notdir $(SRC.LIB:.c=$O)))
+
+SRC.EXE= $(TOP)Modules/python.c
+SRC.PMEXE= pythonpm.c
+
+# Python modules to be dynamically loaded that:
+# 1) have only single source file and require no extra libs
+# 2) use the standard module naming convention
+# (the 'module' in ?????module.c is assumed)
+# - these can be built with implicit rules
+EASYEXTMODULES= array \
+ cmath \
+ _codecs \
+ dl \
+ errno \
+ fcntl \
+ fpectl \
+ fpetest \
+ _locale \
+ math \
+ new \
+ parser \
+ pwd \
+ rgbimg \
+ rotor \
+ select \
+ sha \
+ strop \
+ struct \
+ time \
+ timing
+
+# Python modules to be dynamically loaded that need explicit build rules
+# (either multiple source files and/or non-standard module naming)
+# (NOTE: use shortened names for modules affected by 8 char name limit)
+HARDEXTMODULES= binascii \
+ cPickle \
+ cStringI \
+ _hotshot \
+ imageop \
+ md5 \
+ operator \
+ pcre \
+ regex \
+ _socket \
+ termios \
+ _testcap \
+ unicoded \
+ _weakref \
+ xreadlin
+
+# Python external ($(MODULE.EXT)) modules - can be EASY or HARD
+ifeq ($(ZLIB),yes)
+ HARDEXTMODULES+= zlib
+endif
+ifeq ($(UFC),yes)
+ HARDEXTMODULES+= crypt
+endif
+ifeq ($(TCLTK),yes)
+ HARDEXTMODULES+= _tkinter
+ CFLAGS+= -DHAS_DIRENT -I/TclTk80/include
+ TK_LIBS+= -L/TclTk80/lib -ltcl80 -ltk80
+endif
+ifeq ($(GMPZ),yes)
+ HARDEXTMODULES+= mpz
+endif
+ifeq ($(GREADLINE),yes)
+ HARDEXTMODULES+= readline
+endif
+ifeq ($(BSDDB),yes)
+ HARDEXTMODULES+= bsddb
+endif
+ifeq ($(CURSES),yes)
+ HARDEXTMODULES+= _curses _curses_
+endif
+ifeq ($(EXPAT),yes)
+ HARDEXTMODULES+= pyexpat
+endif
+ifeq ($(GDBM),yes)
+ HARDEXTMODULES+= gdbm dbm
+endif
+
+EXTERNDLLS= $(addsuffix $(MODULE.EXT),$(patsubst %module,%,$(EASYEXTMODULES)))
+EXTERNDLLS+= $(addsuffix $(MODULE.EXT),$(patsubst %module,%,$(HARDEXTMODULES)))
+
+# Targets
+all: $(OUT) $(PYTHON.LIB) $(PYTHON.DEF) $(PYTHON.IMPLIB) $(PYTHON.DLL) \
+ $(PYTHON.EXE) $(PYTHONPM.EXE) $(PGEN.EXE) $(EXTERNDLLS)
+
+clean:
+ rm -f $(OUT)*
+ rm -f $(PYTHON.LIB) $(PYTHON.IMPLIB) $(PYTHON.EXEIMP) $(PYTHON.DLL) \
+ $(PYTHON.EXE) $(PYTHONPM.EXE) $(PGEN.EXE) *$(MODULE.EXT)
+
+lx:
+ @echo Packing everything with lxLite...
+ lxlite $(PYTHON.DLL) $(PYTHON.EXE) $(PYTHONPM.EXE) $(PGEN.EXE)
+
+depend: $(OUTBASE)
+ makedep -f $(OUTBASE)python.dep -o $(BUCK)O -p $(BUCK)\(OUT\) \
+ -r -c $(INCLUDE) $(SRC.LIB) $(SRC.PGEN)
+
+$(OUT): $(OUTBASE)
+
+$(OUT) $(OUTBASE):
+ mkdir.exe $@
+
+$(PYTHON.LIB): $(OBJ.LIB)
+ rm.exe -f $@
+ $(AR) $(ARFLAGS) $@ $^
+
+$(PYTHON.DEF): $(PYTHON.LIB)
+ @echo Creating .DEF file: $@
+ @echo LIBRARY $(PYTHON_LIB) INITINSTANCE TERMINSTANCE >$@
+ @echo DESCRIPTION $(DQUOTE)Python $(PYTHON_VER) Core DLL$(DQUOTE) >>$@
+ @echo PROTMODE >>$@
+ @echo DATA MULTIPLE NONSHARED >>$@
+ @echo EXPORTS >>$@
+ $(EXPLIB) -u $(PYTHON.LIB) >>$@
+
+$(PYTHON.IMPLIB): $(PYTHON.DEF)
+ $(IMPLIB) -o $@ $^
+
+$(PYTHON.EXEIMP): $(PYTHON.DEF)
+ $(IMPLIB) -o $@ $^
+
+$(PYTHON.DLL): $(OUT)dllentry$O $(PYTHON.LIB) $(PYTHON.DEF)
+
+# Explicit make targets for the .EXEs to be able to use LD to link
+# (so that fork() will work if required)
+
+$(PYTHON.EXE): $(SRC.EXE) $(PYTHON.EXEIMP) $(OUT)python.def
+ $(CC) -Zmt $(LDMODE.EXE) -Zcrtdll -Wall $(INCLUDE) -L. -lgcc -o $@ $(SRC.EXE) $(PYTHON.EXEIMP) $(LIBS) $(OUT)python.def
+
+$(PYTHONPM.EXE): $(SRC.PMEXE) $(PYTHON.EXEIMP) $(OUT)pythonpm.def
+ $(CC) -Zmt $(LDMODE.EXE) -Zcrtdll -Wall $(INCLUDE) -L. -lgcc -o $@ $(SRC.PMEXE) $(PYTHON.EXEIMP) $(LIBS) $(OUT)pythonpm.def
+
+$(PGEN.EXE): $(OBJ.PGEN) $(PYTHON.LIB) $(OUT)pgen.def
+
+# Explicit building instructions for those external modules that require
+# awkward handling (due e.g. to non-std naming, or multiple source files)
+# - standard modules
+binascii$(MODULE.EXT): $(OUT)binascii$O $(OUT)binascii_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+cPickle$(MODULE.EXT): $(OUT)cPickle$O $(OUT)cPickle_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+# cStringIO needs to be renamed to be useful (8 char DLL name limit)
+cStringIO$(MODULE.EXT): $(OUT)cStringIO$O $(OUT)cStringIO_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+cStringI$(MODULE.EXT): cStringIO$(MODULE.EXT)
+ cp $^ $@
+
+_hotshot$(MODULE.EXT): $(OUT)_hotshot$O $(OUT)_hotshot_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+imageop$(MODULE.EXT): $(OUT)imageop$O $(OUT)imageop_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+md5$(MODULE.EXT): $(OUT)md5module$O $(OUT)md5c$O $(OUT)md5_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+operator$(MODULE.EXT): $(OUT)operator$O $(OUT)operator_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+pcre$(MODULE.EXT): $(OUT)pcremodule$O $(OUT)pypcre$O $(OUT)pcre_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+regex$(MODULE.EXT): $(OUT)regexmodule$O $(OUT)regexpr$O $(OUT)regex_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+_socket$(MODULE.EXT): $(OUT)socketmodule$O $(OUT)_socket_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+# _symtable needs to be renamed to be useful
+_symtable$(MODULE.EXT): $(OUT)symtablemodule$O $(OUT)_symtable_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+_symtabl$(MODULE.EXT): _symtable$(MODULE.EXT)
+ cp $^ $@
+
+termios$(MODULE.EXT): $(OUT)termios$O $(OUT)termios_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+# _testcapi needs to be renamed to be useful
+_testcapi$(MODULE.EXT): $(OUT)_testcapimodule$O $(OUT)_testcapi_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+_testcap$(MODULE.EXT): _testcapi$(MODULE.EXT)
+ cp $^ $@
+
+# unicodedata needs to be renamed to be useful
+unicodedata$(MODULE.EXT): $(OUT)unicodedata$O $(OUT)unicodedata_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS) $(MODULE_LIBS)
+
+unicoded$(MODULE.EXT): unicodedata$(MODULE.EXT)
+ cp $^ $@
+
+_weakref$(MODULE.EXT): $(OUT)_weakref$O $(OUT)_weakref_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+# xreadlines needs to be renamed to be useful
+xreadlines$(MODULE.EXT): $(OUT)xreadlinesmodule$O $(OUT)xreadlines_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS)
+
+xreadlin$(MODULE.EXT): xreadlines$(MODULE.EXT)
+ cp $^ $@
+
+# - optional modules (requiring other software to be installed)
+bsddb$(MODULE.EXT): $(OUT)bsddbmodule$O $(OUT)bsddb_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) -ldb $(LIBS)
+
+crypt$(MODULE.EXT): $(OUT)cryptmodule$O $(OUT)crypt_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) -lufc $(LIBS)
+
+# The _curses_panel module requires a couple of ncurses library entry
+# points, which are best exposed as exports from the _curses module DLL
+$(OUT)_curses_m.def:
+ @echo Creating .DEF file: $@
+ @echo LIBRARY $(notdir $*) INITINSTANCE TERMINSTANCE >$@
+ @echo DESCRIPTION $(DQUOTE)$(DESCRIPTION.$(notdir $*)$(MODULE.EXT))$(DQUOTE) >>$@
+ @echo DATA MULTIPLE NONSHARED >>$@
+ @echo EXPORTS >>$@
+ @echo init_curses >>$@
+ @echo wnoutrefresh >>$@
+ @echo _nc_panelhook >>$@
+ @echo is_linetouched >>$@
+ @echo mvwin >>$@
+ @echo stdscr >>$@
+ @echo wtouchln >>$@
+
+$(OUT)_curses_panel_m.def:
+ @echo Creating .DEF file: $@
+ @echo LIBRARY $(notdir $*) INITINSTANCE TERMINSTANCE >$@
+ @echo DESCRIPTION $(DQUOTE)Python standard module $(notdir $*)$(DQUOTE) >>$@
+ @echo DATA MULTIPLE NONSHARED >>$@
+ @echo IMPORTS >>$@
+ @echo _curses.wnoutrefresh >>$@
+ @echo _curses._nc_panelhook >>$@
+ @echo _curses.is_linetouched >>$@
+ @echo _curses.mvwin >>$@
+ @echo _curses.stdscr >>$@
+ @echo _curses.wtouchln >>$@
+ @echo EXPORTS >>$@
+ @echo init_curses_panel >>$@
+
+_curses$(MODULE.EXT): $(OUT)_cursesmodule$O $(OUT)_curses_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS) -lncurses
+
+# curses_panel needs to be renamed to be useful
+_curses_panel$(MODULE.EXT): $(OUT)_curses_panel$O $(OUT)_curses_panel_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS) -lpanel
+
+_curses_$(MODULE.EXT): _curses_panel$(MODULE.EXT)
+ cp $^ $@
+
+dbm$(MODULE.EXT): $(OUT)dbmmodule$O $(OUT)dbm_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS) -lgdbm
+
+gdbm$(MODULE.EXT): $(OUT)gdbmmodule$O $(OUT)gdbm_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS) -lgdbm
+
+mpz$(MODULE.EXT): $(OUT)mpzmodule$O $(OUT)mpz_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS) -lgmp
+
+pyexpat$(MODULE.EXT): $(OUT)pyexpat$O $(OUT)pyexpat_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS) -lexpat
+
+readline$(MODULE.EXT): $(OUT)readline$O $(OUT)readline_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS) -lreadline -lncurses
+
+#_tkinter$(MODULE.EXT): $(OUT)_tkinter$O $(OUT)tclNotify$O $(OUT)tkappinit$O
+_tkinter$(MODULE.EXT): $(OUT)_tkinter$O $(OUT)tclNotify$O \
+ $(OUT)_tkinter_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS) $(TK_LIBS)
+
+zlib$(MODULE.EXT): $(OUT)zlibmodule$O $(OUT)zlib_m.def $(PYTHON.IMPLIB)
+ $(LD) $(LDFLAGS.DLL) -o $@ $(^^) $(L^) $(LIBS) -lz
+
+# the test target
+test:
+ ./python -tt ../../lib/test/regrtest.py -l -u "network"
+
+-include $(OUTBASE)python.dep
diff --git a/PC/os2emx/README.os2emx b/PC/os2emx/README.os2emx
new file mode 100644
index 0000000000..bd010ec407
--- /dev/null
+++ b/PC/os2emx/README.os2emx
@@ -0,0 +1,570 @@
+This is a port of Python 2.3 to OS/2 using the EMX development tools
+=========================================================================
+
+What's new since the previous release
+-------------------------------------
+
+This release of the port incorporates the following changes from the
+December 24, 2001 release of the Python 2.2 port:
+
+- based on the Python v2.3 final release source.
+
+
+Licenses and info about Python and EMX
+--------------------------------------
+
+Please read the file README.Python-2.3 included in this package for
+information about Python 2.3. This file is the README file from the
+Python 2.3 source distribution available via http://www.python.org/
+and its mirrors. The file LICENCE.Python-2.3 is the text of the Licence
+from the Python 2.3 source distribution.
+
+Note that the EMX package that this package depends on is released under
+the GNU General Public Licence. Please refer to the documentation
+accompanying the EMX Runtime libraries for more information about the
+implications of this. A copy of version 2 of the GPL is included as the
+file COPYING.gpl2.
+
+Readline and GDBM are covered by the GNU General Public Licence. I think
+Eberhard Mattes' porting changes to BSD DB v1.85 are also GPL'ed (BSD DB
+itself is BSD Licenced). ncurses and expat appear to be covered by MIT
+style licences - please refer to the source distributions for more detail.
+zlib is distributable under a very free license. GNU MP and GNU UFC are
+under the GNU LGPL (see file COPYING.lib).
+
+My patches to the Python-2.x source distributions, and any other packages
+used in this port, are placed in the public domain.
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the author be held liable for any damages arising from the
+use of the software.
+
+I do hope however that it proves useful to someone.
+
+
+Other ports
+-----------
+
+There have been ports of previous versions of Python to OS/2.
+
+The best known would be that by Jeff Rush, most recently of version
+1.5.2. Jeff used IBM's Visual Age C++ (v3) for his ports, and his
+patches have been included in the Python 2.3 source distribution.
+
+Andrew Zabolotny implemented a port of Python v1.5.2 using the EMX
+development tools. His patches against the Python v1.5.2 source
+distribution have become the core of this port, and without his efforts
+this port wouldn't exist. Andrew's port also appears to have been
+compiled with his port of gcc 2.95.2 to EMX, which I have but have
+chosen not to use for the binary distribution of this port (see item 21
+of the "YOU HAVE BEEN WARNED" section below).
+
+Previous Python port releases by me:-
+ - v2.0 on March 31, 2001;
+ - v2.0 on April 25, 2001 (cleanup release + Stackless variant);
+ - v2.1 on June 17, 2001;
+ - v2.0 (Stackless re-release) on June 18, 2001.
+ - v2.1.1 on August 5, 2001;
+ - v2.1.1 on August 12, 2001 (cleanup release);
+ - v2.1.1 (updated DLL) on August 14, 2001.
+ - v2.2b2 on December 8, 2001 (not uploaded to archive sites)
+ - v2.2c1 on December 16, 2001 (not uploaded to archive sites)
+ - v2.2 on December 24, 2001
+
+It is possible to have these earlier ports still usable after installing
+this port - see the README.os2emx.multiple_versions file, contributed by
+Dr David Mertz, for a suggested approach to achieving this.
+
+
+Software requirements
+---------------------
+
+This package requires the EMX Runtime package, available from the
+Hobbes (http://hobbes.nmsu.edu/) and LEO (http://archiv.leo.org/)
+archives of OS/2 software. I have used EMX version 0.9d fix04 in
+developing this port.
+
+My development system is running OS/2 v4 with fixpack 12.
+
+3rd party software which has been linked into dynamically loaded modules:
+- ncurses (see http://dickey.his.com/ for more info, v5.2)
+- GNU Readline (Kai Uwe Rommel's port available from Hobbes or LEO, v2.1)
+- GNU GDBM (Kai Uwe Rommel's port available from Hobbes or LEO, v1.7.3)
+- zlib (Hung-Chi Chu's port available from Hobbes or LEO, v1.1.3)
+- expat (from ftp://ftp.jclark.com/pub/xml/, v1.2)
+- GNU MP (Peter Meerwald's port available from LEO, v2.0.2)
+- GNU UFC (Kai Uwe Rommel's port available from LEO, v2.0.4)
+
+The zlib module requires the Z.DLL to be installed - see the Installation
+section and item 12 of the "YOU HAVE BEEN WARNED" section for more
+information.
+
+About this port
+---------------
+
+I have attempted to make this port as complete and functional as I can,
+notwithstanding the issues in the "YOU HAVE BEEN WARNED" section below.
+
+Core components:
+
+Python.exe is linked as an a.out executable, ie using EMX method E1
+to compile & link the executable. This is so that fork() works (see
+"YOU HAVE BEEN WARNED" item 2).
+
+Python23.dll is created as a normal OMF DLL, with an OMF import
+library and module definition file. There is also an a.out (.a) import
+library to support linking the DLL to a.out executables.
+
+This port has been built with complete support for multithreading.
+
+Modules:
+
+As far as possible, extension modules have been made dynamically loadable
+when the module is intended to be built this way. I haven't yet changed
+the building of Python's standard modules over to using the DistUtils.
+
+See "YOU HAVE BEEN WARNED" item 5 for notes about the fcntl module, and
+"YOU HAVE BEEN WARNED" item 14 for notes about the pwd and grp modules.
+
+Support for case sensitive module import semantics has been added to match
+the Windows release. This can be deactivated by setting the PYTHONCASEOK
+environment variable (the value doesn't matter) - see "YOU HAVE BEEN WARNED"
+item 16.
+
+Optional modules:
+
+Where I've been able to locate the required 3rd party packages already
+ported to OS/2, I've built and included them.
+
+These include ncurses (_curses, _curses_panel), BSD DB (bsddb),
+GNU GDBM (gdbm, dbm), zlib (zlib), GNU Readline (readline), expat
+(pyexpat), GNU MP (mpz) and GNU UFC (crypt).
+
+I have built these modules statically linked against the 3rd party
+libraries, with the exception of zlib. Unfortunately my attempts to use
+the dll version of GNU readline have been a dismal failure, in that when
+the dynamically linked readline module is active other modules
+immediately provoke a core dump when imported.
+
+Only the BSD DB package (part of the BSD package distributed with EMX)
+needed source modifications to be used for this port, pertaining to use
+of errno with multithreading.
+
+The other packages, except for ncurses and zlib, needed Makefile changes
+for multithreading support but no source changes.
+
+The _curses_panel module is a potential problem - see "YOU HAVE BEEN
+WARNED" item 17.
+
+Upstream source patches:
+
+No updates to the Python 2.3 release have become available.
+
+Eberhard Mattes' EMXFIX04 update to his EMX 0.9d tools suite includes
+bug fixes for the BSD DB library. The bsddb module included in this
+port incorporates these fixes.
+
+Library and other distributed Python code:
+
+The Python standard library lives in the Lib directory. All the standard
+library code included with the Python 2.3 source distribution is included
+in the binary archive, with the exception of the dos-8x3 and tkinter
+subdirectories which have been omitted to reduce the size of the binary
+archive - the dos-8x3 components are unnecessary duplicates and Tkinter
+is not supported by this port (yet). All the plat-* subdirectories in the
+source distribution have also been omitted, and a plat-os2emx directory
+included.
+
+The Tools and Demo directories contain a collection of Python scripts.
+To reduce the size of the binary archive, the Demo/sgi, Demo/Tix,
+Demo/tkinter, Tools/audiopy and Tools/IDLE subdirectories have been
+omitted as not being supported by this port. The Misc directory has
+also been omitted.
+
+All subdirectories omitted from the binary archive can be reconstituted
+from the Python 2.3 source distribution, if desired.
+
+Support for building Python extensions:
+
+The Config subdirectory contains the files describing the configuration
+of the interpreter and the Makefile, import libraries for the Python DLL,
+and the module definition file used to create the Python DLL. The
+Include subdirectory contains all the standard Python header files
+needed for building extensions.
+
+As I don't have the Visual Age C++ compiler, I've made no attempt to
+have this port support extensions built with that compiler.
+
+
+Packaging
+---------
+
+This port is packaged into several archives:
+- python-2.3-os2emx-bin-02????.zip (binaries, library modules)
+- python-2.3-os2emx-src-03????.zip (source patches and makefiles)
+
+Documentation for the Python language, as well as the Python 2.3
+source distibution, can be obtained from the Python website
+(http://www.python.org/) or the Python project pages at Sourceforge
+(http://sf.net/projects/python/).
+
+
+Installation
+------------
+
+Obtain and install, as per the included instructions, the EMX runtime
+package.
+
+If you wish to use the zlib module, you will need to obtain and install
+the Z.DLL from Hung-Chi Chu's port of zlib v1.1.3 (zlib113.zip). See also
+"YOU HAVE BEEN WARNED" item 12 below.
+
+Unpack this archive, preserving the subdirectories, in the root directory
+of the drive where you want Python to live.
+
+Add the Python directory (eg C:\Python23) to the PATH and LIBPATH
+variables in CONFIG.SYS.
+
+You should then set the PYTHONHOME and PYTHONPATH environment variables
+in CONFIG.SYS.
+
+PYTHONHOME should be set to Python's top level directory. PYTHONPATH
+should be set to the semicolon separated list of principal Python library
+directories.
+I use:
+ SET PYTHONHOME=F:/Python23
+ SET PYTHONPATH=F:/Python23/Lib;F:/Python23/Lib/plat-os2emx;
+ F:/Python23/Lib/lib-dynload;F:/Python23/Lib/site-packages
+
+NOTE!: the PYTHONPATH setting above is linewrapped for this document - it
+should all be on one line in CONFIG.SYS!
+
+If you wish to use the curses module, you should set the TERM and TERMINFO
+environment variables appropriately.
+
+If you don't already have ncurses installed, I have included a copy of the
+EMX subset of the Terminfo database included with the ncurses-5.2 source
+distribution. This can be used by setting the TERMINFO environment variable
+to the path of the Terminfo subdirectory below the Python home directory.
+On my system this looks like:
+ SET TERMINFO=F:/Python23/Terminfo
+
+For the TERM environment variable, I would try one of the following:
+ SET TERM=ansi
+ SET TERM=os2
+ SET TERM=window
+
+You will have to reboot your system for these changes to CONFIG.SYS to take
+effect.
+
+If you wish to compile all the included Python library modules to bytecode,
+you can change into the Python home directory and run the COMPILEALL.CMD
+batch file.
+
+You can execute the regression tests included with the Python 2.3 source
+distribution by changing to the Python 2.3 home directory and executing the
+REGRTEST.CMD batch file. The following tests are known to fail at this
+time:
+- test_longexp (see "YOU HAVE BEEN WARNED" item 1);
+- test_mhlib (I don't know of any port of MH to OS/2);
+- test_pwd (see "YOU HAVE BEEN WARNED" item 14, probably a bug in my code);
+- test_grp (as per test_pwd);
+- test_strftime (see "YOU HAVE BEEN WARNED" item 20);
+- test_socketserver (fork() related, see "YOU HAVE BEEN WARNED" item 2).
+
+
+YOU HAVE BEEN WARNED!!
+----------------------
+
+I know about a number of nasties in this port.
+
+1. EMX's malloc() and/or the underlying OS/2 VM system aren't particularly
+comfortable with Python's use of heap memory. The test_longexp regression
+test exhausts the available swap space on a machine with 64MB of RAM with
+150MB of available swap space.
+
+Using a crudely instrumented wrapper around malloc()/realloc()/free(), the
+heap memory usage of the expression at the core of the test
+(eval('[' + '2,' * NUMREPS + ']')) is as follows (approximately):
+ NUMREPS = 1 => 300k
+ NUMREPS = 10000 => 22MB
+ NUMREPS = 20500 => 59MB
+
+I don't even have enough memory to try for NUMREPS = 25000 :-(, let alone
+the NUMREPS = 65580 in test_longexp! I do have a report that the test
+succeeds in the presence of sufficient memory (~200MB RAM).
+
+During the course of running the test routine, the Python parser
+allocates lots of 21 byte memory chunks, each of which is actually
+a 64 byte allocation. There are a smaller number of 3 byte allocations
+which consume 12 bytes each. Consequently, more than 3 times as much
+memory is allocated than is actually used.
+
+The Python Object Allocator code (PyMalloc) was introduced in Python 2.1
+for Python's core to be able to wrap the malloc() system to deal with
+problems with "unfriendly" malloc() behaviour, such as this. Unfortunately
+for the OS/2 port, it is only supported for the allocation of memory for
+objects, whereas my research into this problem indicates it is the parser
+which is source of this particular malloc() frenzy.
+
+I have attempted using PyMalloc to manage all of Python's memory
+allocation. While this works fine (modulo the socket regression test
+failing in the absence of a socket.pyc), it is a significant performance
+hit - the time to run the regression test blows out from ~3.5 minutes to
+~5.75 minutes on my system.
+
+I therefore don't plan to pursue this any further for the time being.
+
+Be aware that certain types of expressions could well bring your system
+to its knees as a result of this issue. I have modified the longexp test
+to report failure to highlight this.
+
+2. Eberhard Mattes, author of EMX, writes in his documentation that fork()
+is very inefficient in the OS/2 environment. It also requires that the
+executable be linked in a.out format rather than OMF. Use the os.exec
+and/or the os.spawn family of functions where possible.
+
+{3. Issue resolved...}
+
+4. In the absence of GNU Readline, terminating the interpreter requires a
+control-Z (^Z) followed by a carriage return. Jeff Rush documented this
+problem in his Python 1.5.2 port. With Readline, a control-D (^D) works
+as per the standard Unix environment.
+
+5. EMX only has a partial implementation of fcntl(). The fcntl module
+in this port supports what EMX supports. If fcntl is important to you,
+please review the EMX C Library Reference (included in .INF format in the
+EMXVIEW.ZIP archive as part of the complete EMX development tools suite).
+Because of other side-effects I have modified the test_fcntl.py test
+script to deactivate the exercising of the missing functionality.
+
+6. The BSD DB module is linked against DB v1.85. This version is widely
+known to have bugs, although some patches have become available (and are
+incorporated into the included bsddb module). Unless you have problems
+with software licenses which would rule out GDBM (and the dbm module
+because it is linked against the GDBM library) or need it for file format
+compatibility, you may be better off deleting it and relying on GDBM. I
+haven't looked at porting the version of the module supporting the later
+SleepyCat releases of BSD DB, which would also require a port of the
+SleepyCat DB package.
+
+7. The readline module has been linked against ncurses rather than the
+termcap library supplied with EMX.
+
+{8. Workaround implemented}
+
+9. I have configured this port to use "/" as the preferred path separator
+character, rather than "\" ('\\'), in line with the convention supported
+by EMX. Backslashes are still supported of course, and still appear in
+unexpected places due to outside sources that don't get normalised.
+
+10. While the DistUtils components are now functional, other
+packaging/binary handling tools and utilities such as those included in
+the Demo and Tools directories - freeze in particular - are unlikely to
+work. If you do get them going, I'd like to know about your success.
+
+11. I haven't set out to support the [BEGIN|END]LIBPATH functionality
+supported by one of the earlier ports (Rush's??). If it works let me know.
+
+12. There appear to be several versions of Z.DLL floating around - the one
+I have is 45061 bytes and dated January 22, 1999. I have a report that
+another version causes SYS3175s when the zlib module is imported.
+
+14. As a result of the limitations imposed by EMX's library routines, the
+standard extension module pwd only synthesises a simple passwd database,
+and the grp module cannot be supported at all.
+
+I have written substitutes, in Python naturally, which can process real
+passwd and group files for those applications (such as MailMan) that
+require more than EMX emulates. I have placed pwd.py and grp.py in
+Lib/plat-os2emx, which is usually before Lib/lib-dynload (which contains
+pwd.pyd) in the PYTHONPATH. If you have become attached to what pwd.pyd
+supports, you can put Lib/lib-dynload before Lib/plat-os2emx in PYTHONPATH
+or delete/rename pwd.py & grp.py.
+
+pwd.py & grp.py support locating their data files by looking in the
+environment for them in the following sequence:
+pwd.py: $ETC_PASSWD (%ETC_PASSWD%)
+ $ETC/passwd (%ETC%/passwd)
+ $PYTHONHOME/Etc/passwd (%PYTHONHOME%/Etc/passwd)
+grp.py: $ETC_GROUP (%ETC_GROUP%)
+ $ETC/group (%ETC%/group)
+ $PYTHONHOME/Etc/group (%PYTHONHOME%/Etc/group)
+
+Both modules support using either the ":" character (Unix standard) or
+";" (OS/2, DOS, Windows standard) field separator character, and pwd.py
+implements the following drive letter conversions for the home_directory and
+shell fields (for the ":" separator only):
+ $x -> x:
+ x; -> x:
+
+Example versions of passwd and group are in the Etc subdirectory. Note
+that as of this release, this code fails the regression test. I'm looking
+into why, and hope to have this fixed.
+
+15. As of Python 2.1, termios support has mutated. There is no longer a
+platform specific TERMIOS.py containing the symbolic constants - these
+now live in the termios module. EMX's termios routines don't support all
+of the functionality now exposed by the termios module - refer to the EMX
+documentation to find out what is supported.
+
+16. The case sensitive import semantics introduced in Python 2.1 for other
+case insensitive but case preserving file/operating systems (Windows etc),
+have been incorporated into this port, and are active by default. Setting
+the PYTHONCASEOK environment variable (to any value) reverts to the
+previous (case insensitive) semantics.
+
+17. Because I am statically linking ncurses, the _curses_panel
+module has potential problems arising from separate library data areas.
+To avoid this, I have configured the _curses_.pyd (imported as
+"_curses_panel") to import the ncurses symbols it needs from _curses.pyd.
+As a result the _curses module must be imported before the _curses_panel
+module. As far as I can tell, the modules in the curses package do this.
+If you have problems attempting to use the _curses_panel support please
+let me know, and I'll look into an alternative solution.
+
+18. I tried enabling the Python Object Allocator (PYMALLOC) code. While
+the port built this way passes the regression test, the Numpy extension
+(I tested v19.0.0) as built with with the port's DistUtils code doesn't
+work. Specifically, attempting to "import Numeric" provokes a core dump.
+Supposedly Numpy v20.1.0 contains a fix for this, but for reason outlined
+in item 1 above, PYMALLOC is not enabled in this release.
+
+19. sys.platform now reports "os2emx" instead of "os2". os.name still
+reports "os2". This change was to make it easier to distinguish between
+the VAC++ build (being maintained by Michael Muller) and the EMX build
+(this port), principally for DistUtils.
+
+20. it appears that the %W substitution in the EMX strftime() routine has
+an off-by-one bug. strftime was listed as passing the regression tests
+in previous releases, but this fact appears to have been an oversight in
+the regression test suite. To fix this really requires a portable
+strftime routine - I'm looking into using one from FreeBSD, but its not
+ready yet.
+
+21. previous releases of my Python ports have used the GCC optimisations
+"-O2 -fomit-frame-pointer". After experimenting with various optimisation
+settings, including deactivating assert()ions, I have concluded that "-O2"
+appears the best compromise for GCC 2.8.1 on my hardware. Curiously,
+deactivating assert() (via defining NDEBUG) _negatively_ impacts
+performance, allbeit only slightly, so I've chosen to leave the assert()s
+active.
+
+I did try using Andrew Zabolotny's (p)gcc 2.95.2 compiler, and in
+general concluded that it produced larger objects that ran slower
+than Mattes' gcc 2.8.1 compiler.
+
+Pystone ratings varied from just over 2000/s (no optimisation at all)
+to just under 3300/s (gcc 2.8.1, -O2) on my K6/2-300 system, for
+100,000 iterations per run (rather than the default 10000).
+
+As a result of the optimisation change, the Python DLL is about 10%
+smaller than in the 2.1 release, and many of the dynamically loadable
+modules are smaller too.
+
+[2001/08/12]
+
+22. As of this release, os.spawnv() and os.spawnve() now expose EMX's
+library routines rather than use the emulation in os.py.
+
+In order to make use of some of the features this makes available in
+the OS/2 environment, you should peruse the relevant EMX documentation
+(EMXLIB.INF in the EMXVIEW.ZIP archive accompanying the EMX archives
+on Hobbes or LEO). Be aware that I have exposed all the "mode" options
+supported by EMX, but there are combinations that either cannot be
+practically used by/in Python or have the potential to compromise your
+system's stability.
+
+23. pythonpm.exe in previous releases was just python.exe with the
+WINDOWAPI linker option set in the pythonpm.def file. In practice,
+this turns out to do nothing useful.
+
+I have written a replacement which wraps the Python DLL in a genuine
+Presentation Manager application. This version actually runs the
+Python interpreter in a separate thread from the PM shell, in order
+that PythonPM has a functioning message queue as good PM apps should.
+In its current state, PythonPM's window is hidden. It can be displayed,
+although it will have no content as nothing is ever written to the
+window. Only the "hide" button is available. Although the code
+has support for shutting PythonPM down when the Python interpreter is
+still busy (via the "control" menu), this is not well tested and given
+comments I've come across in EMX documentation suggesting that the
+thread killing operation has problems I would suggest caution in
+relying on this capability.
+
+PythonPM processes commandline parameters normally. The standard input,
+output and error streams are only useful if redirected, as PythonPM's
+window is not a console in any form and so cannot accept or display
+anything. This means that the -i option is ineffective.
+
+Because the Python thread doesn't create its own message queue, creating
+PM Windows and performing most PM operations is not possible from within
+this thread. How this will affect supporting PM extensions (such as
+Tkinter using a PM port of Tcl/Tk, or wxPython using the PM port of
+WxWindows) is still being researched.
+
+Note that os.fork() _DOES_NOT_WORK_ in PythonPM - SYS3175s are the result
+of trying. os.spawnv() _does_ work. PythonPM passes all regression tests
+that the standard Python interpreter (python.exe) passes, with the exception
+of test_fork1 and test_socket which both attempt to use os.fork().
+
+I very much want feedback on the performance, behaviour and utility of
+PythonPM. I would like to add a PM console capability to it, but that
+will be a non-trivial effort. I may be able to leverage the code in
+Illya Vaes' Tcl/Tk port, which would make it easier.
+
+[2001/08/14]
+
+24. os.chdir() now uses EMX's _chdir2(), which supports changing
+both drive and directory at once. Similarly, os.getcwd() now uses
+EMX's _getcwd() which returns drive as well as path.
+
+[2001/12/08] - 2.2 Beta 2
+
+25. pyconfig.h (previously known as config.h) is now located in the
+Include subdirectory with all other include files.
+
+[2001/12/16] - 2.2 Release Candidate 1
+
+[2001/12/08] - 2.2 Final
+
+... probably other issues that I've not encountered, or don't remember :-(
+
+If you encounter other difficulties with this port, which can be
+characterised as peculiar to this port rather than to the Python release,
+I would like to hear about them. However I cannot promise to be able to do
+anything to resolve such problems. See the Contact section below...
+
+
+To do...
+--------
+
+In no particular order of apparent importance or likelihood...
+
+- support Tkinter and/or alternative GUI (wxWindows??)
+
+
+Credits
+-------
+
+In addition to people identified above, I'd like to thank:
+- the BDFL, Guido van Rossum, and crew for Python;
+- Dr David Mertz, for trying out a pre-release of this port;
+- the Python-list/comp.lang.python community;
+- John Poltorak, for input about pwd/grp.
+
+Contact
+-------
+
+Constructive feedback, negative or positive, about this port is welcome
+and should be addressed to me at the e-mail addresses below.
+
+I intend creating a private mailing list for announcements of fixes &
+updates to this port. If you wish to receive such e-mail announcments,
+please send me an e-mail requesting that you be added to this list.
+
+Andrew MacIntyre
+E-mail: andymac@bullseye.apana.org.au, or andymac@pcug.org.au
+Web: http://www.andymac.org/
+
+24 December, 2001.
diff --git a/PC/os2emx/config.c b/PC/os2emx/config.c
new file mode 100644
index 0000000000..89f8dc3133
--- /dev/null
+++ b/PC/os2emx/config.c
@@ -0,0 +1,160 @@
+/* -*- C -*- ***********************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Module configuration */
+
+/* This file contains the table of built-in modules.
+ See init_builtin() in import.c. */
+
+#include "Python.h"
+
+extern void init_codecs();
+extern void init_curses();
+extern void init_curses_panel();
+extern void init_hotshot();
+extern void init_locale();
+extern void init_socket();
+extern void init_sre();
+extern void init_testcapi();
+extern void init_weakref();
+extern void initarray();
+extern void initbinascii();
+extern void initbsddb();
+extern void initcPickle();
+extern void initcStringIO();
+extern void initcmath();
+extern void initdl();
+extern void initerrno();
+extern void initfcntl();
+extern void initfpectl();
+extern void initfpetest();
+extern void initgc();
+extern void initimageop();
+extern void initmath();
+extern void initmd5();
+extern void initnew();
+extern void initos2();
+extern void initoperator();
+extern void initparser();
+extern void initpcre();
+extern void initpwd();
+extern void initregex();
+extern void initrgbimg();
+extern void initrotor();
+extern void initselect();
+extern void initsha();
+extern void initsignal();
+extern void initstrop();
+extern void initstruct();
+extern void inittermios();
+extern void initthread();
+extern void inittime();
+extern void inittiming();
+extern void initunicodedata();
+extern void initxreadlines();
+extern void initzlib();
+
+/* -- ADDMODULE MARKER 1 -- */
+
+extern void PyMarshal_Init();
+extern void initimp();
+
+struct _inittab _PyImport_Inittab[] = {
+
+ {"gc", initgc},
+ {"os2", initos2},
+ {"_sre", init_sre},
+ {"signal", initsignal},
+#ifdef WITH_THREAD
+ {"thread", initthread},
+#endif
+#if !HAVE_DYNAMIC_LOADING
+ {"_codecs", init_codecs},
+ {"_curses", init_curses},
+ {"_curses_panel", init_curses_panel},
+ {"_hotshot", init_hotshot},
+ {"_locale", init_locale},
+ {"_testcapi", init_testcapi},
+ {"_weakref", init_weakref},
+ {"array", initarray},
+ {"binascii", initbinascii},
+ {"bsddb", initbsddb},
+ {"cPickle", initcPickle},
+ {"cStringIO", initcStringIO},
+ {"cmath", initcmath},
+ {"dl", initdl},
+ {"errno", initerrno},
+ {"fcntl", initfcntl},
+ {"fpectl", initfpectl},
+ {"fpetest", initfpetest},
+ {"imageop", initimageop},
+ {"math", initmath},
+ {"md5", initmd5},
+ {"new", initnew},
+ {"operator", initoperator},
+ {"parser", initparser},
+ {"pcre", initpcre},
+ {"pwd", initpwd},
+ {"regex", initregex},
+ {"rgbimg", initrgbimg},
+ {"rotor", initrotor},
+ {"sha", initsha},
+ {"strop", initstrop},
+ {"struct", initstruct},
+ {"termios", inittermios},
+ {"time", inittime},
+ {"timing", inittiming},
+ {"unicodedata", initunicodedata},
+ {"xreadlines", initxreadlines},
+ {"zlib", initzlib},
+#ifdef USE_SOCKET
+ {"_socket", init_socket},
+ {"select", initselect},
+#endif
+#endif
+
+/* -- ADDMODULE MARKER 2 -- */
+
+ /* This module "lives in" with marshal.c */
+ {"marshal", PyMarshal_Init},
+
+ /* This lives it with import.c */
+ {"imp", initimp},
+
+ /* These entries are here for sys.builtin_module_names */
+ {"__main__", NULL},
+ {"__builtin__", NULL},
+ {"sys", NULL},
+ {"exceptions", NULL},
+
+ /* Sentinel */
+ {0, 0}
+};
diff --git a/PC/os2emx/dlfcn.c b/PC/os2emx/dlfcn.c
new file mode 100644
index 0000000000..acf0197c38
--- /dev/null
+++ b/PC/os2emx/dlfcn.c
@@ -0,0 +1,224 @@
+/* -*- C -*- ***********************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/*
+ This library implements dlopen() - functions for OS/2 using
+ DosLoadModule() and company.
+*/
+
+#define INCL_DOS
+#define INCL_DOSERRORS
+#define INCL_DOSSESMGR
+#define INCL_WINPROGRAMLIST
+#define INCL_WINFRAMEMGR
+#include <os2.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+
+/*-------------------------------------- Unix-like dynamic linking emulation -*/
+
+typedef struct _track_rec {
+ char *name;
+ HMODULE handle;
+ void *id;
+ struct _track_rec *next;
+} tDLLchain, *DLLchain;
+
+static DLLchain dlload = NULL; /* A simple chained list of DLL names */
+static char dlerr [256]; /* last error text string */
+static void *last_id;
+
+static DLLchain find_id(void *id)
+{
+ DLLchain tmp;
+
+ for (tmp = dlload; tmp; tmp = tmp->next)
+ if (id == tmp->id)
+ return (tmp);
+
+ return (NULL);
+}
+
+/* load a dynamic-link library and return handle */
+void *dlopen (char *filename, int flags)
+{
+ HMODULE hm;
+ DLLchain tmp;
+ char err[256];
+ char *errtxt;
+ int rc = 0, set_chain = 0;
+
+ for (tmp = dlload; tmp; tmp = tmp->next)
+ if (strnicmp(tmp->name, filename, 999) == 0)
+ break;
+
+ if (!tmp)
+ {
+ tmp = (DLLchain)malloc (sizeof (tDLLchain));
+ if (!tmp)
+ goto nomem;
+ tmp->name = strdup (filename);
+ tmp->next = dlload;
+ set_chain = 1;
+ }
+
+ switch (rc = DosLoadModule((PSZ)&err, sizeof(err), filename, &hm))
+ {
+ case NO_ERROR:
+ tmp->handle = hm;
+ if (set_chain) {
+ do {
+ last_id++;
+ } while ((last_id == 0) || (find_id(last_id)));
+ tmp->id = last_id;
+ dlload = tmp;
+ }
+ return (tmp->id);
+ case ERROR_FILE_NOT_FOUND:
+ case ERROR_PATH_NOT_FOUND:
+ errtxt = "module `%s' not found";
+ break;
+ case ERROR_TOO_MANY_OPEN_FILES:
+ case ERROR_NOT_ENOUGH_MEMORY:
+ case ERROR_SHARING_BUFFER_EXCEEDED:
+nomem:
+ errtxt = "out of system resources";
+ break;
+ case ERROR_ACCESS_DENIED:
+ errtxt = "access denied";
+ break;
+ case ERROR_BAD_FORMAT:
+ case ERROR_INVALID_SEGMENT_NUMBER:
+ case ERROR_INVALID_ORDINAL:
+ case ERROR_INVALID_MODULETYPE:
+ case ERROR_INVALID_EXE_SIGNATURE:
+ case ERROR_EXE_MARKED_INVALID:
+ case ERROR_ITERATED_DATA_EXCEEDS_64K:
+ case ERROR_INVALID_MINALLOCSIZE:
+ case ERROR_INVALID_SEGDPL:
+ case ERROR_AUTODATASEG_EXCEEDS_64K:
+ case ERROR_RELOCSRC_CHAIN_EXCEEDS_SEGLIMIT:
+ errtxt = "invalid module format";
+ break;
+ case ERROR_INVALID_NAME:
+ errtxt = "filename doesn't match module name";
+ break;
+ case ERROR_SHARING_VIOLATION:
+ case ERROR_LOCK_VIOLATION:
+ errtxt = "sharing violation";
+ break;
+ case ERROR_INIT_ROUTINE_FAILED:
+ errtxt = "module initialization failed";
+ break;
+ default:
+ errtxt = "cause `%s', error code = %d";
+ break;
+ }
+ snprintf (dlerr, sizeof (dlerr), errtxt, &err, rc);
+ if (tmp) {
+ if (tmp->name)
+ free(tmp->name);
+ free (tmp);
+ }
+ return (0);
+}
+
+/* return a pointer to the `symbol' in DLL */
+void *dlsym (void *handle, char *symbol)
+{
+ int rc = 0;
+ PFN addr;
+ char *errtxt;
+ int symord = 0;
+ DLLchain tmp = find_id (handle);
+
+ if (!tmp)
+ goto inv_handle;
+
+ if (*symbol == '#')
+ symord = atoi (symbol + 1);
+
+ switch (rc = DosQueryProcAddr(tmp->handle, symord, symbol, &addr))
+ {
+ case NO_ERROR:
+ return ((void *)addr);
+ case ERROR_INVALID_HANDLE:
+inv_handle:
+ errtxt = "invalid module handle";
+ break;
+ case ERROR_PROC_NOT_FOUND:
+ case ERROR_INVALID_NAME:
+ errtxt = "no symbol `%s' in module";
+ break;
+ default:
+ errtxt = "symbol `%s', error code = %d";
+ break;
+ }
+ snprintf (dlerr, sizeof (dlerr), errtxt, symbol, rc);
+ return (NULL);
+}
+
+/* free dynamicaly-linked library */
+int dlclose (void *handle)
+{
+ int rc;
+ DLLchain tmp = find_id (handle);
+
+ if (!tmp)
+ goto inv_handle;
+
+ switch (rc = DosFreeModule (tmp->handle))
+ {
+ case NO_ERROR:
+ free (tmp->name);
+ dlload = tmp->next;
+ free (tmp);
+ return (0);
+ case ERROR_INVALID_HANDLE:
+inv_handle:
+ strcpy(dlerr, "invalid module handle");
+ return (-1);
+ case ERROR_INVALID_ACCESS:
+ strcpy (dlerr, "access denied");
+ return (-1);
+ default:
+ return (-1);
+ }
+}
+
+/* return a string describing last occured dl error */
+char *dlerror()
+{
+ return (dlerr);
+}
diff --git a/PC/os2emx/dlfcn.h b/PC/os2emx/dlfcn.h
new file mode 100644
index 0000000000..214ddac9d8
--- /dev/null
+++ b/PC/os2emx/dlfcn.h
@@ -0,0 +1,50 @@
+/* -*- C -*- ***********************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+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 names of Stichting Mathematisch
+Centrum or CWI or Corporation for National Research Initiatives or
+CNRI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+While CWI is the initial source for this software, a modified version
+is made available by the Corporation for National Research Initiatives
+(CNRI) at the Internet address ftp://ftp.python.org.
+
+STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
+CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/*
+ This library implements dlopen() - functions for OS/2 using
+ DosLoadModule() and company.
+*/
+
+#ifndef _DLFCN_H
+#define _DLFCN_H
+
+/*-------------------------------------- Unix-like dynamic linking emulation -*/
+/* load a dynamic-link library and return handle */
+void *dlopen (char *filename, int flags);
+/* return a pointer to the `symbol' in DLL */
+void *dlsym (void *handle, char *symbol);
+/* free dynamicaly-linked library */
+int dlclose (void *handle);
+/* return a string describing last occured dl error */
+char *dlerror(void);
+
+#endif /* !_DLFCN_H */
diff --git a/PC/os2emx/dllentry.c b/PC/os2emx/dllentry.c
new file mode 100644
index 0000000000..511c3d9679
--- /dev/null
+++ b/PC/os2emx/dllentry.c
@@ -0,0 +1,54 @@
+/*
+ This is the entry point for Python DLL(s).
+ It also provides an getenv() function that works from within DLLs.
+*/
+
+#define NULL 0
+
+/* Make references to imported symbols to pull them from static library */
+#define REF(s) extern void s (); void *____ref_##s = &s;
+
+REF (Py_Main);
+
+#if defined (__EMX__)
+
+#include <signal.h>
+
+extern int _CRT_init (void);
+extern void _CRT_term (void);
+extern void __ctordtorInit (void);
+extern void __ctordtorTerm (void);
+
+unsigned long _DLL_InitTerm (unsigned long mod_handle, unsigned long flag)
+{
+ switch (flag)
+ {
+ case 0:
+ if (_CRT_init ()) return 0;
+ __ctordtorInit ();
+ /* Ignore fatal signals */
+ signal (SIGSEGV, SIG_IGN);
+ signal (SIGFPE, SIG_IGN);
+ return 1;
+ case 1:
+ __ctordtorTerm ();
+ _CRT_term ();
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+#endif
+
+/* A version of getenv() that works from DLLs */
+extern int DosScanEnv (const char *pszName, char **ppszValue);
+
+char *getenv (const char *name)
+{
+ char *value;
+ if (DosScanEnv (name, &value))
+ return NULL;
+ else
+ return value;
+}
diff --git a/PC/os2emx/getpathp.c b/PC/os2emx/getpathp.c
new file mode 100644
index 0000000000..5cb8278c7c
--- /dev/null
+++ b/PC/os2emx/getpathp.c
@@ -0,0 +1,383 @@
+
+/* Return the initial module search path. */
+/* This version used by OS/2+EMX */
+
+/* ----------------------------------------------------------------
+ PATH RULES FOR OS/2+EMX:
+ This describes how sys.path is formed on OS/2+EMX. It describes the
+ functionality, not the implementation (ie, the order in which these
+ are actually fetched is different)
+
+ * Python always adds an empty entry at the start, which corresponds
+ to the current directory.
+
+ * If the PYTHONPATH env. var. exists, it's entries are added next.
+
+ * We attempt to locate the "Python Home" - if the PYTHONHOME env var
+ is set, we believe it. Otherwise, we use the path of our host .EXE's
+ to try and locate our "landmark" (lib\\os.py) and deduce our home.
+ - If we DO have a Python Home: The relevant sub-directories (Lib,
+ plat-win, lib-tk, etc) are based on the Python Home
+ - If we DO NOT have a Python Home, the core Python Path is
+ loaded from the registry. This is the main PythonPath key,
+ and both HKLM and HKCU are combined to form the path)
+
+ * Iff - we can not locate the Python Home, and have not had a PYTHONPATH
+ specified (ie, we have _nothing_ we can assume is a good path), a
+ default path with relative entries is used (eg. .\Lib;.\plat-win, etc)
+
+
+ The end result of all this is:
+ * When running python.exe, or any other .exe in the main Python directory
+ (either an installed version, or directly from the PCbuild directory),
+ the core path is deduced.
+
+ * When Python is hosted in another exe (different directory, embedded via
+ COM, etc), the Python Home will not be deduced, so the core path from
+ the registry is used. Other "application paths "in the registry are
+ always read.
+
+ * If Python can't find its home and there is no registry (eg, frozen
+ exe, some very strange installation setup) you get a path with
+ some default, but relative, paths.
+
+ ---------------------------------------------------------------- */
+
+
+#include "Python.h"
+#include "osdefs.h"
+
+#ifndef PYOS_OS2
+#error This file only compilable on OS/2
+#endif
+
+#define INCL_DOS
+#include <os2.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+/* Search in some common locations for the associated Python libraries.
+ *
+ * Py_GetPath() tries to return a sensible Python module search path.
+ *
+ * The approach is an adaptation for Windows of the strategy used in
+ * ../Modules/getpath.c; it uses the Windows Registry as one of its
+ * information sources.
+ */
+
+#ifndef LANDMARK
+#if defined(PYCC_GCC)
+#define LANDMARK "lib/os.py"
+#else
+#define LANDMARK "lib\\os.py"
+#endif
+#endif
+
+static char prefix[MAXPATHLEN+1];
+static char progpath[MAXPATHLEN+1];
+static char *module_search_path = NULL;
+
+
+static int
+is_sep(char ch) /* determine if "ch" is a separator character */
+{
+#ifdef ALTSEP
+ return ch == SEP || ch == ALTSEP;
+#else
+ return ch == SEP;
+#endif
+}
+
+/* assumes 'dir' null terminated in bounds. Never writes
+ beyond existing terminator.
+*/
+static void
+reduce(char *dir)
+{
+ size_t i = strlen(dir);
+ while (i > 0 && !is_sep(dir[i]))
+ --i;
+ dir[i] = '\0';
+}
+
+static int
+exists(char *filename)
+{
+ struct stat buf;
+ return stat(filename, &buf) == 0;
+}
+
+/* Assumes 'filename' MAXPATHLEN+1 bytes long -
+ may extend 'filename' by one character.
+*/
+static int
+ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
+{
+ if (exists(filename))
+ return 1;
+
+ /* Check for the compiled version of prefix. */
+ if (strlen(filename) < MAXPATHLEN) {
+ strcat(filename, Py_OptimizeFlag ? "o" : "c");
+ if (exists(filename))
+ return 1;
+ }
+ return 0;
+}
+
+/* guarantees buffer will never overflow MAXPATHLEN+1 bytes */
+static void
+join(char *buffer, char *stuff)
+{
+ size_t n, k;
+ if (is_sep(stuff[0]))
+ n = 0;
+ else {
+ n = strlen(buffer);
+ if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
+ buffer[n++] = SEP;
+ }
+ k = strlen(stuff);
+ if (n + k > MAXPATHLEN)
+ k = MAXPATHLEN - n;
+ strncpy(buffer+n, stuff, k);
+ buffer[n+k] = '\0';
+}
+
+/* gotlandmark only called by search_for_prefix, which ensures
+ 'prefix' is null terminated in bounds. join() ensures
+ 'landmark' can not overflow prefix if too long.
+*/
+static int
+gotlandmark(char *landmark)
+{
+ int n, ok;
+
+ n = strlen(prefix);
+ join(prefix, landmark);
+ ok = ismodule(prefix);
+ prefix[n] = '\0';
+ return ok;
+}
+
+/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
+ assumption provided by only caller, calculate_path() */
+static int
+search_for_prefix(char *argv0_path, char *landmark)
+{
+ /* Search from argv0_path, until landmark is found */
+ strcpy(prefix, argv0_path);
+ do {
+ if (gotlandmark(landmark))
+ return 1;
+ reduce(prefix);
+ } while (prefix[0]);
+ return 0;
+}
+
+
+static void
+get_progpath(void)
+{
+ extern char *Py_GetProgramName(void);
+ char *path = getenv("PATH");
+ char *prog = Py_GetProgramName();
+
+ PPIB pib;
+ if ((DosGetInfoBlocks(NULL, &pib) == 0) &&
+ (DosQueryModuleName(pib->pib_hmte, sizeof(progpath), progpath) == 0))
+ return;
+
+ if (prog == NULL || *prog == '\0')
+ prog = "python";
+
+ /* If there is no slash in the argv0 path, then we have to
+ * assume python is on the user's $PATH, since there's no
+ * other way to find a directory to start the search from. If
+ * $PATH isn't exported, you lose.
+ */
+#ifdef ALTSEP
+ if (strchr(prog, SEP) || strchr(prog, ALTSEP))
+#else
+ if (strchr(prog, SEP))
+#endif
+ strncpy(progpath, prog, MAXPATHLEN);
+ else if (path) {
+ while (1) {
+ char *delim = strchr(path, DELIM);
+
+ if (delim) {
+ size_t len = delim - path;
+ /* ensure we can't overwrite buffer */
+#if !defined(PYCC_GCC)
+ len = min(MAXPATHLEN,len);
+#else
+ len = MAXPATHLEN < len ? MAXPATHLEN : len;
+#endif
+ strncpy(progpath, path, len);
+ *(progpath + len) = '\0';
+ }
+ else
+ strncpy(progpath, path, MAXPATHLEN);
+
+ /* join() is safe for MAXPATHLEN+1 size buffer */
+ join(progpath, prog);
+ if (exists(progpath))
+ break;
+
+ if (!delim) {
+ progpath[0] = '\0';
+ break;
+ }
+ path = delim + 1;
+ }
+ }
+ else
+ progpath[0] = '\0';
+}
+
+static void
+calculate_path(void)
+{
+ char argv0_path[MAXPATHLEN+1];
+ char *buf;
+ size_t bufsz;
+ char *pythonhome = Py_GetPythonHome();
+ char *envpath = getenv("PYTHONPATH");
+
+ get_progpath();
+ /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
+ strcpy(argv0_path, progpath);
+ reduce(argv0_path);
+ if (pythonhome == NULL || *pythonhome == '\0') {
+ if (search_for_prefix(argv0_path, LANDMARK))
+ pythonhome = prefix;
+ else
+ pythonhome = NULL;
+ }
+ else
+ strncpy(prefix, pythonhome, MAXPATHLEN);
+
+ if (envpath && *envpath == '\0')
+ envpath = NULL;
+
+ /* We need to construct a path from the following parts.
+ (1) the PYTHONPATH environment variable, if set;
+ (2) the PYTHONPATH config macro, with the leading "."
+ of each component replaced with pythonhome, if set;
+ (3) the directory containing the executable (argv0_path).
+ The length calculation calculates #2 first.
+ */
+
+ /* Calculate size of return buffer */
+ if (pythonhome != NULL) {
+ char *p;
+ bufsz = 1;
+ for (p = PYTHONPATH; *p; p++) {
+ if (*p == DELIM)
+ bufsz++; /* number of DELIM plus one */
+ }
+ bufsz *= strlen(pythonhome);
+ }
+ else
+ bufsz = 0;
+ bufsz += strlen(PYTHONPATH) + 1;
+ bufsz += strlen(argv0_path) + 1;
+ if (envpath != NULL)
+ bufsz += strlen(envpath) + 1;
+
+ module_search_path = buf = malloc(bufsz);
+ if (buf == NULL) {
+ /* We can't exit, so print a warning and limp along */
+ fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
+ if (envpath) {
+ fprintf(stderr, "Using environment $PYTHONPATH.\n");
+ module_search_path = envpath;
+ }
+ else {
+ fprintf(stderr, "Using default static path.\n");
+ module_search_path = PYTHONPATH;
+ }
+ return;
+ }
+
+ if (envpath) {
+ strcpy(buf, envpath);
+ buf = strchr(buf, '\0');
+ *buf++ = DELIM;
+ }
+
+ if (pythonhome == NULL) {
+ strcpy(buf, PYTHONPATH);
+ buf = strchr(buf, '\0');
+ }
+ else {
+ char *p = PYTHONPATH;
+ char *q;
+ size_t n;
+ for (;;) {
+ q = strchr(p, DELIM);
+ if (q == NULL)
+ n = strlen(p);
+ else
+ n = q-p;
+ if (p[0] == '.' && is_sep(p[1])) {
+ strcpy(buf, pythonhome);
+ buf = strchr(buf, '\0');
+ p++;
+ n--;
+ }
+ strncpy(buf, p, n);
+ buf += n;
+ if (q == NULL)
+ break;
+ *buf++ = DELIM;
+ p = q+1;
+ }
+ }
+ if (argv0_path) {
+ *buf++ = DELIM;
+ strcpy(buf, argv0_path);
+ buf = strchr(buf, '\0');
+ }
+ *buf = '\0';
+}
+
+
+/* External interface */
+
+char *
+Py_GetPath(void)
+{
+ if (!module_search_path)
+ calculate_path();
+ return module_search_path;
+}
+
+char *
+Py_GetPrefix(void)
+{
+ if (!module_search_path)
+ calculate_path();
+ return prefix;
+}
+
+char *
+Py_GetExecPrefix(void)
+{
+ return Py_GetPrefix();
+}
+
+char *
+Py_GetProgramFullPath(void)
+{
+ if (!module_search_path)
+ calculate_path();
+ return progpath;
+}
diff --git a/PC/os2emx/pyconfig.h b/PC/os2emx/pyconfig.h
new file mode 100644
index 0000000000..a72f9818e7
--- /dev/null
+++ b/PC/os2emx/pyconfig.h
@@ -0,0 +1,306 @@
+#ifndef Py_CONFIG_H
+#define Py_CONFIG_H
+
+/*
+ config.h.
+ At some time in the past, generated automatically by configure.
+ Maintained manually for better results.
+*/
+
+#define PLATFORM "os2emx"
+#define COMPILER "[EMX GCC " __VERSION__ "]"
+#define PYOS_OS2
+#define PYCC_GCC
+#define PREFIX "/usr"
+
+/* Debugging */
+#ifndef Py_DEBUG
+/*#define Py_DEBUG 1*/
+#endif
+
+/* so that emx socket headers will define IP V4 socket types */
+#define TCPIPV4
+
+/* Use OS/2 flavour of threads */
+#define WITH_THREAD
+#define OS2_THREADS
+
+/* We want sockets */
+#define USE_SOCKET
+#define socklen_t int
+
+/* enable the GC module */
+#define WITH_CYCLE_GC 1
+
+/* Unicode related */
+#define Py_USING_UNICODE
+#define PY_UNICODE_TYPE wchar_t
+#define Py_UNICODE_SIZE SIZEOF_SHORT
+
+/* enable the Python object allocator */
+/*#define WITH_PYMALLOC 1*/
+
+#define PYTHONPATH ".;./Lib;./Lib/plat-" PLATFORM ";./Lib/lib-dynload;./Lib/site-packages"
+
+#define HAVE_TTYNAME 1
+#define HAVE_WAIT 1
+#define HAVE_GETEGID 1
+#define HAVE_GETEUID 1
+#define HAVE_GETGID 1
+#define HAVE_GETPPID 1
+#define HAVE_GETUID 1
+#define HAVE_OPENDIR 1
+#define HAVE_PIPE 1
+#define HAVE_POPEN 1
+#define HAVE_SYSTEM 1
+#define HAVE_TTYNAME 1
+#define HAVE_DYNAMIC_LOADING 1
+
+/* if port of GDBM installed, it includes NDBM emulation */
+#define HAVE_NDBM_H 1
+
+/* need this for spawnv code in posixmodule (cloned from WIN32 def'n) */
+typedef long intptr_t;
+
+/* we don't have tm_zone but do have the external array
+ tzname. */
+#define HAVE_TZNAME 1
+
+/* Define as the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Used for BeOS configuration */
+/* #undef DL_EXPORT_HEADER */
+#ifdef DL_EXPORT_HEADER
+#include DL_EXPORT_HEADER
+#endif
+
+/* Define this if you have the type long long */
+#define HAVE_LONG_LONG 1
+
+/* Define if your compiler supports function prototypes */
+#define HAVE_PROTOTYPES 1
+
+/* Define if your compiler supports variable length function prototypes
+ (e.g. void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */
+#define HAVE_STDARG_PROTOTYPES 1
+
+/* Define if malloc(0) returns a NULL pointer */
+#define MALLOC_ZERO_RETURNS_NULL 1
+
+/* Define to force use of thread-safe errno, h_errno, and other functions */
+#define _REENTRANT 1
+
+/* Define if you can safely include both <sys/select.h> and <sys/time.h>
+ (which you can't on SCO ODT 3.0). */
+#define SYS_SELECT_WITH_SYS_TIME 1
+
+/* The number of bytes in an off_t. */
+#define SIZEOF_OFF_T 4
+
+/* The number of bytes in an time_t. */
+#define SIZEOF_TIME_T 4
+
+/* The number of bytes in a short. */
+#define SIZEOF_SHORT 2
+
+/* The number of bytes in a int. */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long. */
+#define SIZEOF_LONG 4
+
+/* The number of bytes in a long long. */
+#define SIZEOF_LONG_LONG 8
+
+/* The number of bytes in a void *. */
+#define SIZEOF_VOID_P 4
+
+/* Define if you have the alarm function. */
+#define HAVE_ALARM 1
+
+/* Define if you have the clock function. */
+#define HAVE_CLOCK 1
+
+/* Define if you have the dup2 function. */
+#define HAVE_DUP2 1
+
+/* Define if you have the execv function. */
+#define HAVE_EXECV 1
+
+/* Define if you have the spawnv function. */
+#define HAVE_SPAWNV 1
+
+/* Define if you have the flock function. */
+#define HAVE_FLOCK 1
+
+/* Define if you have the fork function. */
+#define HAVE_FORK 1
+
+/* Define if you have the fsync function. */
+#define HAVE_FSYNC 1
+
+/* Define if you have the ftime function. */
+#define HAVE_FTIME 1
+
+/* Define if you have the ftruncate function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define if you have the getcwd function. */
+#define HAVE_GETCWD 1
+
+/* Define if you have the getpeername function. */
+#define HAVE_GETPEERNAME 1
+
+/* Define if you have the getpgrp function. */
+#define HAVE_GETPGRP 1
+
+/* Define if you have the getpid function. */
+#define HAVE_GETPID 1
+
+/* Define if you have the getpwent function. */
+#define HAVE_GETPWENT 1
+
+/* Define if you have the gettimeofday function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define if you have the getwd function. */
+#define HAVE_GETWD 1
+
+/* Define if you have the hypot function. */
+#define HAVE_HYPOT 1
+
+/* Define if you have the kill function. */
+#define HAVE_KILL 1
+
+/* Define if you have the memmove function. */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the mktime function. */
+#define HAVE_MKTIME 1
+
+/* Define if you have the pause function. */
+#define HAVE_PAUSE 1
+
+/* Define if you have the putenv function. */
+#define HAVE_PUTENV 1
+
+/* Define if you have the select function. */
+#define HAVE_SELECT 1
+
+/* Define if you have the setgid function. */
+#define HAVE_SETGID 1
+
+/* Define if you have the setlocale function. */
+#define HAVE_SETLOCALE 1
+
+/* Define if you have the setpgid function. */
+#define HAVE_SETPGID 1
+
+/* Define if you have the setuid function. */
+#define HAVE_SETUID 1
+
+/* Define if you have the setvbuf function. */
+#define HAVE_SETVBUF 1
+
+/* Define if you have the sigaction function. */
+#define HAVE_SIGACTION 1
+
+/* Define if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strftime function. */
+#define HAVE_STRFTIME 1
+
+/* Define if you have the strptime function. */
+#define HAVE_STRPTIME 1
+
+/* Define if you have the tcgetpgrp function. */
+#define HAVE_TCGETPGRP 1
+
+/* Define if you have the tcsetpgrp function. */
+#define HAVE_TCSETPGRP 1
+
+/* Define if you have the times function. */
+#define HAVE_TIMES 1
+
+/* Define if you have the truncate function. */
+#define HAVE_TRUNCATE 1
+
+/* Define if you have the uname function. */
+#define HAVE_UNAME 1
+
+/* Define if you have the waitpid function. */
+#define HAVE_WAITPID 1
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define if you have the <ncurses.h> header file. */
+#define HAVE_NCURSES_H 1
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define if you have the <stdarg.h> header file. */
+#define HAVE_STDARG_H 1
+
+/* Define if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the <sys/file.h> header file. */
+#define HAVE_SYS_FILE_H 1
+
+/* Define if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define if you have the <sys/times.h> header file. */
+#define HAVE_SYS_TIMES_H 1
+
+/* Define if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H 1
+
+/* Define if you have the <sys/utsname.h> header file. */
+#define HAVE_SYS_UTSNAME_H 1
+
+/* Define if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* EMX has an snprintf() */
+#define HAVE_SNPRINTF
+
+#endif /* !Py_CONFIG_H */
+
diff --git a/PC/os2emx/python23.def b/PC/os2emx/python23.def
new file mode 100644
index 0000000000..00fe23a6d3
--- /dev/null
+++ b/PC/os2emx/python23.def
@@ -0,0 +1,931 @@
+LIBRARY python23 INITINSTANCE TERMINSTANCE
+DESCRIPTION "Python 2.3 Core DLL"
+PROTMODE
+DATA MULTIPLE NONSHARED
+EXPORTS
+
+; From python23_s.lib(config)
+ "_PyImport_Inittab"
+
+; From python23_s.lib(dlfcn)
+ "dlopen"
+ "dlsym"
+ "dlclose"
+ "dlerror"
+
+; From python23_s.lib(getpathp)
+ "Py_GetPath"
+ "Py_GetPrefix"
+ "Py_GetExecPrefix"
+ "Py_GetProgramFullPath"
+
+; From python23_s.lib(getbuildinfo)
+ "Py_GetBuildInfo"
+
+; From python23_s.lib(main)
+ "Py_Main"
+ "Py_GetArgcArgv"
+
+; From python23_s.lib(acceler)
+ "PyGrammar_AddAccelerators"
+ "PyGrammar_RemoveAccelerators"
+
+; From python23_s.lib(grammar1)
+ "PyGrammar_FindDFA"
+ "PyGrammar_LabelRepr"
+
+; From python23_s.lib(listnode)
+ "PyNode_ListTree"
+
+; From python23_s.lib(node)
+ "PyNode_New"
+ "PyNode_AddChild"
+ "PyNode_Free"
+
+; From python23_s.lib(parser)
+ "PyParser_New"
+ "PyParser_Delete"
+ "PyParser_AddToken"
+
+; From python23_s.lib(parsetok)
+ "Py_TabcheckFlag"
+ "PyParser_ParseString"
+ "PyParser_ParseStringFlags"
+ "PyParser_ParseFile"
+ "PyParser_ParseFileFlags"
+
+; From python23_s.lib(tokenizer)
+ "PyTokenizer_FromString"
+ "PyTokenizer_FromFile"
+ "PyTokenizer_Free"
+ "PyToken_OneChar"
+ "PyToken_TwoChars"
+ "PyToken_ThreeChars"
+ "PyTokenizer_Get"
+ "_PyParser_TokenNames"
+
+; From python23_s.lib(bitset)
+ "_Py_newbitset"
+ "_Py_delbitset"
+ "_Py_addbit"
+ "_Py_samebitset"
+ "_Py_mergebitset"
+
+; From python23_s.lib(metagrammar)
+ "_Py_meta_grammar"
+
+; From python23_s.lib(myreadline)
+ "PyOS_ReadlineFunctionPointer"
+ "PyOS_StdioReadline"
+ "PyOS_Readline"
+ "PyOS_InputHook"
+
+; From python23_s.lib(abstract)
+ "PyObject_Cmp"
+ "PyObject_Type"
+ "PyObject_Size"
+ "PyMapping_Size"
+ "PyObject_Length"
+ "PyObject_GetItem"
+ "PySequence_GetItem"
+ "PyObject_SetItem"
+ "PySequence_SetItem"
+ "PyObject_DelItem"
+ "PySequence_DelItem"
+ "PyObject_DelItemString"
+ "PyObject_AsCharBuffer"
+ "PyObject_CheckReadBuffer"
+ "PyObject_AsReadBuffer"
+ "PyObject_AsWriteBuffer"
+ "PyNumber_Check"
+ "PyNumber_Or"
+ "PyNumber_Xor"
+ "PyNumber_And"
+ "PyNumber_Lshift"
+ "PyNumber_Rshift"
+ "PyNumber_Subtract"
+ "PyNumber_Multiply"
+ "PyNumber_Divide"
+ "PyNumber_Divmod"
+ "PyNumber_Add"
+ "PyNumber_FloorDivide"
+ "PyNumber_TrueDivide"
+ "PyNumber_Remainder"
+ "PyNumber_Power"
+ "PyNumber_InPlaceOr"
+ "PyNumber_InPlaceXor"
+ "PyNumber_InPlaceAnd"
+ "PyNumber_InPlaceLshift"
+ "PyNumber_InPlaceRshift"
+ "PyNumber_InPlaceSubtract"
+ "PyNumber_InPlaceDivide"
+ "PyNumber_InPlaceFloorDivide"
+ "PyNumber_InPlaceTrueDivide"
+ "PyNumber_InPlaceAdd"
+ "PyNumber_InPlaceMultiply"
+ "PyNumber_InPlaceRemainder"
+ "PyNumber_InPlacePower"
+ "PyNumber_Negative"
+ "PyNumber_Positive"
+ "PyNumber_Invert"
+ "PyNumber_Absolute"
+ "PyNumber_Int"
+ "PyNumber_Long"
+ "PyNumber_Float"
+ "PySequence_Check"
+ "PySequence_Size"
+ "PySequence_Length"
+ "PySequence_Concat"
+ "PySequence_Repeat"
+ "PySequence_InPlaceConcat"
+ "PySequence_InPlaceRepeat"
+ "PySequence_GetSlice"
+ "PySequence_SetSlice"
+ "PySequence_DelSlice"
+ "PySequence_Tuple"
+ "PyObject_GetIter"
+ "PyIter_Next"
+ "PySequence_List"
+ "PySequence_Fast"
+ "_PySequence_IterSearch"
+ "PySequence_Count"
+ "PySequence_Contains"
+ "PySequence_In"
+ "PySequence_Index"
+ "PyMapping_Check"
+ "PyMapping_Length"
+ "PyMapping_GetItemString"
+ "PyMapping_SetItemString"
+ "PyMapping_HasKeyString"
+ "PyMapping_HasKey"
+ "PyObject_CallObject"
+ "PyObject_Call"
+ "PyObject_CallFunction"
+ "PyObject_CallMethod"
+ "PyObject_CallMethodObjArgs"
+ "PyObject_CallFunctionObjArgs"
+ "PyObject_IsInstance"
+ "PyObject_IsSubclass"
+
+; From python23_s.lib(bufferobject)
+ "PyBuffer_FromObject"
+ "PyBuffer_FromReadWriteObject"
+ "PyBuffer_FromMemory"
+ "PyBuffer_FromReadWriteMemory"
+ "PyBuffer_New"
+ "PyBuffer_Type"
+
+; From python23_s.lib(cellobject)
+ "PyCell_New"
+ "PyCell_Get"
+ "PyCell_Set"
+ "PyCell_Type"
+
+; From python23_s.lib(classobject)
+ "PyClass_New"
+ "PyMethod_Function"
+ "PyMethod_Self"
+ "PyMethod_Class"
+ "PyClass_IsSubclass"
+ "PyInstance_New"
+ "PyInstance_NewRaw"
+ "PyMethod_New"
+ "PyMethod_Fini"
+ "PyClass_Type"
+ "PyMethod_Type"
+ "PyInstance_Type"
+
+; From python23_s.lib(cobject)
+ "PyCObject_FromVoidPtr"
+ "PyCObject_FromVoidPtrAndDesc"
+ "PyCObject_AsVoidPtr"
+ "PyCObject_GetDesc"
+ "PyCObject_Import"
+ "PyCObject_Type"
+
+; From python23_s.lib(complexobject)
+ "_Py_c_sum"
+ "_Py_c_diff"
+ "_Py_c_neg"
+ "_Py_c_prod"
+ "_Py_c_quot"
+ "_Py_c_pow"
+ "PyComplex_FromCComplex"
+ "PyComplex_FromDoubles"
+ "PyComplex_RealAsDouble"
+ "PyComplex_ImagAsDouble"
+ "PyComplex_AsCComplex"
+ "PyComplex_Type"
+
+; From python23_s.lib(descrobject)
+ "PyWrapper_New"
+ "PyDescr_NewMethod"
+ "PyDescr_NewMember"
+ "PyDescr_NewGetSet"
+ "PyDescr_NewWrapper"
+ "PyDescr_IsData"
+ "PyDictProxy_New"
+ "PyWrapperDescr_Type"
+ "PyProperty_Type"
+
+; From python23_s.lib(dictobject)
+ "PyDict_New"
+ "PyDict_GetItem"
+ "PyDict_SetItem"
+ "PyDict_DelItem"
+ "PyDict_Clear"
+ "PyDict_Next"
+ "PyDict_Update"
+ "PyDict_MergeFromSeq2"
+ "PyDict_Merge"
+ "PyDict_Copy"
+ "PyDict_Size"
+ "PyDict_Keys"
+ "PyDict_Values"
+ "PyDict_Items"
+ "PyDict_GetItemString"
+ "PyDict_SetItemString"
+ "PyDict_DelItemString"
+ "PyDict_Type"
+ "PyDictIter_Type"
+
+; From python23_s.lib(fileobject)
+ "PyFile_AsFile"
+ "PyFile_Name"
+ "PyFile_FromFile"
+ "PyFile_FromString"
+ "PyFile_SetBufSize"
+ "PyFile_GetLine"
+ "PyFile_SoftSpace"
+ "PyFile_WriteObject"
+ "PyFile_WriteString"
+ "PyObject_AsFileDescriptor"
+ "PyFile_Type"
+
+; From python23_s.lib(floatobject)
+ "PyFloat_FromDouble"
+ "PyFloat_FromString"
+ "PyFloat_AsDouble"
+ "PyFloat_AsStringEx"
+ "PyFloat_AsString"
+ "PyFloat_AsReprString"
+ "PyFloat_Fini"
+ "PyFloat_Type"
+
+; From python23_s.lib(frameobject)
+ "PyFrame_FastToLocals"
+ "PyFrame_New"
+ "PyFrame_BlockSetup"
+ "PyFrame_BlockPop"
+ "PyFrame_LocalsToFast"
+ "PyFrame_Fini"
+ "PyFrame_Type"
+
+; From python23_s.lib(funcobject)
+ "PyFunction_New"
+ "PyFunction_GetCode"
+ "PyFunction_GetGlobals"
+ "PyFunction_GetDefaults"
+ "PyFunction_SetDefaults"
+ "PyFunction_GetClosure"
+ "PyFunction_SetClosure"
+ "PyClassMethod_New"
+ "PyStaticMethod_New"
+ "PyFunction_Type"
+ "PyClassMethod_Type"
+ "PyStaticMethod_Type"
+
+; From python23_s.lib(intobject)
+ "PyInt_GetMax"
+ "PyInt_FromLong"
+ "PyInt_AsLong"
+ "PyInt_FromString"
+ "PyInt_FromUnicode"
+ "PyInt_Fini"
+ "_Py_ZeroStruct"
+ "PyInt_Type"
+ "_Py_TrueStruct"
+
+; From python23_s.lib(iterobject)
+ "PySeqIter_New"
+ "PyCallIter_New"
+ "PySeqIter_Type"
+ "PyCallIter_Type"
+
+; From python23_s.lib(listobject)
+ "PyList_New"
+ "PyList_Size"
+ "PyList_GetItem"
+ "PyList_SetItem"
+ "PyList_Insert"
+ "PyList_Append"
+ "PyList_GetSlice"
+ "PyList_SetSlice"
+ "PyList_Sort"
+ "PyList_Reverse"
+ "PyList_AsTuple"
+ "PyList_Type"
+
+; From python23_s.lib(longobject)
+ "_PyLong_New"
+ "_PyLong_Copy"
+ "PyLong_FromLong"
+ "PyLong_FromUnsignedLong"
+ "PyLong_FromDouble"
+ "PyLong_AsLong"
+ "PyLong_AsUnsignedLong"
+ "_PyLong_FromByteArray"
+ "_PyLong_AsByteArray"
+ "_PyLong_AsScaledDouble"
+ "PyLong_AsDouble"
+ "PyLong_FromVoidPtr"
+ "PyLong_AsVoidPtr"
+ "PyLong_FromLongLong"
+ "PyLong_FromUnsignedLongLong"
+ "PyLong_AsLongLong"
+ "PyLong_AsUnsignedLongLong"
+ "PyLong_FromString"
+ "PyLong_FromUnicode"
+ "PyLong_Type"
+
+; From python23_s.lib(methodobject)
+ "PyCFunction_New"
+ "PyCFunction_GetFunction"
+ "PyCFunction_GetSelf"
+ "PyCFunction_GetFlags"
+ "PyCFunction_Call"
+ "Py_FindMethodInChain"
+ "Py_FindMethod"
+ "PyCFunction_Fini"
+ "PyCFunction_Type"
+
+; From python23_s.lib(moduleobject)
+ "PyModule_New"
+ "PyModule_GetDict"
+ "PyModule_GetName"
+ "PyModule_GetFilename"
+ "_PyModule_Clear"
+ "PyModule_Type"
+
+; From python23_s.lib(object)
+ "Py_DivisionWarningFlag"
+ "PyObject_Init"
+ "PyObject_InitVar"
+ "_PyObject_New"
+ "_PyObject_NewVar"
+ "_PyObject_Del"
+ "PyObject_Print"
+ "PyObject_Str"
+ "PyObject_Repr"
+ "_PyObject_Dump"
+ "PyObject_Unicode"
+ "PyObject_GetAttr"
+ "PyObject_IsTrue"
+ "PyNumber_CoerceEx"
+ "PyObject_Compare"
+ "PyObject_RichCompare"
+ "PyObject_RichCompareBool"
+ "_Py_HashDouble"
+ "PyObject_Hash"
+ "_Py_HashPointer"
+ "PyObject_GetAttrString"
+ "PyObject_HasAttrString"
+ "PyObject_SetAttrString"
+ "PyObject_SetAttr"
+ "PyObject_HasAttr"
+ "_PyObject_GetDictPtr"
+ "PyObject_GenericGetAttr"
+ "PyObject_GenericSetAttr"
+ "PyObject_Not"
+ "PyNumber_Coerce"
+ "PyCallable_Check"
+ "PyObject_Dir"
+ "_Py_ReadyTypes"
+ "PyMem_Malloc"
+ "PyMem_Realloc"
+ "PyMem_Free"
+ "PyObject_Malloc"
+ "PyObject_Realloc"
+ "PyObject_Free"
+ "Py_ReprEnter"
+ "Py_ReprLeave"
+ "_PyTrash_deposit_object"
+ "_PyTrash_destroy_chain"
+ "_Py_NotImplementedStruct"
+ "_Py_NoneStruct"
+ "_Py_cobject_hack"
+ "_Py_abstract_hack"
+ "_PyTrash_delete_nesting"
+ "_PyTrash_delete_later"
+
+; From python23_s.lib(rangeobject)
+ "PyRange_New"
+ "PyRange_Type"
+
+; From python23_s.lib(sliceobject)
+ "PySlice_New"
+ "PySlice_GetIndices"
+ "_Py_EllipsisObject"
+ "PySlice_Type"
+
+; From python23_s.lib(stringobject)
+ "PyString_FromStringAndSize"
+ "PyString_InternInPlace"
+ "PyString_FromString"
+ "PyString_FromFormatV"
+ "PyString_AsString"
+ "_PyString_Resize"
+ "PyString_FromFormat"
+ "PyString_Decode"
+ "PyString_AsDecodedString"
+ "PyString_AsDecodedObject"
+ "PyString_Encode"
+ "PyString_AsEncodedString"
+ "PyString_AsEncodedObject"
+ "PyString_AsStringAndSize"
+ "PyString_Size"
+ "_PyString_Eq"
+ "_PyString_Join"
+ "PyString_Concat"
+ "PyString_ConcatAndDel"
+ "_PyString_FormatLong"
+ "PyString_Format"
+ "PyString_InternFromString"
+ "PyString_Fini"
+ "_Py_ReleaseInternedStrings"
+ "PyString_Type"
+
+; From python23_s.lib(structseq)
+ "PyStructSequence_New"
+ "PyStructSequence_InitType"
+
+; From python23_s.lib(tupleobject)
+ "PyTuple_New"
+ "PyTuple_Size"
+ "PyTuple_GetItem"
+ "PyTuple_SetItem"
+ "PyTuple_GetSlice"
+ "_PyTuple_Resize"
+ "PyTuple_Fini"
+ "PyTuple_Type"
+
+; From python23_s.lib(typeobject)
+ "PyType_IsSubtype"
+ "PyType_GenericAlloc"
+ "PyType_GenericNew"
+ "_PyType_Lookup"
+ "PyType_Ready"
+ "_PyObject_SlotCompare"
+ "PyType_Type"
+ "PyBaseObject_Type"
+ "PySuper_Type"
+
+; From python23_s.lib(unicodeobject)
+ "PyUnicodeUCS2_GetMax"
+ "PyUnicodeUCS2_Resize"
+ "PyUnicodeUCS2_FromUnicode"
+ "PyUnicodeUCS2_FromObject"
+ "PyUnicodeUCS2_FromEncodedObject"
+ "PyUnicodeUCS2_Decode"
+ "PyUnicodeUCS2_GetDefaultEncoding"
+ "PyUnicodeUCS2_DecodeUTF8"
+ "PyUnicodeUCS2_DecodeLatin1"
+ "PyUnicodeUCS2_DecodeASCII"
+ "PyUnicodeUCS2_Encode"
+ "PyUnicodeUCS2_AsEncodedString"
+ "PyUnicodeUCS2_AsUTF8String"
+ "PyUnicodeUCS2_AsLatin1String"
+ "PyUnicodeUCS2_AsASCIIString"
+ "_PyUnicodeUCS2_AsDefaultEncodedString"
+ "PyUnicodeUCS2_AsUnicode"
+ "PyUnicodeUCS2_GetSize"
+ "PyUnicodeUCS2_SetDefaultEncoding"
+ "PyUnicode_DecodeUTF7"
+ "PyUnicode_EncodeUTF7"
+ "PyUnicodeUCS2_EncodeUTF8"
+ "PyUnicodeUCS2_DecodeUTF16"
+ "PyUnicodeUCS2_EncodeUTF16"
+ "PyUnicodeUCS2_AsUTF16String"
+ "PyUnicodeUCS2_DecodeUnicodeEscape"
+ "PyUnicodeUCS2_EncodeUnicodeEscape"
+ "PyUnicodeUCS2_AsUnicodeEscapeString"
+ "PyUnicodeUCS2_DecodeRawUnicodeEscape"
+ "PyUnicodeUCS2_EncodeRawUnicodeEscape"
+ "PyUnicodeUCS2_AsRawUnicodeEscapeString"
+ "PyUnicodeUCS2_EncodeLatin1"
+ "PyUnicodeUCS2_EncodeASCII"
+ "PyUnicodeUCS2_DecodeCharmap"
+ "PyUnicodeUCS2_EncodeCharmap"
+ "PyUnicodeUCS2_AsCharmapString"
+ "PyUnicodeUCS2_TranslateCharmap"
+ "PyUnicodeUCS2_Translate"
+ "PyUnicodeUCS2_EncodeDecimal"
+ "PyUnicodeUCS2_Count"
+ "PyUnicodeUCS2_Find"
+ "PyUnicodeUCS2_Tailmatch"
+ "PyUnicodeUCS2_Join"
+ "PyUnicodeUCS2_Splitlines"
+ "PyUnicodeUCS2_Compare"
+ "PyUnicodeUCS2_Contains"
+ "PyUnicodeUCS2_Concat"
+ "PyUnicodeUCS2_Replace"
+ "PyUnicodeUCS2_Split"
+ "PyUnicodeUCS2_Format"
+ "_PyUnicodeUCS2_Init"
+ "_PyUnicodeUCS2_Fini"
+ "PyUnicode_Type"
+
+; From python23_s.lib(unicodectype)
+ "_PyUnicode_TypeRecords"
+ "_PyUnicodeUCS2_IsLinebreak"
+ "_PyUnicodeUCS2_ToTitlecase"
+ "_PyUnicodeUCS2_IsTitlecase"
+ "_PyUnicodeUCS2_ToDecimalDigit"
+ "_PyUnicodeUCS2_IsDecimalDigit"
+ "_PyUnicodeUCS2_ToDigit"
+ "_PyUnicodeUCS2_IsDigit"
+ "_PyUnicodeUCS2_ToNumeric"
+ "_PyUnicodeUCS2_IsNumeric"
+ "_PyUnicodeUCS2_IsWhitespace"
+ "_PyUnicodeUCS2_IsLowercase"
+ "_PyUnicodeUCS2_IsUppercase"
+ "_PyUnicodeUCS2_ToUppercase"
+ "_PyUnicodeUCS2_ToLowercase"
+ "_PyUnicodeUCS2_IsAlpha"
+
+; From python23_s.lib(weakrefobject)
+ "_PyWeakref_GetWeakrefCount"
+ "PyWeakref_NewRef"
+ "PyWeakref_NewProxy"
+ "PyWeakref_GetObject"
+ "PyObject_ClearWeakRefs"
+ "_PyWeakref_RefType"
+ "_PyWeakref_ProxyType"
+ "_PyWeakref_CallableProxyType"
+
+; From python23_s.lib(bltinmodule)
+ "_PyBuiltin_Init"
+ "Py_FileSystemDefaultEncoding"
+
+; From python23_s.lib(exceptions)
+ "PyExc_TypeError"
+ "PyExc_Exception"
+ "PyExc_StopIteration"
+ "PyExc_StandardError"
+ "PyExc_SystemExit"
+ "PyExc_KeyboardInterrupt"
+ "PyExc_ImportError"
+ "PyExc_EnvironmentError"
+ "PyExc_IOError"
+ "PyExc_OSError"
+ "PyExc_EOFError"
+ "PyExc_RuntimeError"
+ "PyExc_NotImplementedError"
+ "PyExc_NameError"
+ "PyExc_UnboundLocalError"
+ "PyExc_AttributeError"
+ "PyExc_SyntaxError"
+ "PyExc_IndentationError"
+ "PyExc_TabError"
+ "PyExc_AssertionError"
+ "PyExc_LookupError"
+ "PyExc_IndexError"
+ "PyExc_KeyError"
+ "PyExc_ArithmeticError"
+ "PyExc_OverflowError"
+ "PyExc_ZeroDivisionError"
+ "PyExc_FloatingPointError"
+ "PyExc_ValueError"
+ "PyExc_UnicodeError"
+ "PyExc_ReferenceError"
+ "PyExc_SystemError"
+ "PyExc_MemoryError"
+ "PyExc_Warning"
+ "PyExc_UserWarning"
+ "PyExc_DeprecationWarning"
+ "PyExc_SyntaxWarning"
+ "PyExc_OverflowWarning"
+ "PyExc_RuntimeWarning"
+ "PyExc_MemoryErrorInst"
+ "_PyExc_Init"
+ "_PyExc_Fini"
+
+; From python23_s.lib(ceval)
+ "PyEval_InitThreads"
+ "PyEval_AcquireLock"
+ "PyEval_ReleaseLock"
+ "PyEval_AcquireThread"
+ "PyEval_ReleaseThread"
+ "PyEval_ReInitThreads"
+ "PyEval_SaveThread"
+ "PyEval_RestoreThread"
+ "Py_AddPendingCall"
+ "Py_MakePendingCalls"
+ "Py_GetRecursionLimit"
+ "Py_SetRecursionLimit"
+ "PyEval_EvalCode"
+ "PyEval_EvalCodeEx"
+ "PyEval_CallObjectWithKeywords"
+ "PyEval_SetProfile"
+ "PyEval_SetTrace"
+ "PyEval_GetBuiltins"
+ "PyEval_GetLocals"
+ "PyEval_GetGlobals"
+ "PyEval_GetFrame"
+ "PyEval_GetRestricted"
+ "PyEval_MergeCompilerFlags"
+ "Py_FlushLine"
+ "PyEval_CallObject"
+ "PyEval_GetFuncName"
+ "PyEval_GetFuncDesc"
+ "_PyEval_SliceIndex"
+
+; From python23_s.lib(compile)
+ "PyCode_New"
+ "PyNode_Compile"
+ "PyNode_CompileFlags"
+ "PyNode_CompileSymtable"
+ "PySymtable_Free"
+ "PyCode_Addr2Line"
+ "Py_OptimizeFlag"
+ "PyCode_Type"
+
+; From python23_s.lib(codecs)
+ "PyCodec_Register"
+ "_PyCodec_Lookup"
+ "PyCodec_Encoder"
+ "PyCodec_Decoder"
+ "PyCodec_StreamReader"
+ "PyCodec_StreamWriter"
+ "PyCodec_Encode"
+ "PyCodec_Decode"
+ "_PyCodecRegistry_Init"
+ "_PyCodecRegistry_Fini"
+
+; From python23_s.lib(errors)
+ "PyErr_Restore"
+ "PyErr_SetObject"
+ "PyErr_SetNone"
+ "PyErr_SetString"
+ "PyErr_Occurred"
+ "PyErr_GivenExceptionMatches"
+ "PyErr_ExceptionMatches"
+ "PyErr_NormalizeException"
+ "PyErr_Fetch"
+ "PyErr_Clear"
+ "PyErr_BadArgument"
+ "PyErr_NoMemory"
+ "PyErr_SetFromErrnoWithFilename"
+ "PyErr_SetFromErrno"
+ "_PyErr_BadInternalCall"
+ "PyErr_Format"
+ "PyErr_BadInternalCall"
+ "PyErr_NewException"
+ "PyErr_WriteUnraisable"
+ "PyErr_Warn"
+ "PyErr_WarnExplicit"
+ "PyErr_SyntaxLocation"
+ "PyErr_ProgramText"
+
+; From python23_s.lib(frozen)
+ "PyImport_FrozenModules"
+
+; From python23_s.lib(frozenmain)
+ "Py_FrozenMain"
+
+; From python23_s.lib(future)
+ "PyNode_Future"
+
+; From python23_s.lib(getargs)
+ "PyArg_Parse"
+ "PyArg_ParseTuple"
+ "PyArg_VaParse"
+ "PyArg_ParseTupleAndKeywords"
+ "PyArg_UnpackTuple"
+
+; From python23_s.lib(getcompiler)
+ "Py_GetCompiler"
+
+; From python23_s.lib(getcopyright)
+ "Py_GetCopyright"
+
+; From python23_s.lib(getmtime)
+ "PyOS_GetLastModificationTime"
+
+; From python23_s.lib(getplatform)
+ "Py_GetPlatform"
+
+; From python23_s.lib(getversion)
+ "Py_GetVersion"
+
+; From python23_s.lib(graminit)
+ "_PyParser_Grammar"
+
+; From python23_s.lib(import)
+ "_PyImport_Init"
+ "_PyImport_Fini"
+ "PyImport_GetModuleDict"
+ "PyImport_Cleanup"
+ "PyImport_GetMagicNumber"
+ "_PyImport_FixupExtension"
+ "_PyImport_FindExtension"
+ "PyImport_AddModule"
+ "PyImport_ExecCodeModule"
+ "PyImport_ExecCodeModuleEx"
+ "PyImport_ImportFrozenModule"
+ "PyImport_ImportModule"
+ "PyImport_Import"
+ "PyImport_ImportModuleEx"
+ "PyImport_ReloadModule"
+; "initimp"
+ "PyImport_ExtendInittab"
+ "PyImport_AppendInittab"
+ "PyImport_Inittab"
+ "_PyImport_Filetab"
+
+; From python23_s.lib(importdl)
+ "_PyImport_LoadDynamicModule"
+
+; From python23_s.lib(marshal)
+ "PyMarshal_WriteLongToFile"
+ "PyMarshal_WriteObjectToFile"
+ "PyMarshal_ReadShortFromFile"
+ "PyMarshal_ReadLongFromFile"
+ "PyMarshal_ReadLastObjectFromFile"
+ "PyMarshal_ReadObjectFromString"
+ "PyMarshal_ReadObjectFromFile"
+ "PyMarshal_WriteObjectToString"
+ "PyMarshal_Init"
+
+; From python23_s.lib(modsupport)
+ "Py_InitModule4"
+ "Py_BuildValue"
+ "Py_VaBuildValue"
+ "PyEval_CallFunction"
+ "PyEval_CallMethod"
+ "PyModule_AddObject"
+ "PyModule_AddIntConstant"
+ "PyModule_AddStringConstant"
+ "_Py_PackageContext"
+
+; From python23_s.lib(mysnprintf)
+ "PyOS_snprintf"
+ "PyOS_vsnprintf"
+
+; From python23_s.lib(mystrtoul)
+ "PyOS_strtoul"
+ "PyOS_strtol"
+
+; From python23_s.lib(pyfpe)
+ "PyFPE_dummy"
+
+; From python23_s.lib(pystate)
+ "PyInterpreterState_New"
+ "PyInterpreterState_Clear"
+ "PyThreadState_Clear"
+ "PyThreadState_Delete"
+ "PyInterpreterState_Delete"
+ "PyThreadState_New"
+ "PyThreadState_DeleteCurrent"
+ "PyThreadState_Get"
+ "PyThreadState_Swap"
+ "PyThreadState_GetDict"
+ "PyInterpreterState_Head"
+ "PyInterpreterState_Next"
+ "PyInterpreterState_ThreadHead"
+ "PyThreadState_Next"
+ "_PyThreadState_Current"
+
+; From python23_s.lib(pythonrun)
+ "Py_IgnoreEnvironmentFlag"
+ "Py_DebugFlag"
+ "Py_VerboseFlag"
+ "Py_NoSiteFlag"
+ "Py_InteractiveFlag"
+ "Py_FrozenFlag"
+ "Py_IsInitialized"
+ "Py_Initialize"
+ "Py_FatalError"
+ "Py_Finalize"
+ "Py_NewInterpreter"
+ "PyErr_Print"
+ "Py_EndInterpreter"
+ "Py_SetProgramName"
+ "Py_GetProgramName"
+ "Py_SetPythonHome"
+ "Py_GetPythonHome"
+ "PyRun_AnyFile"
+ "PyRun_AnyFileExFlags"
+ "PyRun_AnyFileFlags"
+ "PyRun_AnyFileEx"
+ "Py_FdIsInteractive"
+ "PyRun_InteractiveLoopFlags"
+ "PyRun_SimpleFileExFlags"
+ "PyRun_InteractiveLoop"
+ "PyRun_InteractiveOneFlags"
+ "PyRun_InteractiveOne"
+ "PyRun_SimpleFile"
+ "PyRun_SimpleFileEx"
+ "PyRun_FileExFlags"
+ "PyRun_SimpleString"
+ "PyRun_SimpleStringFlags"
+ "PyRun_StringFlags"
+ "PyErr_PrintEx"
+ "Py_Exit"
+ "PyErr_Display"
+ "PyRun_String"
+ "PyParser_SimpleParseString"
+ "PyRun_File"
+ "PyRun_FileEx"
+ "PyParser_SimpleParseFile"
+ "PyParser_SimpleParseStringFlags"
+ "PyRun_FileFlags"
+ "PyParser_SimpleParseFileFlags"
+ "Py_CompileString"
+ "Py_CompileStringFlags"
+ "Py_SymtableString"
+ "Py_AtExit"
+ "PyOS_getsig"
+ "PyOS_setsig"
+ "Py_UseClassExceptionsFlag"
+ "Py_UnicodeFlag"
+ "_Py_QnewFlag"
+ "_PyThread_Started"
+
+; From python23_s.lib(structmember)
+ "PyMember_Get"
+ "PyMember_GetOne"
+ "PyMember_Set"
+ "PyMember_SetOne"
+
+; From python23_s.lib(symtable)
+ "PySymtableEntry_New"
+ "PySymtableEntry_Type"
+
+; From python23_s.lib(sysmodule)
+ "PySys_GetObject"
+ "PySys_GetFile"
+ "PySys_SetObject"
+ "PySys_ResetWarnOptions"
+ "PySys_AddWarnOption"
+ "_PySys_Init"
+ "PySys_SetPath"
+ "PySys_SetArgv"
+ "PySys_WriteStdout"
+ "PySys_WriteStderr"
+
+; From python23_s.lib(traceback)
+ "PyTraceBack_Here"
+ "PyTraceBack_Print"
+ "PyTraceBack_Type"
+
+; From python23_s.lib(getopt)
+ "_PyOS_GetOpt"
+ "_PyOS_opterr"
+ "_PyOS_optind"
+ "_PyOS_optarg"
+
+; From python23_s.lib(dynload_shlib)
+ "_PyImport_DynLoadFiletab"
+ "_PyImport_GetDynLoadFunc"
+
+; From python23_s.lib(thread)
+ "PyThread_init_thread"
+ "PyThread_start_new_thread"
+ "PyThread_get_thread_ident"
+ "PyThread_exit_thread"
+ "PyThread__exit_thread"
+ "PyThread_allocate_lock"
+ "PyThread_free_lock"
+ "PyThread_acquire_lock"
+ "PyThread_release_lock"
+
+; From python23_s.lib(gcmodule)
+; "initgc"
+ "_PyGC_Dump"
+ "_PyObject_GC_Track"
+ "_PyObject_GC_UnTrack"
+ "_PyObject_GC_Malloc"
+ "_PyObject_GC_New"
+ "_PyObject_GC_NewVar"
+ "_PyObject_GC_Resize"
+ "_PyObject_GC_Del"
+ "_PyGC_generation0"
+
+; From python23_s.lib(signalmodule)
+ "PyErr_CheckSignals"
+; "initsignal"
+ "PyErr_SetInterrupt"
+ "PyOS_InitInterrupts"
+ "PyOS_FiniInterrupts"
+ "PyOS_InterruptOccurred"
+ "PyOS_AfterFork"
+
+; From python23_s.lib(posixmodule)
+; "initos2"
+
+; From python23_s.lib(threadmodule)
+; "initthread"
+
+; From python23_s.lib(_sre)
+; "init_sre"
diff --git a/PC/os2emx/pythonpm.c b/PC/os2emx/pythonpm.c
new file mode 100644
index 0000000000..5accbbd613
--- /dev/null
+++ b/PC/os2emx/pythonpm.c
@@ -0,0 +1,124 @@
+/* OS/2 PM main program - creates a hidden window, and starts Python
+ * interpreter in a separate thread, so that Python scripts can be
+ * run in PM process space without a console Window. The interpreter
+ * is incorporated by linking in the Python DLL.
+ *
+ * As it stands, I don't think this is adequate for supporting Python
+ * GUI modules, as the Python thread doesn't have its own message
+ * queue - which is required of threads that want to create/use
+ * PM windows.
+ *
+ * This code owes a lot to "OS/2 Presentation Manager Programming", by
+ * Charles Petzold.
+ *
+ * Andrew MacIntyre <andymac@bullseye.apana.org.au>, August 2001.
+ * Released under the terms of the Python 2.1.1 licence - see the LICENCE
+ * file in the Python v2.1.1 (or later) source distribution.
+ * Copyright assigned to the Python Software Foundation, 2001.
+ */
+
+#define INCL_DOS
+#define INCL_WIN
+#include <os2.h>
+#include <process.h>
+
+#include "Python.h"
+
+/* use structure to pass command line to Python thread */
+typedef struct
+{
+ int argc;
+ char **argv;
+ HWND Frame;
+ int running;
+} arglist;
+
+/* make this a global to simplify access.
+ * it should only be set from the Python thread, or by the code that
+ * initiates the Python thread when the thread cannot be created.
+ */
+int PythonRC;
+
+extern DL_EXPORT(int) Py_Main(int, char **);
+void PythonThread(void *);
+
+int
+main(int argc, char **argv)
+{
+ ULONG FrameFlags = FCF_TITLEBAR |
+ FCF_SYSMENU |
+ FCF_SIZEBORDER |
+ FCF_HIDEBUTTON |
+ FCF_SHELLPOSITION |
+ FCF_TASKLIST;
+ HAB hab;
+ HMQ hmq;
+ HWND Client;
+ QMSG qmsg;
+ arglist args;
+ int python_tid;
+
+ /* init PM and create message queue */
+ hab = WinInitialize(0);
+ hmq = WinCreateMsgQueue(hab, 0);
+
+ /* create a (hidden) Window to house the window procedure */
+ args.Frame = WinCreateStdWindow(HWND_DESKTOP,
+ 0,
+ &FrameFlags,
+ NULL,
+ "PythonPM",
+ 0L,
+ 0,
+ 0,
+ &Client);
+
+ /* run Python interpreter in a thread */
+ args.argc = argc;
+ args.argv = argv;
+ args.running = 0;
+ if (-1 == (python_tid = _beginthread(PythonThread, NULL, 1024 * 1024, &args)))
+ {
+ /* couldn't start thread */
+ WinAlarm(HWND_DESKTOP, WA_ERROR);
+ PythonRC = 1;
+ }
+ else
+ {
+ /* process PM messages, until Python exits */
+ while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0))
+ WinDispatchMsg(hab, &qmsg);
+ if (args.running > 0)
+ DosKillThread(python_tid);
+ }
+
+ /* destroy window, shutdown message queue and PM */
+ WinDestroyWindow(args.Frame);
+ WinDestroyMsgQueue(hmq);
+ WinTerminate(hab);
+
+ return PythonRC;
+}
+
+void PythonThread(void *argl)
+{
+ HAB hab;
+ arglist *args;
+
+ /* PM initialisation */
+ hab = WinInitialize(0);
+
+ /* start Python */
+ args = (arglist *)argl;
+ args->running = 1;
+ PythonRC = Py_Main(args->argc, args->argv);
+
+ /* enter a critical section and send the termination message */
+ DosEnterCritSec();
+ args->running = 0;
+ WinPostMsg(args->Frame, WM_QUIT, NULL, NULL);
+
+ /* shutdown PM and terminate thread */
+ WinTerminate(hab);
+ _endthread();
+}