summaryrefslogtreecommitdiff
path: root/compiler/utils
diff options
context:
space:
mode:
authorpeter <peter@3ad0048d-3df7-0310-abae-a5850022a9f2>2005-10-20 19:20:38 +0000
committerpeter <peter@3ad0048d-3df7-0310-abae-a5850022a9f2>2005-10-20 19:20:38 +0000
commit5ed980d600661e3e77f429a510f093f4a001dee9 (patch)
tree40d655e7921c1019d039da654a9df550de3cd249 /compiler/utils
parent907c764cb881dab769452696fc5e6bee076c2656 (diff)
downloadfpc-unitrw.tar.gz
* retag for unitrwunitrw
git-svn-id: http://svn.freepascal.org/svn/fpc/branches/unitrw@1551 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/utils')
-rw-r--r--compiler/utils/Makefile2021
-rw-r--r--compiler/utils/Makefile.fpc52
-rw-r--r--compiler/utils/README20
-rw-r--r--compiler/utils/fixlog.pp174
-rw-r--r--compiler/utils/fixmsg.pp66
-rw-r--r--compiler/utils/fixnasm.pp99
-rw-r--r--compiler/utils/fixtab.pp367
-rw-r--r--compiler/utils/fpc.cft204
-rw-r--r--compiler/utils/fpc.mpw2
-rw-r--r--compiler/utils/fpc.pp205
-rw-r--r--compiler/utils/fpccfg.inc224
-rw-r--r--compiler/utils/fpcmkcfg.pp230
-rw-r--r--compiler/utils/fpcsubst.pp241
-rw-r--r--compiler/utils/fpimpdef.pp98
-rw-r--r--compiler/utils/fppkg.pp963
-rw-r--r--compiler/utils/gppc386.pp138
-rw-r--r--compiler/utils/mk68kreg.pp334
-rw-r--r--compiler/utils/mkarmins.pp432
-rw-r--r--compiler/utils/mkarmreg.pp298
-rw-r--r--compiler/utils/mkmpsreg.pp349
-rw-r--r--compiler/utils/mkppcreg.pp396
-rw-r--r--compiler/utils/mkspreg.pp301
-rw-r--r--compiler/utils/mkx86ins.pp454
-rw-r--r--compiler/utils/mkx86reg.pp467
-rw-r--r--compiler/utils/msg2inc.pp815
-rw-r--r--compiler/utils/msgdif.pp529
-rw-r--r--compiler/utils/msgused.pl42
-rw-r--r--compiler/utils/ppudump.pp2191
-rw-r--r--compiler/utils/ppufiles.pp252
-rw-r--r--compiler/utils/ppumove.pp613
-rw-r--r--compiler/utils/samplecfg267
-rw-r--r--compiler/utils/usubst.pp109
32 files changed, 12953 insertions, 0 deletions
diff --git a/compiler/utils/Makefile b/compiler/utils/Makefile
new file mode 100644
index 0000000000..0d14063a26
--- /dev/null
+++ b/compiler/utils/Makefile
@@ -0,0 +1,2021 @@
+#
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2005/10/20]
+#
+default: all
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-emx i386-watcom i386-netwlibc i386-wince m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos powerpc-linux powerpc-netbsd powerpc-macos powerpc-darwin powerpc-morphos sparc-linux sparc-netbsd sparc-solaris x86_64-linux x86_64-freebsd x86_64-win64 arm-linux arm-wince powerpc64-linux
+BSDs = freebsd netbsd openbsd darwin
+UNIXs = linux $(BSDs) solaris qnx
+LIMIT83fs = go32v2 os2 emx watcom
+FORCE:
+.PHONY: FORCE
+override PATH:=$(patsubst %/,%,$(subst \,/,$(PATH)))
+ifneq ($(findstring darwin,$(OSTYPE)),)
+inUnix=1 #darwin
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+ifeq ($(findstring ;,$(PATH)),)
+inUnix=1
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+SEARCHPATH:=$(subst ;, ,$(PATH))
+endif
+endif
+SEARCHPATH+=$(patsubst %/,%,$(subst \,/,$(dir $(MAKE))))
+PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
+ifeq ($(PWD),)
+PWD:=$(strip $(wildcard $(addsuffix /pwd,$(SEARCHPATH))))
+ifeq ($(PWD),)
+$(error You need the GNU utils package to use this Makefile)
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=
+endif
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=.exe
+endif
+ifndef inUnix
+ifeq ($(OS),Windows_NT)
+inWinNT=1
+else
+ifdef OS2_SHELL
+inOS2=1
+endif
+endif
+else
+ifneq ($(findstring cygdrive,$(PATH)),)
+inCygWin=1
+endif
+endif
+ifdef inUnix
+SRCBATCHEXT=.sh
+else
+ifdef inOS2
+SRCBATCHEXT=.cmd
+else
+SRCBATCHEXT=.bat
+endif
+endif
+ifdef inUnix
+PATHSEP=/
+else
+PATHSEP:=$(subst /,\,/)
+ifdef inCygWin
+PATHSEP=/
+endif
+endif
+ifdef PWD
+BASEDIR:=$(subst \,/,$(shell $(PWD)))
+ifdef inCygWin
+ifneq ($(findstring /cygdrive/,$(BASEDIR)),)
+BASENODIR:=$(patsubst /cygdrive%,%,$(BASEDIR))
+BASEDRIVE:=$(firstword $(subst /, ,$(BASENODIR)))
+BASEDIR:=$(subst /cygdrive/$(BASEDRIVE)/,$(BASEDRIVE):/,$(BASEDIR))
+endif
+endif
+else
+BASEDIR=.
+endif
+ifdef inOS2
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO=echo
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+endif
+override DEFAULT_FPCDIR=../..
+ifndef FPC
+ifdef PP
+FPC=$(PP)
+endif
+endif
+ifndef FPC
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+FPC:=$(shell $(FPCPROG) -PB)
+ifneq ($(findstring Error,$(FPC)),)
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+else
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+endif
+override FPC:=$(subst $(SRCEXEEXT),,$(FPC))
+override FPC:=$(subst \,/,$(FPC))$(SRCEXEEXT)
+FOUNDFPC:=$(strip $(wildcard $(FPC)))
+ifeq ($(FOUNDFPC),)
+FOUNDFPC=$(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))
+ifeq ($(FOUNDFPC),)
+$(error Compiler $(FPC) not found)
+endif
+endif
+ifndef FPC_COMPILERINFO
+FPC_COMPILERINFO:=$(shell $(FPC) -iVSPTPSOTO)
+endif
+ifndef FPC_VERSION
+FPC_VERSION:=$(word 1,$(FPC_COMPILERINFO))
+endif
+export FPC FPC_VERSION FPC_COMPILERINFO
+unexport CHECKDEPEND ALLDEPENDENCIES
+ifndef CPU_TARGET
+ifdef CPU_TARGET_DEFAULT
+CPU_TARGET=$(CPU_TARGET_DEFAULT)
+endif
+endif
+ifndef OS_TARGET
+ifdef OS_TARGET_DEFAULT
+OS_TARGET=$(OS_TARGET_DEFAULT)
+endif
+endif
+ifneq ($(words $(FPC_COMPILERINFO)),5)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSO)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTO)
+endif
+ifndef CPU_SOURCE
+CPU_SOURCE:=$(word 2,$(FPC_COMPILERINFO))
+endif
+ifndef CPU_TARGET
+CPU_TARGET:=$(word 3,$(FPC_COMPILERINFO))
+endif
+ifndef OS_SOURCE
+OS_SOURCE:=$(word 4,$(FPC_COMPILERINFO))
+endif
+ifndef OS_TARGET
+OS_TARGET:=$(word 5,$(FPC_COMPILERINFO))
+endif
+FULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+FULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+SOURCESUFFIX=$(OS_SOURCE)
+else
+TARGETSUFFIX=$(FULL_TARGET)
+SOURCESUFFIX=$(FULL_SOURCE)
+endif
+ifneq ($(FULL_TARGET),$(FULL_SOURCE))
+CROSSCOMPILE=1
+endif
+ifeq ($(findstring makefile,$(MAKECMDGOALS)),)
+ifeq ($(findstring $(FULL_TARGET),$(MAKEFILETARGETS)),)
+$(error The Makefile doesn't support target $(FULL_TARGET), please run fpcmake first)
+endif
+endif
+ifneq ($(findstring $(OS_TARGET),$(BSDs)),)
+BSDhier=1
+endif
+ifeq ($(OS_TARGET),linux)
+linuxHier=1
+endif
+export OS_TARGET OS_SOURCE CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
+ifdef FPCDIR
+override FPCDIR:=$(subst \,/,$(FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+else
+override FPCDIR=wrong
+endif
+ifdef DEFAULT_FPCDIR
+ifeq ($(FPCDIR),wrong)
+override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+endif
+endif
+ifeq ($(FPCDIR),wrong)
+ifdef inUnix
+override FPCDIR=/usr/local/lib/fpc/$(FPC_VERSION)
+ifeq ($(wildcard $(FPCDIR)/units),)
+override FPCDIR=/usr/lib/fpc/$(FPC_VERSION)
+endif
+else
+override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(BASEDIR)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=c:/pp
+endif
+endif
+endif
+endif
+endif
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(FPCDIR)/bin/$(TARGETSUFFIX))
+endif
+ifndef BINUTILSPREFIX
+ifndef CROSSBINDIR
+ifdef CROSSCOMPILE
+BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+endif
+endif
+endif
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
+ifeq ($(UNITSDIR),)
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+endif
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_PROGRAMS+=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override CLEAN_UNITS+=ppu crc usubst
+endif
+override INSTALL_FPCPACKAGE=y
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_UNITDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_SOURCEDIR+=..
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_SOURCEDIR+=..
+endif
+ifdef REQUIRE_UNITSDIR
+override UNITSDIR+=$(REQUIRE_UNITSDIR)
+endif
+ifdef REQUIRE_PACKAGESDIR
+override PACKAGESDIR+=$(REQUIRE_PACKAGESDIR)
+endif
+ifdef ZIPINSTALL
+ifneq ($(findstring $(OS_TARGET),$(UNIXs)),)
+UNIXHier=1
+endif
+else
+ifneq ($(findstring $(OS_SOURCE),$(UNIXs)),)
+UNIXHier=1
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef PREFIX
+INSTALL_PREFIX=$(PREFIX)
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef UNIXHier
+INSTALL_PREFIX=/usr/local
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=/pp
+else
+INSTALL_BASEDIR:=/$(PACKAGE_NAME)
+endif
+endif
+endif
+export INSTALL_PREFIX
+ifdef INSTALL_FPCSUBDIR
+export INSTALL_FPCSUBDIR
+endif
+ifndef DIST_DESTDIR
+DIST_DESTDIR:=$(BASEDIR)
+endif
+export DIST_DESTDIR
+ifndef COMPILER_UNITTARGETDIR
+ifdef PACKAGEDIR_MAIN
+COMPILER_UNITTARGETDIR=$(PACKAGEDIR_MAIN)/units/$(TARGETSUFFIX)
+else
+COMPILER_UNITTARGETDIR=units/$(TARGETSUFFIX)
+endif
+endif
+ifndef COMPILER_TARGETDIR
+COMPILER_TARGETDIR=.
+endif
+ifndef INSTALL_BASEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/fpc/$(FPC_VERSION)
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/$(PACKAGE_NAME)
+endif
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)
+endif
+endif
+ifndef INSTALL_BINDIR
+ifdef UNIXHier
+INSTALL_BINDIR:=$(INSTALL_PREFIX)/bin
+else
+INSTALL_BINDIR:=$(INSTALL_BASEDIR)/bin
+ifdef INSTALL_FPCPACKAGE
+ifdef CROSSCOMPILE
+ifdef CROSSINSTALL
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(SOURCESUFFIX)
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+endif
+endif
+endif
+ifndef INSTALL_UNITDIR
+INSTALL_UNITDIR:=$(INSTALL_BASEDIR)/units/$(TARGETSUFFIX)
+ifdef INSTALL_FPCPACKAGE
+ifdef PACKAGE_NAME
+INSTALL_UNITDIR:=$(INSTALL_UNITDIR)/$(PACKAGE_NAME)
+endif
+endif
+endif
+ifndef INSTALL_LIBDIR
+ifdef UNIXHier
+INSTALL_LIBDIR:=$(INSTALL_PREFIX)/lib
+else
+INSTALL_LIBDIR:=$(INSTALL_UNITDIR)
+endif
+endif
+ifndef INSTALL_SOURCEDIR
+ifdef UNIXHier
+ifdef BSDhier
+SRCPREFIXDIR=share/src
+else
+ifdef linuxHier
+SRCPREFIXDIR=share/src
+else
+SRCPREFIXDIR=src
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source
+endif
+endif
+endif
+ifndef INSTALL_DOCDIR
+ifdef UNIXHier
+ifdef BSDhier
+DOCPREFIXDIR=share/doc
+else
+ifdef linuxHier
+DOCPREFIXDIR=share/doc
+else
+DOCPREFIXDIR=doc
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc
+endif
+endif
+endif
+ifndef INSTALL_EXAMPLEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/fpc-$(FPC_VERSION)/examples/$(PACKAGE_NAME)
+endif
+endif
+else
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+endif
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples/$(PACKAGE_NAME)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples
+endif
+endif
+endif
+ifndef INSTALL_DATADIR
+INSTALL_DATADIR=$(INSTALL_BASEDIR)
+endif
+ifdef CROSSCOMPILE
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(CROSSTARGETDIR)/bin/$(SOURCESUFFIX))
+ifeq ($(CROSSBINDIR),)
+CROSSBINDIR:=$(wildcard $(INSTALL_BASEDIR)/cross/$(TARGETSUFFIX)/bin/$(FULL_SOURCE))
+endif
+endif
+else
+CROSSBINDIR=
+endif
+BATCHEXT=.bat
+LOADEREXT=.as
+EXEEXT=.exe
+PPLEXT=.ppl
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.so
+STATICLIBPREFIX=libp
+RSTEXT=.rst
+ifeq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),go32v1)
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+OEXT=.obj
+ASMEXT=.asm
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),emx)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=emx
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),morphos)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=mos
+endif
+ifeq ($(OS_TARGET),atari)
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+ifeq ($(OS_TARGET),darwin)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=dwn
+endif
+else
+ifeq ($(OS_TARGET),go32v1)
+PPUEXT=.pp1
+OEXT=.o1
+ASMEXT=.s1
+SMARTEXT=.sl1
+STATICLIBEXT=.a1
+SHAREDLIBEXT=.so1
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+PPUEXT=.ppw
+OEXT=.ow
+ASMEXT=.sw
+SMARTEXT=.slw
+STATICLIBEXT=.aw
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+PPUEXT=.ppo
+ASMEXT=.so2
+OEXT=.oo2
+AOUTEXT=.out
+SMARTEXT=.sl2
+STATICLIBPREFIX=
+STATICLIBEXT=.ao2
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+PPUEXT=.ppu
+ASMEXT=.asm
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),atari)
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+FPCMADE=fpcmade.$(SHORTSUFFIX)
+ZIPSUFFIX=$(SHORTSUFFIX)
+ZIPCROSSPREFIX=
+ZIPSOURCESUFFIX=src
+ZIPEXAMPLESUFFIX=exm
+else
+FPCMADE=fpcmade.$(TARGETSUFFIX)
+ZIPSOURCESUFFIX=.source
+ZIPEXAMPLESUFFIX=.examples
+ifdef CROSSCOMPILE
+ZIPSUFFIX=.$(SOURCESUFFIX)
+ZIPCROSSPREFIX=$(TARGETSUFFIX)-
+else
+ZIPSUFFIX=.$(TARGETSUFFIX)
+ZIPCROSSPREFIX=
+endif
+endif
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO= __missing_command_ECHO
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+ifndef DATE
+DATE:=$(strip $(wildcard $(addsuffix /gdate$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE:=$(strip $(wildcard $(addsuffix /date$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE= __missing_command_DATE
+else
+DATE:=$(firstword $(DATE))
+endif
+else
+DATE:=$(firstword $(DATE))
+endif
+endif
+export DATE
+ifndef GINSTALL
+GINSTALL:=$(strip $(wildcard $(addsuffix /ginstall$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL:=$(strip $(wildcard $(addsuffix /install$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL= __missing_command_GINSTALL
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+endif
+export GINSTALL
+ifndef CPPROG
+CPPROG:=$(strip $(wildcard $(addsuffix /cp$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(CPPROG),)
+CPPROG= __missing_command_CPPROG
+else
+CPPROG:=$(firstword $(CPPROG))
+endif
+endif
+export CPPROG
+ifndef RMPROG
+RMPROG:=$(strip $(wildcard $(addsuffix /rm$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(RMPROG),)
+RMPROG= __missing_command_RMPROG
+else
+RMPROG:=$(firstword $(RMPROG))
+endif
+endif
+export RMPROG
+ifndef MVPROG
+MVPROG:=$(strip $(wildcard $(addsuffix /mv$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MVPROG),)
+MVPROG= __missing_command_MVPROG
+else
+MVPROG:=$(firstword $(MVPROG))
+endif
+endif
+export MVPROG
+ifndef MKDIRPROG
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /gmkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /mkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG= __missing_command_MKDIRPROG
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+endif
+export MKDIRPROG
+ifndef ECHOREDIR
+ifndef inUnix
+ECHOREDIR=echo
+else
+ECHOREDIR=$(ECHO)
+endif
+endif
+ifndef COPY
+COPY:=$(CPPROG) -fp
+endif
+ifndef COPYTREE
+COPYTREE:=$(CPPROG) -Rfp
+endif
+ifndef MKDIRTREE
+MKDIRTREE:=$(MKDIRPROG) -p
+endif
+ifndef MOVE
+MOVE:=$(MVPROG) -f
+endif
+ifndef DEL
+DEL:=$(RMPROG) -f
+endif
+ifndef DELTREE
+DELTREE:=$(RMPROG) -rf
+endif
+ifndef INSTALL
+ifdef inUnix
+INSTALL:=$(GINSTALL) -c -m 644
+else
+INSTALL:=$(COPY)
+endif
+endif
+ifndef INSTALLEXE
+ifdef inUnix
+INSTALLEXE:=$(GINSTALL) -c -m 755
+else
+INSTALLEXE:=$(COPY)
+endif
+endif
+ifndef MKDIR
+MKDIR:=$(GINSTALL) -m 755 -d
+endif
+export ECHOREDIR COPY COPYTREE MOVE DEL DELTREE INSTALL INSTALLEXE MKDIR
+ifndef PPUMOVE
+PPUMOVE:=$(strip $(wildcard $(addsuffix /ppumove$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(PPUMOVE),)
+PPUMOVE= __missing_command_PPUMOVE
+else
+PPUMOVE:=$(firstword $(PPUMOVE))
+endif
+endif
+export PPUMOVE
+ifndef FPCMAKE
+FPCMAKE:=$(strip $(wildcard $(addsuffix /fpcmake$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(FPCMAKE),)
+FPCMAKE= __missing_command_FPCMAKE
+else
+FPCMAKE:=$(firstword $(FPCMAKE))
+endif
+endif
+export FPCMAKE
+ifndef ZIPPROG
+ZIPPROG:=$(strip $(wildcard $(addsuffix /zip$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ZIPPROG),)
+ZIPPROG= __missing_command_ZIPPROG
+else
+ZIPPROG:=$(firstword $(ZIPPROG))
+endif
+endif
+export ZIPPROG
+ifndef TARPROG
+TARPROG:=$(strip $(wildcard $(addsuffix /tar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG= __missing_command_TARPROG
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+endif
+export TARPROG
+ASNAME=$(BINUTILSPREFIX)as
+LDNAME=$(BINUTILSPREFIX)ld
+ARNAME=$(BINUTILSPREFIX)ar
+RCNAME=$(BINUTILSPREFIX)rc
+ifneq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),win32)
+ifeq ($(CROSSBINDIR),)
+ASNAME=asw
+LDNAME=ldw
+ARNAME=arw
+endif
+endif
+endif
+ifndef ASPROG
+ifdef CROSSBINDIR
+ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
+else
+ASPROG=$(ASNAME)
+endif
+endif
+ifndef LDPROG
+ifdef CROSSBINDIR
+LDPROG=$(CROSSBINDIR)/$(LDNAME)$(SRCEXEEXT)
+else
+LDPROG=$(LDNAME)
+endif
+endif
+ifndef RCPROG
+ifdef CROSSBINDIR
+RCPROG=$(CROSSBINDIR)/$(RCNAME)$(SRCEXEEXT)
+else
+RCPROG=$(RCNAME)
+endif
+endif
+ifndef ARPROG
+ifdef CROSSBINDIR
+ARPROG=$(CROSSBINDIR)/$(ARNAME)$(SRCEXEEXT)
+else
+ARPROG=$(ARNAME)
+endif
+endif
+AS=$(ASPROG)
+LD=$(LDPROG)
+RC=$(RCPROG)
+AR=$(ARPROG)
+PPAS=ppas$(SRCBATCHEXT)
+ifdef inUnix
+LDCONFIG=ldconfig
+else
+LDCONFIG=
+endif
+ifdef DATE
+DATESTR:=$(shell $(DATE) +%Y%m%d)
+else
+DATESTR=
+endif
+ifndef UPXPROG
+ifeq ($(OS_TARGET),go32v2)
+UPXPROG:=1
+endif
+ifeq ($(OS_TARGET),win32)
+UPXPROG:=1
+endif
+ifdef UPXPROG
+UPXPROG:=$(strip $(wildcard $(addsuffix /upx$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(UPXPROG),)
+UPXPROG=
+else
+UPXPROG:=$(firstword $(UPXPROG))
+endif
+else
+UPXPROG=
+endif
+endif
+export UPXPROG
+ZIPOPT=-9
+ZIPEXT=.zip
+ifeq ($(USETAR),bz2)
+TAROPT=vj
+TAREXT=.tar.bz2
+else
+TAROPT=vz
+TAREXT=.tar.gz
+endif
+override REQUIRE_PACKAGES=rtl
+ifeq ($(FULL_TARGET),i386-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifdef REQUIRE_PACKAGES_RTL
+PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_RTL),)
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)),)
+UNITDIR_RTL=$(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)
+else
+UNITDIR_RTL=$(PACKAGEDIR_RTL)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_RTL)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_RTL) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_RTL)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_RTL=
+UNITDIR_RTL:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /rtl/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_RTL),)
+UNITDIR_RTL:=$(firstword $(UNITDIR_RTL))
+else
+UNITDIR_RTL=
+endif
+endif
+ifdef UNITDIR_RTL
+override COMPILER_UNITDIR+=$(UNITDIR_RTL)
+endif
+endif
+ifndef NOCPUDEF
+override FPCOPTDEF=$(CPU_TARGET)
+endif
+ifneq ($(OS_TARGET),$(OS_SOURCE))
+override FPCOPT+=-T$(OS_TARGET)
+endif
+ifeq ($(OS_SOURCE),openbsd)
+override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
+endif
+ifndef CROSSBOOTSTRAP
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-XP$(BINUTILSPREFIX) -Xc
+endif
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-Xr$(RLINKPATH)
+endif
+endif
+ifdef UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(UNITDIR))
+endif
+ifdef LIBDIR
+override FPCOPT+=$(addprefix -Fl,$(LIBDIR))
+endif
+ifdef OBJDIR
+override FPCOPT+=$(addprefix -Fo,$(OBJDIR))
+endif
+ifdef INCDIR
+override FPCOPT+=$(addprefix -Fi,$(INCDIR))
+endif
+ifdef LINKSMART
+override FPCOPT+=-XX
+endif
+ifdef CREATESMART
+override FPCOPT+=-CX
+endif
+ifdef DEBUG
+override FPCOPT+=-gl
+override FPCOPTDEF+=DEBUG
+endif
+ifdef RELEASE
+ifeq ($(CPU_TARGET),i386)
+FPCCPUOPT:=-OG2p3
+else
+ifeq ($(CPU_TARGET),powerpc)
+FPCCPUOPT:=-O1r
+else
+FPCCPUOPT:=
+endif
+endif
+override FPCOPT+=-Ur -Xs $(FPCCPUOPT) -n
+override FPCOPTDEF+=RELEASE
+endif
+ifdef STRIP
+override FPCOPT+=-Xs
+endif
+ifdef OPTIMIZE
+ifeq ($(CPU_TARGET),i386)
+override FPCOPT+=-OG2p3
+endif
+endif
+ifdef VERBOSE
+override FPCOPT+=-vwni
+endif
+ifdef COMPILER_OPTIONS
+override FPCOPT+=$(COMPILER_OPTIONS)
+endif
+ifdef COMPILER_UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(COMPILER_UNITDIR))
+endif
+ifdef COMPILER_LIBRARYDIR
+override FPCOPT+=$(addprefix -Fl,$(COMPILER_LIBRARYDIR))
+endif
+ifdef COMPILER_OBJECTDIR
+override FPCOPT+=$(addprefix -Fo,$(COMPILER_OBJECTDIR))
+endif
+ifdef COMPILER_INCLUDEDIR
+override FPCOPT+=$(addprefix -Fi,$(COMPILER_INCLUDEDIR))
+endif
+ifdef CROSSBINDIR
+override FPCOPT+=-FD$(CROSSBINDIR)
+endif
+ifdef COMPILER_TARGETDIR
+override FPCOPT+=-FE$(COMPILER_TARGETDIR)
+ifeq ($(COMPILER_TARGETDIR),.)
+override TARGETDIRPREFIX=
+else
+override TARGETDIRPREFIX=$(COMPILER_TARGETDIR)/
+endif
+endif
+ifdef COMPILER_UNITTARGETDIR
+override FPCOPT+=-FU$(COMPILER_UNITTARGETDIR)
+ifeq ($(COMPILER_UNITTARGETDIR),.)
+override UNITTARGETDIRPREFIX=
+else
+override UNITTARGETDIRPREFIX=$(COMPILER_UNITTARGETDIR)/
+endif
+else
+ifdef COMPILER_TARGETDIR
+override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR)
+override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX)
+endif
+endif
+ifeq ($(OS_TARGET),linux)
+ifeq ($(FPC_VERSION),1.0.6)
+override FPCOPTDEF+=HASUNIX
+endif
+endif
+ifdef OPT
+override FPCOPT+=$(OPT)
+endif
+ifdef FPCOPTDEF
+override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
+endif
+ifdef CFGFILE
+override FPCOPT+=@$(CFGFILE)
+endif
+ifdef USEENV
+override FPCEXTCMD:=$(FPCOPT)
+override FPCOPT:=!FPCEXTCMD
+export FPCEXTCMD
+endif
+override COMPILER:=$(FPC) $(FPCOPT)
+ifeq (,$(findstring -s ,$(COMPILER)))
+EXECPPAS=
+else
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+EXECPPAS:=@$(PPAS)
+endif
+endif
+.PHONY: fpc_exes
+ifndef CROSSINSTALL
+ifneq ($(TARGET_PROGRAMS),)
+override EXEFILES=$(addsuffix $(EXEEXT),$(TARGET_PROGRAMS))
+override EXEOFILES:=$(addsuffix $(OEXT),$(TARGET_PROGRAMS)) $(addprefix $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS)))
+override ALLTARGET+=fpc_exes
+override INSTALLEXEFILES+=$(EXEFILES)
+override CLEANEXEFILES+=$(EXEFILES) $(EXEOFILES)
+ifeq ($(OS_TARGET),os2)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+ifeq ($(OS_TARGET),emx)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+endif
+endif
+fpc_exes: $(COMPILER_TARGETDIR) $(COMPILER_UNITTARGETDIR) $(EXEFILES)
+ifdef TARGET_RSTS
+override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
+override CLEANRSTFILES+=$(RSTFILES)
+endif
+.PHONY: fpc_all fpc_smart fpc_debug fpc_release
+$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)
+ @$(ECHOREDIR) Compiled > $(FPCMADE)
+fpc_all: $(FPCMADE)
+fpc_smart:
+ $(MAKE) all LINKSMART=1 CREATESMART=1
+fpc_debug:
+ $(MAKE) all DEBUG=1
+fpc_release:
+ $(MAKE) all RELEASE=1
+.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res
+$(COMPILER_UNITTARGETDIR):
+ $(MKDIRTREE) $(COMPILER_UNITTARGETDIR)
+$(COMPILER_TARGETDIR):
+ $(MKDIRTREE) $(COMPILER_TARGETDIR)
+%$(PPUEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(PPUEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.lpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.dpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%.res: %.rc
+ windres -i $< -o $@
+vpath %.pp $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)
+vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)
+.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall
+ifdef INSTALL_UNITS
+override INSTALLPPUFILES+=$(addsuffix $(PPUEXT),$(INSTALL_UNITS))
+endif
+ifdef INSTALL_BUILDUNIT
+override INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT),$(INSTALLPPUFILES))
+endif
+ifdef INSTALLPPUFILES
+override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES)))
+ifneq ($(UNITTARGETDIRPREFIX),)
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPUFILES)))
+override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPULINKFILES))))
+endif
+override INSTALL_CREATEPACKAGEFPC=1
+endif
+ifdef INSTALLEXEFILES
+ifneq ($(TARGETDIRPREFIX),)
+override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(INSTALLEXEFILES)))
+endif
+endif
+fpc_install: all $(INSTALLTARGET)
+ifdef INSTALLEXEFILES
+ $(MKDIR) $(INSTALL_BINDIR)
+ifdef UPXPROG
+ -$(UPXPROG) $(INSTALLEXEFILES)
+endif
+ $(INSTALLEXE) $(INSTALLEXEFILES) $(INSTALL_BINDIR)
+endif
+ifdef INSTALL_CREATEPACKAGEFPC
+ifdef FPCMAKE
+ifdef PACKAGE_VERSION
+ifneq ($(wildcard Makefile.fpc),)
+ $(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) Package.fpc $(INSTALL_UNITDIR)
+endif
+endif
+endif
+endif
+ifdef INSTALLPPUFILES
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)
+ifneq ($(INSTALLPPULINKFILES),)
+ $(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)
+endif
+ifneq ($(wildcard $(LIB_FULLNAME)),)
+ $(MKDIR) $(INSTALL_LIBDIR)
+ $(INSTALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)
+ifdef inUnix
+ ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)
+endif
+endif
+endif
+ifdef INSTALL_FILES
+ $(MKDIR) $(INSTALL_DATADIR)
+ $(INSTALL) $(INSTALL_FILES) $(INSTALL_DATADIR)
+endif
+fpc_sourceinstall: distclean
+ $(MKDIR) $(INSTALL_SOURCEDIR)
+ $(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
+fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
+ifdef HASEXAMPLES
+ $(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
+ $(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef TARGET_EXAMPLEDIRS
+ $(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
+endif
+.PHONY: fpc_clean fpc_cleanall fpc_distclean
+ifdef EXEFILES
+override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
+endif
+ifdef CLEAN_UNITS
+override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
+endif
+ifdef CLEANPPUFILES
+override CLEANPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES)))
+ifdef DEBUGSYMEXT
+override CLEANPPULINKFILES+=$(subst $(PPUEXT),$(DEBUGSYMEXT),$(CLEANPPUFILES))
+endif
+override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUFILES))
+override CLEANPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPULINKFILES)))
+endif
+fpc_clean: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+ -$(DEL) $(CLEANEXEFILES)
+endif
+ifdef CLEANPPUFILES
+ -$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+ -$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+ -$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+ifdef CLEAN_FILES
+ -$(DEL) $(CLEAN_FILES)
+endif
+ifdef LIB_NAME
+ -$(DEL) $(LIB_NAME) $(LIB_FULLNAME)
+endif
+ -$(DEL) $(FPCMADE) Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+ -$(DEL) *$(ASMEXT) *_ppas$(BATCHEXT)
+fpc_cleanall: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+ -$(DEL) $(CLEANEXEFILES)
+endif
+ifdef COMPILER_UNITTARGETDIR
+ifdef CLEANPPUFILES
+ -$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+ -$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+ -$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+endif
+ -$(DELTREE) units
+ -$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
+ifneq ($(PPUEXT),.ppu)
+ -$(DEL) *.o *.ppu *.a
+endif
+ -$(DELTREE) *$(SMARTEXT)
+ -$(DEL) fpcmade.* Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+ -$(DEL) *_ppas$(BATCHEXT)
+ifdef AOUTEXT
+ -$(DEL) *$(AOUTEXT)
+endif
+ifdef DEBUGSYMEXT
+ -$(DEL) *$(DEBUGSYMEXT)
+endif
+fpc_distclean: cleanall
+.PHONY: fpc_baseinfo
+override INFORULES+=fpc_baseinfo
+fpc_baseinfo:
+ @$(ECHO)
+ @$(ECHO) == Package info ==
+ @$(ECHO) Package Name..... $(PACKAGE_NAME)
+ @$(ECHO) Package Version.. $(PACKAGE_VERSION)
+ @$(ECHO)
+ @$(ECHO) == Configuration info ==
+ @$(ECHO)
+ @$(ECHO) FPC.......... $(FPC)
+ @$(ECHO) FPC Version.. $(FPC_VERSION)
+ @$(ECHO) Source CPU... $(CPU_SOURCE)
+ @$(ECHO) Target CPU... $(CPU_TARGET)
+ @$(ECHO) Source OS.... $(OS_SOURCE)
+ @$(ECHO) Target OS.... $(OS_TARGET)
+ @$(ECHO) Full Source.. $(FULL_SOURCE)
+ @$(ECHO) Full Target.. $(FULL_TARGET)
+ @$(ECHO) SourceSuffix. $(SOURCESUFFIX)
+ @$(ECHO) TargetSuffix. $(TARGETSUFFIX)
+ @$(ECHO)
+ @$(ECHO) == Directory info ==
+ @$(ECHO)
+ @$(ECHO) Required pkgs... $(REQUIRE_PACKAGES)
+ @$(ECHO)
+ @$(ECHO) Basedir......... $(BASEDIR)
+ @$(ECHO) FPCDir.......... $(FPCDIR)
+ @$(ECHO) CrossBinDir..... $(CROSSBINDIR)
+ @$(ECHO) UnitsDir........ $(UNITSDIR)
+ @$(ECHO) PackagesDir..... $(PACKAGESDIR)
+ @$(ECHO)
+ @$(ECHO) GCC library..... $(GCCLIBDIR)
+ @$(ECHO) Other library... $(OTHERLIBDIR)
+ @$(ECHO)
+ @$(ECHO) == Tools info ==
+ @$(ECHO)
+ @$(ECHO) As........ $(AS)
+ @$(ECHO) Ld........ $(LD)
+ @$(ECHO) Ar........ $(AR)
+ @$(ECHO) Rc........ $(RC)
+ @$(ECHO)
+ @$(ECHO) Mv........ $(MVPROG)
+ @$(ECHO) Cp........ $(CPPROG)
+ @$(ECHO) Rm........ $(RMPROG)
+ @$(ECHO) GInstall.. $(GINSTALL)
+ @$(ECHO) Echo...... $(ECHO)
+ @$(ECHO) Shell..... $(SHELL)
+ @$(ECHO) Date...... $(DATE)
+ @$(ECHO) FPCMake... $(FPCMAKE)
+ @$(ECHO) PPUMove... $(PPUMOVE)
+ @$(ECHO) Upx....... $(UPXPROG)
+ @$(ECHO) Zip....... $(ZIPPROG)
+ @$(ECHO)
+ @$(ECHO) == Object info ==
+ @$(ECHO)
+ @$(ECHO) Target Loaders........ $(TARGET_LOADERS)
+ @$(ECHO) Target Units.......... $(TARGET_UNITS)
+ @$(ECHO) Target Implicit Units. $(TARGET_IMPLICITUNITS)
+ @$(ECHO) Target Programs....... $(TARGET_PROGRAMS)
+ @$(ECHO) Target Dirs........... $(TARGET_DIRS)
+ @$(ECHO) Target Examples....... $(TARGET_EXAMPLES)
+ @$(ECHO) Target ExampleDirs.... $(TARGET_EXAMPLEDIRS)
+ @$(ECHO)
+ @$(ECHO) Clean Units......... $(CLEAN_UNITS)
+ @$(ECHO) Clean Files......... $(CLEAN_FILES)
+ @$(ECHO)
+ @$(ECHO) Install Units....... $(INSTALL_UNITS)
+ @$(ECHO) Install Files....... $(INSTALL_FILES)
+ @$(ECHO)
+ @$(ECHO) == Install info ==
+ @$(ECHO)
+ @$(ECHO) DateStr.............. $(DATESTR)
+ @$(ECHO) ZipName.............. $(ZIPNAME)
+ @$(ECHO) ZipPrefix............ $(ZIPPREFIX)
+ @$(ECHO) ZipCrossPrefix....... $(ZIPCROSSPREFIX)
+ @$(ECHO) ZipSuffix............ $(ZIPSUFFIX)
+ @$(ECHO) FullZipName.......... $(FULLZIPNAME)
+ @$(ECHO) Install FPC Package.. $(INSTALL_FPCPACKAGE)
+ @$(ECHO)
+ @$(ECHO) Install base dir..... $(INSTALL_BASEDIR)
+ @$(ECHO) Install binary dir... $(INSTALL_BINDIR)
+ @$(ECHO) Install library dir.. $(INSTALL_LIBDIR)
+ @$(ECHO) Install units dir.... $(INSTALL_UNITDIR)
+ @$(ECHO) Install source dir... $(INSTALL_SOURCEDIR)
+ @$(ECHO) Install doc dir...... $(INSTALL_DOCDIR)
+ @$(ECHO) Install example dir.. $(INSTALL_EXAMPLEDIR)
+ @$(ECHO) Install data dir..... $(INSTALL_DATADIR)
+ @$(ECHO)
+ @$(ECHO) Dist destination dir. $(DIST_DESTDIR)
+ @$(ECHO) Dist zip name........ $(DIST_ZIPNAME)
+ @$(ECHO)
+.PHONY: fpc_info
+fpc_info: $(INFORULES)
+.PHONY: fpc_makefile fpc_makefiles fpc_makefile_sub1 fpc_makefile_sub2 \
+ fpc_makefile_dirs
+fpc_makefile:
+ $(FPCMAKE) -w -T$(OS_TARGET) Makefile.fpc
+fpc_makefile_sub1:
+ifdef TARGET_DIRS
+ $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_DIRS))
+endif
+ifdef TARGET_EXAMPLEDIRS
+ $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_EXAMPLEDIRS))
+endif
+fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_EXAMPLEDIRS))
+fpc_makefile_dirs: fpc_makefile_sub1 fpc_makefile_sub2
+fpc_makefiles: fpc_makefile fpc_makefile_dirs
+ifndef DATA2INC
+DATA2INC:=$(strip $(wildcard $(addsuffix /data2inc$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATA2INC),)
+DATA2INC= __missing_command_DATA2INC
+else
+DATA2INC:=$(firstword $(DATA2INC))
+endif
+endif
+export DATA2INC
+all: fpc_all
+debug: fpc_debug
+smart: fpc_smart
+release: fpc_release
+units: fpc_units
+examples:
+shared:
+install: fpc_install
+sourceinstall: fpc_sourceinstall
+exampleinstall: fpc_exampleinstall
+distinstall:
+zipinstall:
+zipsourceinstall:
+zipexampleinstall:
+zipdistinstall:
+clean: fpc_clean
+distclean: fpc_distclean
+cleanall: fpc_cleanall
+info: fpc_info
+makefiles: fpc_makefiles
+.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+ifneq ($(wildcard fpcmake.loc),)
+include fpcmake.loc
+endif
+ppu$(PPUEXT): ppu.pas
+ppufiles$(EXEEXT): ppufiles.pp ppu$(PPUEXT)
+ppudump$(EXEEXT): ppudump.pp ppu$(PPUEXT)
+ppumove$(EXEEXT): ppumove.pp ppu$(PPUEXT)
+fpcsubst$(EXEEXT): fpcsubst.pp usubst.pp
+fpcmkcfg$(EXEEXT): fpcmkcfg.pp usubst.pp fpccfg.inc
+ifneq ($(DATA2INC),)
+fpccfg.inc: fpc.cft
+ $(DATA2INC) -b -s fpc.cft fpccfg.inc DefaultConfig
+endif
+unexport PPUFILES PPUMOVE
diff --git a/compiler/utils/Makefile.fpc b/compiler/utils/Makefile.fpc
new file mode 100644
index 0000000000..1aacfc3c25
--- /dev/null
+++ b/compiler/utils/Makefile.fpc
@@ -0,0 +1,52 @@
+#
+# Makefile.fpc for Free Pascal Compiler Utils
+#
+
+[target]
+programs=fpc fppkg ppufiles ppudump ppumove fpcsubst fpcmkcfg
+rst=fppkg fpcmkcfg fpcsubst
+
+[clean]
+units=ppu crc usubst
+
+[compiler]
+unitdir=..
+sourcedir=..
+
+[install]
+fpcpackage=y
+
+[require]
+tools=data2inc
+
+[default]
+fpcdir=../..
+
+
+[rules]
+#
+# PPU Tools
+#
+ppu$(PPUEXT): ppu.pas
+
+ppufiles$(EXEEXT): ppufiles.pp ppu$(PPUEXT)
+
+ppudump$(EXEEXT): ppudump.pp ppu$(PPUEXT)
+
+ppumove$(EXEEXT): ppumove.pp ppu$(PPUEXT)
+
+fpcsubst$(EXEEXT): fpcsubst.pp usubst.pp
+
+fpcmkcfg$(EXEEXT): fpcmkcfg.pp usubst.pp fpccfg.inc
+
+ifneq ($(DATA2INC),)
+fpccfg.inc: fpc.cft
+ $(DATA2INC) -b -s fpc.cft fpccfg.inc DefaultConfig
+endif
+
+#
+# Don't export some tools, which are found in the current dir if it's in
+# the path, so are not valid for the subdirs
+#
+
+unexport PPUFILES PPUMOVE
diff --git a/compiler/utils/README b/compiler/utils/README
new file mode 100644
index 0000000000..ab7a13eefa
--- /dev/null
+++ b/compiler/utils/README
@@ -0,0 +1,20 @@
+This dirctory contains some utilities that are used during the
+development of the Free Pascal Compiler.
+
+msg2inc : Convert a compiler message file (errorX.msg) to .inc files to
+ include it as the default language in the compiler. It can
+ also convert the .msg to .tex for inclusion the documentation
+
+nasmconv : Convert a Nasm insns.dat to i386tab.inc so it can be used with
+ the compiler
+
+makecfg : This script will make the samplecfg for linux installations
+
+msgdif : analyzes the differences between two msg files
+ msgdif errore.msg errord.msg
+ will print out new error msg, removed old ones
+ and will create a new file new.msg that will
+ contain the new error messages (supposing TeX comment is after
+ the message line itself)
+ removed messages are prepended by "%%% "
+ (they can be useful in case on error enum renaming !)
diff --git a/compiler/utils/fixlog.pp b/compiler/utils/fixlog.pp
new file mode 100644
index 0000000000..4f5a7a932a
--- /dev/null
+++ b/compiler/utils/fixlog.pp
@@ -0,0 +1,174 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ Remove all revision logs from source files after X revisions or
+ older than date X
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program fixlog;
+
+{$mode objfpc}
+{$H+}
+
+uses
+ sysutils;
+
+const
+ bufsize = 32*1024;
+
+var
+ maxrevs,myear,mmonth,mday : integer;
+
+procedure Date2Int(const date:string;var year,month,day:integer);
+begin
+ year:=StrToInt(Copy(date,1,4));
+ month:=StrToInt(Copy(date,6,2));
+ day:=StrToInt(Copy(date,9,2));
+ if (year=0) or (month=0) or (day=0) then
+ begin
+ writeln('wrong date "',date,'", use yyyy/mm/dd');
+ halt(2);
+ end;
+end;
+
+
+procedure dofile(const fn:string);
+var
+ t,f : text;
+ s : string;
+ skip, truncated : boolean;
+ year,month,day,
+ found,revs,i : integer;
+ fbuf,tbuf : pointer;
+begin
+ getmem(fbuf,bufsize);
+ getmem(tbuf,bufsize);
+ write('processing ',fn,': ');
+ assign(t,fn);
+ assign(f,'fixlog.tmp');
+ {$I-}
+ reset(t);
+ {$I+}
+ if ioresult<>0 then
+ begin
+ writeln('error!');
+ exit;
+ end;
+ rewrite(f);
+ settextbuf(t,tbuf^,bufsize);
+ settextbuf(f,fbuf^,bufsize);
+ found:=0;
+ revs:=0;
+ skip:=false;
+ truncated:=false;
+ while not eof(t) do
+ begin
+ readln(t,s);
+ case found of
+ 0 :
+ begin
+ if pos('$Log: ',s)>0 then
+ found:=1;
+ skip:=false;
+ writeln(f,s);
+ end;
+ 1 :
+ begin
+ i:=pos('Revision',s);
+ if i>0 then
+ begin
+ inc(revs);
+ if revs>maxrevs then
+ begin
+ skip:=true;
+ truncated:=true;
+ found:=2;
+ end
+ else
+ begin
+ inc(i,10);
+ while (i<length(s)) and (s[i]<>' ') do
+ inc(i);
+ while (i<length(s)) and (s[i]=' ') do
+ inc(i);
+ if (i<length(s)) and (s[i] in ['0'..'9']) then
+ begin
+ Date2Int(Copy(s,i,10),year,month,day);
+ if (year<Myear) or
+ ((year=MYear) and (month<Mmonth)) or
+ ((year=MYear) and (month=Mmonth) and (day<Mday)) then
+ begin
+ skip:=true;
+ truncated:=true;
+ found:=2;
+// write(year,'/',month,'/',day,' date');
+ end;
+ end;
+ end;
+ end
+ else
+ if pos('}',s)>0 then
+ begin
+ skip:=false;
+ found:=0;
+ end;
+ if not skip then
+ writeln(f,s);
+ end;
+ 2 :
+ begin
+ if pos('}',s)>0 then
+ begin
+ skip:=false;
+ found:=0;
+ end;
+ if not skip then
+ writeln(f,s);
+ end;
+ end;
+ end;
+ close(t);
+ close(f);
+ if revs=0 then
+ writeln(' no log found')
+ else
+ if truncated then
+ writeln(revs-1,' revisions')
+ else
+ writeln(revs,' revisions');
+ erase(t);
+ rename(f,fn);
+ freemem(tbuf);
+ freemem(fbuf);
+end;
+
+var
+ dir : tsearchrec;
+ i : integer;
+ path : string;
+begin
+ writeln('fixlog v1.01 (C) 1999-2002 Peter Vreman');
+ if paramcount<3 then
+ begin
+ writeln('usage: fixlog <revisions> <yyyy-mm-dd> <files> [files]');
+ halt(1);
+ end;
+ MaxRevs:=StrToInt(ParamStr(1));
+ Date2Int(ParamStr(2),MYear,MMonth,MDay);
+ for i:=3 to paramcount do
+ begin
+ path:=ExtractFilePath(paramstr(i));
+ if findfirst(paramstr(i),faAnyFile,dir)=0 then
+ repeat
+ dofile(path+dir.name);
+ until findnext(dir)<>0;
+ findclose(dir);
+ end;
+end.
diff --git a/compiler/utils/fixmsg.pp b/compiler/utils/fixmsg.pp
new file mode 100644
index 0000000000..6bd1cfbe2c
--- /dev/null
+++ b/compiler/utils/fixmsg.pp
@@ -0,0 +1,66 @@
+type
+ trtabrec=record
+ name : string[12];
+ idx : longint;
+ end;
+
+const
+ trtab : array[0..10] of trtabrec=(
+ (name:'general';idx:1000),
+ (name:'scan';idx:2000),
+ (name:'parser';idx:3000),
+ (name:'type';idx:4000),
+ (name:'sym';idx:5000),
+ (name:'cg';idx:6000),
+ (name:'asmr';idx:7000),
+ (name:'asmw';idx:8000),
+ (name:'exec';idx:9000),
+ (name:'unit';idx:10000),
+ (name:'option';idx:11000)
+ );
+
+var
+ t,f : text;
+ s,hs : string;
+ i,j,k : longint;
+begin
+ assign(t,paramstr(1));
+ reset(t);
+ assign(f,'New.msg');
+ rewrite(f);
+ while not eof(t) do
+ begin
+ readln(t,s);
+ if (s<>'') and not(s[1] in ['#','%']) then
+ begin
+ for i:=0 to 10 do
+ if Copy(s,1,length(trtab[i].name))=trtab[i].name then
+ begin
+ j:=pos('=',s);
+ if j>0 then
+ begin
+ inc(j);
+ if s[j] in ['0'..'9'] then
+ begin
+ k:=j;
+ while (s[k] in ['0'..'9']) do
+ inc(k);
+ if s[k]='_' then
+ inc(k);
+ delete(s,j,k-j);
+ end;
+ str(trtab[i].idx,hs);
+ while length(hs)<5 do
+ hs:='0'+hs;
+ hs:=hs+'_';
+ inc(trtab[i].idx);
+ insert(hs,s,j);
+ end;
+ break;
+ end;
+ end;
+ writeln(f,s);
+ end;
+ close(f);
+ close(t);
+end.
diff --git a/compiler/utils/fixnasm.pp b/compiler/utils/fixnasm.pp
new file mode 100644
index 0000000000..01041ede83
--- /dev/null
+++ b/compiler/utils/fixnasm.pp
@@ -0,0 +1,99 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ Convert insns.dat from Nasm to an i386ins.dat for usage with
+ the Free pascal compiler
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program fixnasm;
+
+{$ifndef FPC}
+ procedure readln(var t:text;var s:string);
+ var
+ c : char;
+ i : longint;
+ begin
+ c:=#0;
+ i:=0;
+ while (not eof(t)) and (c<>#10) do
+ begin
+ read(t,c);
+ if c<>#10 then
+ begin
+ inc(i);
+ s[i]:=c;
+ end;
+ end;
+ if (i>0) and (s[i]=#13) then
+ dec(i);
+ s[0]:=chr(i);
+ end;
+{$endif}
+
+const
+ spaces=' ';
+var
+ t,f : text;
+ para,bytes,flags,
+ opcode,lastop,
+ s : string;
+ i,j : longint;
+begin
+ writeln('Fixing insns.dat -> i386ins.dat');
+ assign(t,'insns.dat');
+ reset(t);
+ assign(f,'insns.new');
+ rewrite(f);
+ lastop:='';
+ while not eof(t) do
+ begin
+ readln(t,s);
+ if (s<>'') and (s[1]<>';') then
+ begin
+ i:=pos(' ',s);
+ j:=pos(',',s);
+ if (j>0) and (j<i) then
+ opcode:=Copy(s,1,j-1)
+ else
+ opcode:=Copy(s,1,i-1);
+ if opcode<>lastop then
+ begin
+ writeln(f,'');
+ writeln(f,'[',Copy(s,1,i-1),']');
+ writeln(f,'(Ch_All, Ch_None, Ch_None)');
+ lastop:=opcode;
+ end;
+ while (i<length(s)) and (s[i+1]=' ') do
+ inc(i);
+ Delete(s,1,i);
+ i:=pos(' ',s);
+ para:=Copy(s,1,i-1);
+ para:=para+Copy(spaces,1,22-length(para));
+ while (i<length(s)) and (s[i+1]=' ') do
+ inc(i);
+ Delete(s,1,i);
+ i:=pos(' ',s);
+ bytes:=Copy(s,1,i-1);
+ bytes:=bytes+Copy(spaces,1,32-length(bytes));
+ while (i<length(s)) and (s[i+1]=' ') do
+ inc(i);
+ Delete(s,1,i);
+ i:=pos(' ',s);
+ if i=0 then
+ i:=255;
+ flags:=Copy(s,1,i-1);
+ writeln(f,para,bytes,flags);
+ end
+ else
+ writeln(f,s);
+ end;
+ close(f);
+ close(t);
+end.
diff --git a/compiler/utils/fixtab.pp b/compiler/utils/fixtab.pp
new file mode 100644
index 0000000000..89410c5836
--- /dev/null
+++ b/compiler/utils/fixtab.pp
@@ -0,0 +1,367 @@
+program FixTab;
+uses Dos;
+
+const
+ {Files}
+ InputExt='';
+ OutputExt='*';
+
+
+var
+{General}
+ InFile,
+ OutFile : string[80];
+ ParaFile : word;
+{Specific}
+const
+ TabSize : longint=8;
+ DosEol : boolean=false;
+ Verbose : boolean=false;
+
+{****************************************************************************
+ Routines
+****************************************************************************}
+
+const
+{$IFDEF LINUX}
+ PathCh='/';
+{$ELSE}
+ PathCh='\';
+{$ENDIF}
+
+Function SplitPath(Const HStr:String):String;
+var
+ i : byte;
+begin
+ i:=Length(Hstr);
+ while (i>0) and (Hstr[i]<>PathCh) do
+ dec(i);
+ SplitPath:=Copy(Hstr,1,i);
+end;
+
+
+
+Function SplitFileName(Const HStr:String):String;
+var
+ i : byte;
+begin
+ i:=Length(Hstr);
+ while (i>0) and (Hstr[i]<>PathCh) do
+ dec(i);
+ SplitFileName:=Copy(Hstr,i+1,255);
+end;
+
+
+
+Function SplitName(Const HStr:String):String;
+var
+ i,j : byte;
+begin
+ i:=Length(Hstr);
+ j:=i;
+ while (i>0) and (Hstr[i]<>PathCh) do
+ dec(i);
+ while (j>0) and (Hstr[j]<>'.') do
+ dec(j);
+ if j<=i then
+ j:=255;
+ SplitName:=Copy(Hstr,i+1,j-(i+1));
+end;
+
+
+
+Function SplitExtension(Const HStr:String):String;
+var
+ j,i : byte;
+begin
+ i:=Length(Hstr);
+ j:=i;
+ while (i>0) and (Hstr[i]<>PathCh) do
+ dec(i);
+ while (j>0) and (Hstr[j]<>'.') do
+ dec(j);
+ if j<=i then
+ j:=254;
+ SplitExtension:=Copy(Hstr,j+1,255);
+end;
+
+
+
+Function AddExtension(Const HStr,ext:String):String;
+begin
+ if (Ext<>'') and (SplitExtension(HStr)='') then
+ AddExtension:=Hstr+'.'+Ext
+ else
+ AddExtension:=Hstr;
+end;
+
+
+
+Function ForceExtension(Const HStr,ext:String):String;
+var
+ j : byte;
+begin
+ j:=length(Hstr);
+ while (j>0) and (Hstr[j]<>'.') do
+ dec(j);
+ if j=0 then
+ j:=255;
+ ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext;
+end;
+
+
+function UCase(Const Hstr:string):string;
+var
+ i : byte;
+begin
+ for i:=1to Length(Hstr) do
+ UCase[i]:=Upcase(Hstr[i]);
+ UCase[0]:=chr(Length(Hstr));
+end;
+
+
+
+Function ESpace(HStr:String;len:byte):String;
+begin
+ while length(Hstr)<Len do
+ begin
+ inc(byte(Hstr[0]));
+ Hstr[Length(Hstr)]:=' ';
+ end;
+ ESpace:=Hstr;
+end;
+
+{****************************************************************************
+ Main Stuff
+****************************************************************************}
+
+var
+ Done : array[0..1023] of string[32];
+ Total : word;
+Function FileDone(const fn:string):boolean;
+var
+ i : word;
+begin
+ i:=0;
+ while (i<Total) and (Done[i]<>fn) do
+ inc(i);
+ if Done[i]=fn then
+ FileDone:=true
+ else
+ begin
+ Done[Total]:=fn;
+ inc(Total);
+ FileDone:=false;
+ end;
+end;
+
+
+
+procedure Convert(fn,nfn:string);
+type
+ inbuftype=array[0..31999] of char;
+ outbuftype=array[0..63999] of char;
+var
+ f,g : file;
+ inbuf : ^inbuftype;
+ outbuf : ^outbuftype;
+ Curr,
+ TabCol,
+ col,
+ i,last,
+ innum,
+ outnum : longint;
+
+ procedure WriteBuf;
+ begin
+ if i>last then
+ begin
+ move(InBuf^[last],OutBuf^[OutNum],i-last);
+ inc(OutNum,(i-last));
+ end;
+ Last:=i+1;
+ end;
+
+begin
+{Create New FileName}
+ if SplitExtension(nfn)='*' then
+ nfn:=AddExtension(SplitPath(nfn)+SplitName(nfn),SplitExtension(fn));
+ if SplitName(nfn)='*' then
+ begin
+ if SplitPath(nfn)='' then
+ nfn:=AddExtension(SplitPath(fn)+SplitName(fn),SplitExtension(nfn))
+ else
+ nfn:=AddExtension(SplitPath(nfn)+SplitName(fn),SplitExtension(nfn));
+ end;
+{Done?}
+ if FileDone(nfn) then
+ exit;
+{Open Files}
+ Write('Converting '+ESpace(fn,30)+' ');
+ if fn=nfn then
+ assign(g,ForceExtension(fn,'$T$'))
+ else
+ begin
+ Write('-> '+ESpace(nfn,30)+' ');
+ assign(g,nfn);
+ end;
+ new(inbuf);
+ new(outbuf);
+ assign(f,fn);
+ {$I-}
+ reset(f,1);
+ {$I+}
+ if ioresult<>0 then
+ exit;
+ {$I-}
+ rewrite(g,1);
+ {$I+}
+ if ioresult<>0 then
+ begin
+ close(f);
+ exit;
+ end;
+ Curr:=0;
+ col:=1;
+ last:=0;
+ repeat
+ blockread(f,InBuf^,sizeof(InBufType),innum);
+ outnum:=0;
+ if innum>0 then
+ begin
+ i:=0;
+ while (i<innum) do
+ begin
+ case InBuf^[i] of
+ #9 : begin
+ WriteBuf;
+ OutBuf^[OutNum]:=' ';
+ inc(OutNum);
+ inc(Col);
+ TabCol:=(((Col-1) div TabSize)+1)*TabSize;
+ while (Col<TabCol) do
+ begin
+ OutBuf^[OutNum]:=' ';
+ inc(OutNum);
+ inc(Col);
+ end;
+ end;
+ #13 : begin
+ WriteBuf;
+ while (outnum>0) and (outbuf^[outnum-1] in [' ',#9]) do
+ dec(outnum);
+ end;
+ #10 : begin
+ WriteBuf;
+ while (outnum>0) and (outbuf^[outnum-1] in [' ',#9]) do
+ dec(outnum);
+ if DosEol then
+ begin
+ OutBuf^[OutNum]:=#13;
+ inc(OutNum);
+ end;
+ OutBuf^[OutNum]:=#10;
+ inc(OutNum);
+ col:=0;
+ inc(Curr);
+ if (curr and 31)=0 then
+ Write(Curr:5,#8#8#8#8#8);
+ end;
+ else
+ inc(col);
+ end;
+ inc(i);
+ end;
+ WriteBuf;
+ last:=0;
+ end;
+ blockwrite(g,OutBuf^,outnum);
+ until innum=0;
+ WriteLn(Curr,' Lines');
+ close(g);
+ close(f);
+ if fn=nfn then
+ begin
+ erase(f);
+ rename(g,fn);
+ end;
+ dispose(outbuf);
+ dispose(inbuf);
+end;
+
+
+{****************************************************************************
+ General Stuff
+****************************************************************************}
+
+procedure getpara;
+var
+ ch : char;
+ para : string[128];
+ i,j : word;
+
+ procedure helpscreen;
+ begin
+ writeln('Usage : '+SplitName(ParamStr(0))+' [Options] <InFile(s)>'#10);
+ writeln('<Options> can be : -O<OutFile> Specify OutFile Mask');
+ WriteLn(' -D Use MsDos #13#10 Eols');
+ writeln(' -T<size> Set Size of Tabs');
+ writeln(' -V be more verbose');
+ writeln(' -? or -H This HelpScreen');
+ halt(1);
+ end;
+
+begin
+ for i:=1to paramcount do
+ begin
+ para:=ucase(paramstr(i));
+ if (para[1]='-') then
+ begin
+ ch:=para[2];
+ delete(para,1,2);
+ case ch of
+ 'O' : OutFile:=AddExtension(Para,OutputExt);
+ 'D' : DosEol:=true;
+ 'T' : Val(Para,TabSize,j);
+ 'V' : verbose:=true;
+ '?','H' : helpscreen;
+ end;
+ end
+ else
+ begin
+ if ParaFile=0 then
+ ParaFile:=i;
+ end;
+ end;
+ if (ParaFile=0) then
+ HelpScreen;
+ if OutFile='' then
+ OutFile:=ForceExtension('*',OutPutExt);
+end;
+
+
+
+var
+ Dir : SearchRec;
+ i : word;
+begin
+ GetPara;
+{Main}
+ if Verbose then
+ begin
+ Writeln('fixtab v1.01 (C) 1999-2002 Peter Vreman');
+ Writeln('TabSize ',TabSize);
+ if DosEol then
+ WriteLn('Using MsDos Eols');
+ end;
+ for i:=ParaFile to ParamCount do
+ begin
+ InFile:=AddExtension(ParamStr(i),InputExt);
+ FindFirst(InFile,$20,Dir);
+ while (DosError=0) do
+ begin
+ Convert(SplitPath(InFile)+Dir.Name,OutFile);
+ FindNext(Dir);
+ end;
+ end;
+end.
diff --git a/compiler/utils/fpc.cft b/compiler/utils/fpc.cft
new file mode 100644
index 0000000000..e858c909c4
--- /dev/null
+++ b/compiler/utils/fpc.cft
@@ -0,0 +1,204 @@
+#
+# Config file generated by fpcmkcfg on %BUILDDATE% - %BUILDTIME%
+# Example fpc.cfg for Free Pascal Compiler
+#
+
+# ----------------------
+# Defines (preprocessor)
+# ----------------------
+
+#
+# nested #IFNDEF, #IFDEF, #ENDIF, #ELSE, #DEFINE, #UNDEF are allowed
+#
+# -d is the same as #DEFINE
+# -u is the same as #UNDEF
+#
+
+#
+# Some examples (for switches see below, and the -? helppages)
+#
+# Try compiling with the -dRELEASE or -dDEBUG on the commandline
+#
+
+# For a release compile with optimizes and strip debuginfo
+#IFDEF RELEASE
+ -OG2p3
+ -Xs
+ #WRITE Compiling Release Version
+#ENDIF
+
+# For a debug version compile with debuginfo and all codegeneration checks on
+#IFDEF DEBUG
+ -g
+ -Crtoi
+ #WRITE Compiling Debug Version
+#ENDIF
+
+# ----------------
+# Parsing switches
+# ----------------
+
+# Pascal language mode
+# -Mfpc free pascal dialect (default)
+# -Mobjfpc switch some Delphi 2 extensions on
+# -Mdelphi tries to be Delphi compatible
+# -Mtp tries to be TP/BP 7.0 compatible
+# -Mgpc tries to be gpc compatible
+# -Mmacpas tries to be compatible to the macintosh pascal dialects
+#
+# Turn on Object Pascal extensions by default
+#-Mobjfpc
+
+# Assembler reader mode
+# -Rdefault use default assembler
+# -Ratt read AT&T style assembler
+# -Rintel read Intel style assembler
+#
+# All assembler blocks are AT&T styled by default
+#-Ratt
+
+# Semantic checking
+# -S2 same as -Mobjfpc
+# -Sc supports operators like C (*=,+=,/= and -=)
+# -Sa include assertion code.
+# -Sd same as -Mdelphi
+# -Se<x> compiler stops after the <x> errors (default is 1)
+# -Sg allow LABEL and GOTO
+# -Sh Use ansistrings
+# -Si support C++ styled INLINE
+# -SI<x> set interface style to <x>
+# -SIcomCOM compatible interface (default)
+# -SIcorbaCORBA compatible interface
+# -Sm support macros like C (global)
+# -So same as -Mtp
+# -Sp same as -Mgpc
+# -Ss constructor name must be init (destructor must be done)
+# -St allow static keyword in objects
+#
+# Allow goto, inline, C-operators, C-vars
+-Sgic
+
+# ---------------
+# Code generation
+# ---------------
+
+# Uncomment the next line if you always want static/dynamic units by default
+# (can be overruled with -CD, -CS at the commandline)
+#-CS
+#-CD
+
+# Set the default heapsize to 8Mb
+#-Ch8000000
+
+# Set default codegeneration checks (iocheck, overflow, range, stack)
+#-Ci
+#-Co
+#-Cr
+#-Ct
+
+# Optimizer switches for i386 compiler
+# -Og generate smaller code
+# -OG generate faster code (default)
+# -Or keep certain variables in registers (still BUGGY!!!)
+# -Ou enable uncertain optimizations (see docs)
+# -O1 level 1 optimizations (quick optimizations)
+# -O2 level 2 optimizations (-O1 + slower optimizations)
+# -O3 level 3 optimizations (same as -O2u)
+# -Op target processor
+# -Op1 set target processor to 386/486
+# -Op2 set target processor to Pentium/PentiumMMX (tm)
+# -Op3 set target processor to PPro/PII/c6x86/K6 (tm)
+
+# Optimize always for Size and PII
+#-OG2p3
+
+
+# -----------------------
+# Set Filenames and Paths
+# -----------------------
+
+# Both slashes and backslashes are allowed in paths
+
+# path to the messagefile, not necessary anymore but can be used to override
+# the default language
+#-Fr%basepath%/msg/errore.msg
+#-Fr%basepath%/msg/errorn.msg
+#-Fr%basepath%/msg/errores.msg
+#-Fr%basepath%/msg/errord.msg
+#-Fr%basepath%/msg/errorr.msg
+
+# path to the gcclib
+#-Fl%basepath%/lib
+
+# searchpath for includefiles
+#-Fi/pp/inc;/pp/rtl/inc
+
+# searchpath for includefiles
+# release them only if you know what you do
+# because this could cause a rebuild of the runtime library
+# if you tell them compiler/ide to build the project (FK)
+#-Fi%basepath%/source/rtl/inc;%basepath%/source/rtl/i386
+
+# searchpath for objectfiles
+#-Fo%basepath%/source/rtl/inc;%basepath%/source/rtl/i386
+
+# searchpath for units and other system dependent things
+-Fu%basepath%/units/$FPCTARGET/
+-Fu%basepath%/units/$FPCTARGET/*
+-Fu%basepath%/units/$FPCTARGET/rtl
+
+# searchpath for libraries
+#-Fl%basepath%/lib
+#-Fl/lib;/usr/lib
+
+# searchpath for tools
+-FD%basepath%/bin/$FPCTARGET
+
+
+# -------------
+# Linking
+# -------------
+
+# generate always debugging information for GDB (slows down the compiling
+# process)
+# -gc generate checks for pointers
+# -gd use dbx
+# -gg use gsym
+# -gh use heap trace unit (for memory leak debugging)
+# -gl use line info unit to show more info for backtraces
+# -gv generates programs tracable with valgrind
+# -gw generate dwarf debugging info
+#
+# Enable debuginfo and use the line info unit by default
+#-gl
+
+# always pass an option to the linker
+#-k-s
+
+# Always strip debuginfo from the executable
+-Xs
+
+
+# -------------
+# Miscellaneous
+# -------------
+
+# Write always a nice FPC logo ;)
+-l
+
+# Verbosity
+# e : Show errors (default) d : Show debug info
+# w : Show warnings u : Show unit info
+# n : Show notes t : Show tried/used files
+# h : Show hints m : Show defined macros
+# i : Show general info p : Show compiled procedures
+# l : Show linenumbers c : Show conditionals
+# a : Show everything 0 : Show nothing (except errors)
+# b : Show all procedure r : Rhide/GCC compatibility mode
+# declarations if an error x : Executable info (Win32 only)
+# occurs
+#
+# Display Info, Warnings, Notes and Hints
+-viwn
+# If you don't want so much verbosity use
+#-vw
diff --git a/compiler/utils/fpc.mpw b/compiler/utils/fpc.mpw
new file mode 100644
index 0000000000..8ae99a7ee6
--- /dev/null
+++ b/compiler/utils/fpc.mpw
@@ -0,0 +1,2 @@
+# MPW script which mimics the fpc wrapper application
+ppcppc {Parameters}
diff --git a/compiler/utils/fpc.pp b/compiler/utils/fpc.pp
new file mode 100644
index 0000000000..01511f7419
--- /dev/null
+++ b/compiler/utils/fpc.pp
@@ -0,0 +1,205 @@
+{
+ Copyright (c) 2000-2002 by Florian Klaempfl
+
+ This file is the "loader" for the Free Pascal compiler
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************}
+program fpc;
+
+{$mode objfpc}{$H+}
+
+ uses
+ Sysutils;
+
+ const
+{$ifdef UNIX}
+ exeext='';
+{$else UNIX}
+ {$ifdef AMIGA}
+ exeext='';
+ {$else}
+ {$ifdef MORPHOS}
+ exeext='';
+ {$else}
+ {$ifdef NETWARE}
+ exeext='.nlm';
+ {$else}
+ exeext='.exe';
+ {$endif NETWARE}
+ {$endif MORPHOS}
+ {$endif AMIGA}
+{$endif UNIX}
+
+
+ procedure error(const s : string);
+ begin
+ writeln('Error: ',s);
+ halt(1);
+ end;
+
+
+ function SplitPath(Const HStr:String):String;
+ var
+ i : longint;
+ begin
+ i:=Length(Hstr);
+ while (i>0) and not(Hstr[i] in ['\','/']) do
+ dec(i);
+ SplitPath:=Copy(Hstr,1,i);
+ end;
+
+
+ function FileExists ( Const F : String) : Boolean;
+ var
+ Info : TSearchRec;
+ begin
+ FileExists:= findfirst(F,fareadonly+faarchive+fahidden,info)=0;
+ findclose(Info);
+ end;
+
+ procedure findexe(var ppcbin:string);
+ var
+ path : string;
+ begin
+ { add .exe extension }
+ ppcbin:=ppcbin+exeext;
+
+ { get path of fpc.exe }
+ path:=splitpath(paramstr(0));
+ if FileExists(path+ppcbin) then
+ ppcbin:=path+ppcbin
+ else
+ begin
+ path:=FileSearch(ppcbin,getenvironmentvariable('PATH'));
+ if path<>'' then
+ ppcbin:=path;
+
+ end;
+ end;
+
+ var
+ s : ansistring;
+ processorname,
+ ppcbin,
+ versionStr,
+ processorstr : string;
+ ppccommandline : ansistring;
+ i : longint;
+ errorvalue : Longint;
+ begin
+ ppccommandline:='';
+{$ifdef i386}
+ ppcbin:='ppc386';
+ processorname:='i386';
+{$endif i386}
+{$ifdef m68k}
+ ppcbin:='ppc68k';
+ processorname:='m68k';
+{$endif m68k}
+{$ifdef alpha}
+ ppcbin:='ppcapx';
+ processorname:='alpha';
+{$endif alpha}
+{$ifdef powerpc}
+ ppcbin:='ppcppc';
+ processorname:='powerpc';
+{$endif powerpc}
+{$ifdef arm}
+ ppcbin:='ppcarm';
+ processorname:='arm';
+{$endif arm}
+{$ifdef sparc}
+ ppcbin:='ppcsparc';
+ processorname:='sparc';
+{$endif sparc}
+{$ifdef x86_64}
+ ppcbin:='ppcx64';
+ processorname:='x86_64';
+{$endif x86_64}
+{$ifdef ia64}
+ ppcbin:='ppcia64';
+ processorname:='ia64';
+{$endif ia64}
+ versionstr:=''; { Default is just the name }
+ for i:=1 to paramcount do
+ begin
+ s:=paramstr(i);
+ if pos('-V',s)=1 then
+ versionstr:=copy(s,3,length(s)-2)
+ else
+ begin
+ if pos('-P',s)=1 then
+ begin
+ processorstr:=copy(s,3,length(s)-2);
+ { -PB is a special code that will show the
+ default compiler and exit immediatly. It's
+ main usage is for Makefile }
+ if processorstr='B' then
+ begin
+ { report the full name of the ppcbin }
+ findexe(ppcbin);
+ writeln(ppcbin);
+ halt(0);
+ end
+ { -PP is a special code that will show the
+ processor and exit immediatly. It's
+ main usage is for Makefile }
+ else if processorstr='P' then
+ begin
+ { report the processor }
+ writeln(processorname);
+ halt(0);
+ end
+ else if processorstr='i386' then
+ ppcbin:='ppc386'
+ else if processorstr='m68k' then
+ ppcbin:='ppc68k'
+ else if processorstr='alpha' then
+ ppcbin:='ppcapx'
+ else if processorstr='powerpc' then
+ ppcbin:='ppcppc'
+ else if processorstr='arm' then
+ ppcbin:='ppcarm'
+ else if processorstr='sparc' then
+ ppcbin:='ppcsparc'
+ else if processorstr='ia64' then
+ ppcbin:='ppcia64'
+ else if processorstr='x86_64' then
+ ppcbin:='ppcx64'
+ else error('Illegal processor type "'+processorstr+'"');
+ end
+ else
+ ppccommandline:=ppccommandline+s+' ';
+ end;
+ end;
+
+ if versionstr<>'' then
+ ppcbin:=ppcbin+'-'+versionstr;
+ { find the full path to the specified exe }
+ findexe(ppcbin);
+
+ { call ppcXXX }
+ try
+ errorvalue:=ExecuteProcess(ppcbin,ppccommandline);
+ except
+ on e : exception do
+ error(ppcbin+' can''t be executed, error message: '+e.message);
+ end;
+ if errorvalue<>0 then
+ error(ppcbin+' returned an error exitcode (normal if you did not specify a source file to be compiled)');
+ halt(errorvalue);
+ end.
diff --git a/compiler/utils/fpccfg.inc b/compiler/utils/fpccfg.inc
new file mode 100644
index 0000000000..103f32ab70
--- /dev/null
+++ b/compiler/utils/fpccfg.inc
@@ -0,0 +1,224 @@
+{$ifdef Delphi}
+const DefaultConfig : array[0..24] of string[240]=(
+{$else Delphi}
+const DefaultConfig : array[0..24,1..240] of char=(
+{$endif Delphi}
+ '#'#013#010+
+ '# Config file generated by fpcmkcfg on %BUILDDATE% - %BUILDTIME%'#013#010+
+ '# Example fpc.cfg for Free Pascal Compiler'#013#010+
+ '#'#013#010+
+ #013#010+
+ '# ----------------------'#013#010+
+ '# Defines (preprocessor)'#013#010+
+ '# ----------------------'#013#010+
+ #013#010+
+ '#'#013#010+
+ '# nested #IFNDEF, #IFDEF, #ENDIF, #ELSE',', #DEFINE, #UNDEF are allowed'+
+ #013#010+
+ '#'#013#010+
+ '# -d is the same as #DEFINE'#013#010+
+ '# -u is the same as #UNDEF'#013#010+
+ '#'#013#010+
+ #013#010+
+ '#'#013#010+
+ '# Some examples (for switches see below, and the -? helppages)'#013#010+
+ '#'#013#010+
+ '# Try compiling with the -dRELEASE or -dDEBUG on the commandline'#013#010+
+ '#'#013#010+
+ #013#010+
+ '# F','or a release compile with optimizes and strip debuginfo'#013#010+
+ '#IFDEF RELEASE'#013#010+
+ ' -OG2p3'#013#010+
+ ' -Xs'#013#010+
+ ' #WRITE Compiling Release Version'#013#010+
+ '#ENDIF'#013#010+
+ #013#010+
+ '# For a debug version compile with debuginfo and all codegeneration ch'+
+ 'ecks on'#013#010+
+ '#IFDEF DEBUG'#013#010+
+ ' -g'#013#010+
+ ' -Cr','toi'#013#010+
+ ' #WRITE Compiling Debug Version'#013#010+
+ '#ENDIF'#013#010+
+ #013#010+
+ '# ----------------'#013#010+
+ '# Parsing switches'#013#010+
+ '# ----------------'#013#010+
+ #013#010+
+ '# Pascal language mode'#013#010+
+ '# -Mfpc free pascal dialect (default)'#013#010+
+ '# -Mobjfpc switch some Delphi 2 extensions on'#013#010+
+ '# ',' -Mdelphi tries to be Delphi compatible'#013#010+
+ '# -Mtp tries to be TP/BP 7.0 compatible'#013#010+
+ '# -Mgpc tries to be gpc compatible'#013#010+
+ '# -Mmacpas tries to be compatible to the macintosh pascal diale'+
+ 'cts'#013#010+
+ '#'#013#010+
+ '# Turn on Object ','Pascal extensions by default'#013#010+
+ '#-Mobjfpc'#013#010+
+ #013#010+
+ '# Assembler reader mode'#013#010+
+ '# -Rdefault use default assembler'#013#010+
+ '# -Ratt read AT&T style assembler'#013#010+
+ '# -Rintel read Intel style assembler'#013#010+
+ '#'#013#010+
+ '# All assembler blocks are AT&T style','d by default'#013#010+
+ '#-Ratt'#013#010+
+ #013#010+
+ '# Semantic checking'#013#010+
+ '# -S2 same as -Mobjfpc'#013#010+
+ '# -Sc supports operators like C (*=,+=,/= and -=)'#013#010+
+ '# -Sa include assertion code.'#013#010+
+ '# -Sd same as -Mdelphi'#013#010+
+ '# -Se<x> ',' compiler stops after the <x> errors (default is 1)'+
+ #013#010+
+ '# -Sg allow LABEL and GOTO'#013#010+
+ '# -Sh Use ansistrings'#013#010+
+ '# -Si support C++ styled INLINE'#013#010+
+ '# -SI<x> set interface style to <x>'#013#010+
+ '# -SIcomCOM c','ompatible interface (default)'#013#010+
+ '# -SIcorbaCORBA compatible interface'#013#010+
+ '# -Sm support macros like C (global)'#013#010+
+ '# -So same as -Mtp'#013#010+
+ '# -Sp same as -Mgpc'#013#010+
+ '# -Ss constructor name must be init ','(destructor must be '+
+ 'done)'#013#010+
+ '# -St allow static keyword in objects'#013#010+
+ '#'#013#010+
+ '# Allow goto, inline, C-operators, C-vars'#013#010+
+ '-Sgic'#013#010+
+ #013#010+
+ '# ---------------'#013#010+
+ '# Code generation'#013#010+
+ '# ---------------'#013#010+
+ #013#010+
+ '# Uncomment the next line if you always want sta','tic/dynamic units by'+
+ ' default'#013#010+
+ '# (can be overruled with -CD, -CS at the commandline)'#013#010+
+ '#-CS'#013#010+
+ '#-CD'#013#010+
+ #013#010+
+ '# Set the default heapsize to 8Mb'#013#010+
+ '#-Ch8000000'#013#010+
+ #013#010+
+ '# Set default codegeneration checks (iocheck, overflow, range, stack)'#013+
+ #010+
+ '#-Ci'#013#010+
+ '#-Co'#013#010+
+ '#-Cr'#013#010+
+ '#-','Ct'#013#010+
+ #013#010+
+ '# Optimizer switches for i386 compiler'#013#010+
+ '# -Og generate smaller code'#013#010+
+ '# -OG generate faster code (default)'#013#010+
+ '# -Or keep certain variables in registers (still BUGGY!!!)'#013#010+
+ '# -Ou enable uncertain optimizations (s','ee docs)'#013#010+
+ '# -O1 level 1 optimizations (quick optimizations)'#013#010+
+ '# -O2 level 2 optimizations (-O1 + slower optimizations)'#013#010+
+ '# -O3 level 3 optimizations (same as -O2u)'#013#010+
+ '# -Op target processor'#013#010+
+ '# -Op1 set target pr','ocessor to 386/486'#013#010+
+ '# -Op2 set target processor to Pentium/PentiumMMX (tm)'#013#010+
+ '# -Op3 set target processor to PPro/PII/c6x86/K6 (tm)'#013#010+
+ #013#010+
+ '# Optimize always for Size and PII'#013#010+
+ '#-OG2p3'#013#010+
+ #013#010+
+ #013#010+
+ '# -----------------------'#013#010+
+ '# Set Filenames and P','aths'#013#010+
+ '# -----------------------'#013#010+
+ #013#010+
+ '# Both slashes and backslashes are allowed in paths'#013#010+
+ #013#010+
+ '# path to the messagefile, not necessary anymore but can be used to ov'+
+ 'erride'#013#010+
+ '# the default language'#013#010+
+ '#-Fr%basepath%/msg/errore.msg'#013#010+
+ '#-Fr%basepath%/ms','g/errorn.msg'#013#010+
+ '#-Fr%basepath%/msg/errores.msg'#013#010+
+ '#-Fr%basepath%/msg/errord.msg'#013#010+
+ '#-Fr%basepath%/msg/errorr.msg'#013#010+
+ #013#010+
+ '# path to the gcclib'#013#010+
+ '#-Fl%basepath%/lib'#013#010+
+ #013#010+
+ '# searchpath for includefiles'#013#010+
+ '#-Fi/pp/inc;/pp/rtl/inc'#013#010+
+ #013#010+
+ '# searchpath for includefile','s'#013#010+
+ '# release them only if you know what you do'#013#010+
+ '# because this could cause a rebuild of the runtime library'#013#010+
+ '# if you tell them compiler/ide to build the project (FK)'#013#010+
+ '#-Fi%basepath%/source/rtl/inc;%basepath%/source/rtl/i386'#013#010+
+ #013#010+
+ '# searchpath',' for objectfiles'#013#010+
+ '#-Fo%basepath%/source/rtl/inc;%basepath%/source/rtl/i386'#013#010+
+ #013#010+
+ '# searchpath for units and other system dependent things'#013#010+
+ '-Fu%basepath%/units/$FPCTARGET/'#013#010+
+ '-Fu%basepath%/units/$FPCTARGET/*'#013#010+
+ '-Fu%basepath%/units/$FPCTARGET/rtl'#013#010+
+ #013,#010+
+ '# searchpath for libraries'#013#010+
+ '#-Fl%basepath%/lib'#013#010+
+ '#-Fl/lib;/usr/lib'#013#010+
+ #013#010+
+ '# searchpath for tools'#013#010+
+ '-FD%basepath%/bin/$FPCTARGET'#013#010+
+ #013#010+
+ #013#010+
+ '# -------------'#013#010+
+ '# Linking'#013#010+
+ '# -------------'#013#010+
+ #013#010+
+ '# generate always debugging information for GDB (slows down the c','omp'+
+ 'iling'#013#010+
+ '# process)'#013#010+
+ '# -gc generate checks for pointers'#013#010+
+ '# -gd use dbx'#013#010+
+ '# -gg use gsym'#013#010+
+ '# -gh use heap trace unit (for memory leak debugging)'#013#010+
+ '# -gl use line info unit to show mor','e info for backtrace'+
+ 's'#013#010+
+ '# -gv generates programs tracable with valgrind'#013#010+
+ '# -gw generate dwarf debugging info'#013#010+
+ '#'#013#010+
+ '# Enable debuginfo and use the line info unit by default'#013#010+
+ '#-gl'#013#010+
+ #013#010+
+ '# always pass an option to the linker'#013,#010+
+ '#-k-s'#013#010+
+ #013#010+
+ '# Always strip debuginfo from the executable'#013#010+
+ '-Xs'#013#010+
+ #013#010+
+ #013#010+
+ '# -------------'#013#010+
+ '# Miscellaneous'#013#010+
+ '# -------------'#013#010+
+ #013#010+
+ '# Write always a nice FPC logo ;)'#013#010+
+ '-l'#013#010+
+ #013#010+
+ '# Verbosity'#013#010+
+ '# e : Show errors (default) d : Show debug info'#013#010+
+ '# w',' : Show warnings u : Show unit info'#013#010+
+ '# n : Show notes t : Show tried/used files'#013#010+
+ '# h : Show hints m : Show defined macros'#013#010+
+ '# i : Show general info p : Show compiled pr','ocedures'#013+
+ #010+
+ '# l : Show linenumbers c : Show conditionals'#013#010+
+ '# a : Show everything 0 : Show nothing (except errors'+
+ ')'#013#010+
+ '# b : Show all procedure r : Rhide/GCC compatibility mod'+
+ 'e'#013#010+
+ '# declaration','s if an error x : Executable info (Win32 on'+
+ 'ly)'#013#010+
+ '# occurs'#013#010+
+ '#'#013#010+
+ '# Display Info, Warnings, Notes and Hints'#013#010+
+ '-viwn'#013#010+
+ '# If you don'#039't want so much verbosity use'#013#010+
+ '#-vw'#013#010
+);
diff --git a/compiler/utils/fpcmkcfg.pp b/compiler/utils/fpcmkcfg.pp
new file mode 100644
index 0000000000..802885b70d
--- /dev/null
+++ b/compiler/utils/fpcmkcfg.pp
@@ -0,0 +1,230 @@
+{$mode objfpc}
+{$H+}
+{
+ This file is part of Free Pascal Build tools
+ Copyright (c) 2005 by Michael Van Canneyt
+
+ Create a configuration file
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program fpcmkcfg;
+
+uses usubst,SysUtils,Classes;
+
+{
+ The fpccfg.inc file must be built from a template with the bin2obj
+ command. it needs options:
+ bin2obj -a -o fpccfg.inc -c DefaultConfig fpc.cft
+ where fpc.cft is the template file.
+}
+
+{$i fpccfg.inc}
+
+Const
+ BuildVersion={$I %FPCVERSION%};
+ BuildTarget={$I %FPCTARGET%};
+
+
+Resourcestring
+ SUsage00 = 'Usage: %s [options]';
+ SUsage10 = 'Where options is one or more of';
+ SUSage20 = ' -t filename Template file name. Default is built-in';
+ SUSage30 = ' -o filename Set output file. Default is standard output.';
+ SUsage40 = ' -d name=value define name=value pair.';
+ SUsage50 = ' -h show this help and exit.';
+ SUsage60 = ' -u name remove name from list of name/value pairs.';
+ SUsage70 = ' -l filename read name/value pairs from filename';
+ SUsage80 = ' -b show builtin template and exit.';
+ SUsage90 = ' -v be verbose.';
+ SErrUnknownOption = 'Error: Unknown option.';
+ SErrArgExpected = 'Error: Option "%s" requires an argument.';
+ SErrNoSuchFile = 'Error: File "%s" does not exist.';
+ SErrBackupFailed = 'Error: Backup of file "%s" to "%s" failed.';
+ SErrDelBackupFailed = 'Error: Delete of old backup file "%s" failed.';
+ SWarnIgnoringFile = 'Warning: Ignoring non-existent file: ';
+ SWarnIgnoringPair = 'Warning: ignoring wrong name/value pair: ';
+ SStats = 'Replaced %d placeholders in %d lines.';
+ SSubstInLine = 'Replaced %s placeholders in line %d.';
+
+
+Var
+ Verbose : Boolean;
+ SkipBackup : Boolean;
+ List,Cfg : TStringList;
+ TemplateFileName,
+ OutputFileName : String;
+
+
+
+
+procedure Init;
+
+begin
+ Verbose:=False;
+ List:=TStringList.Create;
+ AddToList(List,'FPCVERSION',BuildVersion);
+ AddToList(List,'FPCTARGET',BuildTarget);
+ AddToList(List,'PWD',GetCurrentDir);
+ AddToList(List,'BUILDDATE',DateToStr(Date));
+ AddToList(List,'BUILDTIME',TimeToStr(Time));
+ Cfg:=TStringList.Create;
+ Cfg.Text:=StrPas(Addr(DefaultConfig));
+end;
+
+Procedure Done;
+
+begin
+ FreeAndNil(List);
+ FreeAndNil(Cfg);
+end;
+
+Procedure Usage;
+
+begin
+ Writeln(Format(SUsage00,[ExtractFileName(Paramstr(0))]));
+ Writeln(SUsage10);
+ Writeln(SUsage20);
+ Writeln(SUsage30);
+ Writeln(SUsage40);
+ Writeln(SUsage50);
+ Writeln(SUsage60);
+ Writeln(SUsage70);
+ Writeln(SUsage80);
+ Writeln(SUsage90);
+ Halt(1);
+end;
+
+Procedure UnknownOption(Const S : String);
+
+begin
+ Writeln(SErrUnknownOption,S);
+ Usage;
+end;
+
+Procedure ShowBuiltIn;
+
+Var
+ I : Integer;
+
+
+begin
+ For I:=0 to Cfg.Count-1 do
+ Writeln(Cfg[I]);
+end;
+
+
+Procedure ProcessCommandline;
+
+Var
+ I : Integer;
+ S : String;
+
+ Function GetOptArg : String;
+
+ begin
+ If I=ParamCount then
+ begin
+ Writeln(StdErr,Format(SErrArgExpected,[S]));
+ Halt(1);
+ end;
+ inc(I);
+ Result:=ParamStr(I);
+ end;
+
+begin
+ I:=1;
+ While( I<=ParamCount) do
+ begin
+ S:=Paramstr(i);
+ If Length(S)<=1 then
+ UnknownOption(S)
+ else
+ case S[2] of
+ 'v' : Verbose:=True;
+ 'h' : Usage;
+ 'b' : begin
+ ShowBuiltin;
+ halt(0);
+ end;
+ 't' : TemplateFileName:=GetOptArg;
+ 'd' : AddPair(List,GetOptArg);
+ 'u' : AddPair(List,GetOptArg+'=');
+ 'o' : OutputFileName:=GetoptArg;
+ 's' : SkipBackup:=True;
+ else
+ UnknownOption(S);
+ end;
+ Inc(I);
+ end;
+ If (TemplateFileName<>'') then
+ begin
+ If Not FileExists(TemplateFileName) then
+ begin
+ Writeln(StdErr,Format(SErrNoSuchFile,[TemplateFileName]));
+ Halt(1);
+ end;
+ Cfg.LoadFromFile(TemplateFileName);
+ AddToList(List,'TEMPLATEFILE',TemplateFileName);
+ end
+ else
+ AddToList(List,'TEMPLATEFILE','builtin');
+end;
+
+
+Procedure CreateFile;
+
+Var
+ Fout : Text;
+ S,BFN : String;
+ I,RCount : INteger;
+
+begin
+ If (OutputFileName<>'')
+ and FileExists(OutputFileName)
+ and not SkipBackup then
+ begin
+ BFN:=ChangeFileExt(OutputFileName,'.bak');
+ If FileExists(BFN) and not DeleteFile(BFN) then
+ begin
+ Writeln(StdErr,Format(SErrDelBackupFailed,[BFN]));
+ Halt(1);
+ end;
+ If not RenameFile(OutputFileName,BFN) then
+ begin
+ Writeln(StdErr,Format(SErrBackupFailed,[OutputFileName,BFN]));
+ Halt(1);
+ end;
+ end;
+ Assign(Fout,OutputFileName);
+ Rewrite(FOut);
+ Try
+ RCount:=0;
+ For I:=0 to Cfg.Count-1 do
+ begin
+ S:=Cfg[i];
+ Inc(RCount,DoSubstitutions(List,S));
+ Writeln(FOut,S);
+ end;
+ If Verbose then
+ Writeln(StdErr,Format(SStats,[RCount,Cfg.Count]));
+ Finally
+ Close(Fout);
+ end;
+end;
+
+begin
+ Init;
+ Try
+ ProcessCommandLine;
+ CreateFile;
+ Finally
+ Done;
+ end;
+end.
diff --git a/compiler/utils/fpcsubst.pp b/compiler/utils/fpcsubst.pp
new file mode 100644
index 0000000000..cb82a162bf
--- /dev/null
+++ b/compiler/utils/fpcsubst.pp
@@ -0,0 +1,241 @@
+{$Mode objfpc}
+{$H+}
+program fpcsubst;
+
+uses SysUtils,Classes,Usubst;
+
+Const
+ BuildVersion={$I %FPCVERSION%};
+ BuildTarget={$I %FPCTARGET%};
+
+Resourcestring
+ SUsage00 = 'Usage: %s [options]';
+ SUsage10 = 'Where options is one or more of';
+ SUSage20 = ' -i filename Set input file. Default is standard input';
+ SUSage30 = ' -o filename Set output file. Default is standard output.';
+ SUsage40 = ' -d name=value define name=value pair.';
+ SUsage50 = ' -h show this help and exit.';
+ SUsage60 = ' -u name remove name from list of name/value pairs.';
+ SUsage70 = ' -l filename read name/value pairs from filename';
+ SUsage80 = ' -b show builtin list and exit.';
+ SUsage90 = ' -v be verbose.';
+ SErrUnknownOption = 'Error: Unknown option.';
+ SErrArgExpected = 'Error: Option "%s" requires an argument.';
+ SErrNoSuchFile = 'Error: File "%s" does not exist.';
+ SErrBackupFailed = 'Error: Backup of file "%s" to "%s" failed.';
+ SErrDelBackupFailed = 'Error: Delete of old backup file "%s" failed.';
+ SWarnIgnoringFile = 'Warning: Ignoring non-existent file: ';
+ SWarnIgnoringPair = 'Warning: ignoring wrong name/value pair: ';
+ SStats = 'Replaced %d placeholders in %d lines.';
+ SSubstInLine = 'Replaced %s placeholders in line %d.';
+
+
+Var
+ List : TStringList;
+ InputFileName : String;
+ OutputFileName : String;
+ Verbose : Boolean;
+ SkipBackup : Boolean;
+
+
+
+
+
+procedure Init;
+
+begin
+ Verbose:=False;
+ List:=TStringList.Create;
+ AddToList(List,'FPCVERSION',BuildVersion);
+ AddToList(List,'FPCTARGET',BuildTarget);
+ AddToList(List,'PWD',GetCurrentDir);
+ AddToList(List,'BUILDDATE',DateToStr(Date));
+ AddToList(List,'BUILDTIME',TimeToStr(Time));
+end;
+
+Procedure Done;
+
+begin
+ FreeAndNil(List);
+end;
+
+Procedure Usage;
+
+begin
+ Writeln(Format(SUsage00,[ExtractFileName(Paramstr(0))]));
+ Writeln(SUsage10);
+ Writeln(SUsage20);
+ Writeln(SUsage30);
+ Writeln(SUsage40);
+ Writeln(SUsage50);
+ Writeln(SUsage60);
+ Writeln(SUsage70);
+ Writeln(SUsage80);
+ Writeln(SUsage90);
+ Halt(1);
+end;
+
+Procedure ShowBuiltIns;
+
+var
+ I : Integer;
+
+begin
+ for I:=0 to List.Count-1 do
+ Writeln(List[i]);
+end;
+
+
+
+
+Procedure AddFromFile(FN : String);
+
+Var
+ F : Text;
+ S : String;
+
+begin
+ If Not FileExists(FN) then
+ begin
+ Writeln(StdErr,SWarnIgnoringFile,FN);
+ Exit;
+ end;
+ Assign(F,FN);
+ Reset(F);
+ Try
+ While not EOF(F) do
+ begin
+ ReadLn(F,S);
+ If (Length(S)>0) and (not (S[1] in ['#',';'])) then
+ If not AddPair(List,S) then
+ If Verbose then
+ Writeln(StdErr,SWarnIgnoringPair,S)
+ end;
+ finally
+ Close(F);
+ end;
+end;
+
+Procedure UnknownOption(Const S : String);
+
+begin
+ Writeln(SErrUnknownOption,S);
+ Usage;
+end;
+
+Procedure ProcessCommandline;
+
+Var
+ I : Integer;
+ S : String;
+
+ Function GetOptArg : String;
+
+ begin
+ If I=ParamCount then
+ begin
+ Writeln(StdErr,Format(SErrArgExpected,[S]));
+ Halt(1);
+ end;
+ inc(I);
+ Result:=ParamStr(I);
+ end;
+
+begin
+ I:=1;
+ While( I<=ParamCount) do
+ begin
+ S:=Paramstr(i);
+ If (Length(S)<=1) or (S[1]<>'-') then
+ UnknownOption(S)
+ else
+ case S[2] of
+ 'v' : Verbose:=True;
+ 'h' : Usage;
+ 'b' : begin
+ ShowBuiltins;
+ halt(0);
+ end;
+ 'l' : AddFromFile(GetOptArg);
+ 'd' : AddPair(List,GetOptArg);
+ 'u' : AddPair(List,GetOptArg+'=');
+ 'i' : InputFileName:=GetOptArg;
+ 'o' : OutputFileName:=GetoptArg;
+ 's' : SkipBackup:=True;
+ else
+ UnknownOption(S);
+ end;
+ Inc(I);
+ end;
+end;
+
+
+
+Procedure DoFile;
+
+Var
+ Fin,Fout : Text;
+ S,BFN : String;
+ N,LCount,RCount : Integer;
+
+
+begin
+ If (InputFileName<>'') and not FileExists(InputFIleName) then
+ begin
+ Writeln(StdErr,Format(SErrNoSuchFile,[InputFileName]));
+ Halt(1)
+ end;
+ If (OutputFileName<>'')
+ and FileExists(OutputFileName)
+ and not SkipBackup then
+ begin
+ BFN:=ChangeFileExt(OutputFileName,'.bak');
+ If FileExists(BFN) and not DeleteFile(BFN) then
+ begin
+ Writeln(StdErr,Format(SErrDelBackupFailed,[BFN]));
+ Halt(1);
+ end;
+ If not RenameFile(OutputFileName,BFN) then
+ begin
+ Writeln(StdErr,Format(SErrBackupFailed,[OutputFileName,BFN]));
+ Halt(1);
+ end;
+ end;
+ Assign(Fin,InputFileName);
+ Assign(Fout,OutputFileName);
+ Reset(Fin);
+ Try
+ Rewrite(FOut);
+ Try
+ LCount:=0;
+ RCount:=0;
+ While Not EOF(Fin) do
+ begin
+ Inc(LCount);
+ ReadLn(Fin,S);
+ N:=DoSubstitutions(List,S);
+ If Verbose and (N>0) then
+ Writeln(StdErr,Format(SSubstInLine,[N,LCount]));
+ Inc(RCount,N);
+ Writeln(Fout,S);
+ end;
+ If Verbose then
+ Writeln(StdErr,Format(SStats,[RCount,LCount]));
+ Finally
+ Close(Fout);
+ end;
+ Finally
+ Close(Fin);
+ end;
+
+end;
+
+begin
+ Init;
+ Try
+ ProcessCommandLine;
+ DoFile;
+ Finally
+ Done;
+ end;
+end.
diff --git a/compiler/utils/fpimpdef.pp b/compiler/utils/fpimpdef.pp
new file mode 100644
index 0000000000..323cb3be95
--- /dev/null
+++ b/compiler/utils/fpimpdef.pp
@@ -0,0 +1,98 @@
+{$APPTYPE CONSOLE}
+program FPimpdef;
+{$DEFINE STANDALONE}
+{$IFNDEF FPC}
+uses
+ dmisc,
+ ImpDef;
+{$ELSE}
+uses
+ DOS,
+ ImpDef;
+{$ENDIF}
+var
+binname:string;
+function Ofound(const short,full:string):longint;
+var
+ i:longint;
+begin
+ Ofound:=-1;
+ for i:=1 to ParamCount do
+ if(paramstr(i)=short)or(paramstr(i)=full)then
+ begin
+ Ofound:=i;
+ exit;
+ end;
+end;
+function GetOption(const short,full:string):string;
+var
+ i:longint;
+begin
+ i:=Ofound(short,full);
+ if i>0 then
+ GetOption:=paramstr(succ(i))
+ else
+ GetOption:='';
+end;
+procedure help_info;
+var
+ fn:string[255];
+ jj:cardinal;
+begin
+ fn:=paramstr(0);
+ for jj:=length(fn)downto 1 do
+ if fn[jj] in [':','\','/']then
+ begin
+ fn:=copy(fn,succ(jj),255);
+ break;
+ end;
+ writeln('Usage: ',fn,' [options]');
+ writeln('Options:');
+ writeln('-i | --input <file> - set input file;');
+ writeln('-o | --output <file> - set output .def file');
+ writeln('-l | --library <file> - set output static library');
+ writeln('-s | --assembler <name> - use <name> for assembler (default asw)');
+ writeln('-r | --archiver <name> - use <name> for archiver (default arw)');
+ writeln('-h | --help - show this screen');
+ halt;
+end;
+{$ifndef UNIX}
+procedure AddExt(var s:string);
+ var
+ s1:string;
+ i:longint;
+ begin
+ s1:=copy(s,length(s)-3,4);
+ for i:=1 to length(s1)do
+ s1[i]:=upcase(s1[i]);
+ if s1<>'.EXE'then
+ s:=s+'.EXE';
+ end;
+{$endif}
+var
+ EnvPath:string;
+begin
+binname:=GetOption('-i','--input');
+if(binname='')or(Ofound('-h','--help')>0)then
+ help_info;
+ as_name:=GetOption('-s','--assembler');
+ if as_name='' then
+ as_name:='as';
+ ar_name:=GetOption('-r','--archiver');
+ if ar_name='' then
+ ar_name:='ar';
+{$ifndef UNIX}
+ AddExt(as_name);
+ AddExt(ar_name);
+{$endif}
+ EnvPath:=GetEnv('Path');
+ if EnvPath='' then
+ EnvPath:=GetEnv('PATH');
+ as_name:=FSearch(as_name,EnvPath);
+ ar_name:=FSearch(ar_name,EnvPath);
+if not makedef(binname,GetOption('-o','--output'),GetOption('-l','--library'))then
+ begin
+ writeln('Export names not found');
+ halt(1);
+ end;
+end.
diff --git a/compiler/utils/fppkg.pp b/compiler/utils/fppkg.pp
new file mode 100644
index 0000000000..eed82ff964
--- /dev/null
+++ b/compiler/utils/fppkg.pp
@@ -0,0 +1,963 @@
+program fppkg;
+
+{$mode objfpc}{$H+}
+
+uses
+ Classes, SysUtils, TypInfo
+ { add your units here };
+
+Resourcestring
+ // SErrInValidArgument = 'Invalid command-line argument at position %d : %s';
+ SErrNeedArgument = 'Option at position %d (%s) needs an argument';
+ SErrMissingConfig = 'Missing configuration Makefile.fpc or fpmake.pp';
+ SErrRunning = 'The FPC make tool encountered the following error: %s';
+ SErrFailedToCompileFPCMake = 'Could not compile fpmake driver program';
+ SLogGeneratingFPMake = 'Generating fpmake.pp';
+ SLogCompilingFPMake = 'Compiling fpmake.pp: ';
+ SLogRunningFPMake = 'Running fpmake';
+
+Type
+
+ TRunMode = (rmHelp,rmCompile,rmBuild,rmInstall,rmArchive,rmClean,rmDownload);
+
+ { TMakeTool }
+
+ TMakeTool = Class(TObject)
+ Private
+ FConvertOnly,
+ FLogging : Boolean;
+ FCompiler : String;
+ FRunMode : TRunMode;
+ FHaveMakefile : Boolean;
+ FHaveFpmake : Boolean;
+ FFPMakeSrc : String;
+ FFPMakeBin : String;
+ Procedure Log(Msg : String);
+ Procedure Error(Msg : String);
+ Procedure Error(Fmt : String; Args : Array of const);
+ Function GetCompiler : String;
+ Public
+ Procedure ProcessCommandLine;
+ procedure CreateFPMake;
+ procedure CompileFPMake(Extra : Boolean);
+ Function RunFPMake : Integer;
+ Procedure Run;
+ end;
+
+ EMakeToolError = Class(Exception);
+
+
+ { TMakeFileConverter }
+ TSectionType = (stNone,stPackage,stTarget,stclean,stinstall,stCompiler,
+ stDefault,stRequire,stRules,stPrerules);
+
+ TMakeFileConverter = Class(TObject)
+ FSection : TSectionType;
+ FPackageName,
+ FpackageDir,
+ FPackageOptions,
+ FPackageDeps,
+ FBuilDUnit,
+ FSubName,
+ FPackageVersion : String;
+ // Reading;
+ procedure DoPackageLine(Const S : String);
+ Procedure DoTargetLine(Line : String; Var T,R,D : TStrings);
+ Procedure DoInstallLine(Line : String; Var IFL : TStrings);
+ procedure DoCleanLine(Line : String; Var CFL : TStrings);
+ procedure DoRequireLine(Line : String);
+ procedure DoCompilerLine(Line : String;Var SD : TStrings);
+ // Writing;
+ procedure WriteOSCPUCheck(Src: TStrings;OS,CPU : String);
+ procedure StartPackage(Src : TStrings; Dir,OS : String);
+ procedure EndPackage(Src : TStrings; Dir,OS : String);
+ procedure DoTargets(Src,T,R,SD : TStrings; Dir,Prefix : String);
+ procedure DoCleans(Src,CFL : TStrings);
+ procedure DoInstalls(Src,IFL : TStrings);
+ Procedure StartInstaller(Src : TStrings);
+ Procedure EndInstaller(Src : TStrings);
+ Function GetLine (L : TStrings; Var I : Integer) : String;
+ Public
+ procedure ConvertFile(const AFileName: String; Src: TStrings; Dir,OS : String);
+ Procedure ConvertFile(Const Source,Dest: String);
+ end;
+
+{ Auxiliary functions }
+
+Function GetWord(var S : String; Sep : Char) : String;
+
+Var
+ L : Integer;
+
+begin
+ L:=Pos(Sep,S);
+ If (L=0) then
+ L:=Length(S)+1;
+ Result:=Copy(S,1,L-1);
+ Delete(S,1,L);
+ S:=Trim(S);
+end;
+
+Function GetWord(var S : String) : String;
+
+begin
+ Result:=GetWord(S,' ');
+end;
+
+
+Function IsCPU (S: String) : Boolean;
+
+begin
+ Result:=Pos(lowercase(S)+',','i386,powerpc,arm,alpha,sparc,')<>0
+end;
+
+Function GetOSCPU(L : String; var OS,CPU : String) : String;
+
+ Procedure Add(Var A : String; ad : String);
+
+ begin
+ If (A<>'') then
+ A:=A+',';
+ A:=A+ad;
+ end;
+
+
+Var
+ S : String;
+
+begin
+ OS:='';
+ CPU:='';
+ S:=GetWord(L,',');
+ While (S<>'') do
+ begin
+ If (S<>'all') then
+ If IsCPU(S) then
+ Add(CPU,S)
+ else
+ Add(OS,S);
+ S:=GetWord(L,',');
+ end;
+end;
+
+
+{ TMakeFileConverter }
+
+procedure TMakeFileConverter.StartInstaller(Src: TStrings);
+
+begin
+ With Src do
+ begin
+ Add('{$mode objfpc}{$H+}');
+ Add('program fpmake;');
+
+ Add('');
+ Add(' { Generated automatically by '+ExtractFileName(Paramstr(0))+' on '+DateToStr(Sysutils.Date)+' }');
+ Add('');
+ Add('uses fpmkunit;');
+ Add('');
+ Add('Var');
+ Add(' T : TTarget;');
+ Add('');
+ Add('begin');
+ Add(' With Installer do ');
+ Add(' begin');
+ end;
+end;
+
+procedure TMakeFileConverter.EndInstaller(Src: TStrings);
+begin
+ With Src do
+ begin
+ Add(' Run;');
+ Add(' end;');
+ Add('end.');
+ Add('');
+ end;
+end;
+
+Function TMakeFileConverter.GetLine (L : TStrings; Var I : Integer) : String;
+
+Var
+ P : Integer;
+ OK : Boolean;
+
+begin
+ OK:=False;
+ Result:='';
+ Repeat
+ Result:=Result+L[i];
+ P:=Pos('#',Result);
+ If (P>0) then
+ Result:=Copy(Result,1,P-1);
+ Result:=Trim(Result);
+ P:=Length(Result);
+ If (P>0) and (Result[P]='\') then
+ Result:=Copy(Result,1,P-1)
+ else
+ OK:=(Result<>'');
+ if Not OK then
+ Inc(I);
+ Until OK or (I>L.Count-1);
+end;
+
+Function SplitNamevalue(Const S : String; Var AName,AValue : String) : boolean;
+
+var
+ L : Integer;
+
+begin
+ L:=Pos('=',S);
+ Result:=(L<>0);
+ If Result then
+ begin
+ AName:=LowerCase(trim(Copy(S,1,L-1)));
+ AValue:=S;
+ Delete(AValue,1,L);
+ AValue:=Trim(Avalue);
+ end
+ else
+ begin
+ AName:='';
+ AValue:='';
+ end;
+end;
+
+
+procedure TMakeFileConverter.StartPackage(Src : TStrings; Dir,OS : String);
+
+Var
+ S : String;
+
+begin
+ With Src do
+ begin
+ Add(' { ');
+ Add(' '+FPackageName);
+ Add(' } ');
+ Add(' StartPackage('''+FPackageName+''');');
+ If (Dir<>'') then
+ Add(' Directory:='''+ExcludeTrailingPathDelimiter(Dir)+''';');
+ If (OS<>'') and (OS<>'all') then
+ Add(' OS:=['+OS+'];');
+ If (FPackageVersion<>'') then
+ Add(' Version:='''+FPackageVersion+''';');
+ If (FPackageOptions<>'') then
+ Add(' Options:='''+FPackageOptions+''';');
+ If (FPackageDeps<>'') then
+ begin
+ S:=GetWord(FPackageDeps);
+ While S<>'' do
+ begin
+ Add(' Dependencies.Add('''+S+''');');
+ S:=GetWord(FPackageDeps);
+ end;
+ end;
+ end;
+end;
+
+procedure TMakeFileConverter.EndPackage(Src : TStrings; Dir,OS : String);
+
+begin
+ Src.add(' EndPackage;');
+ FPackageName:='';
+ FPackageVersion:='';
+ FPackageOptions:='';
+ FBuilDUnit:='';
+ FPackageDeps:='';
+end;
+
+
+procedure TMakeFileConverter.DoPackageLine(Const S : String);
+
+Var V,N : String;
+
+begin
+ SplitNameValue(S,N,V);
+ If (N='name') then
+ FPackageName:=V
+ else If (N='version') then
+ FPackageVersion:=V
+ else If (N='main') then
+ begin
+ FPackageName:='sub';
+ FSubName:=V;
+ end
+ else
+ Writeln(StdErr,'Unknown name/value pair in package section :',N);
+end;
+
+
+{
+ Convert various entries of type
+ XXYY_OSN=words
+ to entries of type
+ prefix_word=OS1,OS2,OS3
+ OS is never empty, 'all' is default.
+ }
+Procedure AddStrings(Var L : TStrings; Values,Prefix,OS : String) ;
+
+Var
+ S,O : String;
+ i : integer;
+
+begin
+ If (L=Nil) then
+ L:=TstringList.Create;
+ If prefix<>'' then
+ prefix:=prefix+'_';
+ S:=GetWord(Values);
+ While (S<>'') do
+ begin
+ S:=Prefix+S;
+ I:=L.IndexOfName(S);
+ If (I<>-1) then
+ begin
+ O:=L.Values[S];
+ If (O='all') then
+ O:='';
+ If (O<>'') then
+ O:=O+',';
+ O:=O+OS;
+ L.Values[S]:=O;
+ end
+ else
+ L.Add(S+'='+OS);
+ S:=GetWord(Values);
+ end;
+end;
+
+
+procedure TMakeFileConverter.DoTargetLine(Line : String; Var T,R,D : TStrings);
+
+Var
+ V,N,OS : String;
+ P : Integer;
+
+begin
+ SplitNameValue(Line,N,V);
+ P:=Pos('_',N);
+ If (P=0) then
+ OS:='all'
+ else
+ begin
+ OS:=N;
+ Delete(OS,1,P);
+ N:=Copy(N,1,P-1);
+ end;
+ If (N='dirs') then
+ AddStrings(D,V,'',OS)
+ else If (N='units') then
+ AddStrings(T,V,'unit',OS)
+ else If (N='implicitunits') then
+ AddStrings(T,V,'unit',OS)
+ else If (N='programs') then
+ AddStrings(T,V,'program',OS)
+ else If (N='examples') then
+ AddStrings(T,V,'exampleunit',OS)
+ else If (N='rsts') then
+ AddStrings(R,V,'',OS)
+ else
+ Writeln(StdErr,'Unknown name/value pair in target section : ',Line);
+end;
+
+procedure TMakeFileConverter.DoInstallLine(Line : String; Var IFL : TStrings);
+
+Var
+ S,V,N,OS : String;
+ P : Integer;
+
+begin
+ SplitNameValue(Line,N,V);
+ P:=Pos('_',N);
+ If (P=0) then
+ OS:='all'
+ else
+ begin
+ OS:=N;
+ Delete(OS,1,P);
+ N:=Copy(N,1,P-1);
+ end;
+ If (N='fpcpackage') then
+ P:=0 // temporary, needs fixing.
+ else If (N='buildunit') then
+ FBuildUnit:=V // temporary, needs fixing.
+ else If (N='units') then
+ begin
+ S:=GetWord(V);
+ While (S<>'') do
+ begin
+ AddStrings(IFL,S+'.o','',OS);
+ AddStrings(IFL,S+'.ppu','',OS);
+ S:=GetWord(V);
+ end;
+ end
+ else
+ Writeln(StdErr,'Unknown name/value pair in install section : ',N);
+end;
+
+procedure TMakeFileConverter.DoCleanLine(Line : String; Var CFL : TStrings);
+
+Var
+ V,N,S,OS : String;
+ P : Integer;
+
+begin
+ SplitNameValue(Line,N,V);
+ P:=Pos('_',N);
+ If (P=0) then
+ OS:='all'
+ else
+ begin
+ OS:=N;
+ Delete(OS,1,P);
+ N:=Copy(N,1,P-1);
+ end;
+ If (N='fpcpackage') then
+ P:=0 // temporary, needs fixing.
+ else If (N='units') then
+ begin
+ S:=GetWord(V);
+ While (S<>'') do
+ begin
+ AddStrings(CFL,S+'.o','',OS);
+ AddStrings(CFL,S+'.ppu','',OS);
+ S:=GetWord(V);
+ end;
+ end
+ else
+ Writeln(StdErr,'Unknown name/value pair in clean section : ',N);
+end;
+
+procedure TMakeFileConverter.DoRequireLine(Line : String);
+
+Var
+ V,N,OS : String;
+ P : Integer;
+
+begin
+ SplitNameValue(Line,N,V);
+ P:=Pos('_',N);
+ If (P=0) then
+ OS:='all'
+ else
+ begin
+ OS:=N;
+ Delete(OS,1,P);
+ N:=Copy(N,1,P-1);
+ end;
+ if (N='packages') then
+ FPackageDeps:=V
+ else If (N='libc') and (Upcase(V)='Y') then
+ P:=0 // Set options ?
+ else
+ Writeln(StdErr,'Unknown name/value pair in require section : ',N);
+end;
+
+
+procedure TMakeFileConverter.DoCompilerLine(Line : String;Var SD : TStrings);
+
+Var
+ V,N,OS : String;
+ P : Integer;
+
+begin
+ SplitNameValue(Line,N,V);
+ P:=Pos('_',N);
+ If (P=0) then
+ OS:='all'
+ else
+ begin
+ OS:=N;
+ Delete(OS,1,P);
+ N:=Copy(N,1,P-1);
+ end;
+ If (N='includedir') then
+ FPackageOptions:=Trim(FPackageOptions+' -Fi'+V)
+ else If (N='options') then
+ FPackageOptions:=Trim(FPackageOptions+' '+V)
+ else If (N='targetdir') then
+ P:=0 // Ignore
+ else if (N='sourcedir') or (N='unitdir') then
+ begin
+ If (SD=Nil) then
+ SD:=TStringList.Create;
+ SD.Add(OS+'='+V);
+ end
+ else
+ Writeln(StdErr,'Unknown name/value pair in compiler section : ',N);
+end;
+
+Function SearchInDirs(Prefix,AName, Dirs : String) : string;
+
+Var
+ D,S : String;
+
+begin
+ S:=GetWord(Dirs);
+ Result:='';
+ While (Result='') and (S<>'') do
+ begin
+ D:=Prefix+S+PathDelim;
+ If FileExists(D+AName+'.pp') or FileExists(D+AName+'.pas') then
+ Result:=S;
+ S:=GetWord(Dirs);
+ end;
+end;
+
+procedure TMakeFileConverter.DoTargets(Src,T,R,SD : TStrings; Dir,Prefix : String);
+
+Var
+ I,J,P : Integer;
+ Pre,N,V,D,DOS,OS,CPU : String;
+ Res : Boolean;
+
+begin
+ If (Dir<>'') then
+ Dir:=IncludeTrailingPathDelimiter(Dir);
+ If (Prefix<>'') then
+ Prefix:=IncludeTrailingPathDelimiter(Prefix);
+ Dir:=Prefix+Dir;
+ Res:=False;
+ If Assigned(T) then
+ For I:=0 to T.Count-1 do
+ begin
+ T.GetNamevalue(I,N,V);
+ P:=Pos('_',N);
+ If (P<>0) then
+ begin
+ Pre:=Copy(N,1,P-1);
+ Delete(N,1,P);
+ end;
+ If Assigned(R) then
+ Res:=R.IndexOfName(N)<>-1;
+ GetOSCPU(V,OS,CPU);
+ Pre[1]:=Upcase(Pre[1]);
+ Src.Add(' T:=Targets.Add'+Pre+'('''+Prefix+N+''');');
+ If (CPU<>'') then
+ Src.Add(' T.CPU:=['+CPU+'];');
+ If (OS<>'') then
+ Src.Add(' T.OS:=['+OS+'];');
+ If res then
+ Src.add(' T.ResourceStrings:=True;');
+ If (CompareText(FBuildUnit,N)=0) then
+ Src.add(' T.Install:=False;');
+ if Assigned(SD) then
+ for J:=0 to SD.Count-1 do
+ begin
+ SD.GetNameValue(J,DOS,D);
+ If (DOS<>'all') then
+ Src.Add(' if (Defaults.OS='+DOS+') then');
+ Src.add(' T.Directory:='''+SearchInDirs(Dir,N,D)+''';');
+ end;
+ end;
+end;
+
+procedure TMakeFileConverter.WriteOSCPUCheck(Src: TStrings;OS,CPU : String);
+
+Var
+ S : String;
+
+begin
+ If (CPU<>'') then
+ S:='(Defaults.CPU='+CPU+')';
+ If (OS<>'') then
+ begin
+ IF (S<>'') then
+ S:=S+' OR ';
+ S:=S+'(Defaults.OS='+CPU+')';
+ end;
+ If (S<>'') then
+ Src.Add(' If '+S+' then');
+end;
+
+procedure TMakeFileConverter.DoInstalls(Src,IFL : TStrings);
+
+Var
+ I,J,P : Integer;
+ Pre,N,V,D,DOS,OS,CPU : String;
+
+begin
+ If Assigned(IFL) then
+ For I:=0 to IFL.Count-1 do
+ begin
+ IFL.GetNamevalue(I,N,V);
+ GetOSCPU(V,OS,CPU);
+ WriteOSCPUCheck(Src,OS,CPU);
+ Src.add(' InstallFiles.Add('''+N+''');');
+ end;
+end;
+
+procedure TMakeFileConverter.DoCleans(Src,CFL : TStrings);
+
+Var
+ I,J,P : Integer;
+ N,V,DOS,OS,CPU : String;
+
+
+begin
+ If Assigned(CFL) then
+ For I:=0 to CFL.Count-1 do
+ begin
+ CFL.GetNamevalue(I,N,V);
+ GetOSCPU(V,OS,CPU);
+ WriteOSCPUCheck(Src,OS,CPU);
+ Src.add(' CleanFiles.Add('''+N+''');');
+ end;
+end;
+
+
+
+procedure TMakeFileConverter.ConvertFile(const AFileName: String; Src: TStrings; Dir,OS : String);
+
+ Function IsSection(var S : String) : Boolean;
+
+ Var
+ L : Integer;
+
+ begin
+ L:=Length(S);
+ Result:=(L>0) and (S[1]='[') and (S[L]=']');
+ If Result then
+ S:=trim(Copy(S,2,L-2));
+ end;
+
+Var
+ R,L,T,D,S,SD,IFL,CFL : TStrings;
+ I,J : Integer;
+ Prefix,Line,DN : String;
+ B : Boolean;
+
+begin
+ Writeln('Converting '+AFileName);
+ T:=Nil;
+ D:=Nil;
+ S:=Nil;
+ SD:=Nil;
+ R:=Nil;
+ IFL:=Nil;
+ CFL:=Nil;
+ FPackageOptions:='';
+ FPackageDir:='';
+ L:=TStringList.Create;
+ try
+ L.LoadFromFile(AFileName);
+ I:=0;
+ While (I<L.Count) do
+ begin
+ Line:=GetLine(L,I);
+ If IsSection(Line) then
+ begin
+ J:=GetEnumValue(TypeInfo(TSectionType),'st'+Line);
+ If (J=-1) then
+ begin
+ FSection:=stNone;
+ Writeln(stdErr,'Unsupported section: ',Line);
+ end
+ else
+ FSection:=TSectiontype(J);
+ end
+ else
+ case FSection of
+ stPackage : DoPackageLine(Line);
+ stTarget : DoTargetLine(Line,T,R,D);
+ stInstall : DoInstallLine(Line,IFL);
+ stClean : DoCleanLine(Line,CFL);
+ stCompiler : DoCompilerLine(Line,SD);
+ strequire : DoRequireLine(Line);
+ end;
+ inc(I);
+ end;
+ // If there are only 'dir' entries, then there is no package name.
+ B:=False;
+ if (FPackageName<>'') then
+ begin
+ Prefix:='';
+ B:=FPackageName<>'sub';
+ If B then
+ StartPackage(Src,Dir,OS)
+ else
+ Prefix:=Dir;
+ DoTargets(Src,T,R,SD,Dir,Prefix);
+ DoInstalls(Src,IFL);
+ DoCleans(Src,CFL);
+ end;
+ If Assigned(D) then
+ begin
+ If (Dir<>'') then
+ Dir:=IncludeTrailingPathDelimiter(Dir);
+ For I:=0 to D.Count-1 do
+ begin
+ D.GetNameValue(I,DN,Line);
+ If (Line<>'all') and (Line<>'') then
+ OS:=Line;
+ DN:=Dir+DN+PathDelim;
+ If FileExists(DN+'Makefile.fpc') then
+ ConvertFile(DN+'Makefile.fpc',Src,DN,OS);
+ end;
+ end;
+ If B then
+ EndPackage(Src,Dir,OS);
+ Finally
+ S.Free;
+ IFL.Free;
+ CFL.Free;
+ D.Free;
+ SD.Free;
+ T.Free;
+ L.Free;
+ end;
+end;
+
+procedure TMakeFileConverter.ConvertFile(const Source, Dest: String);
+
+Var
+ L : TStrings;
+
+begin
+ L:=TStringList.Create;
+ Try
+ StartInstaller(L);
+ ConvertFile(Source,L,'','');
+ EndInstaller(L);
+ L.SaveToFile(Dest);
+ Finally
+ L.Free;
+ end;
+end;
+
+{ TMakeTool }
+
+procedure TMakeTool.CompileFPMake(Extra: Boolean);
+
+Var
+ O,C : String;
+
+begin
+ C:=GetCompiler;
+ O:=FFPmakeSrc;
+ If Extra then
+ O:='-Fafpmkext '+O;
+ Log(SLogCompilingFPMake+C+' '+O);
+ If ExecuteProcess(C,O)<>0 then
+ Error(SErrFailedToCompileFPCMake)
+end;
+
+procedure TMakeTool.CreateFPMake;
+begin
+ Log(SLogGeneratingFPMake);
+ With TMakeFileConverter.Create do
+ try
+ ConvertFile('Makefile.fpc','fpmake.pp');
+ finally
+ Free;
+ end;
+end;
+
+
+Function TMakeTool.RunFPMake : Integer;
+
+ Function MaybeQuote(Const S : String) : String;
+
+ begin
+ If Pos(' ',S)=0 then
+ Result:=S
+ else
+ Result:='"'+S+'"';
+ end;
+
+
+Var
+ I : integer;
+ D,O : String;
+
+begin
+ Log(SLogRunningFPMake);
+ D:=IncludeTrailingPathDelimiter(GetCurrentDir);
+ O:='';
+ For I:=1 to ParamCount do
+ begin
+ If (O<>'') then
+ O:=O+' ';
+ O:=O+MaybeQuote(ParamStr(I));
+ end;
+ Result:=ExecuteProcess(D+FFPMakeBin,O);
+end;
+
+procedure TMakeTool.Log(Msg: String);
+begin
+ If FLogging then
+ Writeln(stdErr,Msg);
+end;
+
+procedure TMakeTool.Error(Msg: String);
+begin
+ Raise EMakeToolError.Create(Msg);
+end;
+
+procedure TMakeTool.Error(Fmt: String; Args: array of const);
+begin
+ Raise EMakeToolError.CreateFmt(Fmt,Args);
+end;
+
+function TMakeTool.GetCompiler: String;
+begin
+ If (FCompiler='') then
+ begin
+ {$if defined(cpui386)}
+ FCompiler:='ppc386';
+ {$elseif defined(cpuAlpha)}
+ FCompiler:='ppcaxp';
+ {$elseif defined(cpusparc)}
+ FCompiler:='ppcsparc';
+ {$elseif defined(cpuarm)}
+ FCompiler:='ppcarm';
+ {$elseif defined(cpum68k)}
+ FCompiler:='ppcm68k';
+ {$elseif defined(cpux86_64)}
+ FCompiler:='ppcx64';
+ {$elseif defined(cpupowerpc)}
+ FCompiler:='ppcppc';
+ {$else}
+ {$Fatal Unknown architecture}
+ {$endif}
+ end;
+ If (ExtractFilePath(FCompiler)<>'') then
+ Result:=FCompiler
+ else
+ begin
+ Result:=FileSearch(FCompiler,GetEnvironmentVariable('PATH'));
+ If (Result='') then
+ Result:=FCompiler;
+ end;
+end;
+
+
+procedure TMakeTool.ProcessCommandLine;
+
+ Function CheckOption(Index : Integer;Short,Long : String): Boolean;
+
+ var
+ O : String;
+
+ begin
+ O:=Paramstr(Index);
+ Result:=(O='-'+short) or (O='--'+long) or (copy(O,1,Length(Long)+3)=('--'+long+'='));
+ end;
+
+ Function OptionArg(Var Index : Integer) : String;
+
+ Var
+ P : Integer;
+
+ begin
+ if (Length(ParamStr(Index))>1) and (Paramstr(Index)[2]<>'-') then
+ begin
+ If Index<ParamCount then
+ begin
+ Inc(Index);
+ Result:=Paramstr(Index);
+ end
+ else
+ Error(SErrNeedArgument,[Index,ParamStr(Index)]);
+ end
+ else If length(ParamStr(Index))>2 then
+ begin
+ P:=Pos('=',Paramstr(Index));
+ If (P=0) then
+ Error(SErrNeedArgument,[Index,ParamStr(Index)])
+ else
+ begin
+ Result:=Paramstr(Index);
+ Delete(Result,1,P);
+ end;
+ end;
+ end;
+
+Var
+ I : Integer;
+
+begin
+ I:=0;
+ FLogging:=False;
+ FRunMode:=rmhelp;
+ FConvertOnly:=False;
+ While (I<ParamCount) do
+ begin
+ Inc(I);
+ if Checkoption(I,'n','convert') then
+ FConvertOnly:=True
+ else if Checkoption(I,'m','compile') then
+ FRunMode:=rmCompile
+ else if Checkoption(I,'b','build') then
+ FRunMode:=rmBuild
+ else if CheckOption(I,'i','install') then
+ FRunMode:=rmInstall
+ else if CheckOption(I,'c','clean') then
+ FRunMode:=rmClean
+ else if CheckOption(I,'a','archive') then
+ FRunMode:=rmarchive
+ else if CheckOption(I,'d','download') then
+ FRunMode:=rmDownload
+ else if CheckOption(I,'h','help') then
+ FRunMode:=rmhelp
+ // Check.
+ else if CheckOption(I,'r','compiler') then
+ FCompiler:=OptionArg(I)
+ else if CheckOption(I,'v','verbose') then
+ Flogging:=Pos('info',Lowercase(OptionArg(I)))<>0;
+ end;
+end;
+
+
+procedure TMakeTool.Run;
+
+
+begin
+ Try
+ ProcessCommandLine;
+ If FConvertOnly then
+ CreateFPMake
+ else
+ begin
+ FHaveMakefile:=FileExists('Makefile.fpc');
+ FFPMakeSrc:='fpmake.pp';
+ FHaveFpmake:=FileExists(FFPMakeSrc);
+ If Not FHaveFPMake then
+ begin
+ FHaveFPMake:=FileExists('fpmake.pas');
+ If FHaveFPMake then
+ FFPMakeSrc:='fpmake.pas';
+ end;
+ if Not (FHaveFPMake or FHaveMakeFile) then
+ Error(SErrMissingConfig);
+ If (Not FHaveFPMake) or (FileAge(FFPMakeSrc)<FileAge('Makefile.fpc')) then
+ CreateFPMake;
+ {$ifndef unix}
+ FFPMakeBin:='fpmake.exe';
+ {$else}
+ FFPMakeBin:='fpmake';
+ {$endif}
+ if FileAge(FFPMakeBin)<FileAge(FFPMakeSrc) then
+ CompileFPMake(FRunMode in [rmArchive,rmDownload]);
+ Halt(RunFPMake);
+ end;
+ except
+ On E : Exception do
+ begin
+ Writeln(StdErr,Format(SErrRunning,[E.Message]));
+ Halt(1);
+ end;
+ end;
+end;
+
+
+begin
+ With TMakeTool.Create do
+ try
+ run;
+ finally
+ Free;
+ end;
+end.
+
diff --git a/compiler/utils/gppc386.pp b/compiler/utils/gppc386.pp
new file mode 100644
index 0000000000..d2d1b45384
--- /dev/null
+++ b/compiler/utils/gppc386.pp
@@ -0,0 +1,138 @@
+{
+ Copyright (c) 2000-2002 by Pierre Muller
+
+ This program allows to run the Makefiles
+ with the compiler running inside GDB
+
+ GDB only stops if there is something special
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************}
+
+program fpc_with_gdb;
+
+{
+ This program uses several files :
+
+ -- 'gdb4fpc.ini' contains the standard breakpoints (see below)
+
+ -- 'gdb.fpc' is an optional file that can contain any other
+ instruction that GDB should do before starting.
+ Note that if gdb.fpc is present, no "run" command is
+ inserted if gdb4fpc.ini is found
+ but it can be inserted in gdb.fpc itself
+}
+
+uses
+ dos;
+
+const
+{$ifdef Unix}
+ GDBExeName = 'gdbpas';
+ GDBIniName = '.gdbinit';
+ DefaultCompilerName = 'ppc386';
+{$else}
+ GDBExeName = 'gdbpas.exe';
+ GDBIniName = 'gdb.ini';
+ DefaultCompilerName = 'ppc386.exe';
+{$endif not linux}
+
+ { If you add a gdb.fpc file in a given directory }
+ { GDB will read it; this allows you to add }
+ { special tests in specific directories PM }
+ FpcGDBIniName = 'gdb.fpc';
+ GDBIniTempName = 'gdb4fpc.ini';
+
+var
+ fpcgdbini : text;
+ CompilerName,Dir,Name,Ext : String;
+ GDBError,GDBExitCode,i : longint;
+
+begin
+
+ fsplit(paramstr(0),Dir,Name,Ext);
+ if (length(Name)>3) and (UpCase(Name[1])='G') then
+ CompilerName:=Copy(Name,2,255)+Ext
+ else
+ CompilerName:=DefaultCompilerName;
+
+ { support for info functions directly : used in makefiles }
+ if (paramcount=1) and (pos('-i',Paramstr(1))=1) then
+ begin
+ Exec(fsearch(CompilerName,GetEnv('PATH')),Paramstr(1));
+ exit;
+ end;
+
+ if fsearch(GDBIniTempName,'./')<>'' then
+ begin
+ Assign(fpcgdbini,GDBIniTempName);
+ erase(fpcgdbini);
+ end;
+ Assign(fpcgdbini,GdbIniTempName);
+ Rewrite(fpcgdbini);
+
+ Writeln(fpcgdbini,'set language pascal');
+ Writeln(fpcgdbini,'b SYSTEM_EXIT');
+ Writeln(fpcgdbini,'cond 1 EXITCODE <> 0');
+ Writeln(fpcgdbini,'b INTERNALERROR');
+ Writeln(fpcgdbini,'b HANDLEERRORADDRFRAME');
+ Writeln(fpcgdbini,'set $_exitcode := -1');
+ Write(fpcgdbini,'set args');
+
+ { this will not work correctly if there are " or '' inside the command line :( }
+ for i:=1 to Paramcount do
+ begin
+ if pos(' ',Paramstr(i))>0 then
+ Write(fpcgdbini,' "'+ParamStr(i)+'"')
+ else
+ Write(fpcgdbini,' '+ParamStr(i));
+ end;
+ Writeln(fpcgdbini);
+ if fsearch(FpcGDBIniName,'./')<>'' then
+ begin
+ Writeln(fpcgdbini,'source '+FpcGDBIniName);
+ end
+ else
+ Writeln(fpcgdbini,'run');
+ Writeln(fpcgdbini,'if ($_exitcode = -1)');
+ Writeln(fpcgdbini,' echo Program not completed');
+ Writeln(fpcgdbini,'else');
+ Writeln(fpcgdbini,' quit');
+ Writeln(fpcgdbini,'end');
+ Close(fpcgdbini);
+
+ Exec(fsearch(GDBExeName,GetEnv('PATH')),
+{$ifdef win32}
+ '--nw '+
+{$endif win32}
+ '--nx --quiet --command='+GDBIniTempName+' '+CompilerName);
+ GDBError:=DosError;
+ GDBExitCode:=DosExitCode;
+ if (GDBError<>0) or (GDBExitCode<>0) then
+ begin
+ Writeln('Error running GDB');
+ if (GDBError<>0) then
+ Writeln('DosError = ',GDBError);
+ if (GDBExitCode<>0) then
+ Writeln('DosExitCode = ',GDBExitCode);
+ if GDBExitCode<>0 then
+ RunError(GDBExitCode)
+ else
+ RunError(GDBError);
+ end
+ else
+ Erase(fpcgdbini);
+end.
diff --git a/compiler/utils/mk68kreg.pp b/compiler/utils/mk68kreg.pp
new file mode 100644
index 0000000000..fd7eb76aa8
--- /dev/null
+++ b/compiler/utils/mk68kreg.pp
@@ -0,0 +1,334 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl
+
+ Convert spreg.dat to several .inc files for usage with
+ the Free pascal compiler
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program mkspreg;
+
+const Version = '1.00';
+ max_regcount = 200;
+
+var s : string;
+ i : longint;
+ line : longint;
+ regcount:byte;
+ regcount_bsstart:byte;
+ names,
+ regtypes,
+ supregs,
+ numbers,
+ stdnames,
+ gasnames,
+ stabs : array[0..max_regcount-1] of string[63];
+ regnumber_index,
+ std_regname_index,gas_regname_index : array[0..max_regcount-1] of byte;
+
+{$ifndef FPC}
+ procedure readln(var t:text;var s:string);
+ var
+ c : char;
+ i : longint;
+ begin
+ c:=#0;
+ i:=0;
+ while (not eof(t)) and (c<>#10) do
+ begin
+ read(t,c);
+ if c<>#10 then
+ begin
+ inc(i);
+ s[i]:=c;
+ end;
+ end;
+ if (i>0) and (s[i]=#13) then
+ dec(i);
+ s[0]:=chr(i);
+ end;
+{$endif}
+
+function tostr(l : longint) : string;
+
+begin
+ str(l,tostr);
+end;
+
+function readstr : string;
+
+ var
+ result : string;
+
+ begin
+ result:='';
+ while (s[i]<>',') and (i<=length(s)) do
+ begin
+ result:=result+s[i];
+ inc(i);
+ end;
+ readstr:=result;
+ end;
+
+
+procedure readcomma;
+ begin
+ if s[i]<>',' then
+ begin
+ writeln('Missing "," at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ inc(i);
+ end;
+
+
+procedure skipspace;
+
+ begin
+ while (s[i] in [' ',#9]) do
+ inc(i);
+ end;
+
+procedure openinc(var f:text;const fn:string);
+begin
+ writeln('creating ',fn);
+ assign(f,fn);
+ rewrite(f);
+ writeln(f,'{ don''t edit, this file is generated from m68kreg.dat }');
+end;
+
+
+procedure closeinc(var f:text);
+begin
+ writeln(f);
+ close(f);
+end;
+
+procedure build_regnum_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ regnumber_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if numbers[regnumber_index[j]]>=numbers[regnumber_index[i]] then
+ break;
+ t:=regnumber_index[i];
+ regnumber_index[i]:=regnumber_index[j];
+ regnumber_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure build_std_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ std_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if stdnames[std_regname_index[j]]>=stdnames[std_regname_index[i]] then
+ break;
+ t:=std_regname_index[i];
+ std_regname_index[i]:=std_regname_index[j];
+ std_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure build_gas_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ gas_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if gasnames[gas_regname_index[j]]>=gasnames[gas_regname_index[i]] then
+ break;
+ t:=gas_regname_index[i];
+ gas_regname_index[i]:=gas_regname_index[j];
+ gas_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure read_spreg_file;
+
+var infile:text;
+
+begin
+ { open dat file }
+ assign(infile,'m68kreg.dat');
+ reset(infile);
+ while not(eof(infile)) do
+ begin
+ { handle comment }
+ readln(infile,s);
+ inc(line);
+ while (s[1]=' ') do
+ delete(s,1,1);
+ if (s='') or (s[1]=';') then
+ continue;
+
+ i:=1;
+ names[regcount]:=readstr;
+ readcomma;
+ regtypes[regcount]:=readstr;
+ readcomma;
+ supregs[regcount]:=readstr;
+ readcomma;
+ stdnames[regcount]:=readstr;
+ readcomma;
+ gasnames[regcount]:=readstr;
+ readcomma;
+ stabs[regcount]:=readstr;
+ { Create register number }
+ if supregs[regcount][1]<>'$' then
+ begin
+ writeln('Missing $ before number, at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ numbers[regcount]:=regtypes[regcount]+'0000'+copy(supregs[regcount],2,255);
+ if i<length(s) then
+ begin
+ writeln('Extra chars at end of line, at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ inc(regcount);
+ if regcount>max_regcount then
+ begin
+ writeln('Error: Too much registers, please increase maxregcount in source');
+ halt(2);
+ end;
+ end;
+ close(infile);
+end;
+
+procedure write_inc_files;
+
+var
+ norfile,stdfile,gasfile,supfile,
+ numfile,stabfile,confile,
+ rnifile,srifile,grifile:text;
+ first:boolean;
+
+begin
+ { create inc files }
+ openinc(confile,'r68kcon.inc');
+ openinc(supfile,'r68ksup.inc');
+ openinc(numfile,'r68knum.inc');
+ openinc(stdfile,'r68kstd.inc');
+ openinc(gasfile,'r68kgas.inc');
+ openinc(stabfile,'r68ksta.inc');
+ openinc(norfile,'r68knor.inc');
+ openinc(rnifile,'r68krni.inc');
+ openinc(srifile,'r68ksri.inc');
+ openinc(grifile,'r68kgri.inc');
+ first:=true;
+ for i:=0 to regcount-1 do
+ begin
+ if not first then
+ begin
+ writeln(numfile,',');
+ writeln(stdfile,',');
+ writeln(gasfile,',');
+ writeln(stabfile,',');
+ writeln(rnifile,',');
+ writeln(srifile,',');
+ writeln(grifile,',');
+ end
+ else
+ first:=false;
+ writeln(supfile,'RS_',names[i],' = ',supregs[i],';');
+ writeln(confile,'NR_'+names[i],' = ','tregister(',numbers[i],')',';');
+ write(numfile,'tregister(',numbers[i],')');
+ write(stdfile,'''',stdnames[i],'''');
+ write(gasfile,'''',gasnames[i],'''');
+ write(stabfile,stabs[i]);
+ write(rnifile,regnumber_index[i]);
+ write(srifile,std_regname_index[i]);
+ write(grifile,gas_regname_index[i]);
+ end;
+ write(norfile,regcount);
+ close(confile);
+ close(supfile);
+ closeinc(numfile);
+ closeinc(stdfile);
+ closeinc(gasfile);
+ closeinc(stabfile);
+ closeinc(norfile);
+ closeinc(rnifile);
+ closeinc(srifile);
+ closeinc(grifile);
+ writeln('Done!');
+ writeln(regcount,' registers procesed');
+end;
+
+
+begin
+ writeln('Register Table Converter Version ',Version);
+ line:=0;
+ regcount:=0;
+ read_spreg_file;
+ regcount_bsstart:=1;
+ while 2*regcount_bsstart<regcount do
+ regcount_bsstart:=regcount_bsstart*2;
+ build_regnum_index;
+ build_std_regname_index;
+ build_gas_regname_index;
+ write_inc_files;
+end.
diff --git a/compiler/utils/mkarmins.pp b/compiler/utils/mkarmins.pp
new file mode 100644
index 0000000000..bfce0f2e5e
--- /dev/null
+++ b/compiler/utils/mkarmins.pp
@@ -0,0 +1,432 @@
+{
+ Copyright (c) 1998-2005 by Peter Vreman and Florian Klaempfl
+
+ Convert i386ins.dat from Nasm to a .inc file for usage with
+ the Free pascal compiler
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program mkarmins;
+
+const
+ Version = '0.9';
+
+var
+ s : string;
+ i : longint;
+ x86_64 : boolean;
+
+{$ifndef FPC}
+ procedure readln(var t:text;var s:string);
+ var
+ c : char;
+ i : longint;
+ begin
+ c:=#0;
+ i:=0;
+ while (not eof(t)) and (c<>#10) do
+ begin
+ read(t,c);
+ if c<>#10 then
+ begin
+ inc(i);
+ s[i]:=c;
+ end;
+ end;
+ if (i>0) and (s[i]=#13) then
+ dec(i);
+ s[0]:=chr(i);
+ end;
+{$endif}
+
+ function lower(const s : string) : string;
+ {
+ return lowercased string of s
+ }
+ var
+ i : longint;
+ begin
+ for i:=1 to length(s) do
+ if s[i] in ['A'..'Z'] then
+ lower[i]:=char(byte(s[i])+32)
+ else
+ lower[i]:=s[i];
+ lower[0]:=s[0];
+ end;
+
+ function Replace(var s:string;const s1,s2:string):boolean;
+ var
+ i : longint;
+ begin
+ i:=pos(s1,s);
+ if i>0 then
+ begin
+ Delete(s,i,length(s1));
+ Insert(s2,s,i);
+ Replace:=true;
+ end
+ else
+ Replace:=false;
+ end;
+
+
+function formatop(s:string):string;
+ const
+ replaces=19;
+ replacetab : array[1..replaces,1..2] of string[32]=(
+ (':',' or ot_colon'),
+ ('mem8','mem or ot_bits8'),
+ ('mem16','mem or ot_bits16'),
+ ('mem32','mem or ot_bits32'),
+ ('mem64','mem or ot_bits64'),
+ ('mem80','mem or ot_bits80'),
+ ('mem','memory'),
+ ('memory_offs','mem_offs'),
+ ('imm8','imm or ot_bits8'),
+ ('imm16','imm or ot_bits16'),
+ ('imm32','imm or ot_bits32'),
+ ('imm64','imm or ot_bits64'),
+ ('imm80','imm or ot_bits80'),
+ ('imm','immediate'),
+ ('rm8','regmem or ot_bits8'),
+ ('rm16','regmem or ot_bits16'),
+ ('rm32','regmem or ot_bits32'),
+ ('rm64','regmem or ot_bits64'),
+ ('rm80','regmem or ot_bits80')
+ );
+ var
+ i : longint;
+ begin
+ for i:=1to replaces do
+ replace(s,replacetab[i,1],replacetab[i,2]);
+ formatop:=s;
+ end;
+
+
+function readnumber : longint;
+
+ var
+ base : longint;
+ result : longint;
+
+ begin
+ result:=0;
+ if s[i]='\' then
+ begin
+ base:=8;
+ inc(i);
+ if s[i]='x' then
+ begin
+ base:=16;
+ inc(i);
+ end;
+ end
+ else
+ base:=10;
+ s[i]:=upcase(s[i]);
+ while s[i] in ['0'..'9','A'..'F'] do
+ begin
+ case s[i] of
+ '0'..'9':
+ result:=result*base+ord(s[i])-ord('0');
+
+ 'A'..'F':
+ result:=result*base+ord(s[i])-ord('A')+10;
+ end;
+ inc(i);
+ end;
+ readnumber:=result;
+ end;
+
+function tostr(l : longint) : string;
+
+ var
+ hs : string;
+
+ begin
+ str(l,hs);
+ tostr:=hs;
+ end;
+
+function readstr : string;
+
+ var
+ result : string;
+
+ begin
+ result:='';
+ while (s[i] in ['0'..'9','A'..'Z','a'..'z','_']) and (i<=length(s)) do
+ begin
+ result:=result+s[i];
+ inc(i);
+ end;
+ readstr:=result;
+ end;
+
+procedure skipspace;
+
+ begin
+ while (s[i] in [' ',#9]) do
+ inc(i);
+ end;
+
+procedure openinc(var f:text;const fn:string);
+begin
+ writeln('creating ',fn);
+ assign(f,fn);
+ rewrite(f);
+ writeln(f,'{ don''t edit, this file is generated from armins.dat }');
+ writeln(f,'(');
+end;
+
+
+procedure closeinc(var f:text);
+begin
+ writeln(f);
+ writeln(f,');');
+ close(f);
+end;
+
+
+var
+ attsuffix,
+ hs : string;
+ j : longint;
+ firstopcode,
+ first : boolean;
+ maxinfolen,
+ code : byte;
+ insns : longint;
+ attsuffile,propfile,opfile,
+ nopfile,attfile,
+ infile,insfile : text;
+ { instruction fields }
+ skip : boolean;
+ last,
+ ops : longint;
+ attopcode,
+ opcode,
+ codes,
+ flags : string;
+ optypes : array[1..4] of string;
+begin
+ writeln('Narm Instruction Table Converter Version ',Version);
+ insns:=0;
+ maxinfolen:=0;
+ { open dat file }
+ assign(infile,'../arm/armins.dat');
+ { create inc files }
+ openinc(insfile,'armtab.inc');
+ openinc(opfile,'armop.inc');
+ assign(nopfile,'armnop.inc');
+ openinc(attfile,'armatt.inc');
+ openinc(attsuffile,'armatts.inc');
+ {
+ openinc(intfile,'i386int.inc');
+ openinc(propfile,'i386prop.inc');
+ }
+ rewrite(nopfile);
+ writeln(nopfile,'{ don''t edit, this file is generated from armins.dat }');
+ reset(infile);
+ first:=true;
+ opcode:='';
+ firstopcode:=true;
+ while not(eof(infile)) do
+ begin
+ { handle comment }
+ readln(infile,s);
+ while (s[1]=' ') do
+ delete(s,1,1);
+ if (s='') or (s[1]=';') then
+ continue;
+ if (s[1]='[') then
+ begin
+ i:=pos(',',s);
+ j:=pos(']',s);
+ if i=0 then
+ begin
+ opcode:='A_'+Copy(s,2,j-2);
+ attopcode:=Copy(s,2,j-2);
+ { Conditional }
+ if (attopcode[length(attopcode)]='c') and
+ (attopcode[length(attopcode)-1]='c') then
+ begin
+ dec(byte(attopcode[0]),2);
+ dec(byte(opcode[0]),2);
+ end;
+ attsuffix:='attsufNONE';
+ end
+ else
+ begin
+ opcode:='A_'+Copy(s,2,i-2);
+ { intel conditional }
+ if (opcode[length(attopcode)]='c') and
+ (opcode[length(attopcode)-1]='c') then
+ dec(byte(opcode[0]),2);
+ attopcode:=Copy(s,i+1,j-i-1);
+ { att Suffix }
+ case attopcode[length(attopcode)] of
+ 'X' :
+ begin
+ dec(attopcode[0]);
+ attsuffix:='attsufINT';
+ end;
+ 'F' :
+ begin
+ dec(attopcode[0]);
+ attsuffix:='attsufFPU';
+ end;
+ 'R' :
+ begin
+ dec(attopcode[0]);
+ attsuffix:='attsufFPUint';
+ end;
+ else
+ attsuffix:='attsufNONE';
+ end;
+ { att Conditional }
+ if (attopcode[length(attopcode)]='C') and
+ (attopcode[length(attopcode)-1]='C') then
+ dec(byte(attopcode[0]),2);
+ end;
+ attopcode:=Lower(attopcode);
+ if firstopcode then
+ firstopcode:=false
+ else
+ begin
+ writeln(opfile,',');
+ writeln(attfile,',');
+ writeln(attsuffile,',');
+{ writeln(propfile,','); }
+ end;
+ write(opfile,opcode);
+ write(attfile,'''',attopcode,'''');
+ write(attsuffile,attsuffix);
+ { read the next line which contains the Change options }
+ {
+ repeat
+ readln(infile,s);
+ until eof(infile) or ((s<>'') and (s[1]<>';'));
+ write(propfile,'(Ch: ',s,')');
+ }
+ continue;
+ end;
+ { we must have an opcode }
+ if opcode='' then
+ runerror(234);
+ { clear }
+ ops:=0;
+ optypes[1]:='';
+ optypes[2]:='';
+ optypes[3]:='';
+ optypes[4]:='';
+ codes:='';
+ flags:='';
+ skip:=false;
+ { ops and optypes }
+ i:=1;
+ repeat
+ hs:=readstr;
+ if (hs='void') or (hs='ignore') then
+ break;
+ inc(ops);
+ optypes[ops]:=optypes[ops]+'ot_'+formatop(hs);
+{ if s[i]=':' then
+ begin
+ inc(i);
+ optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
+ end;}
+ while s[i]='|' do
+ begin
+ inc(i);
+ optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
+ end;
+ if s[i] in [',',':'] then
+ inc(i)
+ else
+ break;
+ until false;
+ for j:=1 to 4-ops do
+ optypes[4-j+1]:='ot_none';
+ { codes }
+ skipspace;
+ j:=0;
+ last:=0;
+ if s[i] in ['\','0'..'9'] then
+ begin
+ while not(s[i] in [' ',#9]) do
+ begin
+ code:=readnumber;
+(*
+ { for some codes we want also to change the optypes, but not
+ if the last byte was a 1 then this byte belongs to a direct
+ copy }
+ if last<>1 then
+ begin
+ case code of
+ 12,13,14 :
+ optypes[code-11]:=optypes[code-11]+' or ot_signed';
+ end;
+ end;
+*)
+ codes:=codes+'#'+tostr(code);
+ last:=code;
+ inc(j);
+ end;
+ end
+ else
+ begin
+ readstr;
+ codes:='#0';
+ end;
+ if j>maxinfolen then
+ maxinfolen:=j;
+ { flags }
+ skipspace;
+ while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
+ begin
+ hs:=readstr;
+ if hs<>'ND' then
+ begin
+ if flags<>'' then
+ flags:=flags+' or ';
+ flags:=flags+'if_'+lower(hs);
+ end;
+ if (s[i]=',') and (i<=length(s)) then
+ inc(i)
+ else
+ break;
+ end;
+ { write instruction }
+ if not skip then
+ begin
+ if not(first) then
+ writeln(insfile,',')
+ else
+ first:=false;
+ writeln(insfile,' (');
+ writeln(insfile,' opcode : ',opcode,';');
+ writeln(insfile,' ops : ',ops,';');
+ writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],',',optypes[4],');');
+ writeln(insfile,' code : ',codes,';');
+ writeln(insfile,' flags : ',flags);
+ write(insfile,' )');
+ inc(insns);
+ end;
+ end;
+ close(infile);
+ closeinc(insfile);
+ closeinc(attfile);
+ closeinc(attsuffile);
+ closeinc(opfile);
+ writeln(nopfile,insns,';');
+ close(nopfile);
+{ closeinc(propfile); }
+ writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
+end.
diff --git a/compiler/utils/mkarmreg.pp b/compiler/utils/mkarmreg.pp
new file mode 100644
index 0000000000..01b4053d6c
--- /dev/null
+++ b/compiler/utils/mkarmreg.pp
@@ -0,0 +1,298 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl
+
+ Convert spreg.dat to several .inc files for usage with
+ the Free pascal compiler
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program mkspreg;
+
+const Version = '1.00';
+ max_regcount = 200;
+
+var s : string;
+ i : longint;
+ line : longint;
+ regcount:byte;
+ regcount_bsstart:byte;
+ names,
+ regtypes,
+ supregs,
+ numbers,
+ stdnames,
+ stabs,dwarf : array[0..max_regcount-1] of string[63];
+ regnumber_index,
+ std_regname_index : array[0..max_regcount-1] of byte;
+
+{$ifndef FPC}
+ procedure readln(var t:text;var s:string);
+ var
+ c : char;
+ i : longint;
+ begin
+ c:=#0;
+ i:=0;
+ while (not eof(t)) and (c<>#10) do
+ begin
+ read(t,c);
+ if c<>#10 then
+ begin
+ inc(i);
+ s[i]:=c;
+ end;
+ end;
+ if (i>0) and (s[i]=#13) then
+ dec(i);
+ s[0]:=chr(i);
+ end;
+{$endif}
+
+function tostr(l : longint) : string;
+
+begin
+ str(l,tostr);
+end;
+
+function readstr : string;
+
+ var
+ result : string;
+
+ begin
+ result:='';
+ while (s[i]<>',') and (i<=length(s)) do
+ begin
+ result:=result+s[i];
+ inc(i);
+ end;
+ readstr:=result;
+ end;
+
+
+procedure readcomma;
+ begin
+ if s[i]<>',' then
+ begin
+ writeln('Missing "," at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ inc(i);
+ end;
+
+
+procedure skipspace;
+
+ begin
+ while (s[i] in [' ',#9]) do
+ inc(i);
+ end;
+
+procedure openinc(var f:text;const fn:string);
+begin
+ writeln('creating ',fn);
+ assign(f,fn);
+ rewrite(f);
+ writeln(f,'{ don''t edit, this file is generated from armreg.dat }');
+end;
+
+
+procedure closeinc(var f:text);
+begin
+ writeln(f);
+ close(f);
+end;
+
+procedure build_regnum_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ regnumber_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if numbers[regnumber_index[j]]>=numbers[regnumber_index[i]] then
+ break;
+ t:=regnumber_index[i];
+ regnumber_index[i]:=regnumber_index[j];
+ regnumber_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure build_std_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ std_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if stdnames[std_regname_index[j]]>=stdnames[std_regname_index[i]] then
+ break;
+ t:=std_regname_index[i];
+ std_regname_index[i]:=std_regname_index[j];
+ std_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+
+procedure read_spreg_file;
+
+var infile:text;
+
+begin
+ { open dat file }
+ assign(infile,'armreg.dat');
+ reset(infile);
+ while not(eof(infile)) do
+ begin
+ { handle comment }
+ readln(infile,s);
+ inc(line);
+ while (s[1]=' ') do
+ delete(s,1,1);
+ if (s='') or (s[1]=';') then
+ continue;
+
+ i:=1;
+ names[regcount]:=readstr;
+ readcomma;
+ regtypes[regcount]:=readstr;
+ readcomma;
+ supregs[regcount]:=readstr;
+ readcomma;
+ stdnames[regcount]:=readstr;
+ readcomma;
+ stabs[regcount]:=readstr;
+ readcomma;
+ dwarf[regcount]:=readstr;
+ { Create register number }
+ if supregs[regcount][1]<>'$' then
+ begin
+ writeln('Missing $ before number, at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ numbers[regcount]:=regtypes[regcount]+'0000'+copy(supregs[regcount],2,255);
+ if i<length(s) then
+ begin
+ writeln('Extra chars at end of line, at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ inc(regcount);
+ if regcount>max_regcount then
+ begin
+ writeln('Error: Too much registers, please increase maxregcount in source');
+ halt(2);
+ end;
+ end;
+ close(infile);
+end;
+
+procedure write_inc_files;
+
+var
+ norfile,stdfile,supfile,
+ numfile,stabfile,dwarffile,confile,
+ rnifile,srifile:text;
+ first:boolean;
+
+begin
+ { create inc files }
+ openinc(confile,'rarmcon.inc');
+ openinc(supfile,'rarmsup.inc');
+ openinc(numfile,'rarmnum.inc');
+ openinc(stdfile,'rarmstd.inc');
+ openinc(stabfile,'rarmsta.inc');
+ openinc(dwarffile,'rarmdwa.inc');
+ openinc(norfile,'rarmnor.inc');
+ openinc(rnifile,'rarmrni.inc');
+ openinc(srifile,'rarmsri.inc');
+ first:=true;
+ for i:=0 to regcount-1 do
+ begin
+ if not first then
+ begin
+ writeln(numfile,',');
+ writeln(stdfile,',');
+ writeln(stabfile,',');
+ writeln(dwarffile,',');
+ writeln(rnifile,',');
+ writeln(srifile,',');
+ end
+ else
+ first:=false;
+ writeln(supfile,'RS_',names[i],' = ',supregs[i],';');
+ writeln(confile,'NR_'+names[i],' = ','tregister(',numbers[i],')',';');
+ write(numfile,'tregister(',numbers[i],')');
+ write(stdfile,'''',stdnames[i],'''');
+ write(stabfile,stabs[i]);
+ write(dwarffile,dwarf[i]);
+ write(rnifile,regnumber_index[i]);
+ write(srifile,std_regname_index[i]);
+ end;
+ write(norfile,regcount);
+ close(confile);
+ close(supfile);
+ closeinc(numfile);
+ closeinc(stdfile);
+ closeinc(stabfile);
+ closeinc(dwarffile);
+ closeinc(norfile);
+ closeinc(rnifile);
+ closeinc(srifile);
+ writeln('Done!');
+ writeln(regcount,' registers procesed');
+end;
+
+
+begin
+ writeln('Register Table Converter Version ',Version);
+ line:=0;
+ regcount:=0;
+ read_spreg_file;
+ regcount_bsstart:=1;
+ while 2*regcount_bsstart<regcount do
+ regcount_bsstart:=regcount_bsstart*2;
+ build_regnum_index;
+ build_std_regname_index;
+ write_inc_files;
+end.
diff --git a/compiler/utils/mkmpsreg.pp b/compiler/utils/mkmpsreg.pp
new file mode 100644
index 0000000000..b8130bb511
--- /dev/null
+++ b/compiler/utils/mkmpsreg.pp
@@ -0,0 +1,349 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl
+
+ Convert mipsreg.dat to several .inc files for usage with
+ the Free pascal compiler
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program mkmipsreg;
+
+const Version = '1.00';
+ max_regcount = 200;
+
+var s : string;
+ i : longint;
+ line : longint;
+ regcount:byte;
+ regcount_bsstart:byte;
+ names,
+ regtypes,
+ supregs,
+ numbers,
+ stdnames,
+ gasnames,
+ dwarfs,
+ stabs : array[0..max_regcount-1] of string[63];
+ regnumber_index,
+ std_regname_index,
+ gas_regname_index,
+ mot_regname_index : array[0..max_regcount-1] of byte;
+
+{$ifndef FPC}
+ procedure readln(var t:text;var s:string);
+ var
+ c : char;
+ i : longint;
+ begin
+ c:=#0;
+ i:=0;
+ while (not eof(t)) and (c<>#10) do
+ begin
+ read(t,c);
+ if c<>#10 then
+ begin
+ inc(i);
+ s[i]:=c;
+ end;
+ end;
+ if (i>0) and (s[i]=#13) then
+ dec(i);
+ s[0]:=chr(i);
+ end;
+{$endif}
+
+function tostr(l : longint) : string;
+
+begin
+ str(l,tostr);
+end;
+
+function readstr : string;
+
+ var
+ result : string;
+
+ begin
+ result:='';
+ while (s[i]<>',') and (i<=length(s)) do
+ begin
+ result:=result+s[i];
+ inc(i);
+ end;
+ readstr:=result;
+ end;
+
+
+procedure readcomma;
+ begin
+ if s[i]<>',' then
+ begin
+ writeln('Missing "," at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ inc(i);
+ end;
+
+
+procedure skipspace;
+
+ begin
+ while (s[i] in [' ',#9]) do
+ inc(i);
+ end;
+
+procedure openinc(var f:text;const fn:string);
+begin
+ writeln('creating ',fn);
+ assign(f,fn);
+ rewrite(f);
+ writeln(f,'{ don''t edit, this file is generated from mipsreg.dat }');
+end;
+
+
+procedure closeinc(var f:text);
+begin
+ writeln(f);
+ close(f);
+end;
+
+procedure build_regnum_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ regnumber_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if numbers[regnumber_index[j]]>=numbers[regnumber_index[i]] then
+ break;
+ t:=regnumber_index[i];
+ regnumber_index[i]:=regnumber_index[j];
+ regnumber_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure build_std_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ std_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if stdnames[std_regname_index[j]]>=stdnames[std_regname_index[i]] then
+ break;
+ t:=std_regname_index[i];
+ std_regname_index[i]:=std_regname_index[j];
+ std_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+
+procedure build_gas_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ gas_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if gasnames[gas_regname_index[j]]>=gasnames[gas_regname_index[i]] then
+ break;
+ t:=gas_regname_index[i];
+ gas_regname_index[i]:=gas_regname_index[j];
+ gas_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+
+procedure read_mipsreg_file;
+
+var infile:text;
+
+begin
+ { open dat file }
+ assign(infile,'mipsreg.dat');
+ reset(infile);
+ while not(eof(infile)) do
+ begin
+ { handle comment }
+ readln(infile,s);
+ inc(line);
+ while (s[1]=' ') do
+ delete(s,1,1);
+ if (s='') or (s[1]=';') then
+ continue;
+
+ i:=1;
+ names[regcount]:=readstr;
+ readcomma;
+ regtypes[regcount]:=readstr;
+ readcomma;
+ supregs[regcount]:=readstr;
+ readcomma;
+ stdnames[regcount]:=readstr;
+ readcomma;
+ gasnames[regcount]:=readstr;
+ readcomma;
+ stabs[regcount]:=readstr;
+ readcomma;
+ dwarfs[regcount]:=readstr;
+ { Create register number }
+ if supregs[regcount][1]<>'$' then
+ begin
+ writeln('Missing $ before number, at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ numbers[regcount]:=regtypes[regcount]+'0000'+copy(supregs[regcount],2,255);
+ if i<length(s) then
+ begin
+ writeln('Extra chars at end of line, at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ inc(regcount);
+ if regcount>max_regcount then
+ begin
+ writeln('Error: Too much registers, please increase maxregcount in source');
+ halt(2);
+ end;
+ end;
+ close(infile);
+end;
+
+procedure write_inc_files;
+
+var
+ norfile,stdfile,supfile,
+ numfile,stabfile,confile,gasfile,dwarffile,
+ rnifile,srifile,mrifile,grifile : text;
+ first:boolean;
+
+begin
+ { create inc files }
+ openinc(confile,'rmipscon.inc');
+ openinc(supfile,'rmipssup.inc');
+ openinc(numfile,'rmipsnum.inc');
+ openinc(stdfile,'rmipsstd.inc');
+ openinc(gasfile,'rmipsgas.inc');
+ openinc(stabfile,'rmipssta.inc');
+ openinc(dwarffile,'rmipsdwf.inc');
+ openinc(norfile,'rmipsnor.inc');
+ openinc(rnifile,'rmipsrni.inc');
+ openinc(srifile,'rmipssri.inc');
+ openinc(grifile,'rmipsgri.inc');
+ openinc(mrifile,'rmipsmri.inc');
+ first:=true;
+ for i:=0 to regcount-1 do
+ begin
+ if not first then
+ begin
+ writeln(numfile,',');
+ writeln(stdfile,',');
+ writeln(gasfile,',');
+ writeln(stabfile,',');
+ writeln(dwarffile,',');
+ writeln(rnifile,',');
+ writeln(srifile,',');
+ writeln(grifile,',');
+ writeln(mrifile,',');
+ end
+ else
+ first:=false;
+ writeln(supfile,'RS_',names[i],' = ',supregs[i],';');
+ writeln(confile,'NR_'+names[i],' = ','tregister(',numbers[i],')',';');
+ write(numfile,'tregister(',numbers[i],')');
+ write(stdfile,'''',stdnames[i],'''');
+ write(gasfile,'''',gasnames[i],'''');
+ write(stabfile,stabs[i]);
+ write(dwarffile,dwarfs[i]);
+ write(rnifile,regnumber_index[i]);
+ write(srifile,std_regname_index[i]);
+ write(grifile,gas_regname_index[i]);
+ write(mrifile,mot_regname_index[i]);
+ end;
+ write(norfile,regcount);
+ close(confile);
+ close(supfile);
+ closeinc(numfile);
+ closeinc(stdfile);
+ closeinc(gasfile);
+ closeinc(stabfile);
+ closeinc(dwarffile);
+ closeinc(norfile);
+ closeinc(rnifile);
+ closeinc(srifile);
+ closeinc(grifile);
+ closeinc(mrifile);
+ writeln('Done!');
+ writeln(regcount,' registers procesed');
+end;
+
+
+begin
+ writeln('Register Table Converter Version ',Version);
+ line:=0;
+ regcount:=0;
+ read_mipsreg_file;
+ regcount_bsstart:=1;
+ while 2*regcount_bsstart<regcount do
+ regcount_bsstart:=regcount_bsstart*2;
+ build_regnum_index;
+ build_std_regname_index;
+ build_gas_regname_index;
+ write_inc_files;
+end.
diff --git a/compiler/utils/mkppcreg.pp b/compiler/utils/mkppcreg.pp
new file mode 100644
index 0000000000..de4bca26d0
--- /dev/null
+++ b/compiler/utils/mkppcreg.pp
@@ -0,0 +1,396 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl
+
+ Convert ppcreg.dat to several .inc files for usage with
+ the Free pascal compiler
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program mkppcreg;
+
+const Version = '1.00';
+ max_regcount = 200;
+
+var s : string;
+ i : longint;
+ line : longint;
+ regcount:byte;
+ regcount_bsstart:byte;
+ names,
+ regtypes,
+ supregs,
+ numbers,
+ stdnames,
+ gasnames,
+ gssnames,
+ motnames,
+ dwarfs,
+ stabs : array[0..max_regcount-1] of string[63];
+ regnumber_index,
+ std_regname_index,
+ gas_regname_index,
+ mot_regname_index : array[0..max_regcount-1] of byte;
+
+{$ifndef FPC}
+ procedure readln(var t:text;var s:string);
+ var
+ c : char;
+ i : longint;
+ begin
+ c:=#0;
+ i:=0;
+ while (not eof(t)) and (c<>#10) do
+ begin
+ read(t,c);
+ if c<>#10 then
+ begin
+ inc(i);
+ s[i]:=c;
+ end;
+ end;
+ if (i>0) and (s[i]=#13) then
+ dec(i);
+ s[0]:=chr(i);
+ end;
+{$endif}
+
+function tostr(l : longint) : string;
+
+begin
+ str(l,tostr);
+end;
+
+function readstr : string;
+
+ var
+ result : string;
+
+ begin
+ result:='';
+ while (s[i]<>',') and (i<=length(s)) do
+ begin
+ result:=result+s[i];
+ inc(i);
+ end;
+ readstr:=result;
+ end;
+
+
+procedure readcomma;
+ begin
+ if s[i]<>',' then
+ begin
+ writeln('Missing "," at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ inc(i);
+ end;
+
+
+procedure skipspace;
+
+ begin
+ while (s[i] in [' ',#9]) do
+ inc(i);
+ end;
+
+procedure openinc(var f:text;const fn:string);
+begin
+ writeln('creating ',fn);
+ assign(f,fn);
+ rewrite(f);
+ writeln(f,'{ don''t edit, this file is generated from ppcreg.dat }');
+end;
+
+
+procedure closeinc(var f:text);
+begin
+ writeln(f);
+ close(f);
+end;
+
+procedure build_regnum_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ regnumber_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if numbers[regnumber_index[j]]>=numbers[regnumber_index[i]] then
+ break;
+ t:=regnumber_index[i];
+ regnumber_index[i]:=regnumber_index[j];
+ regnumber_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure build_std_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ std_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if stdnames[std_regname_index[j]]>=stdnames[std_regname_index[i]] then
+ break;
+ t:=std_regname_index[i];
+ std_regname_index[i]:=std_regname_index[j];
+ std_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+
+procedure build_gas_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ gas_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if gasnames[gas_regname_index[j]]>=gasnames[gas_regname_index[i]] then
+ break;
+ t:=gas_regname_index[i];
+ gas_regname_index[i]:=gas_regname_index[j];
+ gas_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+
+procedure build_mot_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ mot_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if motnames[mot_regname_index[j]]>=motnames[mot_regname_index[i]] then
+ break;
+ t:=mot_regname_index[i];
+ mot_regname_index[i]:=mot_regname_index[j];
+ mot_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+
+procedure read_ppcreg_file;
+
+var infile:text;
+
+begin
+ { open dat file }
+ assign(infile,'ppcreg.dat');
+ reset(infile);
+ while not(eof(infile)) do
+ begin
+ { handle comment }
+ readln(infile,s);
+ inc(line);
+ while (s[1]=' ') do
+ delete(s,1,1);
+ if (s='') or (s[1]=';') then
+ continue;
+
+ i:=1;
+ names[regcount]:=readstr;
+ readcomma;
+ regtypes[regcount]:=readstr;
+ readcomma;
+ supregs[regcount]:=readstr;
+ readcomma;
+ stdnames[regcount]:=readstr;
+ readcomma;
+ gasnames[regcount]:=readstr;
+ readcomma;
+ gssnames[regcount]:=readstr;
+ readcomma;
+ motnames[regcount]:=readstr;
+ readcomma;
+ stabs[regcount]:=readstr;
+ readcomma;
+ dwarfs[regcount]:=readstr;
+ { Create register number }
+ if supregs[regcount][1]<>'$' then
+ begin
+ writeln('Missing $ before number, at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ numbers[regcount]:=regtypes[regcount]+'0000'+copy(supregs[regcount],2,255);
+ if i<length(s) then
+ begin
+ writeln('Extra chars at end of line, at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ inc(regcount);
+ if regcount>max_regcount then
+ begin
+ writeln('Error: Too much registers, please increase maxregcount in source');
+ halt(2);
+ end;
+ end;
+ close(infile);
+end;
+
+procedure write_inc_files;
+
+var
+ norfile,stdfile,motfile,supfile,
+ numfile,stabfile,confile,gasfile,gssfile,dwarffile,
+ rnifile,srifile,mrifile,grifile : text;
+ first:boolean;
+
+begin
+ { create inc files }
+ openinc(confile,'rppccon.inc');
+ openinc(supfile,'rppcsup.inc');
+ openinc(numfile,'rppcnum.inc');
+ openinc(stdfile,'rppcstd.inc');
+ openinc(gasfile,'rppcgas.inc');
+ openinc(gssfile,'rppcgss.inc');
+ openinc(motfile,'rppcmot.inc');
+ openinc(stabfile,'rppcstab.inc');
+ openinc(dwarffile,'rppcdwrf.inc');
+ openinc(norfile,'rppcnor.inc');
+ openinc(rnifile,'rppcrni.inc');
+ openinc(srifile,'rppcsri.inc');
+ openinc(grifile,'rppcgri.inc');
+ openinc(mrifile,'rppcmri.inc');
+ first:=true;
+ for i:=0 to regcount-1 do
+ begin
+ if not first then
+ begin
+ writeln(numfile,',');
+ writeln(stdfile,',');
+ writeln(gasfile,',');
+ writeln(gssfile,',');
+ writeln(motfile,',');
+ writeln(stabfile,',');
+ writeln(dwarffile,',');
+ writeln(rnifile,',');
+ writeln(srifile,',');
+ writeln(grifile,',');
+ writeln(mrifile,',');
+ end
+ else
+ first:=false;
+ writeln(supfile,'RS_',names[i],' = ',supregs[i],';');
+ writeln(confile,'NR_'+names[i],' = ','tregister(',numbers[i],')',';');
+ write(numfile,'tregister(',numbers[i],')');
+ write(stdfile,'''',stdnames[i],'''');
+ write(gasfile,'''',gasnames[i],'''');
+ write(gssfile,'''',gssnames[i],'''');
+ write(motfile,'''',motnames[i],'''');
+ write(stabfile,stabs[i]);
+ write(dwarffile,dwarfs[i]);
+ write(rnifile,regnumber_index[i]);
+ write(srifile,std_regname_index[i]);
+ write(grifile,gas_regname_index[i]);
+ write(mrifile,mot_regname_index[i]);
+ end;
+ write(norfile,regcount);
+ close(confile);
+ close(supfile);
+ closeinc(numfile);
+ closeinc(stdfile);
+ closeinc(gasfile);
+ closeinc(gssfile);
+ closeinc(motfile);
+ closeinc(stabfile);
+ closeinc(dwarffile);
+ closeinc(norfile);
+ closeinc(rnifile);
+ closeinc(srifile);
+ closeinc(grifile);
+ closeinc(mrifile);
+ writeln('Done!');
+ writeln(regcount,' registers procesed');
+end;
+
+
+begin
+ writeln('Register Table Converter Version ',Version);
+ line:=0;
+ regcount:=0;
+ read_ppcreg_file;
+ regcount_bsstart:=1;
+ while 2*regcount_bsstart<regcount do
+ regcount_bsstart:=regcount_bsstart*2;
+ build_regnum_index;
+ build_std_regname_index;
+ build_gas_regname_index;
+ build_mot_regname_index;
+ write_inc_files;
+end.
diff --git a/compiler/utils/mkspreg.pp b/compiler/utils/mkspreg.pp
new file mode 100644
index 0000000000..5208064750
--- /dev/null
+++ b/compiler/utils/mkspreg.pp
@@ -0,0 +1,301 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl
+
+ Convert spreg.dat to several .inc files for usage with
+ the Free pascal compiler
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program mkspreg;
+
+const Version = '1.00';
+ max_regcount = 200;
+
+var s : string;
+ i : longint;
+ line : longint;
+ regcount:byte;
+ regcount_bsstart:byte;
+ supregs,
+ subregs,
+ names,
+ regtypes,
+ numbers,
+ stdnames,
+ stabs,
+ dwarfs : array[0..max_regcount-1] of string[63];
+ regnumber_index,
+ std_regname_index : array[0..max_regcount-1] of byte;
+
+{$ifndef FPC}
+ procedure readln(var t:text;var s:string);
+ var
+ c : char;
+ i : longint;
+ begin
+ c:=#0;
+ i:=0;
+ while (not eof(t)) and (c<>#10) do
+ begin
+ read(t,c);
+ if c<>#10 then
+ begin
+ inc(i);
+ s[i]:=c;
+ end;
+ end;
+ if (i>0) and (s[i]=#13) then
+ dec(i);
+ s[0]:=chr(i);
+ end;
+{$endif}
+
+function tostr(l : longint) : string;
+
+begin
+ str(l,tostr);
+end;
+
+function readstr : string;
+
+ var
+ result : string;
+
+ begin
+ result:='';
+ while (s[i]<>',') and (i<=length(s)) do
+ begin
+ result:=result+s[i];
+ inc(i);
+ end;
+ readstr:=result;
+ end;
+
+
+procedure readcomma;
+ begin
+ if s[i]<>',' then
+ begin
+ writeln('Missing "," at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ inc(i);
+ end;
+
+
+procedure skipspace;
+
+ begin
+ while (s[i] in [' ',#9]) do
+ inc(i);
+ end;
+
+procedure openinc(var f:text;const fn:string);
+begin
+ writeln('creating ',fn);
+ assign(f,fn);
+ rewrite(f);
+ writeln(f,'{ don''t edit, this file is generated from spreg.dat }');
+end;
+
+
+procedure closeinc(var f:text);
+begin
+ writeln(f);
+ close(f);
+end;
+
+procedure build_regnum_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ regnumber_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if numbers[regnumber_index[j]]>=numbers[regnumber_index[i]] then
+ break;
+ t:=regnumber_index[i];
+ regnumber_index[i]:=regnumber_index[j];
+ regnumber_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure build_std_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ std_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if stdnames[std_regname_index[j]]>=stdnames[std_regname_index[i]] then
+ break;
+ t:=std_regname_index[i];
+ std_regname_index[i]:=std_regname_index[j];
+ std_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+
+procedure read_spreg_file;
+var
+ infile:text;
+begin
+ { open dat file }
+ assign(infile,'spreg.dat');
+ reset(infile);
+ while not(eof(infile)) do
+ begin
+ { handle comment }
+ readln(infile,s);
+ inc(line);
+ while (s[1]=' ') do
+ delete(s,1,1);
+ if (s='') or (s[1]=';') then
+ continue;
+
+ i:=1;
+ names[regcount]:=readstr;
+ readcomma;
+ regtypes[regcount]:=readstr;
+ readcomma;
+ subregs[regcount]:=readstr;
+ readcomma;
+ supregs[regcount]:=readstr;
+ readcomma;
+ stdnames[regcount]:=readstr;
+ readcomma;
+ stabs[regcount]:=readstr;
+ readcomma;
+ dwarfs[regcount]:=readstr;
+ { Create register number }
+ if supregs[regcount][1]<>'$' then
+ begin
+ writeln('Missing $ before number, at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ numbers[regcount]:=regtypes[regcount]+copy(subregs[regcount],2,255)+'00'+copy(supregs[regcount],2,255);
+ if i<length(s) then
+ begin
+ writeln('Extra chars at end of line, at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ inc(regcount);
+ if regcount>max_regcount then
+ begin
+ writeln('Error: Too much registers, please increase maxregcount in source');
+ halt(2);
+ end;
+ end;
+ close(infile);
+end;
+
+procedure write_inc_files;
+
+var
+ norfile,stdfile,supfile,
+ numfile,stabfile,dwarffile,confile,
+ rnifile,srifile:text;
+ first:boolean;
+
+begin
+ { create inc files }
+ openinc(confile,'rspcon.inc');
+ openinc(supfile,'rspsup.inc');
+ openinc(numfile,'rspnum.inc');
+ openinc(stdfile,'rspstd.inc');
+ openinc(stabfile,'rspstab.inc');
+ openinc(dwarffile,'rspdwrf.inc');
+ openinc(norfile,'rspnor.inc');
+ openinc(rnifile,'rsprni.inc');
+ openinc(srifile,'rspsri.inc');
+ first:=true;
+ for i:=0 to regcount-1 do
+ begin
+ if not first then
+ begin
+ writeln(numfile,',');
+ writeln(stdfile,',');
+ writeln(stabfile,',');
+ writeln(dwarffile,',');
+ writeln(rnifile,',');
+ writeln(srifile,',');
+ end
+ else
+ first:=false;
+ writeln(confile,'NR_',names[i],' = tregister(',numbers[i],');');
+ writeln(supfile,'RS_',names[i],' = ',supregs[i],';');
+ write(numfile,'NR_',names[i]);
+ write(stdfile,'''',stdnames[i],'''');
+ write(stabfile,stabs[i]);
+ write(dwarffile,dwarfs[i]);
+ write(rnifile,regnumber_index[i]);
+ write(srifile,std_regname_index[i]);
+ end;
+ write(norfile,regcount);
+ close(confile);
+ close(supfile);
+ closeinc(numfile);
+ closeinc(stdfile);
+ closeinc(stabfile);
+ closeinc(dwarffile);
+ closeinc(norfile);
+ closeinc(rnifile);
+ closeinc(srifile);
+ writeln('Done!');
+ writeln(regcount,' registers procesed');
+end;
+
+
+begin
+ writeln('Register Table Converter Version ',Version);
+ line:=0;
+ regcount:=0;
+ read_spreg_file;
+ regcount_bsstart:=1;
+ while 2*regcount_bsstart<regcount do
+ regcount_bsstart:=regcount_bsstart*2;
+ build_regnum_index;
+ build_std_regname_index;
+ write_inc_files;
+end.
diff --git a/compiler/utils/mkx86ins.pp b/compiler/utils/mkx86ins.pp
new file mode 100644
index 0000000000..2601eae9d2
--- /dev/null
+++ b/compiler/utils/mkx86ins.pp
@@ -0,0 +1,454 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl
+
+ Convert i386ins.dat from Nasm to a .inc file for usage with
+ the Free pascal compiler
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program mkx86ins;
+
+const
+ Version = '1.5.0';
+
+var
+ s : string;
+ i : longint;
+ x86_64 : boolean;
+
+{$ifndef FPC}
+ procedure readln(var t:text;var s:string);
+ var
+ c : char;
+ i : longint;
+ begin
+ c:=#0;
+ i:=0;
+ while (not eof(t)) and (c<>#10) do
+ begin
+ read(t,c);
+ if c<>#10 then
+ begin
+ inc(i);
+ s[i]:=c;
+ end;
+ end;
+ if (i>0) and (s[i]=#13) then
+ dec(i);
+ s[0]:=chr(i);
+ end;
+{$endif}
+
+ function lower(const s : string) : string;
+ {
+ return lowercased string of s
+ }
+ var
+ i : longint;
+ begin
+ for i:=1 to length(s) do
+ if s[i] in ['A'..'Z'] then
+ lower[i]:=char(byte(s[i])+32)
+ else
+ lower[i]:=s[i];
+ lower[0]:=s[0];
+ end;
+
+ function Replace(var s:string;const s1,s2:string):boolean;
+ var
+ i : longint;
+ begin
+ i:=pos(s1,s);
+ if i>0 then
+ begin
+ Delete(s,i,length(s1));
+ Insert(s2,s,i);
+ Replace:=true;
+ end
+ else
+ Replace:=false;
+ end;
+
+
+function formatop(s:string):string;
+ const
+ replaces=19;
+ replacetab : array[1..replaces,1..2] of string[32]=(
+ (':',' or ot_colon'),
+ ('mem8','mem or ot_bits8'),
+ ('mem16','mem or ot_bits16'),
+ ('mem32','mem or ot_bits32'),
+ ('mem64','mem or ot_bits64'),
+ ('mem80','mem or ot_bits80'),
+ ('mem','memory'),
+ ('memory_offs','mem_offs'),
+ ('imm8','imm or ot_bits8'),
+ ('imm16','imm or ot_bits16'),
+ ('imm32','imm or ot_bits32'),
+ ('imm64','imm or ot_bits64'),
+ ('imm80','imm or ot_bits80'),
+ ('imm','immediate'),
+ ('rm8','regmem or ot_bits8'),
+ ('rm16','regmem or ot_bits16'),
+ ('rm32','regmem or ot_bits32'),
+ ('rm64','regmem or ot_bits64'),
+ ('rm80','regmem or ot_bits80')
+ );
+ var
+ i : longint;
+ begin
+ for i:=1to replaces do
+ replace(s,replacetab[i,1],replacetab[i,2]);
+ formatop:=s;
+ end;
+
+
+function readnumber : longint;
+
+ var
+ base : longint;
+ result : longint;
+
+ begin
+ result:=0;
+ if s[i]='\' then
+ begin
+ base:=8;
+ inc(i);
+ if s[i]='x' then
+ begin
+ base:=16;
+ inc(i);
+ end;
+ end
+ else
+ base:=10;
+ s[i]:=upcase(s[i]);
+ while s[i] in ['0'..'9','A'..'F'] do
+ begin
+ case s[i] of
+ '0'..'9':
+ result:=result*base+ord(s[i])-ord('0');
+
+ 'A'..'F':
+ result:=result*base+ord(s[i])-ord('A')+10;
+ end;
+ inc(i);
+ end;
+ readnumber:=result;
+ end;
+
+function tostr(l : longint) : string;
+
+ var
+ hs : string;
+
+ begin
+ str(l,hs);
+ tostr:=hs;
+ end;
+
+function readstr : string;
+
+ var
+ result : string;
+
+ begin
+ result:='';
+ while (s[i] in ['0'..'9','A'..'Z','a'..'z','_']) and (i<=length(s)) do
+ begin
+ result:=result+s[i];
+ inc(i);
+ end;
+ readstr:=result;
+ end;
+
+procedure skipspace;
+
+ begin
+ while (s[i] in [' ',#9]) do
+ inc(i);
+ end;
+
+procedure openinc(var f:text;const fn:string);
+begin
+ writeln('creating ',fn);
+ assign(f,fn);
+ rewrite(f);
+ writeln(f,'{ don''t edit, this file is generated from x86ins.dat }');
+ writeln(f,'(');
+end;
+
+
+procedure closeinc(var f:text);
+begin
+ writeln(f);
+ writeln(f,');');
+ close(f);
+end;
+
+
+var
+ attsuffix,
+ hs : string;
+ j : longint;
+ firstopcode,
+ first : boolean;
+ maxinfolen,
+ code : byte;
+ insns : longint;
+ attsuffile,propfile,opfile,
+ nopfile,attfile,intfile,
+ infile,insfile : text;
+ { instruction fields }
+ skip : boolean;
+ last,
+ ops : longint;
+ intopcode,
+ attopcode,
+ opcode,
+ codes,
+ flags : string;
+ optypes : array[1..3] of string;
+begin
+ writeln('Nasm Instruction Table Converter Version ',Version);
+ x86_64:=paramstr(1)='x86_64';
+ insns:=0;
+ maxinfolen:=0;
+ { open dat file }
+ assign(infile,'../x86/x86ins.dat');
+ if x86_64 then
+ begin
+ { create inc files }
+ openinc(insfile,'x8664tab.inc');
+ openinc(opfile,'x8664op.inc');
+ assign(nopfile,'x8664nop.inc');
+ openinc(attfile,'x8664att.inc');
+ openinc(attsuffile,'x8664ats.inc');
+ openinc(intfile,'x8664int.inc');
+ openinc(propfile,'x8664pro.inc');
+ end
+ else
+ begin
+ { create inc files }
+ openinc(insfile,'i386tab.inc');
+ openinc(opfile,'i386op.inc');
+ assign(nopfile,'i386nop.inc');
+ openinc(attfile,'i386att.inc');
+ openinc(attsuffile,'i386atts.inc');
+ openinc(intfile,'i386int.inc');
+ openinc(propfile,'i386prop.inc');
+ end;
+ rewrite(nopfile);
+ writeln(nopfile,'{ don''t edit, this file is generated from x86ins.dat }');
+ reset(infile);
+ first:=true;
+ opcode:='';
+ firstopcode:=true;
+ while not(eof(infile)) do
+ begin
+ { handle comment }
+ readln(infile,s);
+ while (s[1]=' ') do
+ delete(s,1,1);
+ if (s='') or (s[1]=';') then
+ continue;
+ if (s[1]='[') then
+ begin
+ i:=pos(',',s);
+ j:=pos(']',s);
+ if i=0 then
+ begin
+ opcode:='A_'+Copy(s,2,j-2);
+ intopcode:=Copy(s,2,j-2);
+ { Conditional }
+ if (intopcode[length(intopcode)]='c') and
+ (intopcode[length(intopcode)-1]='c') then
+ dec(byte(intopcode[0]),2);
+ attopcode:=intopcode;
+ attsuffix:='attsufNONE';
+ end
+ else
+ begin
+ opcode:='A_'+Copy(s,2,i-2);
+ intopcode:=Copy(s,2,i-2);
+ { intel conditional }
+ if (intopcode[length(intopcode)]='c') and
+ (intopcode[length(intopcode)-1]='c') then
+ dec(byte(intopcode[0]),2);
+ attopcode:=Copy(s,i+1,j-i-1);
+ { att Suffix }
+ case attopcode[length(attopcode)] of
+ 'X' :
+ begin
+ dec(attopcode[0]);
+ attsuffix:='attsufINT';
+ end;
+ 'F' :
+ begin
+ dec(attopcode[0]);
+ attsuffix:='attsufFPU';
+ end;
+ 'R' :
+ begin
+ dec(attopcode[0]);
+ attsuffix:='attsufFPUint';
+ end;
+ else
+ attsuffix:='attsufNONE';
+ end;
+ { att Conditional }
+ if (attopcode[length(attopcode)]='C') and
+ (attopcode[length(attopcode)-1]='C') then
+ dec(byte(attopcode[0]),2);
+ end;
+ intopcode:=Lower(intopcode);
+ attopcode:=Lower(attopcode);
+ if firstopcode then
+ firstopcode:=false
+ else
+ begin
+ writeln(opfile,',');
+ writeln(attfile,',');
+ writeln(attsuffile,',');
+ writeln(intfile,',');
+ writeln(propfile,',');
+ end;
+ write(opfile,opcode);
+ write(intfile,'''',intopcode,'''');
+ write(attfile,'''',attopcode,'''');
+ write(attsuffile,attsuffix);
+ { read the next line which contains the Change options }
+ repeat
+ readln(infile,s);
+ until eof(infile) or ((s<>'') and (s[1]<>';'));
+ write(propfile,'(Ch: ',s,')');
+ continue;
+ end;
+ { we must have an opcode }
+ if opcode='' then
+ runerror(234);
+ { clear }
+ ops:=0;
+ optypes[1]:='';
+ optypes[2]:='';
+ optypes[3]:='';
+ codes:='';
+ flags:='';
+ skip:=false;
+ { ops and optypes }
+ i:=1;
+ repeat
+ hs:=readstr;
+ if (hs='void') or (hs='ignore') then
+ break;
+ inc(ops);
+ optypes[ops]:=optypes[ops]+'ot_'+formatop(hs);
+{ if s[i]=':' then
+ begin
+ inc(i);
+ optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
+ end;}
+ while s[i]='|' do
+ begin
+ inc(i);
+ optypes[ops]:=optypes[ops]+' or ot_'+formatop(readstr);
+ end;
+ if s[i] in [',',':'] then
+ inc(i)
+ else
+ break;
+ until false;
+ for j:=1 to 3-ops do
+ optypes[3-j+1]:='ot_none';
+ { codes }
+ skipspace;
+ j:=0;
+ last:=0;
+ if s[i] in ['\','0'..'9'] then
+ begin
+ while not(s[i] in [' ',#9]) do
+ begin
+ code:=readnumber;
+ { for some codes we want also to change the optypes, but not
+ if the last byte was a 1 then this byte belongs to a direct
+ copy }
+ if last<>1 then
+ begin
+ case code of
+ 12,13,14 :
+ optypes[code-11]:=optypes[code-11]+' or ot_signed';
+ end;
+ end;
+ codes:=codes+'#'+tostr(code);
+ last:=code;
+ inc(j);
+ end;
+ end
+ else
+ begin
+ readstr;
+ codes:='#0';
+ end;
+ if j>maxinfolen then
+ maxinfolen:=j;
+ { flags }
+ skipspace;
+ while not(s[i] in [' ',#9,#13,#10]) and (i<=length(s)) do
+ begin
+ hs:=readstr;
+ if x86_64 then
+ begin
+ if (upcase(hs)='NOX86_64') then
+ skip:=true;
+ end
+ else
+ begin
+ if (upcase(hs)='X86_64') then
+ skip:=true;
+ end;
+ if hs<>'ND' then
+ begin
+ if flags<>'' then
+ flags:=flags+' or ';
+ flags:=flags+'if_'+lower(hs);
+ end;
+ if (s[i]=',') and (i<=length(s)) then
+ inc(i)
+ else
+ break;
+ end;
+ { write instruction }
+ if not skip then
+ begin
+ if not(first) then
+ writeln(insfile,',')
+ else
+ first:=false;
+ writeln(insfile,' (');
+ writeln(insfile,' opcode : ',opcode,';');
+ writeln(insfile,' ops : ',ops,';');
+ writeln(insfile,' optypes : (',optypes[1],',',optypes[2],',',optypes[3],');');
+ writeln(insfile,' code : ',codes,';');
+ writeln(insfile,' flags : ',flags);
+ write(insfile,' )');
+ inc(insns);
+ end;
+ end;
+ close(infile);
+ closeinc(insfile);
+ closeinc(intfile);
+ closeinc(attfile);
+ closeinc(attsuffile);
+ closeinc(opfile);
+ writeln(nopfile,insns,';');
+ close(nopfile);
+ closeinc(propfile);
+ writeln(insns,' nodes procesed (maxinfolen=',maxinfolen,')');
+end.
diff --git a/compiler/utils/mkx86reg.pp b/compiler/utils/mkx86reg.pp
new file mode 100644
index 0000000000..4b0cf7ef6d
--- /dev/null
+++ b/compiler/utils/mkx86reg.pp
@@ -0,0 +1,467 @@
+{
+ Copyright (c) 1998-2002 by Peter Vreman and Florian Klaempfl
+
+ Convert i386reg.dat to several .inc files for usage with
+ the Free pascal compiler
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+{$mode objfpc}
+{$i+}
+program mkx86reg;
+
+const Version = '1.00';
+ max_regcount = 128;
+
+var s : string;
+ i : longint;
+ line : longint;
+ regcount:byte;
+ regcount_bsstart:byte;
+ names,numbers,stdnames,intnames,nasmnames,attnames,stabs,dwarf32,dwarf64,ots,ops:
+ array[0..max_regcount-1] of string[63];
+ regnumber_index,std_regname_index,int_regname_index,att_regname_index,
+ nasm_regname_index:array[0..max_regcount-1] of byte;
+ x86_64 : boolean;
+ fileprefix : string;
+
+{$ifndef FPC}
+ procedure readln(var t:text;var s:string);
+ var
+ c : char;
+ i : longint;
+ begin
+ c:=#0;
+ i:=0;
+ while (not eof(t)) and (c<>#10) do
+ begin
+ read(t,c);
+ if c<>#10 then
+ begin
+ inc(i);
+ s[i]:=c;
+ end;
+ end;
+ if (i>0) and (s[i]=#13) then
+ dec(i);
+ s[0]:=chr(i);
+ end;
+{$endif}
+
+function tostr(l : longint) : string;
+
+begin
+ str(l,tostr);
+end;
+
+function readstr : string;
+ begin
+ result:='';
+ while (s[i]<>',') and (i<=length(s)) do
+ begin
+ result:=result+s[i];
+ inc(i);
+ end;
+ readstr:=result;
+ end;
+
+
+procedure readcomma;
+ begin
+ if s[i]<>',' then
+ begin
+ writeln('Missing "," at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ inc(i);
+ end;
+
+
+procedure skipspace;
+
+ begin
+ while (s[i] in [' ',#9]) do
+ inc(i);
+ end;
+
+procedure openinc(var f:text;const fn:string);
+begin
+ writeln('creating ',fn);
+ assign(f,fn);
+ rewrite(f);
+ writeln(f,'{ don''t edit, this file is generated from x86reg.dat }');
+end;
+
+
+procedure closeinc(var f:text);
+begin
+ writeln(f);
+ close(f);
+end;
+
+procedure build_regnum_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ regnumber_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if numbers[regnumber_index[j]]>=numbers[regnumber_index[i]] then
+ break;
+ t:=regnumber_index[i];
+ regnumber_index[i]:=regnumber_index[j];
+ regnumber_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure build_std_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ std_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if stdnames[std_regname_index[j]]>=stdnames[std_regname_index[i]] then
+ break;
+ t:=std_regname_index[i];
+ std_regname_index[i]:=std_regname_index[j];
+ std_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure build_int_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ int_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if intnames[int_regname_index[j]]>=intnames[int_regname_index[i]] then
+ break;
+ t:=int_regname_index[i];
+ int_regname_index[i]:=int_regname_index[j];
+ int_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure build_att_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ att_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if attnames[att_regname_index[j]]>=attnames[att_regname_index[i]] then
+ break;
+ t:=att_regname_index[i];
+ att_regname_index[i]:=att_regname_index[j];
+ att_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure build_nasm_regname_index;
+
+var h,i,j,p,t:byte;
+
+begin
+ {Build the registernumber2regindex index.
+ Step 1: Fill.}
+ for i:=0 to regcount-1 do
+ nasm_regname_index[i]:=i;
+ {Step 2: Sort. We use a Shell-Metzner sort.}
+ p:=regcount_bsstart;
+ repeat
+ for h:=0 to regcount-p-1 do
+ begin
+ i:=h;
+ repeat
+ j:=i+p;
+ if nasmnames[nasm_regname_index[j]]>=nasmnames[nasm_regname_index[i]] then
+ break;
+ t:=nasm_regname_index[i];
+ nasm_regname_index[i]:=nasm_regname_index[j];
+ nasm_regname_index[j]:=t;
+ if i<p then
+ break;
+ dec(i,p);
+ until false;
+ end;
+ p:=p shr 1;
+ until p=0;
+end;
+
+procedure read_x86reg_file;
+
+var infile:text;
+ cpustr:string;
+
+begin
+ { open dat file }
+ assign(infile,'x86reg.dat');
+ reset(infile);
+ while not(eof(infile)) do
+ begin
+ { handle comment }
+ readln(infile,s);
+ inc(line);
+ while (s[1]=' ') do
+ delete(s,1,1);
+ if (s='') or (s[1]=';') then
+ continue;
+
+ i:=1;
+ names[regcount]:=readstr;
+ readcomma;
+ numbers[regcount]:=readstr;
+ readcomma;
+ stdnames[regcount]:=readstr;
+ readcomma;
+ attnames[regcount]:=readstr;
+ readcomma;
+ intnames[regcount]:=readstr;
+ readcomma;
+ nasmnames[regcount]:=readstr;
+ readcomma;
+ stabs[regcount]:=readstr;
+ readcomma;
+ dwarf32[regcount]:=readstr;
+ readcomma;
+ dwarf64[regcount]:=readstr;
+ readcomma;
+ ots[regcount]:=readstr;
+ readcomma;
+ ops[regcount]:=readstr;
+ if s[i]=',' then
+ begin
+ readcomma;
+ cpustr:=readstr;
+ end
+ else
+ cpustr:='';
+ if i<length(s) then
+ begin
+ writeln('Extra chars at end of line, at line ',line);
+ writeln('Line: "',s,'"');
+ halt(1);
+ end;
+ if (cpustr<>'64') or x86_64 then
+ begin
+ inc(regcount);
+ if regcount>max_regcount then
+ begin
+ writeln('Error: Too much registers, please increase maxregcount in source');
+ halt(2);
+ end;
+ end;
+ end;
+ close(infile);
+end;
+
+procedure write_inc_files;
+
+var attfile,intfile,otfile,opfile,
+ norfile,nasmfile,stdfile,
+ numfile,stabfile,dwrffile,confile,
+ rnifile,irifile,srifile,
+ arifile,nrifile:text;
+ first:boolean;
+
+begin
+ { create inc files }
+ openinc(confile,fileprefix+'con.inc');
+ openinc(numfile,fileprefix+'num.inc');
+ openinc(stdfile,fileprefix+'std.inc');
+ openinc(attfile,fileprefix+'att.inc');
+ openinc(intfile,fileprefix+'int.inc');
+ if not(x86_64) then
+ begin
+ openinc(nasmfile,fileprefix+'nasm.inc');
+ end;
+ openinc(stabfile,fileprefix+'stab.inc');
+ openinc(dwrffile,fileprefix+'dwrf.inc');
+ openinc(otfile,fileprefix+'ot.inc');
+ openinc(opfile,fileprefix+'op.inc');
+ openinc(norfile,fileprefix+'nor.inc');
+ openinc(rnifile,fileprefix+'rni.inc');
+ openinc(srifile,fileprefix+'sri.inc');
+ openinc(arifile,fileprefix+'ari.inc');
+ openinc(irifile,fileprefix+'iri.inc');
+ if not(x86_64) then
+ begin
+ openinc(nrifile,fileprefix+'nri.inc');
+ end;
+ first:=true;
+ for i:=0 to regcount-1 do
+ begin
+ if not first then
+ begin
+ writeln(numfile,',');
+ writeln(stdfile,',');
+ writeln(attfile,',');
+ writeln(intfile,',');
+ if not(x86_64) then
+ begin
+ writeln(nasmfile,',');
+ end;
+ writeln(stabfile,',');
+ writeln(dwrffile,',');
+ writeln(otfile,',');
+ writeln(opfile,',');
+ writeln(rnifile,',');
+ writeln(srifile,',');
+ writeln(arifile,',');
+ writeln(irifile,',');
+ if not(x86_64) then
+ begin
+ writeln(nrifile,',');
+ end;
+ end
+ else
+ first:=false;
+ writeln(confile,names[i],' = ','tregister(',numbers[i],')',';');
+ write(numfile,'tregister(',numbers[i],')');
+ write(stdfile,'''',stdnames[i],'''');
+ write(attfile,'''',attnames[i],'''');
+ write(intfile,'''',intnames[i],'''');
+ if not(x86_64) then
+ begin
+ write(nasmfile,'''',nasmnames[i],'''');
+ end;
+ write(stabfile,stabs[i]);
+ if x86_64 then
+ write(dwrffile,dwarf64[i])
+ else
+ write(dwrffile,dwarf32[i]);
+ write(otfile,ots[i]);
+ write(opfile,ops[i]);
+ write(rnifile,regnumber_index[i]);
+ write(srifile,std_regname_index[i]);
+ write(arifile,att_regname_index[i]);
+ write(irifile,int_regname_index[i]);
+ if not(x86_64) then
+ begin
+ write(nrifile,nasm_regname_index[i]);
+ end;
+ end;
+ write(norfile,regcount);
+ close(confile);
+ closeinc(numfile);
+ closeinc(attfile);
+ closeinc(stdfile);
+ closeinc(intfile);
+ if not(x86_64) then
+ begin
+ closeinc(nasmfile);
+ end;
+ closeinc(stabfile);
+ closeinc(dwrffile);
+ closeinc(otfile);
+ closeinc(opfile);
+ closeinc(norfile);
+ closeinc(rnifile);
+ closeinc(srifile);
+ closeinc(arifile);
+ closeinc(irifile);
+ if not(x86_64) then
+ begin
+ closeinc(nrifile);
+ end;
+ writeln('Done!');
+ writeln(regcount,' registers procesed');
+end;
+
+
+begin
+ writeln('Register Table Converter Version ',Version);
+ x86_64:=paramstr(1)='x86_64';
+ if x86_64 then
+ fileprefix:='r8664'
+ else
+ fileprefix:='r386';
+ line:=0;
+ regcount:=0;
+ read_x86reg_file;
+ regcount_bsstart:=1;
+ while 2*regcount_bsstart<regcount do
+ regcount_bsstart:=regcount_bsstart*2;
+ build_regnum_index;
+ if not(x86_64) then
+ begin
+ build_int_regname_index;
+ build_nasm_regname_index;
+ end;
+ build_std_regname_index;
+ build_att_regname_index;
+ write_inc_files;
+end.
diff --git a/compiler/utils/msg2inc.pp b/compiler/utils/msg2inc.pp
new file mode 100644
index 0000000000..905d530952
--- /dev/null
+++ b/compiler/utils/msg2inc.pp
@@ -0,0 +1,815 @@
+{
+ This program is part of the Free Pascal run time library.
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ Convert a .msg file to an .inc file with a const array of char
+ And for the lazy docwriters it can also generate some TeX output
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+program msg2inc;
+uses
+ strings;
+
+{$ifdef unix}
+ {$define EOL_ONE_CHAR}
+{$endif unix}
+{$ifdef amiga}
+ {$define EOL_ONE_CHAR}
+{$endif amiga}
+{$ifdef morphos}
+ {$define EOL_ONE_CHAR}
+{$endif}
+{$ifdef macos}
+ {$define EOL_ONE_CHAR}
+{$endif}
+
+const
+ version='1.00';
+{$ifdef EOL_ONE_CHAR}
+ eollen=1;
+{$else}
+ eollen=2;
+{$endif}
+ msgparts = 20;
+
+type
+ TMode=(M_Char,M_Tex,M_Intel,M_String,M_Renumber);
+var
+ InFile,
+ OutFile,
+ OutName : string;
+ Mode : TMode;
+ TexHeader : boolean;
+
+ MsgTxt : pchar;
+ EnumTxt : pchar;
+ enumsize,
+ msgsize : longint;
+
+ msgidxmax : array[1..msgparts] of longint;
+ msgs : array[0..msgparts,0..999] of boolean;
+
+procedure LoadMsgFile(const fn:string);
+var
+ f : text;
+ error,
+ multiline : boolean;
+ code : word;
+ numpart,numidx,
+ line,i,j,num : longint;
+ ptxt,
+ penum : pchar;
+ number,
+ s,s1 : string;
+
+ procedure err(const msgstr:string);
+ begin
+ writeln('error in line ',line,': ',msgstr);
+ error:=true;
+ end;
+
+begin
+ Writeln('Loading messagefile ',fn);
+{Read the message file}
+ assign(f,fn);
+ {$I-}
+ reset(f);
+ {$I+}
+ if ioresult<>0 then
+ begin
+ WriteLn('fatal error: '+fn+' not found');
+ halt(1);
+ end;
+{ First parse the file and count bytes needed }
+ fillchar(msgidxmax,sizeof(msgidxmax),0);
+ fillchar(msgs,sizeof(msgs),0);
+ error:=false;
+ line:=0;
+ multiline:=false;
+ msgsize:=0;
+ while not eof(f) do
+ begin
+ readln(f,s);
+ inc(line);
+ if multiline then
+ begin
+ if s=']' then
+ multiline:=false
+ else
+ inc(msgsize,length(s)+1); { +1 for linebreak }
+ end
+ else
+ begin
+ if (s<>'') and not(s[1] in ['#',';','%']) then
+ begin
+ i:=pos('=',s);
+ if i>0 then
+ begin
+ j:=i+1;
+ if not(s[j] in ['0'..'9']) then
+ err('no number found')
+ else
+ begin
+ while (s[j] in ['0'..'9']) do
+ inc(j);
+ end;
+ if j-i-1<>5 then
+ err('number length is not 5');
+ number:=Copy(s,i+1,j-i-1);
+ { update the max index }
+ val(number,num,code);
+ numpart:=num div 1000;
+ if numpart=0 then
+ err('number should be > 1000');
+ numidx:=num mod 1000;
+ { duplicate ? }
+ if msgs[numpart,numidx] then
+ err('duplicate number found');
+ msgs[numpart,numidx]:=true;
+ { check range }
+ if numpart > msgparts then
+ err('number is to large')
+ else
+ if numidx > msgidxmax[numpart] then
+ msgidxmax[numpart]:=numidx;
+ if s[j+1]='[' then
+ begin
+ inc(msgsize,j-i);
+ multiline:=true
+ end
+ else
+ inc(msgsize,length(s)-i+1);
+ inc(enumsize,j);
+ end
+ else
+ err('no = found');
+ end;
+ end;
+ end;
+ if multiline then
+ err('still in multiline mode');
+ if error then
+ begin
+ close(f);
+ writeln('aborting');
+ halt(1);
+ end;
+{ alloc memory }
+ getmem(msgtxt,msgsize);
+ ptxt:=msgtxt;
+ getmem(enumtxt,enumsize);
+ penum:=enumtxt;
+{ now read the buffer in mem }
+ reset(f);
+ while not eof(f) do
+ begin
+ readln(f,s);
+ if multiline then
+ begin
+ if s=']' then
+ begin
+ multiline:=false;
+ { overwrite last eol }
+ dec(ptxt);
+ ptxt^:=#0;
+ inc(ptxt);
+ end
+ else
+ begin
+ move(s[1],ptxt^,length(s));
+ inc(ptxt,length(s));
+ ptxt^:=#10;
+ inc(ptxt);
+ end;
+ end
+ else
+ begin
+ if (s<>'') and not(s[1] in ['#',';','%']) then
+ begin
+ i:=pos('=',s);
+ if i>0 then
+ begin
+ j:=i+1;
+ while (s[j] in ['0'..'9']) do
+ inc(j);
+ {enum}
+ move(s[1],penum^,i-1);
+ inc(penum,i-1);
+ penum^:='=';
+ inc(penum);
+ number:=Copy(s,i+1,j-i-1);
+ move(number[1],penum^,length(number));
+ inc(penum,length(number));
+ penum^:=#0;
+ inc(penum);
+ { multiline start then no txt }
+ if s[j+1]='[' then
+ begin
+ s1:=Copy(s,i+1,j-i);
+ move(s1[1],ptxt^,length(s1));
+ inc(ptxt,length(s1));
+ multiline:=true;
+ end
+ else
+ begin
+ { txt including number }
+ s1:=Copy(s,i+1,255);
+ move(s1[1],ptxt^,length(s1));
+ inc(ptxt,length(s1));
+ ptxt^:=#0;
+ inc(ptxt);
+ end;
+ end;
+ end;
+ end;
+ end;
+ close(f);
+end;
+
+
+{*****************************************************************************
+ WriteEnumFile
+*****************************************************************************}
+
+procedure WriteEnumFile(const fn,typename:string);
+var
+ t : text;
+ i : longint;
+ p : pchar;
+ start : boolean;
+begin
+ writeln('Writing enumfile '+fn);
+{Open textfile}
+ assign(t,fn);
+ rewrite(t);
+ writeln(t,'const');
+{Parse buffer in msgbuf and create indexs}
+ p:=enumtxt;
+ start:=true;
+ for i:=1 to enumsize do
+ begin
+ if start then
+ begin
+ write(t,' ');
+ start:=false;
+ end;
+ if p^=#0 then
+ begin
+ writeln(t,';');
+ start:=true;
+ end
+ else
+ begin
+ write(t,p^);
+ end;
+ inc(p);
+ end;
+ writeln(t,'');
+ { msgtxt size }
+ writeln(t,' MsgTxtSize = ',msgsize,';');
+ writeln(t,'');
+ { max msg idx table }
+ writeln(t,' MsgIdxMax : array[1..20] of longint=(');
+ write(t,' ');
+ for i:=1 to 20 do
+ begin
+ write(t,msgidxmax[i]+1);
+ if i<20 then
+ write(t,',');
+ if i=10 then
+ begin
+ writeln(t,'');
+ write(t,' ');
+ end;
+ end;
+ writeln(t,'');
+ writeln(t,' );');
+ close(t);
+end;
+
+
+{*****************************************************************************
+ WriteStringFile
+*****************************************************************************}
+
+procedure WriteStringFile(const fn,constname:string);
+const
+ maxslen=240; { to overcome aligning problems }
+
+ function l0(l:longint):string;
+ var
+ s : string[16];
+ begin
+ str(l,s);
+ while (length(s)<5) do
+ s:='0'+s;
+ l0:=s;
+ end;
+
+var
+ t : text;
+ f : file;
+ slen,
+ len,i : longint;
+ p : pchar;
+ s : string;
+ start,
+ quote : boolean;
+begin
+ writeln('Writing stringfile ',fn);
+{Open textfile}
+ assign(t,fn);
+ rewrite(t);
+ writeln(t,'{$ifdef Delphi}');
+ writeln(t,'const '+constname+' : array[0..000000] of string[',maxslen,']=(');
+ writeln(t,'{$else Delphi}');
+ writeln(t,'const '+constname+' : array[0..000000,1..',maxslen,'] of char=(');
+ write(t,'{$endif Delphi}');
+{Parse buffer in msgbuf and create indexs}
+ p:=msgtxt;
+ slen:=0;
+ len:=0;
+ quote:=false;
+ start:=true;
+ for i:=1 to msgsize do
+ begin
+ if slen>=maxslen then
+ begin
+ if quote then
+ begin
+ write(t,'''');
+ quote:=false;
+ end;
+ write(t,',');
+ slen:=0;
+ inc(len);
+ end;
+ if (len>70) or (start) then
+ begin
+ if quote then
+ begin
+ write(t,'''');
+ quote:=false;
+ end;
+ if slen>0 then
+ writeln(t,'+')
+ else
+ writeln(t);
+ len:=0;
+ start:=false;
+ end;
+ if (len=0) then
+ write(t,' ');
+ if (ord(p^)>=32) and (p^<>#39) then
+ begin
+ if not quote then
+ begin
+ write(t,'''');
+ quote:=true;
+ inc(len);
+ end;
+ write(t,p^);
+ inc(len);
+ end
+ else
+ begin
+ if quote then
+ begin
+ write(t,'''');
+ inc(len);
+ quote:=false;
+ end;
+ write(t,'#'+chr(ord(p^) div 100+48)+chr((ord(p^) mod 100) div 10+48)+chr(ord(p^) mod 10+48));
+ inc(len,3);
+ end;
+ if p^ in [#0,#10] then
+ start:=true;
+ inc(slen);
+ inc(p);
+ end;
+ if quote then
+ write(t,'''');
+ writeln(t,'');
+ writeln(t,');');
+ close(t);
+{update arraysize}
+ s:=l0(msgsize div maxslen); { we start with 0 }
+ assign(f,fn);
+ reset(f,1);
+ seek(f,34+eollen+length(constname));
+ blockwrite(f,s[1],5);
+ seek(f,90+3*eollen+2*length(constname));
+ blockwrite(f,s[1],5);
+ close(f);
+end;
+
+
+{*****************************************************************************
+ WriteCharFile
+*****************************************************************************}
+
+procedure WriteCharFile(const fn,constname:string);
+
+ function l0(l:longint):string;
+ var
+ s : string[16];
+ begin
+ str(l,s);
+ while (length(s)<5) do
+ s:='0'+s;
+ l0:=s;
+ end;
+
+ function createconst(b:byte):string;
+ begin
+ if (b in [32..127]) and (b<>39) then
+ createconst:=''''+chr(b)+''''
+ else
+ createconst:='#'+chr(b div 100+48)+chr((b mod 100) div 10+48)+chr(b mod 10+48)
+ end;
+
+var
+ t : text;
+ f : file;
+ cidx,i : longint;
+ p : pchar;
+ s : string;
+begin
+ writeln('Writing charfile '+fn);
+{Open textfile}
+ assign(t,fn);
+ rewrite(t);
+ writeln(t,'const ',constname,' : array[1..00000] of char=(');
+{Parse buffer in msgbuf and create indexs}
+ p:=msgtxt;
+ cidx:=0;
+ for i:=1to msgsize do
+ begin
+ if cidx=15 then
+ begin
+ if cidx>0 then
+ writeln(t,',')
+ else
+ writeln(t,'');
+ write(t,' ');
+ cidx:=0;
+ end
+ else
+ if cidx>0 then
+ write(t,',')
+ else
+ write(t,' ');
+ write(t,createconst(ord(p^)));
+ inc(cidx);
+ inc(p);
+ end;
+ writeln(t,');');
+ close(t);
+{update arraysize}
+ s:=l0(msgsize);
+ assign(f,fn);
+ reset(f,1);
+ seek(f,18+length(constname));
+ blockwrite(f,s[1],5);
+ close(f);
+end;
+
+
+{*****************************************************************************
+ WriteIntelFile
+*****************************************************************************}
+
+procedure WriteIntelFile(const fn,constname:string);
+var
+ t : text;
+ len,i : longint;
+ p : pchar;
+ start,
+ quote : boolean;
+begin
+ writeln('Writing Intelfile ',fn);
+{Open textfile}
+ assign(t,fn);
+ rewrite(t);
+ writeln(t,'procedure '+constname+';assembler;');
+ writeln(t,'asm');
+{Parse buffer in msgbuf and create indexs}
+ p:=msgtxt;
+ len:=0;
+ start:=true;
+ quote:=false;
+ for i:=1to msgsize do
+ begin
+ if len>70 then
+ begin
+ if quote then
+ begin
+ write(t,'''');
+ quote:=false;
+ end;
+ writeln(t,'');
+ start:=true;
+ end;
+ if start then
+ begin
+ write(t,' db ''');
+ len:=0;
+ quote:=true;
+ end;
+ if (ord(p^)>=32) and (p^<>#39) then
+ begin
+ if not quote then
+ begin
+ write(t,',''');
+ quote:=true;
+ inc(len);
+ end;
+ write(t,p^);
+ inc(len);
+ end
+ else
+ begin
+ if quote then
+ begin
+ write(t,'''');
+ inc(len);
+ quote:=false;
+ end;
+ write(t,','+chr(ord(p^) div 100+48)+chr((ord(p^) mod 100) div 10+48)+chr(ord(p^) mod 10+48));
+ inc(len,4);
+ end;
+ inc(p);
+ end;
+ if quote then
+ write(t,'''');
+ writeln(t,'');
+ writeln(t,'end;');
+ close(t);
+end;
+
+
+{*****************************************************************************
+ RenumberFile
+*****************************************************************************}
+
+procedure RenumberFile(const fn,name:string);
+var
+ f,t : text;
+ i : longint;
+ s,s1 : string;
+begin
+ Writeln('Renumbering ',fn);
+{Read the message file}
+ assign(f,fn);
+ {$I-}
+ reset(f);
+ {$I+}
+ if ioresult<>0 then
+ begin
+ WriteLn('*** message file '+fn+' not found ***');
+ exit;
+ end;
+ assign(t,'msg2inc.$$$');
+ rewrite(t);
+ i:=0;
+ while not eof(f) do
+ begin
+ readln(f,s);
+ if (copy(s,1,length(Name))=Name) and (s[3] in ['0'..'9']) then
+ begin
+ inc(i);
+ str(i,s1);
+ while length(s1)<3 do
+ s1:='0'+s1;
+ writeln(t,Name+s1+Copy(s,6,255));
+ end
+ else
+ writeln(t,s);
+ end;
+ close(t);
+ close(f);
+{ rename new file }
+ erase(f);
+ rename(t,fn);
+end;
+
+
+{*****************************************************************************
+ WriteTexFile
+*****************************************************************************}
+
+Function EscapeString (Const S : String) : String;
+Var
+ I : longint;
+ hs : string;
+begin
+ hs:='';
+ for i:=1 to length(s) do
+ if (S[i]='$') then
+ begin
+ if (s[i+1] in ['0'..'9']) then
+ hs:=hs+'arg'
+ else
+ hs:=hs+'\$';
+ end
+ else
+ hs:=hs+s[i];
+ EscapeString:=hs;
+end;
+
+procedure WriteTexFile(const infn,outfn:string);
+var
+ t,f : text;
+ line,
+ i,k : longint;
+ s,s1 : string;
+ texoutput : boolean;
+begin
+ Writeln('Loading messagefile ',infn);
+ writeln('Writing TeXfile ',outfn);
+{ Open infile }
+ assign(f,infn);
+ {$I-}
+ reset(f);
+ {$I+}
+ if ioresult<>0 then
+ begin
+ WriteLn('*** message file '+infn+' not found ***');
+ exit;
+ end;
+{ Open outfile }
+ assign(t,outfn);
+ rewrite(t);
+ If texheader then
+ begin
+ writeln (t,'\documentclass{article}');
+ writeln (t,'\usepackage{html}');
+ writeln (t,'\usepackage{fpc}');
+ writeln (t,'\begin{document}');
+ end;
+{ Parse }
+ line:=0;
+ TexOutput:=False;
+ while not eof(f) do
+ begin
+ readln(f,s);
+ inc(line);
+ If Pos ('# BeginOfTeX',S)=1 then
+ TexOutPut:=True
+ else if pos ('# EndOfTeX',S)=1 then
+ TexOutPut:=False;
+ if (s<>'') and not(s[1] in ['#',';']) and TeXOutPut then
+ begin
+ if s[1]='%' then
+ begin
+ Delete(s,1,1);
+ writeln(t,s);
+ end
+ else
+ begin
+ i:=pos('=',s);
+ if i>0 then
+ begin
+ inc(i);
+ while s[i] in ['0'..'9'] do
+ inc(i);
+ inc(i);
+ s1:='';
+ k:=0;
+ while (k<5) and (s[i+k]<>'_') do
+ begin
+ case s[i+k] of
+ 'W' : s1:='Warning: ';
+ 'E' : s1:='Error: ';
+ 'F' : s1:='Fatal: ';
+ 'N' : s1:='Note: ';
+ 'I' : s1:='Info: ';
+ 'H' : s1:='Hint: ';
+ end;
+ inc(k);
+ end;
+ if s[i+k]='_' then
+ inc(i,k+1);
+ writeln(t,'\item ['+s1+escapestring(Copy(s,i,255))+']');
+ end
+ else
+ writeln('error in line: ',line,' skipping');
+ end;
+ end;
+ end;
+ If TexHeader then
+ writeln (t,'\end{document}');
+ close(t);
+ close(f);
+end;
+
+
+{*****************************************************************************
+ Main Program
+*****************************************************************************}
+
+procedure getpara;
+var
+ ch : char;
+ para : string;
+ files,i : word;
+
+ procedure helpscreen;
+ begin
+ writeln('usage : msg2inc [Options] <msgfile> <incfile> <constname>');
+ writeln('<Options> can be : -T Create .doc TeX file');
+ writeln(' -TS Create .doc TeX file (stand-alone)');
+ writeln(' -I Intel style asm output');
+ writeln(' -S array of string');
+ writeln(' -C array of char');
+ writeln(' -R renumber section <incfile>');
+ writeln(' -V Show version');
+ writeln(' -? or -H This HelpScreen');
+ halt(1);
+ end;
+
+begin
+ Mode:=M_String;
+ FIles:=0;
+ for i:=1to paramcount do
+ begin
+ para:=paramstr(i);
+ if (para[1]='-') then
+ begin
+ ch:=upcase(para[2]);
+ delete(para,1,2);
+ case ch of
+ 'T' : begin
+ case upcase(para[1]) of
+ 'S' : TexHeader:=True;
+ end;
+ Mode:=M_Tex;
+ end;
+ 'I' : Mode:=M_Intel;
+ 'S' : Mode:=M_String;
+ 'C' : Mode:=M_Char;
+ 'R' : Mode:=M_Renumber;
+ 'V' : begin
+ Writeln('Msg2Inc ',version,' for Free Pascal (C) 1998-2002 Peter Vreman');
+ Writeln;
+ Halt;
+ end;
+ '?','H' : helpscreen;
+ end;
+ end
+ else
+ begin
+ inc(Files);
+ if Files>3 then
+ HelpScreen;
+ case Files of
+ 1 : InFile:=Para;
+ 2 : OutFile:=Para;
+ 3 : OutName:=Para;
+ end;
+ end;
+ end;
+ case Mode of
+ M_Renumber,
+ M_Tex : if Files<2 then
+ Helpscreen;
+ else
+ if FIles<3 then
+ HelpScreen;
+ end;
+end;
+
+
+begin
+ GetPara;
+ case Mode of
+ M_Renumber : begin
+ Renumberfile(Infile,OutFile);
+ end;
+ M_Tex : begin
+ WriteTexFile(InFile,Outfile);
+ end;
+ M_Intel : begin
+ Loadmsgfile(InFile);
+ WriteEnumFile(OutFile+'idx.inc',OutName+'const');
+ WriteIntelFile(OutFile+'txt.inc',OutName+'txt');
+ end;
+ M_String : begin
+ Loadmsgfile(InFile);
+ WriteEnumFile(OutFile+'idx.inc',OutName+'const');
+ WriteStringFile(OutFile+'txt.inc',OutName+'txt');
+ end;
+ M_Char : begin
+ Loadmsgfile(InFile);
+ WriteEnumFile(OutFile+'idx.inc',OutName+'const');
+ WriteCharFile(OutFile+'txt.inc',OutName+'txt');
+ end;
+ end;
+end.
diff --git a/compiler/utils/msgdif.pp b/compiler/utils/msgdif.pp
new file mode 100644
index 0000000000..1052f30bc8
--- /dev/null
+++ b/compiler/utils/msgdif.pp
@@ -0,0 +1,529 @@
+{
+ This program is part of the Free Pascal run time library.
+ Copyright (c) 1998-2002 by Peter Vreman
+
+ Show the differences between two .msg files
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+{ May be we need to compare a prefixes of option_help_pages too?
+ Currently this is not performed }
+
+Program messagedif;
+
+{$h+} {Huge strings}
+
+Uses
+ Strings;
+
+Type
+ TEnum = String;
+ TText = String;
+
+ PMsg = ^TMsg;
+ TMsg = Record
+ Line, ctxt, cnb : Longint;
+ enum : TEnum;
+ text : TText;
+ comment : pchar;
+ Next,Prev : PMsg;
+ FileNext,
+ Equivalent : PMsg;
+ end;
+Var
+ OrgFileName,DiffFileName : String;
+ OrgRoot,DiffRoot : PMsg;
+ OrgFirst,DiffFirst : PMsg;
+ Last : PMsg;
+
+const
+ NewFileName = 'new.msg';
+ Is_interactive : boolean = false;
+ Auto_verbosity : boolean = false;
+
+
+Procedure GetTranslation( p : PMsg);
+var
+ s : string;
+ i,j,k : longint;
+begin
+ i:=pos('_',p^.text);
+ if i>0 then
+ for j:=i+1 to Length(p^.text) do
+ if p^.text[j]='_' then
+ begin
+ i:=j;
+ break;
+ end;
+ if (i>0) and (i<=15) then
+ Writeln(P^.Enum,' type "',copy(p^.text,1,i-1),'" "',copy(p^.text,i+1,255),'"')
+ else
+ Writeln(P^.enum,' "',p^.text,'"');
+ Writeln('Type translated error message in,');
+ Writeln('Press return to keep it unchanged, or "q" to finish interactive mode');
+ Readln(s);
+ if s='' then
+ exit;
+ if s='q' then
+ begin
+ Is_interactive:=false;
+ exit;
+ end;
+ j:=pos('_',s);
+ if j>0 then
+ for k:=j+1 to Length(s) do
+ if s[j]='_' then
+ begin
+ j:=k;
+ break;
+ end;
+ if (j>0) then
+ begin
+ if copy(p^.text,1,i)<>copy(s,1,j) then
+ Writeln('Warning : different verbosity !!');
+ p^.text:=s;
+ end
+ else
+ p^.text:=copy(p^.text,1,i)+s;
+end;
+
+Function NewMsg (Var RM : PMsg; L : Longint; Const E : TEnum;Const T : TText;C : pchar;NbLn,TxtLn : longint) : PMsg;
+
+Var
+ P,R : PMsg;
+
+begin
+ New(P);
+ with P^ do
+ begin
+ Line:=L;
+ Text:=T;
+ enum:=E;
+ comment:=c;
+ cnb:=NbLn;
+ ctxt:=TxtLn;
+ next:=Nil;
+ prev:=Nil;
+ filenext:=nil;
+ equivalent:=nil;
+ if assigned(last) then
+ last^.FileNext:=P;
+ last:=P;
+ end;
+ R:=RM;
+ While (R<>Nil) and (UpCase(R^.enum)>UpCase(P^.Enum)) do
+ begin
+ P^.Prev:=R;
+ R:=R^.next;
+ end;
+ if assigned(R) and (UpCase(R^.Enum)=UpCase(P^.Enum)) then
+ Writeln('Error ',R^.Enum,' duplicate');
+ P^.Next:=R;
+ If R<>Nil then
+ R^.Prev:=P;
+ If P^.Prev<>Nil then
+ P^.Prev^.Next:=P
+ else
+ RM:=P;
+ NewMsg:=P;
+end;
+
+Procedure PrintList(const name : string;R : PMsg);
+var
+ P : PMsg;
+ f : text;
+begin
+ P:=R;
+ Assign(f,name);
+ Rewrite(f);
+ while assigned(P) do
+ begin
+ Writeln(f,UpCase(P^.Enum));
+ P:=P^.Next;
+ end;
+ Close(f);
+end;
+
+Procedure Usage;
+
+begin
+ Writeln('Usage : msgdif [options] <org-file> <dif-file>');
+ Writeln('Options:');
+ Writeln(' -i allow to enter translated messages interactively');
+ Writeln(' -y1 use <org-file> verbosity (do not query acknowledge)');
+ Writeln('');
+ Writeln('Generates "',NewFileName,'" that contain the messages from <dif-file>');
+ Writeln('with a new messages from <org-file>');
+ Writeln('');
+ Writeln('Example:');
+ Writeln(' msgdif errore.msg errorr.msg');
+ halt(1)
+end;
+
+Procedure ProcessOptions;
+var
+ i,count : longint;
+begin
+ Is_interactive:=false;
+ Auto_verbosity:=false;
+
+ count:=paramcount; i:=1;
+ while (count>0) and (Paramstr(i)[1]='-') do
+ case UpCase(Paramstr(i)[2]) of
+ 'I': begin
+ Is_interactive:=true;
+ dec(count); Inc(i);
+ end;
+ 'Y': case Paramstr(i)[3] of
+ '1': begin
+ Auto_verbosity:=true;
+ dec(count); Inc(i);
+ end;
+ else
+ Writeln ('Error: unknown option ', Paramstr(i));
+ Usage;
+ end;
+ else
+ Writeln ('Error: unknown option ', Paramstr(i));
+ Usage;
+ end;
+ If Count<>2 then begin
+ Writeln ('Error: there must be exactly two message files');
+ Usage;
+ end;
+
+ OrgfileName:=Paramstr(i);
+ DiffFileName:=Paramstr(i+1);
+ if (OrgFileName=NewFileName) or (DiffFileName=NewFileName) then
+ begin
+ Writeln('The file names must be different from ',NewFileName);
+ Halt(1);
+ end;
+end;
+
+Procedure ProcessFile (FileName : String; Var Root,First : PMsg);
+
+Const
+ ArrayLength = 65500;
+Var F : Text;
+ S,prevS : String;
+ J,LineNo,Count,NbLn,TxtLn : Longint;
+ chararray : array[0..ArrayLength] of char;
+ currentindex : longint;
+ c : pchar;
+ multiline : boolean;
+begin
+ Assign(F,FileName);
+ Reset(F);
+ Write ('Processing: ',Filename,'...');
+ LineNo:=0;
+ NbLn:=0;
+ TxtLn:=0;
+ Count:=0;
+ currentindex:=0;
+ Root:=Nil;
+ First:=nil;
+ Last:=nil;
+ PrevS:='';
+ multiline:=false;
+ While not eof(f) do
+ begin
+ Readln(F,S);
+ Inc(LineNo);
+ If multiline then
+ begin
+ PrevS:=PrevS+#10+S; Inc(TxtLn);
+ if (Length(S)<>0) and (S[1]=']') then
+ multiline:=false;
+ end
+ else
+ if (length(S)>0) and Not (S[1] in ['%','#']) Then
+ begin
+ J:=Pos('=',S);
+ If j<1 then
+ writeln (Filename,'(',LineNo,') : Invalid entry')
+ else
+ begin
+ chararray[currentindex]:=#0;
+ c:=strnew(@chararray);
+ if PrevS<>'' then
+ NewMsg(Root,LineNo,Copy(PrevS,1,Pos('=',PrevS)-1),
+ Copy(PrevS,Pos('=',PrevS)+1,Length(PrevS)),c,NbLn,TxtLn)
+ else
+ StrDispose(c);
+ currentindex:=0;
+ NbLn:=0; TxtLn:=0;
+ PrevS:=S; Inc(TxtLn);
+ if S[j+7]='[' then multiline:=true;
+ if First=nil then
+ First:=Root;
+ Inc(Count);
+ end;
+ end
+ else
+ begin
+ if currentindex+length(s)+1>ArrayLength then
+ Writeln('Comment too long : over ',ArrayLength,' chars')
+ else
+ begin
+ strpcopy(@chararray[currentindex],s+#10);
+ inc(currentindex,length(s)+1);
+ inc(NbLn);
+ end;
+ end;
+ end;
+ chararray[currentindex]:=#0;
+ c:=strnew(@chararray);
+ if PrevS<>'' then
+ NewMsg(Root,LineNo,Copy(PrevS,1,Pos('=',PrevS)-1),
+ Copy(PrevS,Pos('=',PrevS)+1,Length(PrevS)),c,NbLn,TxtLn);
+ Writeln (' Done. Read ',LineNo,' lines, got ',Count,' constants.');
+ Close(f);
+end;
+
+Procedure ShowDiff (POrg,PDiff : PMsg);
+
+Var
+ count,orgcount,diffcount : longint;
+
+Procedure NotFound (Org : Boolean; P : PMsg);
+
+begin
+ With P^ do
+ If Org Then
+ Writeln ('Not found in ',DiffFileName,' : ',Enum,' ',OrgFileName,'(',Line,')')
+ else
+ Writeln ('Extra in ',DiffFileName,'(',line,') : ',enum);
+ if org then
+ inc(orgcount)
+ else
+ inc(diffcount);
+end;
+
+begin
+ orgcount:=0;
+ diffcount:=0;
+ count:=0;
+ While (Porg<>Nil) and (PDiff<>Nil) do
+ begin
+// Writeln (POrg^.enum,'<=>',PDiff^.Enum);
+ If UpCase(Porg^.Enum)>UpCase(PDiff^.Enum) then
+ begin
+ NotFound (True,Porg);
+ POrg:=POrg^.Next
+ end
+ else If UpCase(POrg^.enum)=UpCase(PDiff^.Enum) then
+ begin
+ inc(count);
+ POrg^.Equivalent:=PDiff;
+ PDiff^.Equivalent:=POrg;
+ POrg:=POrg^.Next;
+ PDiff:=PDiff^.Next;
+ end
+ else
+ begin
+ NotFound (False,PDiff);
+ PDiff:=PDiff^.Next
+ end;
+ end;
+ While POrg<>Nil do
+ begin
+ NotFound(True,Porg);
+ POrg:=pOrg^.Next;
+ end;
+ While PDiff<>Nil do
+ begin
+ NotFound(False,PDiff);
+ PDiff:=PDiff^.Next;
+ end;
+ Writeln(count,' messages found in common to both files');
+ Writeln(orgcount,' messages only in ',OrgFileName);
+ Writeln(diffcount,' messages only in ',DiffFileName);
+end;
+
+type TArgSet = set of 0..31;
+
+function MsgToSet(const Msg, FileName: string; var R: TArgSet): Boolean;
+ var
+ i, j, num : integer;
+ code : word;
+ begin
+ R:=[];
+ MsgToSet:=false;
+ for i:=1 to Length(Msg) do
+ if Msg[i]='$' then
+ begin
+ j:=i+1;
+ while Msg[j] in ['0'..'9'] do Inc(j);
+ if j > i+1 then
+ begin
+ val(copy(Msg,i+1,j-i-1),num,code);
+ if num > high(TArgSet) then begin
+ WriteLn('Error in ', FileName,': ', Msg);
+ WriteLn(' number at position ', i);
+ WriteLn(' must be LE ', high(TArgSet));
+ Exit;
+ end;
+ R:=R+[num];
+ end;
+ end;
+ MsgToSet:=true;
+ end;
+
+
+procedure CheckParm(const s1, s2: string);
+ var
+ R1, R2: TArgSet;
+ begin
+ if MsgToSet(s1,OrgFileName, R1) <> true then Exit;
+ if MsgToSet(s2,DiffFileName,R2) <> true then Exit;
+ if R1<>R2 then begin
+ WriteLn('Error: set of arguments is different');
+ WriteLn(' ',s1);
+ WriteLn(' ',s2);
+ end;
+ end;
+
+procedure WriteReorderedFile(FileName : string;orgnext,diffnext : PMsg);
+ var t,t2,t3 : text;
+ i,ntcount : longint;
+ j : integer;
+ s,s2,s3 : string;
+ is_msg : boolean;
+ nextdiffkept : pmsg;
+ begin
+ ntcount:=0;
+ Assign(t,FileName);
+ Rewrite(t);
+ Writeln(t,'%%% Reordering of ',DiffFileName,' respective to ',OrgFileName);
+ Writeln(t,'%%% Contains all comments from ',DiffFileName);
+ Assign(t2,DiffFileName);
+ Reset(t2);
+ Assign(t3,OrgFileName);
+ Reset(t3);
+ i:=2;
+ s:='';s3:='';
+ nextdiffkept:=diffnext;
+ while assigned(nextdiffkept) and (nextdiffkept^.equivalent=nil) do
+ nextdiffkept:=nextdiffkept^.filenext;
+ { First write the header of diff }
+ repeat
+ Readln(t2,s);
+ is_msg:=(pos('=',s)>1) and (s[1]<>'%') and (s[1]<>'#');
+ if not is_msg then
+ begin
+ Writeln(t,s);
+ inc(i);
+ end;
+ until is_msg;
+ { Write all messages in Org order }
+ while assigned(orgnext) do
+ begin
+ if not assigned(orgnext^.equivalent) then
+ begin
+ { Insert a new error msg with the english comments }
+ Writeln('New error ',orgnext^.enum,' added');
+ If Is_interactive then
+ GetTranslation(orgnext);
+ Writeln(t,orgnext^.enum,'=',orgnext^.text);
+ inc(i,orgnext^.ctxt);
+ Write(t,orgnext^.comment);
+ inc(i,orgnext^.cnb);
+ end
+ else
+ begin
+ inc(i);
+ if orgnext^.text=orgnext^.equivalent^.text then
+ begin
+ Writeln(FileName,'(',i,') ',orgnext^.enum,' not translated');
+ If Is_interactive then
+ GetTranslation(orgnext^.equivalent);
+ if orgnext^.text=orgnext^.equivalent^.text then
+ inc(ntcount);
+ end;
+ s2:=orgnext^.text;
+ j:=pos('_',copy(s2,7,20)) + 6;
+ s2:=upcase(copy(s2,1,j));
+ s3:=orgnext^.equivalent^.text;
+ j:=pos('_',copy(s3,7,20)) + 6;
+ s3:=upcase(copy(s3,1,j));
+ { that are the conditions in verbose unit }
+ if (length(s3)<12) and (s2<>s3) then
+ begin
+ Writeln('Warning: different options for ',orgnext^.enum);
+ Writeln(' ',orgnext^.text);
+ Writeln(' ',orgnext^.equivalent^.text);
+ s:='N';
+ if Auto_verbosity then
+ s:='Y'
+ else
+ If Is_interactive then
+ begin
+ Write('Use ',s2,' verbosity ? [y/n] ');
+ Readln(s);
+ end;
+ if UpCase(s[1])='Y' then
+ begin
+ orgnext^.equivalent^.text:=s2+copy(orgnext^.equivalent^.text,
+ length(s3)+1,Length(orgnext^.equivalent^.text));
+ WriteLn(' Using ', s2);
+ end;
+ end;
+
+ CheckParm(orgnext^.text, orgnext^.equivalent^.text);
+
+ Writeln(t,orgnext^.enum,'=',orgnext^.equivalent^.text);
+ Dec(i); Inc(i,orgnext^.equivalent^.ctxt);
+ if assigned(orgnext^.equivalent^.comment) and
+ (strlen(orgnext^.equivalent^.comment)>0) then
+ begin
+ Write(t,orgnext^.equivalent^.comment);
+ inc(i,orgnext^.equivalent^.cnb);
+ end
+ else if assigned(orgnext^.comment) and
+ (strlen(orgnext^.comment)>0) then
+ begin
+ Writeln('Comment from ',OrgFileName,' for enum ',orgnext^.enum,' added');
+ Write(t,orgnext^.comment);
+ inc(i,orgnext^.cnb);
+ end;
+ end;
+ orgnext:=orgnext^.filenext;
+ end;
+
+ while assigned(diffnext) do
+ begin
+ if not assigned(diffnext^.Equivalent) then
+ begin
+ { Skip removed enum in errore.msg}
+ { maybe a renaming of an enum !}
+ Writeln(diffnext^.enum,' commented out');
+ Writeln(t,'%%% ',diffnext^.enum,'=',diffnext^.text);
+ inc(i,diffnext^.ctxt);
+ Write(t,diffnext^.comment);
+ inc(i,diffnext^.cnb);
+ end;
+ diffnext:=diffnext^.filenext;
+ end;
+ Close(t);
+ Close(t2);
+ Close(t3);
+ Writeln(ntcount,' not translated items found');
+ end;
+
+begin
+ ProcessOptions;
+ ProcessFile(OrgFileName,orgroot,orgfirst);
+ ProcessFile(DiffFileName,diffRoot,difffirst);
+ PrintList('org.lst',OrgRoot);
+ PrintList('diff.lst',DiffRoot);
+ ShowDiff (OrgRoot,DiffRoot);
+ WriteReorderedFile(NewFileName,orgfirst,difffirst);
+end.
diff --git a/compiler/utils/msgused.pl b/compiler/utils/msgused.pl
new file mode 100644
index 0000000000..6ac46d655b
--- /dev/null
+++ b/compiler/utils/msgused.pl
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+#
+# find not used messages
+
+unlink("./msgidx.inc");
+unlink("./msgtxt.inc");
+@compiler_src = (glob("./*.inc"),
+ glob("./*.pas"));
+
+open(MESSAGE_FILE, "< ./msg/errore.msg") or
+ die "Couldn't open <./msg/errore.msg> for reading: $!\n";
+
+open(FOUND, "> MSG-OK.TXT") or
+ die "Couldn't open <MSG-OK.TXT> for writing: $!\n";
+
+select FOUND; $| = 1;
+
+open(NOT_FOUND, "> MSG_BAD.TXT") or
+ die "Couldn't open <MSG_BAD.TXT> for writing: $!\n";
+
+select NOT_FOUND; $| = 1;
+
+while (<MESSAGE_FILE>)
+{
+ if (/^(\w\w\w*?_\w\w*?_\w\w*?)=/)
+ {
+ $msg = $1;
+ $found = `grep -il $msg @compiler_src`;
+ if ($found) {
+ print stderr "$msg\n";
+ print FOUND $msg . "\n";
+ }
+ else {
+ print stderr "NOT FOUND \t $msg\n";
+ print NOT_FOUND $msg . "\n";
+ }
+ }
+}
+
+close(IN);
+close(FOUND);
+close(NOT_FOUND);
diff --git a/compiler/utils/ppudump.pp b/compiler/utils/ppudump.pp
new file mode 100644
index 0000000000..1d73b79276
--- /dev/null
+++ b/compiler/utils/ppudump.pp
@@ -0,0 +1,2191 @@
+{
+ Copyright (c) 1998-2002 by the FPC Development Team
+
+ Dumps the contents of a FPC unit file (PPU File)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************}
+{$ifdef TP}
+ {$N+,E+}
+{$endif}
+program pppdump;
+uses
+ dos,
+ ppu;
+
+const
+ Version = 'Version 2.0.0';
+ Title = 'PPU-Analyser';
+ Copyright = 'Copyright (c) 1998-2005 by the Free Pascal Development Team';
+
+{ verbosity }
+ v_none = $0;
+ v_header = $1;
+ v_defs = $2;
+ v_syms = $4;
+ v_interface = $8;
+ v_implementation = $10;
+ v_browser = $20;
+ v_all = $ff;
+
+type
+ tprocinfoflag=(
+ {# procedure uses asm }
+ pi_uses_asm,
+ {# procedure does a call }
+ pi_do_call,
+ {# procedure has a try statement = no register optimization }
+ pi_uses_exceptions,
+ {# procedure is declared as @var(assembler), don't optimize}
+ pi_is_assembler,
+ {# procedure contains data which needs to be finalized }
+ pi_needs_implicit_finally
+ );
+ tprocinfoflags=set of tprocinfoflag;
+
+ { Copied from systems.pas }
+ tsystemcpu=
+ (
+ cpu_no, { 0 }
+ cpu_i386, { 1 }
+ cpu_m68k, { 2 }
+ cpu_alpha, { 3 }
+ cpu_powerpc, { 4 }
+ cpu_sparc, { 5 }
+ cpu_vm, { 6 }
+ cpu_iA64, { 7 }
+ cpu_x86_64, { 8 }
+ cpu_mips, { 9 }
+ cpu_arm { 10 }
+ );
+
+var
+ ppufile : tppufile;
+ space : string;
+ unitindex : longint;
+ verbose : longint;
+ derefdata : pbyte;
+ derefdatalen : longint;
+
+{****************************************************************************
+ Helper Routines
+****************************************************************************}
+
+const has_errors : boolean = false;
+Procedure Error(const S : string);
+Begin
+ Writeln(S);
+ has_errors:=true;
+End;
+
+
+function ToStr(w:longint):String;
+begin
+ Str(w,ToStr);
+end;
+
+Function Target2Str(w:longint):string;
+type
+ { taken from systems.pas }
+ ttarget =
+ (
+ target_none, { 0 }
+ target_i386_GO32V1, { 1 }
+ target_i386_GO32V2, { 2 }
+ target_i386_linux, { 3 }
+ target_i386_OS2, { 4 }
+ target_i386_Win32, { 5 }
+ target_i386_freebsd, { 6 }
+ target_m68k_Amiga, { 7 }
+ target_m68k_Atari, { 8 }
+ target_m68k_Mac, { 9 }
+ target_m68k_linux, { 10 }
+ target_m68k_PalmOS, { 11 }
+ target_alpha_linux, { 12 }
+ target_powerpc_linux, { 13 }
+ target_powerpc_macos, { 14 }
+ target_i386_sunos, { 15 }
+ target_i386_beos, { 16 }
+ target_i386_netbsd, { 17 }
+ target_m68k_netbsd, { 18 }
+ target_i386_Netware, { 19 }
+ target_i386_qnx, { 20 }
+ target_i386_wdosx, { 21 }
+ target_sparc_sunos, { 22 }
+ target_sparc_linux, { 23 }
+ target_i386_openbsd, { 24 }
+ target_m68k_openbsd, { 25 }
+ system_x86_64_linux, { 26 }
+ system_powerpc_macosx, { 27 }
+ target_i386_emx, { 28 }
+ target_powerpc_netbsd, { 29 }
+ target_powerpc_openbsd, { 30 }
+ target_arm_linux, { 31 }
+ target_i386_watcom, { 32 }
+ target_powerpc_MorphOS, { 33 }
+ target_x86_64_freebsd, { 34 }
+ target_i386_netwlibc, { 35 }
+ system_powerpc_Amiga, { 36 }
+ system_x86_64_win64, { 37 }
+ system_arm_wince, { 38 }
+ system_ia64_win64, { 39 }
+ system_i386_wince, { 40 }
+ system_x86_6432_linux, { 41 }
+ system_arm_gba { 42 }
+ );
+const
+ Targets : array[ttarget] of string[17]=(
+ { 0 } 'none',
+ { 1 } 'GO32V1',
+ { 2 } 'GO32V2',
+ { 3 } 'Linux-i386',
+ { 4 } 'OS/2',
+ { 5 } 'Win32',
+ { 6 } 'FreeBSD-i386',
+ { 7 } 'Amiga',
+ { 8 } 'Atari',
+ { 9 } 'MacOS-m68k',
+ { 10 } 'Linux-m68k',
+ { 11 } 'PalmOS-m68k',
+ { 12 } 'Linux-alpha',
+ { 13 } 'Linux-ppc',
+ { 14 } 'MacOS-ppc',
+ { 15 } 'Solaris-i386',
+ { 16 } 'BeOS-i386',
+ { 17 } 'NetBSD-i386',
+ { 18 } 'NetBSD-m68k',
+ { 19 } 'Netware-i386-clib',
+ { 20 } 'Qnx-i386',
+ { 21 } 'WDOSX-i386',
+ { 22 } 'Solaris-sparc',
+ { 23 } 'Linux-sparc',
+ { 24 } 'OpenBSD-i386',
+ { 25 } 'OpenBSD-m68k',
+ { 26 } 'Linux-x86-64',
+ { 27 } 'MacOSX-ppc',
+ { 28 } 'OS/2 via EMX',
+ { 29 } 'NetBSD-powerpc',
+ { 30 } 'OpenBSD-powerpc',
+ { 31 } 'Linux-arm',
+ { 32 } 'Watcom-i386',
+ { 33 } 'MorphOS-powerpc',
+ { 34 } 'FreeBSD-x86-64',
+ { 35 } 'Netware-i386-libc',
+ { 36 } 'Amiga-PowerPC',
+ { 37 } 'Win64-x64',
+ { 38 } 'WinCE-ARM',
+ { 39 } 'Win64-iA64',
+ { 40 } 'WinCE-i386',
+ { 41 } 'Linux-x64',
+ { 42 } 'GBA-ARM'
+ );
+begin
+ if w<=ord(high(ttarget)) then
+ Target2Str:=Targets[ttarget(w)]
+ else
+ Target2Str:='<!! Unknown target value '+tostr(w)+'>';
+end;
+
+
+Function Cpu2Str(w:longint):string;
+const
+ CpuTxt : array[tsystemcpu] of string[8]=
+ ('none','i386','m68k','alpha','powerpc','sparc','vis','ia64','x86_64','mips','arm');
+begin
+ if w<=ord(high(tsystemcpu)) then
+ Cpu2Str:=CpuTxt[tsystemcpu(w)]
+ else
+ Cpu2Str:='<!! Unknown cpu value '+tostr(w)+'>';
+end;
+
+
+Function Varspez2Str(w:longint):string;
+const
+ varspezstr : array[0..4] of string[6]=('Value','Const','Var','Out','Hidden');
+begin
+ if w<=ord(high(varspezstr)) then
+ Varspez2Str:=varspezstr[w]
+ else
+ Varspez2Str:='<!! Unknown varspez value '+tostr(w)+'>';
+end;
+
+Function VarRegable2Str(w:longint):string;
+const
+ varregableStr : array[0..3] of string[6]=('None','IntReg','FPUReg','MMReg');
+begin
+ if w<=ord(high(varregablestr)) then
+ Varregable2Str:=varregablestr[w]
+ else
+ Varregable2Str:='<!! Unknown regable value '+tostr(w)+'>';
+end;
+
+
+function PPUFlags2Str(flags:longint):string;
+type
+ tflagopt=record
+ mask : longint;
+ str : string[30];
+ end;
+const
+ flagopts=19;
+ flagopt : array[1..flagopts] of tflagopt=(
+ (mask: $1 ;str:'init'),
+ (mask: $2 ;str:'final'),
+ (mask: $4 ;str:'big_endian'),
+ (mask: $8 ;str:'dbx'),
+ (mask: $10 ;str:'browser'),
+ (mask: $20 ;str:'in_library'),
+ (mask: $40 ;str:'smart_linked'),
+ (mask: $80 ;str:'static_linked'),
+ (mask: $100 ;str:'shared_linked'),
+ (mask: $200 ;str:'local_browser'),
+ (mask: $400 ;str:'no_link'),
+ (mask: $800 ;str:'has_resources'),
+ (mask: $1000 ;str:'little_endian'),
+ (mask: $2000 ;str:'release'),
+ (mask: $4000 ;str:'local_threadvars'),
+ (mask: $8000 ;str:'fpu_emulation_on'),
+ (mask: $10000 ;str:'has_debug_info'),
+ (mask: $20000 ;str:'local_symtable'),
+ (mask: $40000 ;str:'uses_variants')
+ );
+var
+ i : longint;
+ first : boolean;
+ s : string;
+begin
+ s:='';
+ if flags<>0 then
+ begin
+ first:=true;
+ for i:=1to flagopts do
+ if (flags and flagopt[i].mask)<>0 then
+ begin
+ if first then
+ first:=false
+ else
+ s:=s+', ';
+ s:=s+flagopt[i].str;
+ end;
+ end
+ else
+ s:='none';
+ PPUFlags2Str:=s;
+end;
+
+
+const
+ HexTbl : array[0..15] of char='0123456789ABCDEF';
+function HexB(b:byte):string;
+begin
+ HexB[0]:=#2;
+ HexB[1]:=HexTbl[b shr 4];
+ HexB[2]:=HexTbl[b and $f];
+end;
+
+
+function hexstr(val : cardinal;cnt : byte) : string;
+const
+ HexTbl : array[0..15] of char='0123456789ABCDEF';
+var
+ i : longint;
+begin
+ hexstr[0]:=char(cnt);
+ for i:=cnt downto 1 do
+ begin
+ hexstr[i]:=hextbl[val and $f];
+ val:=val shr 4;
+ end;
+end;
+
+
+ Function L0(l:longint):string;
+ {
+ return the string of value l, if l<10 then insert a zero, so
+ the string is always at least 2 chars '01','02',etc
+ }
+ var
+ s : string;
+ begin
+ Str(l,s);
+ if l<10 then
+ s:='0'+s;
+ L0:=s;
+ end;
+
+
+ function filetimestring( t : longint) : string;
+ {
+ convert dos datetime t to a string YY/MM/DD HH:MM:SS
+ }
+ var
+ DT : DateTime;
+ begin
+ if t=-1 then
+ begin
+ FileTimeString:='Not Found';
+ exit;
+ end;
+ unpacktime(t,DT);
+ filetimestring:=L0(dt.Year)+'/'+L0(dt.Month)+'/'+L0(dt.Day)+' '+L0(dt.Hour)+':'+L0(dt.min)+':'+L0(dt.sec);
+ end;
+
+
+{****************************************************************************
+ Read Routines
+****************************************************************************}
+
+Procedure ReadLinkContainer(const prefix:string);
+{
+ Read a serie of strings and write to the screen starting every line
+ with prefix
+}
+ function maskstr(m:longint):string;
+ const
+ { link options }
+ link_none = $0;
+ link_allways = $1;
+ link_static = $2;
+ link_smart = $4;
+ link_shared = $8;
+ var
+ s : string;
+ begin
+ s:='';
+ if (m and link_allways)<>0 then
+ s:=s+'always ';
+ if (m and link_static)<>0 then
+ s:=s+'static ';
+ if (m and link_smart)<>0 then
+ s:=s+'smart ';
+ if (m and link_shared)<>0 then
+ s:=s+'shared ';
+ maskstr:=s;
+ end;
+
+var
+ s : string;
+ m : longint;
+begin
+ while not ppufile.endofentry do
+ begin
+ s:=ppufile.getstring;
+ m:=ppufile.getlongint;
+ WriteLn(prefix,s,' (',maskstr(m),')');
+ end;
+end;
+
+
+Procedure ReadContainer(const prefix:string);
+{
+ Read a serie of strings and write to the screen starting every line
+ with prefix
+}
+begin
+ while not ppufile.endofentry do
+ WriteLn(prefix,ppufile.getstring);
+end;
+
+
+procedure ReadLoadUnit;
+var
+ ucrc,uintfcrc : cardinal;
+begin
+ while not ppufile.EndOfEntry do
+ begin
+ write('Uses unit: ',ppufile.getstring);
+ ucrc:=cardinal(ppufile.getlongint);
+ uintfcrc:=cardinal(ppufile.getlongint);
+ writeln(' (Crc: ',hexstr(ucrc,8),', IntfcCrc: ',hexstr(uintfcrc,8),')');
+ end;
+end;
+
+
+Procedure ReadDerefmap;
+var
+ i,mapsize : longint;
+begin
+ mapsize:=ppufile.getword;
+ writeln('DerefMapsize: ',mapsize);
+ for i:=0 to mapsize-1 do
+ writeln('DerefMap[',i,'] = ',ppufile.getstring);
+end;
+
+
+Procedure ReadDerefdata;
+begin
+ derefdatalen:=ppufile.entrysize;
+ if derefdatalen=0 then
+ begin
+ writeln('!! Error: derefdatalen=0');
+ exit;
+ end;
+ Writeln('Derefdata length: ',derefdatalen);
+ derefdata:=allocmem(derefdatalen);
+ ppufile.getdata(derefdata^,derefdatalen);
+end;
+
+
+Procedure ReadRef;
+begin
+ if (verbose and v_browser)=0 then
+ exit;
+ while (not ppufile.endofentry) and (not ppufile.error) do
+ Writeln(space,' - Refered : ',ppufile.getword,', (',ppufile.getlongint,',',ppufile.getword,')');
+end;
+
+
+Procedure ReadAsmSymbols;
+type
+ { Copied from aasmbase.pas }
+ TAsmsymbind=(AB_NONE,AB_EXTERNAL,AB_COMMON,AB_LOCAL,AB_GLOBAL);
+ TAsmsymtype=(AT_NONE,AT_FUNCTION,AT_DATA,AT_SECTION,AT_LABEL);
+var
+ s,
+ bindstr,
+ typestr : string;
+ i : longint;
+begin
+ writeln(space,'Number of AsmSymbols: ',ppufile.getlongint);
+ i:=0;
+ while (not ppufile.endofentry) and (not ppufile.error) do
+ begin
+ s:=ppufile.getstring;
+ case tasmsymbind(ppufile.getbyte) of
+ AB_EXTERNAL :
+ bindstr:='External';
+ AB_COMMON :
+ bindstr:='Common';
+ AB_LOCAL :
+ bindstr:='Local';
+ AB_GLOBAL :
+ bindstr:='Global';
+ else
+ bindstr:='<Error !!>'
+ end;
+ case tasmsymtype(ppufile.getbyte) of
+ AT_FUNCTION :
+ typestr:='Function';
+ AT_DATA :
+ typestr:='Data';
+ AT_SECTION :
+ typestr:='Section';
+ AT_LABEL :
+ typestr:='Label';
+ else
+ typestr:='<Error !!>'
+ end;
+ Writeln(space,' ',i,' : ',s,' [',bindstr,',',typestr,']');
+ inc(i);
+ end;
+end;
+
+
+Procedure ReadPosInfo;
+var
+ info : byte;
+ fileindex,line,column : longint;
+begin
+ with ppufile do
+ begin
+ {
+ info byte layout in bits:
+ 0-1 - amount of bytes for fileindex
+ 2-3 - amount of bytes for line
+ 4-5 - amount of bytes for column
+ }
+ info:=getbyte;
+ case (info and $03) of
+ 0 : fileindex:=getbyte;
+ 1 : fileindex:=getword;
+ 2 : fileindex:=(getbyte shl 16) or getword;
+ 3 : fileindex:=getlongint;
+ end;
+ case ((info shr 2) and $03) of
+ 0 : line:=getbyte;
+ 1 : line:=getword;
+ 2 : line:=(getbyte shl 16) or getword;
+ 3 : line:=getlongint;
+ end;
+ case ((info shr 4) and $03) of
+ 0 : column:=getbyte;
+ 1 : column:=getword;
+ 2 : column:=(getbyte shl 16) or getword;
+ 3 : column:=getlongint;
+ end;
+ Writeln(fileindex,' (',line,',',column,')');
+ end;
+end;
+
+
+procedure readderef;
+type
+ tdereftype = (deref_nil,
+ deref_sym,
+ deref_def,
+ deref_aktrecord,
+ deref_aktstatic,
+ deref_aktglobal,
+ deref_aktlocal,
+ deref_aktpara,
+ deref_unit,
+ deref_record,
+ deref_local,
+ deref_para,
+ deref_parent_object
+ );
+var
+ b : tdereftype;
+ first : boolean;
+ idx : longint;
+ i,n : byte;
+ pdata : pbyte;
+begin
+ if not assigned(derefdata) then
+ exit;
+ first:=true;
+ idx:=ppufile.getlongint;
+ if (idx>derefdatalen) then
+ begin
+ writeln('!! Error: Deref idx ',idx,' > ',derefdatalen);
+ exit;
+ end;
+ write('(',idx,') ');
+ pdata:=@derefdata[idx];
+ i:=0;
+ n:=pdata[i];
+ inc(i);
+ if n<1 then
+ begin
+ writeln('!! Error: Deref len < 1');
+ exit;
+ end;
+ while (i<n) do
+ begin
+ if not first then
+ write(', ')
+ else
+ first:=false;
+ b:=tdereftype(pdata[i]);
+ inc(i);
+ case b of
+ deref_nil :
+ write('Nil');
+ deref_def :
+ begin
+ idx:=pdata[i] shl 8;
+ idx:=idx or pdata[i+1];
+ inc(i,2);
+ write('Definition ',idx);
+ end;
+ deref_sym :
+ begin
+ idx:=pdata[i] shl 8;
+ idx:=idx or pdata[i+1];
+ inc(i,2);
+ write('Symbol ',idx);
+ end;
+ deref_aktrecord :
+ write('AktRecord');
+ deref_aktstatic :
+ write('AktStatic');
+ deref_aktglobal :
+ write('AktGlobal');
+ deref_aktlocal :
+ write('AktLocal');
+ deref_aktpara :
+ write('AktPara');
+ deref_unit :
+ begin
+ idx:=pdata[i] shl 8;
+ idx:=idx or pdata[i+1];
+ inc(i,2);
+ write('Unit ',idx);
+ end;
+ deref_record :
+ write('RecordDef');
+ deref_para :
+ write('Parameter of procdef');
+ deref_local :
+ write('Local of procdef');
+ deref_parent_object :
+ write('Parent object');
+ else
+ begin
+ writeln('!! unsupported dereftyp: ',ord(b));
+ break;
+ end;
+ end;
+ end;
+ writeln;
+end;
+
+
+procedure readtype;
+begin
+ readderef;
+end;
+
+
+procedure readsymlist(const s:string);
+type
+ tsltype = (sl_none,
+ sl_load,
+ sl_call,
+ sl_subscript,
+ sl_vec
+ );
+const
+ slstr : array[tsltype] of string[9] = ('',
+ 'load',
+ 'call',
+ 'subscript',
+ 'vec'
+ );
+var
+ sl : tsltype;
+begin
+ readderef;
+ repeat
+ sl:=tsltype(ppufile.getbyte);
+ if sl=sl_none then
+ break;
+ write(s,'(',slstr[sl],') ');
+ case sl of
+ sl_call,
+ sl_load,
+ sl_subscript :
+ readderef;
+ sl_vec :
+ writeln(ppufile.getlongint);
+ end;
+ until false;
+end;
+
+
+procedure readsymoptions;
+type
+ tsymoption=(sp_none,
+ sp_public,
+ sp_private,
+ sp_published,
+ sp_protected,
+ sp_static,
+ sp_hint_deprecated,
+ sp_hint_platform,
+ sp_hint_library,
+ sp_hint_unimplemented,
+ sp_has_overloaded,
+ sp_internal { internal symbol, not reported as unused }
+ );
+ tsymoptions=set of tsymoption;
+ tsymopt=record
+ mask : tsymoption;
+ str : string[30];
+ end;
+const
+ symopts=11;
+ symopt : array[1..symopts] of tsymopt=(
+ (mask:sp_public; str:'Public'),
+ (mask:sp_private; str:'Private'),
+ (mask:sp_published; str:'Published'),
+ (mask:sp_protected; str:'Protected'),
+ (mask:sp_static; str:'Static'),
+ (mask:sp_hint_deprecated;str:'Hint Deprecated'),
+ (mask:sp_hint_deprecated;str:'Hint Platform'),
+ (mask:sp_hint_deprecated;str:'Hint Library'),
+ (mask:sp_hint_deprecated;str:'Hint Unimplemented'),
+ (mask:sp_has_overloaded; str:'Has overloaded'),
+ (mask:sp_internal; str:'Internal')
+ );
+var
+ symoptions : tsymoptions;
+ i : longint;
+ first : boolean;
+begin
+ ppufile.getsmallset(symoptions);
+ if symoptions<>[] then
+ begin
+ first:=true;
+ for i:=1to symopts do
+ if (symopt[i].mask in symoptions) then
+ begin
+ if first then
+ first:=false
+ else
+ write(', ');
+ write(symopt[i].str);
+ end;
+ end;
+ writeln;
+end;
+
+
+procedure readcommonsym(const s:string);
+begin
+ writeln(space,'** Symbol Nr. ',ppufile.getword,' **');
+ writeln(space,s,ppufile.getstring);
+ write(space,' File Pos : ');
+ readposinfo;
+ write(space,' SymOptions : ');
+ readsymoptions;
+end;
+
+
+procedure readcommondef(const s:string);
+type
+ tdefoption=(df_none,
+ df_has_inittable, { init data has been generated }
+ df_has_rttitable, { rtti data has been generated }
+ df_unique
+ );
+ tdefoptions=set of tdefoption;
+var
+ defopts : tdefoptions;
+begin
+ writeln(space,'** Definition Nr. ',ppufile.getword,' **');
+ writeln(space,s);
+ write (space,' Type symbol : ');
+ readderef;
+ ppufile.getsmallset(defopts);
+
+ if df_unique in defopts then
+ writeln (space,' Unique type symbol');
+
+ if df_has_rttitable in defopts then
+ begin
+ write (space,' RTTI symbol : ');
+ readderef;
+ end;
+ if df_has_inittable in defopts then
+ begin
+ write (space,' Init symbol : ');
+ readderef;
+ end;
+end;
+
+
+{ Read abstract procdef and return if inline procdef }
+type
+ tproccalloption=(pocall_none,
+ { procedure uses C styled calling }
+ pocall_cdecl,
+ { C++ calling conventions }
+ pocall_cppdecl,
+ { Far16 for OS/2 }
+ pocall_far16,
+ { Old style FPC default calling }
+ pocall_oldfpccall,
+ { Procedure has compiler magic}
+ pocall_internproc,
+ { procedure is a system call, applies e.g. to MorphOS and PalmOS }
+ pocall_syscall,
+ { pascal standard left to right }
+ pocall_pascal,
+ { procedure uses register (fastcall) calling }
+ pocall_register,
+ { safe call calling conventions }
+ pocall_safecall,
+ { procedure uses stdcall call }
+ pocall_stdcall,
+ { Special calling convention for cpus without a floating point
+ unit. Floating point numbers are passed in integer registers
+ instead of floating point registers. Depending on the other
+ available calling conventions available for the cpu
+ this replaces either pocall_fastcall or pocall_stdcall.
+ }
+ pocall_softfloat,
+ { Metrowerks Pascal. Special case on Mac OS (X): passes all }
+ { constant records by reference. }
+ pocall_mwpascal
+ );
+ tproccalloptions=set of tproccalloption;
+ tproctypeoption=(potype_none,
+ potype_proginit, { Program initialization }
+ potype_unitinit, { unit initialization }
+ potype_unitfinalize, { unit finalization }
+ potype_constructor, { Procedure is a constructor }
+ potype_destructor, { Procedure is a destructor }
+ potype_operator, { Procedure defines an operator }
+ potype_procedure,
+ potype_function
+ );
+ tproctypeoptions=set of tproctypeoption;
+ tprocoption=(po_none,
+ po_classmethod, { class method }
+ po_virtualmethod, { Procedure is a virtual method }
+ po_abstractmethod, { Procedure is an abstract method }
+ po_staticmethod, { static method }
+ po_overridingmethod, { method with override directive }
+ po_methodpointer, { method pointer, only in procvardef, also used for 'with object do' }
+ po_interrupt, { Procedure is an interrupt handler }
+ po_iocheck, { IO checking should be done after a call to the procedure }
+ po_assembler, { Procedure is written in assembler }
+ po_msgstr, { method for string message handling }
+ po_msgint, { method for int message handling }
+ po_exports, { Procedure has export directive (needed for OS/2) }
+ po_external, { Procedure is external (in other object or lib)}
+ po_overload, { procedure is declared with overload directive }
+ po_varargs, { printf like arguments }
+ po_internconst, { procedure has constant evaluator intern }
+ { flag that only the address of a method is returned and not a full methodpointer }
+ po_addressonly,
+ { procedure is exported }
+ po_public,
+ { calling convention is specified explicitly }
+ po_hascallingconvention,
+ { reintroduce flag }
+ po_reintroduce,
+ { location of parameters is given explicitly as it is necessary for some syscall
+ conventions like that one of MorphOS }
+ po_explicitparaloc,
+ { no stackframe will be generated, used by lowlevel assembler like get_frame }
+ po_nostackframe,
+ po_has_mangledname,
+ po_has_public_name,
+ po_forward,
+ po_global,
+ po_has_inlininginfo,
+ { The different kind of syscalls on MorphOS }
+ po_syscall_legacy,
+ po_syscall_sysv,
+ po_syscall_basesysv,
+ po_syscall_sysvbase,
+ po_syscall_r12base,
+ po_local,
+ { Procedure can be inlined }
+ po_inline,
+ { Procedure is used for internal compiler calls }
+ po_compilerproc
+ );
+ tprocoptions=set of tprocoption;
+procedure read_abstract_proc_def(var proccalloption:tproccalloption;var procoptions:tprocoptions);
+type
+ tproccallopt=record
+ mask : tproccalloption;
+ str : string[30];
+ end;
+ tproctypeopt=record
+ mask : tproctypeoption;
+ str : string[30];
+ end;
+ tprocopt=record
+ mask : tprocoption;
+ str : string[30];
+ end;
+const
+ proccalloptionStr : array[tproccalloption] of string[14]=('',
+ 'CDecl',
+ 'CPPDecl',
+ 'Far16',
+ 'OldFPCCall',
+ 'InternProc',
+ 'SysCall',
+ 'Pascal',
+ 'Register',
+ 'SafeCall',
+ 'StdCall',
+ 'SoftFloat',
+ 'MWPascal'
+ );
+ proctypeopts=8;
+ proctypeopt : array[1..proctypeopts] of tproctypeopt=(
+ (mask:potype_proginit; str:'ProgInit'),
+ (mask:potype_unitinit; str:'UnitInit'),
+ (mask:potype_unitfinalize;str:'UnitFinalize'),
+ (mask:potype_constructor; str:'Constructor'),
+ (mask:potype_destructor; str:'Destructor'),
+ (mask:potype_operator; str:'Operator'),
+ (mask:potype_function; str:'Function'),
+ (mask:potype_procedure; str:'Procedure')
+ );
+ procopts=35;
+ procopt : array[1..procopts] of tprocopt=(
+ (mask:po_classmethod; str:'ClassMethod'),
+ (mask:po_virtualmethod; str:'VirtualMethod'),
+ (mask:po_abstractmethod; str:'AbstractMethod'),
+ (mask:po_staticmethod; str:'StaticMethod'),
+ (mask:po_overridingmethod;str:'OverridingMethod'),
+ (mask:po_methodpointer; str:'MethodPointer'),
+ (mask:po_interrupt; str:'Interrupt'),
+ (mask:po_iocheck; str:'IOCheck'),
+ (mask:po_assembler; str:'Assembler'),
+ (mask:po_msgstr; str:'MsgStr'),
+ (mask:po_msgint; str:'MsgInt'),
+ (mask:po_exports; str:'Exports'),
+ (mask:po_external; str:'External'),
+ (mask:po_overload; str:'Overload'),
+ (mask:po_varargs; str:'VarArgs'),
+ (mask:po_internconst; str:'InternConst'),
+ (mask:po_addressonly; str:'AddressOnly'),
+ (mask:po_public; str:'Public'),
+ (mask:po_hascallingconvention;str:'HasCallingConvention'),
+ (mask:po_reintroduce; str:'ReIntroduce'),
+ (mask:po_explicitparaloc; str:'ExplicitParaloc'),
+ (mask:po_nostackframe; str:'NoStackFrame'),
+ (mask:po_has_mangledname; str:'HasMangledName'),
+ (mask:po_has_public_name; str:'HasPublicName'),
+ (mask:po_forward; str:'Forward'),
+ (mask:po_global; str:'Global'),
+ (mask:po_has_inlininginfo;str:'HasInliningInfo'),
+ (mask:po_syscall_legacy; str:'SyscallLegacy'),
+ (mask:po_syscall_sysv; str:'SyscallSysV'),
+ (mask:po_syscall_basesysv;str:'SyscallBaseSysV'),
+ (mask:po_syscall_sysvbase;str:'SyscallSysVBase'),
+ (mask:po_syscall_r12base; str:'SyscallR12Base'),
+ (mask:po_local; str:'Local'),
+ (mask:po_inline; str:'Inline'),
+ (mask:po_compilerproc; str:'CompilerProc')
+ );
+var
+ proctypeoption : tproctypeoption;
+ i : longint;
+ first : boolean;
+ tempbuf : array[0..255] of byte;
+begin
+ write(space,' Return type : ');
+ readtype;
+ writeln(space,' Fpu used : ',ppufile.getbyte);
+ proctypeoption:=tproctypeoption(ppufile.getbyte);
+ write(space,' TypeOption : ');
+ first:=true;
+ for i:=1 to proctypeopts do
+ if (proctypeopt[i].mask=proctypeoption) then
+ begin
+ if first then
+ first:=false
+ else
+ write(', ');
+ write(proctypeopt[i].str);
+ end;
+ writeln;
+ proccalloption:=tproccalloption(ppufile.getbyte);
+ writeln(space,' CallOption : ',proccalloptionStr[proccalloption]);
+ ppufile.getnormalset(procoptions);
+ if procoptions<>[] then
+ begin
+ write(space,' Options : ');
+ first:=true;
+ for i:=1to procopts do
+ if (procopt[i].mask in procoptions) then
+ begin
+ if first then
+ first:=false
+ else
+ write(', ');
+ write(procopt[i].str);
+ end;
+ writeln;
+ end;
+ if (po_explicitparaloc in procoptions) then
+ begin
+ i:=ppufile.getbyte;
+ ppufile.getdata(tempbuf,i);
+ end;
+end;
+
+
+type
+ { options for variables }
+ tvaroption=(vo_none,
+ vo_is_C_var,
+ vo_is_external,
+ vo_is_dll_var,
+ vo_is_thread_var,
+ vo_has_local_copy,
+ vo_is_const, { variable is declared as const (parameter) and can't be written to }
+ vo_is_exported,
+ vo_is_high_para,
+ vo_is_funcret,
+ vo_is_self,
+ vo_is_vmt,
+ vo_is_result, { special result variable }
+ vo_is_parentfp,
+ vo_is_loop_counter, { used to detect assignments to loop counter }
+ vo_is_hidden_para,
+ vo_has_explicit_paraloc,
+ vo_is_syscall_lib,
+ vo_has_mangledname
+ );
+ tvaroptions=set of tvaroption;
+ { register variable }
+ tvarregable=(vr_none,
+ vr_intreg,
+ vr_fpureg,
+ vr_mmreg
+ );
+procedure readabstractvarsym(const s:string;var varoptions:tvaroptions);
+type
+ tvaropt=record
+ mask : tvaroption;
+ str : string[30];
+ end;
+const
+ varopts=18;
+ varopt : array[1..varopts] of tvaropt=(
+ (mask:vo_is_C_var; str:'CVar'),
+ (mask:vo_is_external; str:'External'),
+ (mask:vo_is_dll_var; str:'DLLVar'),
+ (mask:vo_is_thread_var; str:'ThreadVar'),
+ (mask:vo_has_local_copy; str:'HasLocalCopy'),
+ (mask:vo_is_const; str:'Constant'),
+ (mask:vo_is_exported; str:'Exported'),
+ (mask:vo_is_high_para; str:'HighValue'),
+ (mask:vo_is_funcret; str:'Funcret'),
+ (mask:vo_is_self; str:'Self'),
+ (mask:vo_is_vmt; str:'VMT'),
+ (mask:vo_is_result; str:'Result'),
+ (mask:vo_is_parentfp; str:'ParentFP'),
+ (mask:vo_is_loop_counter; str:'LoopCounter'),
+ (mask:vo_is_hidden_para; str:'Hidden'),
+ (mask:vo_has_explicit_paraloc;str:'ExplicitParaloc'),
+ (mask:vo_is_syscall_lib; str:'SysCallLib'),
+ (mask:vo_has_mangledname; str:'HasMangledName')
+ );
+var
+ i : longint;
+ first : boolean;
+begin
+ readcommonsym(s);
+ writeln(space,' Spez : ',Varspez2Str(ppufile.getbyte));
+ writeln(space,' Regable : ',Varregable2Str(ppufile.getbyte));
+ write (space,' Var Type : ');
+ readtype;
+ ppufile.getsmallset(varoptions);
+ if varoptions<>[] then
+ begin
+ write(space,' Options : ');
+ first:=true;
+ for i:=1to varopts do
+ if (varopt[i].mask in varoptions) then
+ begin
+ if first then
+ first:=false
+ else
+ write(', ');
+ write(varopt[i].str);
+ end;
+ writeln;
+ end;
+end;
+
+
+procedure readnodetree;
+var
+ l : longint;
+ p : pointer;
+begin
+ with ppufile do
+ begin
+ if space<>'' then
+ Writeln(space,'------ nodetree ------');
+ if readentry=ibnodetree then
+ begin
+ l:=entrysize;
+ Writeln(space,'Tree size : ',l);
+ { Read data to prevent error that entry is not completly read }
+ getmem(p,l);
+ getdata(p^,l);
+ freemem(p);
+ end
+ else
+ begin
+ Writeln('!! ibnodetree not found');
+ end;
+ end;
+end;
+
+
+{****************************************************************************
+ Read Symbols Part
+****************************************************************************}
+
+procedure readsymbols(const s:string);
+type
+ pguid = ^tguid;
+ tguid = packed record
+ D1: LongWord;
+ D2: Word;
+ D3: Word;
+ D4: array[0..7] of Byte;
+ end;
+
+ absolutetyp = (tovar,toasm,toaddr);
+ tconsttyp = (constnone,
+ constord,conststring,constreal,
+ constset,constpointer,constnil,
+ constresourcestring,constwstring,constguid
+ );
+var
+ b : byte;
+ pc : pchar;
+ totalsyms,
+ symcnt,
+ i,j,len : longint;
+ guid : tguid;
+ tempbuf : array[0..127] of char;
+ varoptions : tvaroptions;
+begin
+ symcnt:=1;
+ with ppufile do
+ begin
+ if space<>'' then
+ Writeln(space,'------ ',s,' ------');
+ if readentry=ibstartsyms then
+ begin
+ totalsyms:=getlongint;
+ Writeln(space,'Number of symbols : ',totalsyms);
+ Writeln(space,'Symtable datasize : ',getlongint);
+ Writeln(space,'Symtable alignment: ',getlongint);
+ end
+ else
+ begin
+ totalsyms:=-1;
+ Writeln('!! ibstartsym not found');
+ end;
+ repeat
+ b:=readentry;
+ if not (b in [iberror,ibendsyms]) then
+ inc(symcnt);
+ case b of
+
+ ibunitsym :
+ readcommonsym('Unit symbol ');
+
+ iblabelsym :
+ readcommonsym('Label symbol ');
+
+ ibtypesym :
+ begin
+ readcommonsym('Type symbol ');
+ write(space,' Result Type : ');
+ readtype;
+ end;
+
+ ibprocsym :
+ begin
+ readcommonsym('Procedure symbol ');
+ len:=ppufile.getword;
+ for i:=1 to len do
+ begin
+ write(space,' Definition : ');
+ readderef;
+ end;
+ end;
+
+ ibconstsym :
+ begin
+ readcommonsym('Constant symbol ');
+ b:=getbyte;
+ case tconsttyp(b) of
+ constord :
+ begin
+ write (space,' OrdinalType : ');
+ readtype;
+ writeln(space,' Value : ',getint64);
+ end;
+ constpointer :
+ begin
+ write (space,' PointerType : ');
+ readtype;
+ writeln(space,' Value : ',getlongint)
+ end;
+ conststring,
+ constresourcestring :
+ begin
+ len:=getlongint;
+ getmem(pc,len+1);
+ getdata(pc^,len);
+ (pc+len)^:= #0;
+ writeln(space,' Length : ',len);
+ writeln(space,' Value : "',pc,'"');
+ freemem(pc,len+1);
+ if tconsttyp(b)=constresourcestring then
+ writeln(space,' Index : ',getlongint);
+ end;
+ constreal :
+ writeln(space,' Value : ',getreal);
+ constset :
+ begin
+ write (space,' Set Type : ');
+ readtype;
+ for i:=1to 4 do
+ begin
+ write (space,' Value : ');
+ for j:=1to 8 do
+ begin
+ if j>1 then
+ write(',');
+ write(hexb(getbyte));
+ end;
+ writeln;
+ end;
+ end;
+ constwstring:
+ begin
+ end;
+ constguid:
+ begin
+ getdata(guid,sizeof(guid));
+ write (space,' IID String: {',hexstr(guid.d1,8),'-',hexstr(guid.d2,4),'-',hexstr(guid.d3,4),'-');
+ for i:=0 to 7 do
+ begin
+ write(hexstr(guid.d4[i],2));
+ if i=1 then write('-');
+ end;
+ writeln('}');
+ end
+ else
+ Writeln ('!! Invalid unit format : Invalid const type encountered: ',b);
+ end;
+ end;
+
+ ibabsolutevarsym :
+ begin
+ readabstractvarsym('Absolute variable symbol ',varoptions);
+ Write (space,' Relocated to ');
+ b:=getbyte;
+ case absolutetyp(b) of
+ tovar :
+ readsymlist(space+' Sym : ');
+ toasm :
+ Writeln('Assembler name : ',getstring);
+ toaddr :
+ begin
+ Write('Address : ',getlongint);
+ if tsystemcpu(ppufile.header.cpu)=cpu_i386 then
+ WriteLn(' (Far: ',getbyte<>0,')');
+ end;
+ else
+ Writeln ('!! Invalid unit format : Invalid absolute type encountered: ',b);
+ end;
+ end;
+
+ ibfieldvarsym :
+ begin
+ readabstractvarsym('Field Variable symbol ',varoptions);
+ writeln(space,' Address : ',getlongint);
+ end;
+
+ ibglobalvarsym :
+ begin
+ readabstractvarsym('Global Variable symbol ',varoptions);
+ write (space,' DefaultConst : ');
+ readderef;
+ if (vo_has_mangledname in varoptions) then
+ writeln(space,' Mangledname : ',getstring);
+ end;
+
+ iblocalvarsym :
+ begin
+ readabstractvarsym('Local Variable symbol ',varoptions);
+ write (space,' DefaultConst : ');
+ readderef;
+ end;
+
+ ibparavarsym :
+ begin
+ readabstractvarsym('Parameter Variable symbol ',varoptions);
+ write (space,' DefaultConst : ');
+ readderef;
+ writeln(space,' ParaNr : ',getword);
+ if (vo_has_explicit_paraloc in varoptions) then
+ begin
+ i:=getbyte;
+ getdata(tempbuf,i);
+ end;
+ end;
+
+ ibenumsym :
+ begin
+ readcommonsym('Enumeration symbol ');
+ write (space,' Definition : ');
+ readderef;
+ writeln(space,' Value : ',getlongint);
+ end;
+
+ ibsyssym :
+ begin
+ readcommonsym('Internal system symbol ');
+ writeln(space,' Internal Nr : ',getlongint);
+ end;
+
+ ibrttisym :
+ begin
+ readcommonsym('RTTI symbol ');
+ writeln(space,' RTTI Type : ',getbyte);
+ end;
+
+ ibmacrosym :
+ begin
+ readcommonsym('Macro symbol ');
+ writeln(space,' Name: ',getstring);
+ writeln(space,' Defined: ',getbyte);
+ writeln(space,' Compiler var: ',getbyte);
+ len:=getlongint;
+ writeln(space,' Value length: ',len);
+ if len > 0 then
+ begin
+ getmem(pc,len+1);
+ getdata(pc^,len);
+ (pc+len)^:= #0;
+ writeln(space,' Value: "',pc,'"');
+ freemem(pc,len+1);
+ end;
+ end;
+
+ ibtypedconstsym :
+ begin
+ readcommonsym('Typed constant ');
+ write (space,' Constant Type : ');
+ readtype;
+ writeln(space,' ReallyConst : ',(getbyte<>0));
+ end;
+
+ ibpropertysym :
+ begin
+ readcommonsym('Property ');
+ i:=getlongint;
+ writeln(space,' PropOptions : ',i);
+ if (i and 32)>0 then
+ begin
+ write (space,' OverrideProp : ');
+ readderef;
+ end
+ else
+ begin
+ write (space,' Prop Type : ');
+ readtype;
+ writeln(space,' Index : ',getlongint);
+ writeln(space,' Default : ',getlongint);
+ write (space,' Index Type : ');
+ readtype;
+ write (space,' Readaccess : ');
+ readsymlist(space+' Sym: ');
+ write (space,' Writeaccess : ');
+ readsymlist(space+' Sym: ');
+ write (space,' Storedaccess : ');
+ readsymlist(space+' Sym: ');
+ end;
+ end;
+
+ iberror :
+ begin
+ Writeln('!! Error in PPU');
+ exit;
+ end;
+
+ ibendsyms :
+ break;
+
+ else
+ WriteLn('!! Skipping unsupported PPU Entry in Symbols: ',b);
+ end;
+ if not EndOfEntry then
+ Writeln('!! Entry has more information stored');
+ until false;
+ if (totalsyms<>-1) and (symcnt-1<>totalsyms) then
+ Writeln('!! Only read ',symcnt-1,' of ',totalsyms,' symbols');
+ end;
+end;
+
+
+{****************************************************************************
+ Read defintions Part
+****************************************************************************}
+
+procedure readdefinitions(const s:string;start_read : boolean);
+type
+ tsettype = (normset,smallset,varset);
+ tbasetype = (
+ uvoid,
+ u8bit,u16bit,u32bit,u64bit,
+ s8bit,s16bit,s32bit,s64bit,
+ bool8bit,bool16bit,bool32bit,
+ uchar,uwidechar,scurrency
+ );
+ tobjectdeftype = (odt_none,
+ odt_class,
+ odt_object,
+ odt_interfacecom,
+ odt_interfacecorba,
+ odt_cppclass
+ );
+ tvarianttype = (
+ vt_normalvariant,vt_olevariant
+ );
+var
+ b : byte;
+ totaldefs,l,j,
+ defcnt : longint;
+ calloption : tproccalloption;
+ procoptions : tprocoptions;
+ procinfooptions : tprocinfoflag;
+
+begin
+ defcnt:=0;
+ with ppufile do
+ begin
+ if space<>'' then
+ Writeln(space,'------ ',s,' ------');
+ if not start_read then
+ if readentry=ibstartdefs then
+ begin
+ totaldefs:=getlongint;
+ Writeln(space,'Number of definitions: ',totaldefs);
+ end
+ else
+ begin
+ totaldefs:=-1;
+ Writeln('!! ibstartdef not found');
+ end;
+ repeat
+ b:=readentry;
+ if not (b in [iberror,ibenddefs]) then
+ inc(defcnt);
+ case b of
+
+ ibpointerdef :
+ begin
+ readcommondef('Pointer definition');
+ write (space,' Pointed Type : ');
+ readtype;
+ writeln(space,' Is Far : ',(getbyte<>0));
+ end;
+
+ iborddef :
+ begin
+ readcommondef('Ordinal definition');
+ write (space,' Base type : ');
+ b:=getbyte;
+ case tbasetype(b) of
+ uvoid : writeln('uvoid');
+ u8bit : writeln('u8bit');
+ u16bit : writeln('u16bit');
+ u32bit : writeln('s32bit');
+ u64bit : writeln('u64bit');
+ s8bit : writeln('s8bit');
+ s16bit : writeln('s16bit');
+ s32bit : writeln('s32bit');
+ s64bit : writeln('s64bit');
+ bool8bit : writeln('bool8bit');
+ bool16bit : writeln('bool16bit');
+ bool32bit : writeln('bool32bit');
+ uchar : writeln('uchar');
+ uwidechar : writeln('uwidechar');
+ scurrency : writeln('ucurrency');
+ else writeln('!! Warning: Invalid base type ',b);
+ end;
+ writeln(space,' Range : ',getint64,' to ',getint64);
+ end;
+
+ ibfloatdef :
+ begin
+ readcommondef('Float definition');
+ writeln(space,' Float type : ',getbyte);
+ end;
+
+ ibarraydef :
+ begin
+ readcommondef('Array definition');
+ write (space,' Element type : ');
+ readtype;
+ write (space,' Range Type : ');
+ readtype;
+ writeln(space,' Range : ',getlongint,' to ',getlongint);
+ writeln(space,' Is Constructor : ',(getbyte<>0));
+ writeln(space,' Is Dynamic : ',(getbyte<>0));
+ end;
+
+ ibprocdef :
+ begin
+ readcommondef('Procedure definition');
+ read_abstract_proc_def(calloption,procoptions);
+ if (po_has_mangledname in procoptions) then
+ writeln(space,' Mangled name : ',getstring);
+ writeln(space,' Number : ',getword);
+ writeln(space,' Level : ',getbyte);
+ write (space,' Class : ');
+ readderef;
+ write (space,' Procsym : ');
+ readderef;
+ write (space,' File Pos : ');
+ readposinfo;
+ write (space,' SymOptions : ');
+ readsymoptions;
+ if tsystemcpu(ppufile.header.cpu)=cpu_powerpc then
+ begin
+ { library symbol for AmigaOS/MorphOS }
+ write (space,' Library symbol : ');
+ readderef;
+ end;
+ if (po_inline in procoptions) then
+ begin
+ write (space,' FuncretSym : ');
+ readderef;
+ ppufile.getsmallset(procinfooptions);
+ writeln(space,' ProcInfoOptions : ',dword(procinfooptions));
+ b := ppufile.getbyte;
+ writeln(space,' Inline node tree : ',b);
+ end;
+ if not EndOfEntry then
+ Writeln('!! Entry has more information stored');
+ space:=' '+space;
+ { parast }
+ readdefinitions('parast',false);
+ readsymbols('parast');
+ { localst }
+ if (po_has_inlininginfo in procoptions) or
+ ((ppufile.header.flags and uf_local_browser)<>0) then
+ begin
+ readdefinitions('localst',false);
+ readsymbols('localst');
+ end;
+ if (po_has_inlininginfo in procoptions) then
+ readnodetree;
+ delete(space,1,4);
+ end;
+
+ ibprocvardef :
+ begin
+ readcommondef('Procedural type (ProcVar) definition');
+ read_abstract_proc_def(calloption,procoptions);
+ if not EndOfEntry then
+ Writeln('!! Entry has more information stored');
+ space:=' '+space;
+ { parast }
+ readdefinitions('parast',false);
+ readsymbols('parast');
+ delete(space,1,4);
+ end;
+
+ ibshortstringdef :
+ begin
+ readcommondef('ShortString definition');
+ writeln(space,' Length : ',getbyte);
+ end;
+
+ ibwidestringdef :
+ begin
+ readcommondef('WideString definition');
+ writeln(space,' Length : ',getlongint);
+ end;
+
+ ibansistringdef :
+ begin
+ readcommondef('AnsiString definition');
+ writeln(space,' Length : ',getlongint);
+ end;
+
+ iblongstringdef :
+ begin
+ readcommondef('Longstring definition');
+ writeln(space,' Length : ',getlongint);
+ end;
+
+ ibrecorddef :
+ begin
+ readcommondef('Record definition');
+ writeln(space,' DataSize : ',getlongint);
+ writeln(space,' FieldAlign : ',getbyte);
+ writeln(space,' RecordAlign : ',getbyte);
+ writeln(space,' PadAlign : ',getbyte);
+ if not EndOfEntry then
+ Writeln('!! Entry has more information stored');
+ {read the record definitions and symbols}
+ space:=' '+space;
+ readdefinitions('fields',false);
+ readsymbols('fields');
+ Delete(space,1,4);
+ end;
+
+ ibobjectdef :
+ begin
+ readcommondef('Object/Class definition');
+ b:=getbyte;
+ write (space,' Type : ');
+ case tobjectdeftype(b) of
+ odt_class : writeln('class');
+ odt_object : writeln('object');
+ odt_interfacecom : writeln('interfacecom');
+ odt_interfacecorba : writeln('interfacecorba');
+ odt_cppclass : writeln('cppclass');
+ else writeln('!! Warning: Invalid object type ',b);
+ end;
+ writeln(space,' Name of Class : ',getstring);
+ writeln(space,' DataSize : ',getlongint);
+ writeln(space,' FieldAlign : ',getbyte);
+ writeln(space,' RecordAlign : ',getbyte);
+ writeln(space,' Vmt offset : ',getlongint);
+ write(space, ' Ancestor Class : ');
+ readderef;
+ writeln(space,' Options : ',getlongint);
+
+ if tobjectdeftype(b) in [odt_interfacecom,odt_interfacecorba] then
+ begin
+ { IIDGUID }
+ for j:=1to 16 do
+ getbyte;
+ writeln(space,' IID String : ',getstring);
+ writeln(space,' Last VTable idx : ',getlongint);
+ end;
+
+ if tobjectdeftype(b) in [odt_class,odt_interfacecorba] then
+ begin
+ l:=getlongint;
+ writeln(space,' Impl Intf Count : ',l);
+ for j:=1 to l do
+ begin
+ write (space,' - Definition : ');
+ readderef;
+ writeln(space,' IOffset : ',getlongint);
+ end;
+ end;
+
+ if not EndOfEntry then
+ Writeln('!! Entry has more information stored');
+ {read the record definitions and symbols}
+ space:=' '+space;
+ readdefinitions('fields',false);
+ readsymbols('fields');
+ Delete(space,1,4);
+ end;
+
+ ibfiledef :
+ begin
+ ReadCommonDef('File definition');
+ write (space,' Type : ');
+ case getbyte of
+ 0 : writeln('Text');
+ 1 : begin
+ writeln('Typed');
+ write (space,' File of Type : ');
+ Readtype;
+ end;
+ 2 : writeln('Untyped');
+ end;
+ end;
+
+ ibformaldef :
+ readcommondef('Generic Definition (void-typ)');
+
+ ibenumdef :
+ begin
+ readcommondef('Enumeration type definition');
+ write(space,'Base enumeration type : ');
+ readderef;
+ writeln(space,' Smallest element : ',getlongint);
+ writeln(space,' Largest element : ',getlongint);
+ writeln(space,' Size : ',getlongint);
+ end;
+
+ ibclassrefdef :
+ begin
+ readcommondef('Class reference definition');
+ write (space,' Pointed Type : ');
+ readtype;
+ end;
+
+ ibsetdef :
+ begin
+ readcommondef('Set definition');
+ write (space,' Element type : ');
+ readtype;
+ b:=getbyte;
+ case tsettype(b) of
+ smallset : writeln(space,' Set with 32 Elements');
+ normset : writeln(space,' Set with 256 Elements');
+ varset : writeln(space,' Set with ',getlongint,' Elements');
+ else writeln('!! Warning: Invalid set type ',b);
+ end;
+ end;
+
+ ibvariantdef :
+ begin
+ readcommondef('Variant definition');
+ write (space,' Varianttype : ');
+ b:=getbyte;
+ case tvarianttype(b) of
+ vt_normalvariant :
+ writeln('Normal');
+ vt_olevariant :
+ writeln('OLE');
+ else
+ writeln('!! Warning: Invalid varianttype ',b);
+ end;
+
+ end;
+
+ iberror :
+ begin
+ Writeln('!! Error in PPU');
+ exit;
+ end;
+
+ ibenddefs :
+ break;
+
+ else
+ WriteLn('!! Skipping unsupported PPU Entry in definitions: ',b);
+ end;
+ if not EndOfEntry then
+ Writeln('!! Entry has more information stored');
+ until false;
+ if (totaldefs<>-1) and (defcnt<>totaldefs) then
+ Writeln('!! Only read ',defcnt,' of ',totaldefs,' definitions');
+ end;
+end;
+
+
+{****************************************************************************
+ Read General Part
+****************************************************************************}
+
+procedure readinterface;
+var
+ b : byte;
+ sourcenumber : longint;
+begin
+ with ppufile do
+ begin
+ repeat
+ b:=readentry;
+ case b of
+
+ ibmodulename :
+ Writeln('Module Name: ',getstring);
+
+ ibsourcefiles :
+ begin
+ sourcenumber:=1;
+ while not EndOfEntry do
+ begin
+ Writeln('Source file ',sourcenumber,' : ',getstring,' ',filetimestring(getlongint));
+ inc(sourcenumber);
+ end;
+ end;
+{$IFDEF MACRO_DIFF_HINT}
+ ibusedmacros :
+ begin
+ while not EndOfEntry do
+ begin
+ Write('Conditional ',getstring);
+ b:=getbyte;
+ if boolean(b)=true then
+ write(' defined at startup')
+ else
+ write(' not defined at startup');
+ b:=getbyte;
+ if boolean(b)=true then
+ writeln(' was used')
+ else
+ writeln;
+ end;
+ end;
+{$ENDIF}
+ ibloadunit :
+ ReadLoadUnit;
+
+ iblinkunitofiles :
+ ReadLinkContainer('Link unit object file: ');
+
+ iblinkunitstaticlibs :
+ ReadLinkContainer('Link unit static lib: ');
+
+ iblinkunitsharedlibs :
+ ReadLinkContainer('Link unit shared lib: ');
+
+ iblinkotherofiles :
+ ReadLinkContainer('Link other object file: ');
+
+ iblinkotherstaticlibs :
+ ReadLinkContainer('Link other static lib: ');
+
+ iblinkothersharedlibs :
+ ReadLinkContainer('Link other shared lib: ');
+
+ ibderefdata :
+ ReadDerefData;
+
+ ibderefmap :
+ ReadDerefMap;
+
+ iberror :
+ begin
+ Writeln('Error in PPU');
+ exit;
+ end;
+
+ ibendinterface :
+ break;
+
+ else
+ WriteLn('!! Skipping unsupported PPU Entry in General Part: ',b);
+ end;
+ until false;
+ end;
+end;
+
+
+
+{****************************************************************************
+ Read Implementation Part
+****************************************************************************}
+
+procedure readimplementation;
+var
+ b : byte;
+begin
+ with ppufile do
+ begin
+ repeat
+ b:=readentry;
+ case b of
+ ibasmsymbols :
+ ReadAsmSymbols;
+
+ ibloadunit :
+ ReadLoadUnit;
+
+ iberror :
+ begin
+ Writeln('Error in PPU');
+ exit;
+ end;
+ ibendimplementation :
+ break;
+ else
+ WriteLn('!! Skipping unsupported PPU Entry in Implementation: ',b);
+ end;
+ until false;
+ end;
+end;
+
+
+{****************************************************************************
+ Read Browser Part
+****************************************************************************}
+
+procedure readbrowser;
+var
+ b : byte;
+const indent : string = '';
+begin
+ Writeln(indent,'Start of symtable browser');
+ indent:=indent+'**';
+ with ppufile do
+ begin
+ repeat
+ b:=readentry;
+ case b of
+ ibbeginsymtablebrowser :
+ begin
+ { here we must read object and record symtables !! }
+ indent:=indent+' ';
+ Writeln(indent,'Record/Object symtable');
+ readbrowser;
+ Indent:=Copy(Indent,1,Length(Indent)-2);
+ end;
+ ibsymref :
+ begin
+ readderef;
+ readref;
+ end;
+ ibdefref :
+ begin
+ readderef;
+ readref;
+ if ((ppufile.header.flags and uf_local_browser)<>0) and
+ (UnitIndex=0) then
+ begin
+ { parast and localst }
+ indent:=indent+' ';
+ b:=ppufile.readentry;
+ if b=ibbeginsymtablebrowser then
+ readbrowser;
+ b:=ppufile.readentry;
+ if b=ibbeginsymtablebrowser then
+ readbrowser;
+ Indent:=Copy(Indent,1,Length(Indent)-2);
+ end;
+ end;
+ iberror :
+ begin
+ Writeln('Error in PPU');
+ exit;
+ end;
+ ibendsymtablebrowser :
+ break;
+ else
+ begin
+ WriteLn('!! Skipping unsupported PPU Entry in Browser: ',b);
+ Halt;
+ end;
+ end;
+ until false;
+ end;
+ Indent:=Copy(Indent,1,Length(Indent)-2);
+ Writeln(Indent,'End of symtable browser');
+end;
+
+
+
+
+procedure dofile (filename : string);
+var
+ b : byte;
+begin
+{ reset }
+ space:='';
+{ fix filename }
+ if pos('.',filename)=0 then
+ filename:=filename+'.ppu';
+ ppufile:=tppufile.create(filename);
+ if not ppufile.openfile then
+ begin
+ writeln ('IO-Error when opening : ',filename,', Skipping');
+ exit;
+ end;
+{ PPU File is open, check for PPU Id }
+ if not ppufile.CheckPPUID then
+ begin
+ writeln(Filename,' : Not a valid PPU file, Skipping');
+ exit;
+ end;
+{ Check PPU Version }
+ Writeln('Analyzing ',filename,' (v',ppufile.GetPPUVersion,')');
+ if ppufile.GetPPUVersion<16 then
+ begin
+ writeln(Filename,' : Old PPU Formats (<v16) are not supported, Skipping');
+ exit;
+ end;
+{ Write PPU Header Information }
+ if (verbose and v_header)<>0 then
+ begin
+ Writeln;
+ Writeln('Header');
+ Writeln('-------');
+ with ppufile.header do
+ begin
+ Writeln('Compiler version : ',ppufile.header.compiler shr 14,'.',
+ (ppufile.header.compiler shr 7) and $7f,'.',
+ ppufile.header.compiler and $7f);
+ WriteLn('Target processor : ',Cpu2Str(cpu));
+ WriteLn('Target operating system : ',Target2Str(target));
+ Writeln('Unit flags : ',PPUFlags2Str(flags));
+ Writeln('FileSize (w/o header) : ',size);
+ Writeln('Checksum : ',hexstr(checksum,8));
+ Writeln('Interface Checksum : ',hexstr(interface_checksum,8));
+ end;
+ end;
+{read the general stuff}
+ if (verbose and v_interface)<>0 then
+ begin
+ Writeln;
+ Writeln('Interface section');
+ Writeln('------------------');
+ readinterface;
+ end
+ else
+ ppufile.skipuntilentry(ibendinterface);
+{read the definitions}
+ if (verbose and v_defs)<>0 then
+ begin
+ Writeln;
+ Writeln('Interface definitions');
+ Writeln('----------------------');
+ readdefinitions('interface',false);
+ end
+ else
+ ppufile.skipuntilentry(ibenddefs);
+{read the symbols}
+ if (verbose and v_syms)<>0 then
+ begin
+ Writeln;
+ Writeln('Interface Symbols');
+ Writeln('------------------');
+ readsymbols('interface');
+ end
+ else
+ ppufile.skipuntilentry(ibendsyms);
+
+{read the macro symbols}
+ if (verbose and v_syms)<>0 then
+ begin
+ Writeln;
+ Writeln('Interface Macro Symbols');
+ Writeln('-----------------------');
+ end;
+ if ppufile.readentry<>ibexportedmacros then
+ begin
+ Writeln('!! Error in PPU');
+ exit;
+ end;
+ if boolean(ppufile.getbyte) then
+ begin
+ {skip the definition section for macros (since they are never used) }
+ ppufile.skipuntilentry(ibenddefs);
+ {read the macro symbols}
+ if (verbose and v_syms)<>0 then
+ readsymbols('interface macro')
+ else
+ ppufile.skipuntilentry(ibendsyms);
+ end
+ else
+ Writeln('(no exported macros)');
+
+{read the implementation stuff}
+ if (verbose and v_implementation)<>0 then
+ begin
+ Writeln;
+ Writeln('Implementation section');
+ Writeln('-----------------------');
+ readimplementation;
+ end
+ else
+ ppufile.skipuntilentry(ibendimplementation);
+{read the static browser units stuff}
+ if (ppufile.header.flags and uf_local_symtable)<>0 then
+ begin
+ if (verbose and v_defs)<>0 then
+ begin
+ Writeln;
+ Writeln('Static definitions');
+ Writeln('----------------------');
+ readdefinitions('implementation',false);
+ end
+ else
+ ppufile.skipuntilentry(ibenddefs);
+ {read the symbols}
+ if (verbose and v_syms)<>0 then
+ begin
+ Writeln;
+ Writeln('Static Symbols');
+ Writeln('------------------');
+ readsymbols('implementation');
+ end
+ else
+ ppufile.skipuntilentry(ibendsyms);
+ end;
+{read the browser units stuff}
+ if (ppufile.header.flags and uf_has_browser)<>0 then
+ begin
+ if (verbose and v_browser)<>0 then
+ begin
+ Writeln;
+ Writeln('Browser section');
+ Writeln('---------------');
+ UnitIndex:=0;
+ repeat
+ b:=ppufile.readentry;
+ if b = ibendbrowser then break;
+ if b=ibbeginsymtablebrowser then
+ begin
+ Writeln('Unit ',UnitIndex);
+ readbrowser;
+ Inc(UnitIndex);
+ end
+ else
+ Writeln('Wrong end browser entry ',b,' should be ',ibendbrowser);
+ until false;
+ end;
+ end;
+{read the static browser units stuff}
+ if (ppufile.header.flags and uf_local_browser)<>0 then
+ begin
+ if (verbose and v_browser)<>0 then
+ begin
+ Writeln;
+ Writeln('Static browser section');
+ Writeln('---------------');
+ UnitIndex:=0;
+ b:=ppufile.readentry;
+ if b=ibbeginsymtablebrowser then
+ readbrowser
+ else
+ Writeln('Wrong end browser entry ',b,' should be ',ibendbrowser);
+ end;
+ end;
+{shutdown ppufile}
+ ppufile.closefile;
+ ppufile.free;
+ Writeln;
+end;
+
+
+
+procedure help;
+begin
+ writeln('usage: ppudump [options] <filename1> <filename2>...');
+ writeln;
+ writeln('[options] can be:');
+ writeln(' -V<verbose> Set verbosity to <verbose>');
+ writeln(' H - Show header info');
+ writeln(' I - Show interface');
+ writeln(' M - Show implementation');
+ writeln(' S - Show interface symbols');
+ writeln(' D - Show interface definitions');
+ writeln(' B - Show browser info');
+ writeln(' A - Show all');
+ writeln(' -h, -? This helpscreen');
+ halt;
+end;
+
+var
+ startpara,
+ nrfile,i : longint;
+ para : string;
+begin
+ writeln(Title+' '+Version);
+ writeln(Copyright);
+ writeln;
+ if paramcount<1 then
+ begin
+ writeln('usage: dumpppu [options] <filename1> <filename2>...');
+ halt(1);
+ end;
+{ turn verbose on by default }
+ verbose:=v_all;
+{ read options }
+ startpara:=1;
+ while copy(paramstr(startpara),1,1)='-' do
+ begin
+ para:=paramstr(startpara);
+ case upcase(para[2]) of
+ 'V' : begin
+ verbose:=0;
+ for i:=3 to length(para) do
+ case upcase(para[i]) of
+ 'H' : verbose:=verbose or v_header;
+ 'I' : verbose:=verbose or v_interface;
+ 'M' : verbose:=verbose or v_implementation;
+ 'D' : verbose:=verbose or v_defs;
+ 'S' : verbose:=verbose or v_syms;
+ 'B' : verbose:=verbose or v_browser;
+ 'A' : verbose:=verbose or v_all;
+ end;
+ end;
+ 'H' : help;
+ '?' : help;
+ end;
+ inc(startpara);
+ end;
+{ process files }
+ for nrfile:=startpara to paramcount do
+ dofile (paramstr(nrfile));
+ if has_errors then
+ Halt(1);
+end.
diff --git a/compiler/utils/ppufiles.pp b/compiler/utils/ppufiles.pp
new file mode 100644
index 0000000000..66ff08736f
--- /dev/null
+++ b/compiler/utils/ppufiles.pp
@@ -0,0 +1,252 @@
+{
+ Copyright (c) 1999-2002 by Peter Vreman
+
+ List files needed by PPU
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************}
+Program ppufiles;
+
+uses
+ dos,
+ ppu;
+
+const
+ Version = 'Version 1.00';
+ Title = 'PPU-Files';
+ Copyright = 'Copyright (c) 1999-2002 by the Free Pascal Development Team';
+
+ PPUExt = 'ppu';
+
+type
+ poutfile = ^toutfile;
+ toutfile = record
+ name : string;
+ next : poutfile;
+ end;
+
+var
+ skipdup,
+ showstatic,
+ showshared,
+ showobjects : boolean;
+
+ OutFiles : poutfile;
+
+
+{*****************************************************************************
+ Helpers
+*****************************************************************************}
+
+Procedure Error(const s:string;stop:boolean);
+{
+ Write an error message to stderr
+}
+begin
+{$ifdef FPC}
+ writeln(stderr,s);
+{$else}
+ writeln(s);
+{$endif}
+ if stop then
+ halt(1);
+end;
+
+
+Function AddExtension(Const HStr,ext:String):String;
+{
+ Return a filename which will have extension ext added if no
+ extension is found
+}
+var
+ j : longint;
+begin
+ j:=length(Hstr);
+ while (j>0) and (Hstr[j]<>'.') do
+ dec(j);
+ if j=0 then
+ AddExtension:=Hstr+'.'+Ext
+ else
+ AddExtension:=HStr;
+end;
+
+
+Function SplitPath(Const HStr:String):String;
+var
+ i : longint;
+begin
+ i:=Length(Hstr);
+ while (i>0) and not(Hstr[i] in ['\','/']) do
+ dec(i);
+ SplitPath:=Copy(Hstr,1,i);
+end;
+
+
+Procedure AddFile(const s:string);
+var
+ p : poutfile;
+begin
+ p:=nil;
+ if skipdup then
+ begin
+ p:=outfiles;
+ while assigned(p) do
+ begin
+ if s=p^.name then
+ break;
+ p:=p^.next;
+ end;
+ end;
+ if not assigned(p) then
+ begin
+ new(p);
+ p^.name:=s;
+ p^.next:=outfiles;
+ outfiles:=p;
+ end;
+end;
+
+
+Function DoPPU(const PPUFn:String):Boolean;
+{
+ Convert one file (in Filename) to library format.
+ Return true if successful, false otherwise.
+}
+Var
+ inppu : tppufile;
+ b : byte;
+
+ procedure showfiles;
+ begin
+ while not inppu.endofentry do
+ begin
+ AddFile(inppu.getstring);
+ inppu.getlongint;
+ end;
+ end;
+
+begin
+ DoPPU:=false;
+ inppu:=tppufile.create(PPUFn);
+ if not inppu.openfile then
+ begin
+ inppu.free;
+ Error('Error: Could not open : '+PPUFn,false);
+ Exit;
+ end;
+{ Check the ppufile }
+ if not inppu.CheckPPUId then
+ begin
+ inppu.free;
+ Error('Error: Not a PPU File : '+PPUFn,false);
+ Exit;
+ end;
+ if inppu.GetPPUVersion<CurrentPPUVersion then
+ begin
+ inppu.free;
+ Error('Error: Wrong PPU Version : '+PPUFn,false);
+ Exit;
+ end;
+{ read until the object files are found }
+ repeat
+ b:=inppu.readentry;
+ case b of
+ ibendinterface,
+ ibend :
+ break;
+ iblinkunitstaticlibs :
+ if showstatic then
+ showfiles;
+ iblinkunitsharedlibs :
+ if showshared then
+ showfiles;
+ iblinkunitofiles :
+ if showobjects then
+ showfiles;
+ end;
+ until false;
+ inppu.free;
+ DoPPU:=True;
+end;
+
+
+
+var
+ i,parafile : longint;
+ dir : SearchRec;
+ s,InFile : String;
+ p : poutfile;
+begin
+{ defaults }
+ skipdup:=true;
+{ options }
+ i:=1;
+ while (i<=paramcount) do
+ begin
+ s:=paramstr(i);
+ if s[1]<>'-' then
+ break;
+ case upcase(s[2]) of
+ 'L' : showshared:=true;
+ 'S' : showstatic:=true;
+ 'O' : showobjects:=true;
+ 'A' : skipdup:=false;
+ '?','H' :
+ begin
+ writeln('usage: ppufiles [options] <files>');
+ writeln('options:');
+ writeln(' -A Show all files (don''t remove duplicates)');
+ writeln(' -L Show only shared libraries');
+ writeln(' -S Show only static libraries');
+ writeln(' -O Show only object files');
+ writeln(' -H This helpscreen');
+ end;
+ end;
+ inc(i);
+ end;
+ { default shows everything }
+ if i=1 then
+ begin
+ showshared:=true;
+ showstatic:=true;
+ showobjects:=true;
+ end;
+{ files }
+ parafile:=i;
+ for i:=parafile to ParamCount do
+ begin
+ InFile:=AddExtension(ParamStr(i),PPUExt);
+ FindFirst(InFile,$20,Dir);
+ while (DosError=0) do
+ begin
+ DoPPU(SplitPath(InFile)+Dir.Name);
+ FindNext(Dir);
+ end;
+{$ifdef fpc}
+ FindClose(Dir);
+{$endif}
+ end;
+{ Display the files }
+ while assigned(outfiles) do
+ begin
+ p:=outfiles;
+ write(outfiles^.name);
+ outfiles:=outfiles^.next;
+ dispose(p);
+ if assigned(outfiles) then
+ write(' ');
+ end;
+end.
diff --git a/compiler/utils/ppumove.pp b/compiler/utils/ppumove.pp
new file mode 100644
index 0000000000..8250004622
--- /dev/null
+++ b/compiler/utils/ppumove.pp
@@ -0,0 +1,613 @@
+{
+ Copyright (c) 1999-2002 by the FPC Development Team
+
+ Add multiple FPC units into a static/shared library
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************}
+{$ifndef TP}
+ {$H+}
+{$endif}
+Program ppumove;
+uses
+{$ifdef unix}
+ {$ifdef ver1_0}
+ linux,
+ {$else}
+ Baseunix,Unix, UnixUtil,
+ {$endif}
+{$else unix}
+ dos,
+{$endif unix}
+ ppu,
+ getopts;
+
+const
+ Version = 'Version 1.00';
+ Title = 'PPU-Mover';
+ Copyright = 'Copyright (c) 1998-2002 by the Free Pascal Development Team';
+
+ ShortOpts = 'o:e:d:qhsvbw';
+ BufSize = 4096;
+ PPUExt = 'ppu';
+ ObjExt = 'o';
+ StaticLibExt ='a';
+{$ifdef unix}
+ SharedLibExt ='so';
+ BatchExt ='.sh';
+{$else}
+ SharedLibExt ='dll';
+ BatchExt ='.bat';
+{$endif unix}
+
+ { link options }
+ link_none = $0;
+ link_allways = $1;
+ link_static = $2;
+ link_smart = $4;
+ link_shared = $8;
+
+Type
+ PLinkOEnt = ^TLinkOEnt;
+ TLinkOEnt = record
+ Name : string;
+ Next : PLinkOEnt;
+ end;
+
+Var
+ ArBin,LDBin,StripBin,
+ OutputFile,
+ OutputFileForLink, { the name of the output file needed when linking }
+ DestPath,
+ PPLExt,
+ LibExt : string;
+ Batch,
+ Quiet,
+ MakeStatic : boolean;
+ Buffer : Pointer;
+ ObjFiles : PLinkOEnt;
+ BatchFile : Text;
+
+{*****************************************************************************
+ Helpers
+*****************************************************************************}
+
+Procedure Error(const s:string;stop:boolean);
+{
+ Write an error message to stderr
+}
+begin
+{$ifdef FPC}
+ writeln(stderr,s);
+{$else}
+ writeln(s);
+{$endif}
+ if stop then
+ halt(1);
+end;
+
+
+function Shell(const s:string):longint;
+{
+ Run a shell commnad and return the exitcode
+}
+begin
+ if Batch then
+ begin
+ Writeln(BatchFile,s);
+ Shell:=0;
+ exit;
+ end;
+{$ifdef unix}
+ Shell:={$ifdef ver1_0}linux{$else}unix{$endif}.shell(s);
+{$else}
+ exec(getenv('COMSPEC'),'/C '+s);
+ Shell:=DosExitCode;
+{$endif}
+end;
+
+
+Function FileExists (Const F : String) : Boolean;
+{
+ Returns True if the file exists, False if not.
+}
+Var
+{$ifdef unix}
+ info : Stat;
+{$else}
+ info : searchrec;
+{$endif}
+begin
+{$ifdef unix}
+ FileExists:={$ifdef VER1_0}FStat{$ELSE}FpStat{$endif} (F,Info){$ifndef VER1_0}=0{$endif};
+{$else}
+ FindFirst (F,anyfile,Info);
+ FileExists:=DosError=0;
+{$endif}
+end;
+
+
+Function AddExtension(Const HStr,ext:String):String;
+{
+ Return a filename which will have extension ext added if no
+ extension is found
+}
+var
+ j : longint;
+begin
+ j:=length(Hstr);
+ while (j>0) and (Hstr[j]<>'.') do
+ dec(j);
+ if j=0 then
+ AddExtension:=Hstr+'.'+Ext
+ else
+ AddExtension:=HStr;
+end;
+
+
+Function ForceExtension(Const HStr,ext:String):String;
+{
+ Return a filename which certainly has the extension ext
+}
+var
+ j : longint;
+begin
+ j:=length(Hstr);
+ while (j>0) and (Hstr[j]<>'.') do
+ dec(j);
+ if j=0 then
+ j:=255;
+ ForceExtension:=Copy(Hstr,1,j-1)+'.'+Ext;
+end;
+
+
+Procedure AddToLinkFiles(const S : String);
+{
+ Adds a filename to a list of object files to link to.
+ No duplicates allowed.
+}
+Var
+ P : PLinKOEnt;
+begin
+ P:=ObjFiles;
+ { Don't add files twice }
+ While (P<>nil) and (p^.name<>s) do
+ p:=p^.next;
+ if p=nil then
+ begin
+ new(p);
+ p^.next:=ObjFiles;
+ p^.name:=s;
+ ObjFiles:=P;
+ end;
+end;
+
+
+Function ExtractLib(const libfn:string):string;
+{
+ Extract a static library libfn and return the files with a
+ wildcard
+}
+var
+ n : namestr;
+ d : dirstr;
+ e : extstr;
+begin
+{ create the temp dir first }
+ fsplit(libfn,d,n,e);
+ {$I-}
+ mkdir(n+'.sl');
+ {$I+}
+ if ioresult<>0 then;
+{ Extract }
+ if Shell(arbin+' x '+libfn)<>0 then
+ Error('Fatal: Error running '+arbin,true);
+{ Remove the lib file, it's extracted so it can be created with ease }
+ if PPLExt=PPUExt then
+ Shell('rm '+libfn);
+{$ifdef unix}
+ ExtractLib:=n+'.sl/*';
+{$else}
+ ExtractLib:=n+'.sl\*';
+{$endif}
+end;
+
+
+Function DoPPU(const PPUFn,PPLFn:String):Boolean;
+{
+ Convert one file (in Filename) to library format.
+ Return true if successful, false otherwise.
+}
+Var
+ inppu,
+ outppu : tppufile;
+ b,
+ untilb : byte;
+ l,m : longint;
+ f : file;
+ s : string;
+begin
+ DoPPU:=false;
+ If Not Quiet then
+ Write ('Processing ',PPUFn,'...');
+ inppu:=tppufile.create(PPUFn);
+ if not inppu.openfile then
+ begin
+ inppu.free;
+ Error('Error: Could not open : '+PPUFn,false);
+ Exit;
+ end;
+{ Check the ppufile }
+ if not inppu.CheckPPUId then
+ begin
+ inppu.free;
+ Error('Error: Not a PPU File : '+PPUFn,false);
+ Exit;
+ end;
+ if inppu.GetPPUVersion<CurrentPPUVersion then
+ begin
+ inppu.free;
+ Error('Error: Wrong PPU Version : '+PPUFn,false);
+ Exit;
+ end;
+{ No .o file generated for this ppu, just skip }
+ if (inppu.header.flags and uf_no_link)<>0 then
+ begin
+ inppu.free;
+ If Not Quiet then
+ Writeln (' No files.');
+ DoPPU:=true;
+ Exit;
+ end;
+{ Already a lib? }
+ if (inppu.header.flags and uf_in_library)<>0 then
+ begin
+ inppu.free;
+ Error('Error: PPU is already in a library : '+PPUFn,false);
+ Exit;
+ end;
+{ We need a static linked unit }
+ if (inppu.header.flags and uf_static_linked)=0 then
+ begin
+ inppu.free;
+ Error('Error: PPU is not static linked : '+PPUFn,false);
+ Exit;
+ end;
+{ Create the new ppu }
+ if PPUFn=PPLFn then
+ outppu:=tppufile.create('ppumove.$$$')
+ else
+ outppu:=tppufile.create(PPLFn);
+ outppu.createfile;
+{ Create new header, with the new flags }
+ outppu.header:=inppu.header;
+ outppu.header.flags:=outppu.header.flags or uf_in_library;
+ if MakeStatic then
+ outppu.header.flags:=outppu.header.flags or uf_static_linked
+ else
+ outppu.header.flags:=outppu.header.flags or uf_shared_linked;
+{ read until the object files are found }
+ untilb:=iblinkunitofiles;
+ repeat
+ b:=inppu.readentry;
+ if b in [ibendinterface,ibend] then
+ begin
+ inppu.free;
+ outppu.free;
+ Error('Error: No files to be linked found : '+PPUFn,false);
+ Exit;
+ end;
+ if b<>untilb then
+ begin
+ repeat
+ inppu.getdatabuf(buffer^,bufsize,l);
+ outppu.putdata(buffer^,l);
+ until l<bufsize;
+ outppu.writeentry(b);
+ end;
+ until (b=untilb);
+{ we have now reached the section for the files which need to be added,
+ now add them to the list }
+ case b of
+ iblinkunitofiles :
+ begin
+ { add all o files, and save the entry when not creating a static
+ library to keep staticlinking possible }
+ while not inppu.endofentry do
+ begin
+ s:=inppu.getstring;
+ m:=inppu.getlongint;
+ if not MakeStatic then
+ begin
+ outppu.putstring(s);
+ outppu.putlongint(m);
+ end;
+ AddToLinkFiles(s);
+ end;
+ if not MakeStatic then
+ outppu.writeentry(b);
+ end;
+{ iblinkunitstaticlibs :
+ begin
+ AddToLinkFiles(ExtractLib(inppu.getstring));
+ if not inppu.endofentry then
+ begin
+ repeat
+ inppu.getdatabuf(buffer^,bufsize,l);
+ outppu.putdata(buffer^,l);
+ until l<bufsize;
+ outppu.writeentry(b);
+ end;
+ end; }
+ end;
+{ just add a new entry with the new lib }
+ if MakeStatic then
+ begin
+ outppu.putstring(outputfileforlink);
+ outppu.putlongint(link_static);
+ outppu.writeentry(iblinkunitstaticlibs)
+ end
+ else
+ begin
+ outppu.putstring(outputfileforlink);
+ outppu.putlongint(link_shared);
+ outppu.writeentry(iblinkunitsharedlibs);
+ end;
+{ read all entries until the end and write them also to the new ppu }
+ repeat
+ b:=inppu.readentry;
+ { don't write ibend, that's written automaticly }
+ if b<>ibend then
+ begin
+ repeat
+ inppu.getdatabuf(buffer^,bufsize,l);
+ outppu.putdata(buffer^,l);
+ until l<bufsize;
+ outppu.writeentry(b);
+ end;
+ until b=ibend;
+{ write the last stuff and close }
+ outppu.flush;
+ outppu.writeheader;
+ outppu.free;
+ inppu.free;
+{ rename }
+ if PPUFn=PPLFn then
+ begin
+ {$I-}
+ assign(f,PPUFn);
+ erase(f);
+ assign(f,'ppumove.$$$');
+ rename(f,PPUFn);
+ {$I+}
+ if ioresult<>0 then;
+ end;
+{ the end }
+ If Not Quiet then
+ Writeln (' Done.');
+ DoPPU:=True;
+end;
+
+
+Function DoFile(const FileName:String):Boolean;
+{
+ Process a file, mainly here for wildcard support under Dos
+}
+{$ifndef unix}
+var
+ dir : searchrec;
+{$endif}
+begin
+{$ifdef unix}
+ DoFile:=DoPPU(FileName,ForceExtension(FileName,PPLExt));
+{$else}
+ DoFile:=false;
+ findfirst(filename,$20,dir);
+ while doserror=0 do
+ begin
+ if not DoPPU(Dir.Name,ForceExtension(Dir.Name,PPLExt)) then
+ exit;
+ findnext(dir);
+ end;
+ findclose(dir);
+ DoFile:=true;
+{$endif}
+end;
+
+
+Procedure DoLink;
+{
+ Link the object files together to form a (shared) library, the only
+ problem here is the 255 char limit of Names
+}
+Var
+ Names : String;
+ f : file;
+ Err : boolean;
+ P : PLinkOEnt;
+begin
+ if not Quiet then
+ Write ('Linking ');
+ P:=ObjFiles;
+ names:='';
+ While p<>nil do
+ begin
+ if Names<>'' then
+ Names:=Names+' '+P^.name
+ else
+ Names:=p^.Name;
+ p:=p^.next;
+ end;
+ if Names='' then
+ begin
+ If not Quiet then
+ Writeln('Error: no files found to be linked');
+ exit;
+ end;
+ If not Quiet then
+ WriteLn(names);
+{ Run ar or ld to create the lib }
+ If MakeStatic then
+ Err:=Shell(arbin+' rs '+outputfile+' '+names)<>0
+ else
+ begin
+ Err:=Shell(ldbin+' -shared -o '+OutputFile+' '+names)<>0;
+ if not Err then
+ Shell(stripbin+' --strip-unneeded '+OutputFile);
+ end;
+ If Err then
+ Error('Fatal: Library building stage failed.',true);
+{ fix permission to 644, so it's not 755 }
+{$ifdef unix}
+ {$ifdef VER1_0}ChMod{$ELSE}FPChmod{$endif}(OutputFile,420);
+{$endif}
+{ Rename to the destpath }
+ if DestPath<>'' then
+ begin
+ Assign(F, OutputFile);
+ Rename(F,DestPath+'/'+OutputFile);
+ end;
+end;
+
+
+Procedure usage;
+{
+ Print usage and exit.
+}
+begin
+ Writeln(paramstr(0),': [-qhwvbs] [-e ext] [-o name] [-d path] file [file ...]');
+ Halt(0);
+end;
+
+
+
+Procedure processopts;
+{
+ Process command line opions, and checks if command line options OK.
+}
+var
+ C : char;
+begin
+ if paramcount=0 then
+ usage;
+{ Reset }
+ ObjFiles:=Nil;
+ Quiet:=False;
+ Batch:=False;
+ OutputFile:='';
+ PPLExt:='ppu';
+ ArBin:='ar';
+ LdBin:='ld';
+ StripBin:='strip';
+ repeat
+ c:=Getopt (ShortOpts);
+ Case C of
+ EndOfOptions : break;
+ 's' : MakeStatic:=True;
+ 'o' : OutputFile:=OptArg;
+ 'd' : DestPath:=OptArg;
+ 'e' : PPLext:=OptArg;
+ 'q' : Quiet:=True;
+ 'w' : begin
+ ArBin:='arw';
+ LdBin:='ldw';
+ end;
+ 'b' : Batch:=true;
+ '?' : Usage;
+ 'h' : Usage;
+ end;
+ until false;
+{ Test filenames on the commandline }
+ if (OptInd>Paramcount) then
+ Error('Error: no input files',true);
+ if (OptInd<ParamCount) and (OutputFile='') then
+ Error('Error: when moving multiple units, specify an output name.',true);
+{ alloc a buffer }
+ GetMem (Buffer,Bufsize);
+ If Buffer=Nil then
+ Error('Error: could not allocate memory for buffer.',true);
+end;
+
+
+var
+ i : longint;
+begin
+ ProcessOpts;
+{ Write Header }
+ if not Quiet then
+ begin
+ Writeln(Title+' '+Version);
+ Writeln(Copyright);
+ Writeln;
+ end;
+{ Check if shared is allowed }
+{$ifndef unix}
+ if arbin<>'arw' then
+ begin
+ Writeln('Warning: shared library not supported for Go32, switching to static library');
+ MakeStatic:=true;
+ end;
+{$endif}
+{ fix the libext and outputfilename }
+ if Makestatic then
+ LibExt:=StaticLibExt
+ else
+ LibExt:=SharedLibExt;
+ if OutputFile='' then
+ OutPutFile:=Paramstr(OptInd);
+{ fix filename }
+{$ifdef unix}
+ if Copy(OutputFile,1,3)<>'lib' then
+ OutputFile:='lib'+OutputFile;
+ { For unix skip replacing the extension if a full .so.X.X if specified }
+ i:=pos('.so.',Outputfile);
+ if i<>0 then
+ OutputFileForLink:=Copy(Outputfile,4,i-4)
+ else
+ begin
+ OutputFile:=ForceExtension(OutputFile,LibExt);
+ OutputFileForLink:=Copy(Outputfile,4,length(Outputfile)-length(LibExt)-4);
+ end;
+{$else}
+ OutputFile:=ForceExtension(OutputFile,LibExt);
+ OutputFileForLink:=OutputFile;
+{$endif}
+{ Open BatchFile }
+ if Batch then
+ begin
+ Assign(BatchFile,'pmove'+BatchExt);
+ Rewrite(BatchFile);
+ end;
+{ Process Files }
+ i:=OptInd;
+ While (i<=ParamCount) and Dofile(AddExtension(Paramstr(i),PPUExt)) do
+ Inc(i);
+{ Do Linking stage }
+ DoLink;
+{ Close BatchFile }
+ if Batch then
+ begin
+ if Not Quiet then
+ Writeln('Writing pmove'+BatchExt);
+ Close(BatchFile);
+{$ifdef unix}
+ {$ifdef VER1_0}ChMod{$ELSE}FPChmod{$endif}('pmove'+BatchExt,493);
+{$endif}
+ end;
+{ The End }
+ if Not Quiet then
+ Writeln('Done.');
+end.
diff --git a/compiler/utils/samplecfg b/compiler/utils/samplecfg
new file mode 100644
index 0000000000..bad2d8f569
--- /dev/null
+++ b/compiler/utils/samplecfg
@@ -0,0 +1,267 @@
+#!/bin/sh
+#
+# $Id: samplecfg,v 1.13 2005/02/19 18:50:20 florian Exp $
+#
+# Generate Sample Free Pascal configuration file
+#
+
+HOSTOS=`uname -s | tr A-Z a-z`
+echo Running on $HOSTOS
+
+if [ $# = 0 ]; then
+ echo 'Usage :'
+ echo 'samplecfg fpcdir confdir'
+ echo 'fpcdir = Path where FPC is installed'
+ echo 'confdir = Path to /etc'
+ exit 1
+fi
+if [ $2 ]; then
+ sysdir=$2
+ [ -d $sysdir ] || mkdir $sysdir
+else
+ sysdir=/etc
+fi
+
+# Detect if we have write permission in root.
+if [ -w $sysdir ] ; then
+ echo Write permission in $sysdir.
+ thefile=$sysdir/fpc.cfg
+else
+ echo No write premission in $sysdir.
+ thefile=$HOME/.fpc.cfg
+fi
+#
+if [ -f $thefile ] ; then
+ mv $thefile $thefile.orig >/dev/null 2>&1
+ if [ $? = 0 ]; then
+ echo Saved old config to $thefile.orig
+ else
+ echo Could not save old config. Bailing out...
+ exit
+ fi
+fi
+
+# Find path to libgcc.a
+GCCSPEC=`(gcc -v 2>&1)| head -n 1| awk '{ print $4 } '`
+if [ -z "$GCCSPEC" ] ; then
+ GCCSPEC=`gcc -print-libgcc-file-name`
+fi
+GCCDIR=`dirname $GCCSPEC`
+echo $GCCDIR
+if [ -f $GCCDIR ]; then
+# include ports tree dir for FreeBSDers.
+case $HOSTOS in
+ freebsd)
+ GCCDIR=-Fl/usr/local/lib
+ ;;
+ openbsd)
+ GCCDIR=-Fl/usr/local/lib
+ ;;
+ netbsd)
+ GCCDIR=-Fl/usr/pkg/lib
+ ;;
+esac
+else
+ echo Found libgcc.a in $GCCDIR
+ GCCDIR=-Fl$GCCDIR
+fi
+# Write the file
+echo Writing sample configuration file to $thefile
+cat <<EOFCFG > $thefile
+#
+# Example fpc.cfg for Free Pascal Compiler
+#
+
+# ----------------------
+# Defines (preprocessor)
+# ----------------------
+
+#
+# nested #IFNDEF, #IFDEF, #ENDIF, #ELSE, #DEFINE, #UNDEF are allowed
+#
+# -d is the same as #DEFINE
+# -u is the same as #UNDEF
+#
+
+#
+# Some examples (for switches see below, and the -? helppages)
+#
+# Try compiling with the -dRELEASE or -dDEBUG on the commandline
+#
+
+# For a release compile with optimizes and strip debuginfo
+#IFDEF RELEASE
+ -OG2p3
+ -Xs
+ #WRITE Compiling Release Version
+#ENDIF
+
+# For a debug version compile with debuginfo and all codegeneration checks on
+#IFDEF DEBUG
+ -g
+ -Crtoi
+ #WRITE Compiling Debug Version
+#ENDIF
+
+# set binutils prefix
+#IFDEF FPC_CROSSCOMPILING
+ -XP$fpctarget-
+#ENDIF
+
+# ----------------
+# Parsing switches
+# ----------------
+
+# Pascal language mode
+# -Mfpc free pascal dialect (default)
+# -Mobjfpc switch some Delphi 2 extensions on
+# -Mdelphi tries to be Delphi compatible
+# -Mtp tries to be TP/BP 7.0 compatible
+# -Mgpc tries to be gpc compatible
+# -Mmacpas tries to be compatible to the macintosh pascal dialects
+#
+# Turn on Object Pascal extensions by default
+#-Mobjfpc
+
+# Assembler reader mode
+# -Rdefault use default assembler
+# -Ratt read AT&T style assembler
+# -Rintel read Intel style assembler
+#
+# All assembler blocks are AT&T styled by default
+#-Ratt
+
+# Semantic checking
+# -S2 same as -Mobjfpc
+# -Sc supports operators like C (*=,+=,/= and -=)
+# -Sa include assertion code.
+# -Sd same as -Mdelphi
+# -Se<x> compiler stops after the <x> errors (default is 1)
+# -Sg allow LABEL and GOTO
+# -Sh Use ansistrings
+# -Si support C++ styled INLINE
+# -SI<x> set interface style to <x>
+# -SIcomCOM compatible interface (default)
+# -SIcorbaCORBA compatible interface
+# -Sm support macros like C (global)
+# -So same as -Mtp
+# -Sp same as -Mgpc
+# -Ss constructor name must be init (destructor must be done)
+# -St allow static keyword in objects
+#
+# Allow goto, inline, C-operators, C-vars
+-Sgic
+
+# ---------------
+# Code generation
+# ---------------
+
+# Uncomment the next line if you always want static/dynamic units by default
+# (can be overruled with -CD, -CS at the commandline)
+#-CS
+#-CD
+
+# Set the default heapsize to 8Mb
+#-Ch8000000
+
+# Set default codegeneration checks (iocheck, overflow, range, stack)
+#-Ci
+#-Co
+#-Cr
+#-Ct
+
+# Optimizer switches for i386 compiler
+# -Og generate smaller code
+# -OG generate faster code (default)
+# -Or keep certain variables in registers (still BUGGY!!!)
+# -Ou enable uncertain optimizations (see docs)
+# -O1 level 1 optimizations (quick optimizations)
+# -O2 level 2 optimizations (-O1 + slower optimizations)
+# -O3 level 3 optimizations (same as -O2u)
+# -Op target processor
+# -Op1 set target processor to 386/486
+# -Op2 set target processor to Pentium/PentiumMMX (tm)
+# -Op3 set target processor to PPro/PII/c6x86/K6 (tm)
+
+# Optimize always for Size and PII
+#-OG2p3
+
+
+# -----------------------
+# Set Filenames and Paths
+# -----------------------
+
+# Slashes are also allowed under dos
+
+# path to the messagefile, not necessary anymore but can be used to override
+# the default language
+#-Fr$1/msg/errore.msg
+#-Fr$1/msg/errorn.msg
+
+# searchpath for includefiles
+#-Fi/pp/inc;/pp/rtl/inc
+
+# searchpath for units and other system dependent things
+-Fu$1/units/\$fpctarget
+-Fu$1/units/\$fpctarget/*
+-Fu$1/units/\$fpctarget/rtl
+#-Fu~/fpc/packages/base/*/units/$fpctarget;~/fpc/fcl/units/$fpctarget;~/fpc/rtl/units/$fpctarget
+
+# searchpath for libraries
+$GCCDIR
+#-Fl/pp/lib
+#-Fl/lib;/usr/lib
+
+
+# -------------
+# Linking
+# -------------
+
+# generate always debugging information for GDB (slows down the compiling
+# process)
+# -gc generate checks for pointers
+# -gd use dbx
+# -gg use gsym
+# -gh use heap trace unit (for memory leak debugging)
+# -gl use line info unit to show more info for backtraces
+# -gv generates programs tracable with valgrind
+# -gw generate dwarf debugging info
+#
+# Enable debuginfo and use the line info unit by default
+#-gl
+
+# always pass an option to the linker
+#-k-s
+
+# Always strip debuginfo from the executable
+-Xs
+
+
+# -------------
+# Miscellaneous
+# -------------
+
+# Write always a nice FPC logo ;)
+-l
+
+# Verbosity
+# e : Show errors (default) d : Show debug info
+# w : Show warnings u : Show unit info
+# n : Show notes t : Show tried/used files
+# h : Show hints m : Show defined macros
+# i : Show general info p : Show compiled procedures
+# l : Show linenumbers c : Show conditionals
+# a : Show everything 0 : Show nothing (except errors)
+# b : Show all procedure r : Rhide/GCC compatibility mode
+# declarations if an error x : Executable info (Win32 only)
+# occurs
+#
+# Display Info, Warnings, Notes and Hints
+-viwn
+# If you don't want so much verbosity use
+#-vw
+
+#
+# That's all folks
+#
+EOFCFG
diff --git a/compiler/utils/usubst.pp b/compiler/utils/usubst.pp
new file mode 100644
index 0000000000..56c0ed38f7
--- /dev/null
+++ b/compiler/utils/usubst.pp
@@ -0,0 +1,109 @@
+{$mode objfpc}
+{$H+}
+{
+ This file is part of Free Pascal build tools
+ Copyright (c) 2005 by Michael Van Canneyt
+
+ Implements string substitutions
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+unit usubst;
+
+interface
+
+uses SysUtils,Classes;
+
+// Add N=V pair to list.
+Procedure AddToList(List : TStrings; Const N,V : String);
+// Split NV to N/V and call AddToList
+Function AddPair(List : TStrings; Const NV : String) : Boolean;
+// Perform substitutions in S, from List.
+Function DoSubStitutions(List : TStrings; Var S : String) : Integer;
+
+implementation
+
+Procedure AddToList(List : TStrings; Const N,V : String);
+
+var
+ I : Integer;
+
+begin
+ I:=List.IndexOfName(N);
+ If (V='') then
+ begin
+ If (I<>-1) then
+ List.Delete(I)
+ end
+ else
+ begin
+ If (I=-1) then
+ List.Add(N+'='+V)
+ else
+ List[I]:=N+'='+V;
+ end;
+end;
+
+Function AddPair(List : TStrings; Const NV : String) : Boolean;
+
+Var
+ P,I : Integer;
+ N,V : string;
+
+begin
+ P:=Pos('=',NV);
+ Result:=(P<>0);
+ If Result then
+ begin
+ V:=NV;
+ N:=Copy(V,1,P-1);
+ Delete(V,1,P);
+ AddToList(List,N,V);
+ end;
+end;
+
+Function DoSubstitutions(List : TStrings; Var S : String) : Integer;
+
+Var
+ N,T : String;
+ P : Integer;
+
+begin
+ Result:=0;
+ T:=S;
+ S:='';
+ P:=Pos('%',T);
+ While (P>0) do
+ begin
+ S:=S+Copy(T,1,P-1);
+ Delete(T,1,P);
+ If (Length(T)>0) then
+ if (T[1]='%') then
+ begin
+ S:=S+'%';
+ Delete(T,1,1);
+ end
+ else
+ begin
+ P:=Pos('%',T);
+ If (P=0) then
+ S:=S+'%'
+ else
+ begin
+ N:=Copy(T,1,P-1);
+ Delete(T,1,P);
+ S:=S+List.Values[N];
+ end;
+ end;
+ P:=Pos('%',T);
+ end;
+ S:=S+T;
+end;
+
+end.