diff options
| author | michael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2007-09-17 19:01:12 +0000 |
|---|---|---|
| committer | michael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2007-09-17 19:01:12 +0000 |
| commit | 26f39c550e9ec0b493a301d31300190c936d9c58 (patch) | |
| tree | ab75aca7138d518ab1eb6dd13ac40536abcaf8a4 /packages/fcl-json | |
| parent | 0fa233aa4f011488751ab4e23a6e70025faad1c2 (diff) | |
| download | fpc-26f39c550e9ec0b493a301d31300190c936d9c58.tar.gz | |
* Initial implementation
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@8522 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/fcl-json')
| -rw-r--r-- | packages/fcl-json/Makefile | 2783 | ||||
| -rw-r--r-- | packages/fcl-json/Makefile.fpc | 29 | ||||
| -rw-r--r-- | packages/fcl-json/src/fpjson.pp | 1448 | ||||
| -rw-r--r-- | packages/fcl-json/src/jsonparser.pp | 237 | ||||
| -rw-r--r-- | packages/fcl-json/src/jsonscanner.pp | 355 | ||||
| -rw-r--r-- | packages/fcl-json/tests/testjson.lpi | 65 | ||||
| -rw-r--r-- | packages/fcl-json/tests/testjson.pp | 21 | ||||
| -rw-r--r-- | packages/fcl-json/tests/testjsondata.pp | 1786 | ||||
| -rw-r--r-- | packages/fcl-json/tests/testjsonparser.pp | 364 |
9 files changed, 7088 insertions, 0 deletions
diff --git a/packages/fcl-json/Makefile b/packages/fcl-json/Makefile new file mode 100644 index 0000000000..3723584b1c --- /dev/null +++ b/packages/fcl-json/Makefile @@ -0,0 +1,2783 @@ +# +# Don't edit, this file is generated by FPCMake Version 2.0.0 [2007/04/28] +# +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-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded +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 $(FPCDIR)/packages/base $(FPCDIR)/packages/extra) +override PACKAGE_NAME=fcl-json +override PACKAGE_VERSION=2.2.0 +ifeq ($(FULL_TARGET),i386-linux) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-go32v2) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-win32) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-os2) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-freebsd) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-beos) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-netbsd) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-solaris) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-qnx) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-netware) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-openbsd) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-wdosx) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-darwin) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-emx) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-watcom) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-netwlibc) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-wince) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-embedded) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-symbian) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-linux) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-freebsd) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-netbsd) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-amiga) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-atari) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-openbsd) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-palmos) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-embedded) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-linux) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-netbsd) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-amiga) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-macos) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-darwin) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-morphos) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-embedded) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),sparc-linux) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),sparc-netbsd) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),sparc-solaris) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),sparc-embedded) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),x86_64-linux) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),x86_64-freebsd) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),x86_64-win64) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),x86_64-embedded) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-linux) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-palmos) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-wince) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-gba) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-nds) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-embedded) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-symbian) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc64-linux) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc64-darwin) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc64-embedded) +override TARGET_UNITS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-linux) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-go32v2) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-win32) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-os2) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-freebsd) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-beos) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-netbsd) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-solaris) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-qnx) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-netware) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-openbsd) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-wdosx) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-darwin) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-emx) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-watcom) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-netwlibc) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-wince) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-embedded) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),i386-symbian) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-linux) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-freebsd) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-netbsd) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-amiga) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-atari) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-openbsd) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-palmos) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),m68k-embedded) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-linux) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-netbsd) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-amiga) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-macos) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-darwin) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-morphos) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc-embedded) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),sparc-linux) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),sparc-netbsd) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),sparc-solaris) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),sparc-embedded) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),x86_64-linux) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),x86_64-freebsd) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),x86_64-win64) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),x86_64-embedded) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-linux) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-palmos) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-wince) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-gba) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-nds) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-embedded) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),arm-symbian) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc64-linux) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc64-darwin) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +ifeq ($(FULL_TARGET),powerpc64-embedded) +override TARGET_RSTS+=fpjson jsonscanner jsonparser +endif +override INSTALL_FPCPACKAGE=y +ifeq ($(FULL_TARGET),i386-linux) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-go32v2) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-win32) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-os2) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-freebsd) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-beos) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-netbsd) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-solaris) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-qnx) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-netware) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-openbsd) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-wdosx) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-darwin) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-emx) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-watcom) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-netwlibc) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-wince) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-embedded) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-symbian) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),m68k-linux) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),m68k-freebsd) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),m68k-netbsd) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),m68k-amiga) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),m68k-atari) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),m68k-openbsd) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),m68k-palmos) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),m68k-embedded) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),powerpc-linux) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),powerpc-netbsd) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),powerpc-amiga) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),powerpc-macos) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),powerpc-darwin) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),powerpc-morphos) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),powerpc-embedded) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),sparc-linux) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),sparc-netbsd) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),sparc-solaris) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),sparc-embedded) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),x86_64-linux) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),x86_64-freebsd) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),x86_64-win64) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),x86_64-embedded) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),arm-linux) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),arm-palmos) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),arm-wince) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),arm-gba) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),arm-nds) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),arm-embedded) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),arm-symbian) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),powerpc64-linux) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),powerpc64-darwin) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),powerpc64-embedded) +override COMPILER_OPTIONS+=-S2h +endif +ifeq ($(FULL_TARGET),i386-linux) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-go32v2) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-win32) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-os2) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-freebsd) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-beos) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-netbsd) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-solaris) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-qnx) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-netware) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-openbsd) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-wdosx) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-darwin) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-emx) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-watcom) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-netwlibc) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-wince) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-embedded) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),i386-symbian) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),m68k-linux) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),m68k-freebsd) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),m68k-netbsd) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),m68k-amiga) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),m68k-atari) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),m68k-openbsd) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),m68k-palmos) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),m68k-embedded) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),powerpc-linux) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),powerpc-netbsd) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),powerpc-amiga) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),powerpc-macos) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),powerpc-darwin) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),powerpc-morphos) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),powerpc-embedded) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),sparc-linux) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),sparc-netbsd) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),sparc-solaris) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),sparc-embedded) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),x86_64-linux) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),x86_64-freebsd) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),x86_64-win64) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),x86_64-embedded) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),arm-linux) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),arm-palmos) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),arm-wince) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),arm-gba) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),arm-nds) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),arm-embedded) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),arm-symbian) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),powerpc64-linux) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),powerpc64-darwin) +override COMPILER_SOURCEDIR+=src +endif +ifeq ($(FULL_TARGET),powerpc64-embedded) +override COMPILER_SOURCEDIR+=src +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 +ifndef INSTALL_SHAREDDIR +INSTALL_SHAREDDIR=$(INSTALL_PREFIX)/lib +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 +SHAREDLIBPREFIX=libfp +STATICLIBPREFIX=libp +IMPORTLIBPREFIX=libimp +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 +ifeq ($(OS_TARGET),gba) +EXEEXT=.gba +SHAREDLIBEXT=.so +SHORTSUFFIX=gba +endif +ifeq ($(OS_TARGET),symbian) +SHAREDLIBEXT=.dll +SHORTSUFFIX=symbian +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=.s +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 /gtar$(SRCEXEEXT),$(SEARCHPATH)))) +ifeq ($(TARPROG),) +TARPROG:=$(strip $(wildcard $(addsuffix /tar$(SRCEXEEXT),$(SEARCHPATH)))) +ifeq ($(TARPROG),) +TARPROG= __missing_command_TARPROG +else +TARPROG:=$(firstword $(TARPROG)) +endif +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 fcl-base +ifeq ($(FULL_TARGET),i386-linux) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-go32v2) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-win32) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_WINUNITS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-os2) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-freebsd) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-beos) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-netbsd) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-solaris) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-qnx) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-netware) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-openbsd) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-wdosx) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-darwin) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-emx) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-watcom) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-netwlibc) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-wince) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-embedded) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),i386-symbian) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),m68k-linux) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),m68k-freebsd) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),m68k-netbsd) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),m68k-amiga) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),m68k-atari) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),m68k-openbsd) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),m68k-palmos) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),m68k-embedded) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),powerpc-linux) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),powerpc-netbsd) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),powerpc-amiga) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),powerpc-macos) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),powerpc-darwin) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),powerpc-morphos) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),powerpc-embedded) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),sparc-linux) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),sparc-netbsd) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),sparc-solaris) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),sparc-embedded) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),x86_64-linux) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),x86_64-freebsd) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),x86_64-win64) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_WINUNITS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),x86_64-embedded) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),arm-linux) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),arm-palmos) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),arm-wince) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),arm-gba) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),arm-nds) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),arm-embedded) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),arm-symbian) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),powerpc64-linux) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),powerpc64-darwin) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_NETDB=1 +REQUIRE_PACKAGES_LIBASYNC=1 +REQUIRE_PACKAGES_PTHREADS=1 +REQUIRE_PACKAGES_FCL-BASE=1 +endif +ifeq ($(FULL_TARGET),powerpc64-embedded) +REQUIRE_PACKAGES_RTL=1 +REQUIRE_PACKAGES_HASH=1 +REQUIRE_PACKAGES_PASZLIB=1 +REQUIRE_PACKAGES_FCL-BASE=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 +ifdef REQUIRE_PACKAGES_HASH +PACKAGEDIR_HASH:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /hash/Makefile.fpc,$(PACKAGESDIR)))))) +ifneq ($(PACKAGEDIR_HASH),) +ifneq ($(wildcard $(PACKAGEDIR_HASH)/units/$(TARGETSUFFIX)),) +UNITDIR_HASH=$(PACKAGEDIR_HASH)/units/$(TARGETSUFFIX) +else +UNITDIR_HASH=$(PACKAGEDIR_HASH) +endif +ifdef CHECKDEPEND +$(PACKAGEDIR_HASH)/$(FPCMADE): + $(MAKE) -C $(PACKAGEDIR_HASH) $(FPCMADE) +override ALLDEPENDENCIES+=$(PACKAGEDIR_HASH)/$(FPCMADE) +endif +else +PACKAGEDIR_HASH= +UNITDIR_HASH:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /hash/Package.fpc,$(UNITSDIR))))) +ifneq ($(UNITDIR_HASH),) +UNITDIR_HASH:=$(firstword $(UNITDIR_HASH)) +else +UNITDIR_HASH= +endif +endif +ifdef UNITDIR_HASH +override COMPILER_UNITDIR+=$(UNITDIR_HASH) +endif +endif +ifdef REQUIRE_PACKAGES_PASZLIB +PACKAGEDIR_PASZLIB:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /paszlib/Makefile.fpc,$(PACKAGESDIR)))))) +ifneq ($(PACKAGEDIR_PASZLIB),) +ifneq ($(wildcard $(PACKAGEDIR_PASZLIB)/units/$(TARGETSUFFIX)),) +UNITDIR_PASZLIB=$(PACKAGEDIR_PASZLIB)/units/$(TARGETSUFFIX) +else +UNITDIR_PASZLIB=$(PACKAGEDIR_PASZLIB) +endif +ifdef CHECKDEPEND +$(PACKAGEDIR_PASZLIB)/$(FPCMADE): + $(MAKE) -C $(PACKAGEDIR_PASZLIB) $(FPCMADE) +override ALLDEPENDENCIES+=$(PACKAGEDIR_PASZLIB)/$(FPCMADE) +endif +else +PACKAGEDIR_PASZLIB= +UNITDIR_PASZLIB:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /paszlib/Package.fpc,$(UNITSDIR))))) +ifneq ($(UNITDIR_PASZLIB),) +UNITDIR_PASZLIB:=$(firstword $(UNITDIR_PASZLIB)) +else +UNITDIR_PASZLIB= +endif +endif +ifdef UNITDIR_PASZLIB +override COMPILER_UNITDIR+=$(UNITDIR_PASZLIB) +endif +endif +ifdef REQUIRE_PACKAGES_NETDB +PACKAGEDIR_NETDB:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /netdb/Makefile.fpc,$(PACKAGESDIR)))))) +ifneq ($(PACKAGEDIR_NETDB),) +ifneq ($(wildcard $(PACKAGEDIR_NETDB)/units/$(TARGETSUFFIX)),) +UNITDIR_NETDB=$(PACKAGEDIR_NETDB)/units/$(TARGETSUFFIX) +else +UNITDIR_NETDB=$(PACKAGEDIR_NETDB) +endif +ifdef CHECKDEPEND +$(PACKAGEDIR_NETDB)/$(FPCMADE): + $(MAKE) -C $(PACKAGEDIR_NETDB) $(FPCMADE) +override ALLDEPENDENCIES+=$(PACKAGEDIR_NETDB)/$(FPCMADE) +endif +else +PACKAGEDIR_NETDB= +UNITDIR_NETDB:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /netdb/Package.fpc,$(UNITSDIR))))) +ifneq ($(UNITDIR_NETDB),) +UNITDIR_NETDB:=$(firstword $(UNITDIR_NETDB)) +else +UNITDIR_NETDB= +endif +endif +ifdef UNITDIR_NETDB +override COMPILER_UNITDIR+=$(UNITDIR_NETDB) +endif +endif +ifdef REQUIRE_PACKAGES_LIBASYNC +PACKAGEDIR_LIBASYNC:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /libasync/Makefile.fpc,$(PACKAGESDIR)))))) +ifneq ($(PACKAGEDIR_LIBASYNC),) +ifneq ($(wildcard $(PACKAGEDIR_LIBASYNC)/units/$(TARGETSUFFIX)),) +UNITDIR_LIBASYNC=$(PACKAGEDIR_LIBASYNC)/units/$(TARGETSUFFIX) +else +UNITDIR_LIBASYNC=$(PACKAGEDIR_LIBASYNC) +endif +ifdef CHECKDEPEND +$(PACKAGEDIR_LIBASYNC)/$(FPCMADE): + $(MAKE) -C $(PACKAGEDIR_LIBASYNC) $(FPCMADE) +override ALLDEPENDENCIES+=$(PACKAGEDIR_LIBASYNC)/$(FPCMADE) +endif +else +PACKAGEDIR_LIBASYNC= +UNITDIR_LIBASYNC:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /libasync/Package.fpc,$(UNITSDIR))))) +ifneq ($(UNITDIR_LIBASYNC),) +UNITDIR_LIBASYNC:=$(firstword $(UNITDIR_LIBASYNC)) +else +UNITDIR_LIBASYNC= +endif +endif +ifdef UNITDIR_LIBASYNC +override COMPILER_UNITDIR+=$(UNITDIR_LIBASYNC) +endif +endif +ifdef REQUIRE_PACKAGES_PTHREADS +PACKAGEDIR_PTHREADS:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /pthreads/Makefile.fpc,$(PACKAGESDIR)))))) +ifneq ($(PACKAGEDIR_PTHREADS),) +ifneq ($(wildcard $(PACKAGEDIR_PTHREADS)/units/$(TARGETSUFFIX)),) +UNITDIR_PTHREADS=$(PACKAGEDIR_PTHREADS)/units/$(TARGETSUFFIX) +else +UNITDIR_PTHREADS=$(PACKAGEDIR_PTHREADS) +endif +ifdef CHECKDEPEND +$(PACKAGEDIR_PTHREADS)/$(FPCMADE): + $(MAKE) -C $(PACKAGEDIR_PTHREADS) $(FPCMADE) +override ALLDEPENDENCIES+=$(PACKAGEDIR_PTHREADS)/$(FPCMADE) +endif +else +PACKAGEDIR_PTHREADS= +UNITDIR_PTHREADS:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /pthreads/Package.fpc,$(UNITSDIR))))) +ifneq ($(UNITDIR_PTHREADS),) +UNITDIR_PTHREADS:=$(firstword $(UNITDIR_PTHREADS)) +else +UNITDIR_PTHREADS= +endif +endif +ifdef UNITDIR_PTHREADS +override COMPILER_UNITDIR+=$(UNITDIR_PTHREADS) +endif +endif +ifdef REQUIRE_PACKAGES_FCL-BASE +PACKAGEDIR_FCL-BASE:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-base/Makefile.fpc,$(PACKAGESDIR)))))) +ifneq ($(PACKAGEDIR_FCL-BASE),) +ifneq ($(wildcard $(PACKAGEDIR_FCL-BASE)/units/$(TARGETSUFFIX)),) +UNITDIR_FCL-BASE=$(PACKAGEDIR_FCL-BASE)/units/$(TARGETSUFFIX) +else +UNITDIR_FCL-BASE=$(PACKAGEDIR_FCL-BASE) +endif +ifdef CHECKDEPEND +$(PACKAGEDIR_FCL-BASE)/$(FPCMADE): + $(MAKE) -C $(PACKAGEDIR_FCL-BASE) $(FPCMADE) +override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-BASE)/$(FPCMADE) +endif +else +PACKAGEDIR_FCL-BASE= +UNITDIR_FCL-BASE:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-base/Package.fpc,$(UNITSDIR))))) +ifneq ($(UNITDIR_FCL-BASE),) +UNITDIR_FCL-BASE:=$(firstword $(UNITDIR_FCL-BASE)) +else +UNITDIR_FCL-BASE= +endif +endif +ifdef UNITDIR_FCL-BASE +override COMPILER_UNITDIR+=$(UNITDIR_FCL-BASE) +endif +endif +ifdef REQUIRE_PACKAGES_WINUNITS +PACKAGEDIR_WINUNITS:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /winunits/Makefile.fpc,$(PACKAGESDIR)))))) +ifneq ($(PACKAGEDIR_WINUNITS),) +ifneq ($(wildcard $(PACKAGEDIR_WINUNITS)/units/$(TARGETSUFFIX)),) +UNITDIR_WINUNITS=$(PACKAGEDIR_WINUNITS)/units/$(TARGETSUFFIX) +else +UNITDIR_WINUNITS=$(PACKAGEDIR_WINUNITS) +endif +ifdef CHECKDEPEND +$(PACKAGEDIR_WINUNITS)/$(FPCMADE): + $(MAKE) -C $(PACKAGEDIR_WINUNITS) $(FPCMADE) +override ALLDEPENDENCIES+=$(PACKAGEDIR_WINUNITS)/$(FPCMADE) +endif +else +PACKAGEDIR_WINUNITS= +UNITDIR_WINUNITS:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /winunits/Package.fpc,$(UNITSDIR))))) +ifneq ($(UNITDIR_WINUNITS),) +UNITDIR_WINUNITS:=$(firstword $(UNITDIR_WINUNITS)) +else +UNITDIR_WINUNITS= +endif +endif +ifdef UNITDIR_WINUNITS +override COMPILER_UNITDIR+=$(UNITDIR_WINUNITS) +endif +endif +ifndef NOCPUDEF +override FPCOPTDEF=$(CPU_TARGET) +endif +ifneq ($(OS_TARGET),$(OS_SOURCE)) +override FPCOPT+=-T$(OS_TARGET) +endif +ifneq ($(CPU_TARGET),$(CPU_SOURCE)) +override FPCOPT+=-P$(CPU_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 +ifneq ($(findstring 2.0.,$(FPC_VERSION)),) +ifeq ($(CPU_TARGET),i386) +FPCCPUOPT:=-OG2p3 +endif +ifeq ($(CPU_TARGET),powerpc) +FPCCPUOPT:=-O1r +endif +else +FPCCPUOPT:=-O2 +endif +override FPCOPT+=-Ur -Xs $(FPCCPUOPT) -n +override FPCOPTDEF+=RELEASE +endif +ifdef STRIP +override FPCOPT+=-Xs +endif +ifdef OPTIMIZE +override FPCOPT+=-O2 +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 +ifdef CREATESHARED +override FPCOPT+=-Cg +ifeq ($(CPU_TARGET),i386) +override FPCOPT+=-Aas +endif +endif +ifeq ($(findstring 2.0.,$(FPC_VERSION)),) +ifeq ($(OS_TARGET),linux) +ifeq ($(CPU_TARGET),x86_64) +override FPCOPT+=-Cg +endif +endif +endif +ifdef LINKSHARED +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 AFULL_TARGET=$(CPU_TARGET)-$(OS_TARGET) +override AFULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE) +ifneq ($(AFULL_TARGET),$(AFULL_SOURCE)) +override ACROSSCOMPILE=1 +endif +ifdef ACROSSCOMPILE +override FPCOPT+=$(CROSSOPT) +endif +override COMPILER:=$(FPC) $(FPCOPT) +ifeq (,$(findstring -s ,$(COMPILER))) +EXECPPAS= +else +ifeq ($(FULL_SOURCE),$(FULL_TARGET)) +EXECPPAS:=@$(PPAS) +endif +endif +.PHONY: fpc_units +ifneq ($(TARGET_UNITS),) +override ALLTARGET+=fpc_units +override UNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_UNITS)) +override IMPLICITUNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_IMPLICITUNITS)) +override INSTALLPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES) +override CLEANPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES) +endif +fpc_units: $(COMPILER_UNITTARGETDIR) $(UNITPPUFILES) +ifdef TARGET_RSTS +override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS)) +override CLEANRSTFILES+=$(RSTFILES) +endif +.PHONY: fpc_all fpc_smart fpc_debug fpc_release fpc_shared +$(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_shared +override INSTALLTARGET+=fpc_shared_install +ifndef SHARED_LIBVERSION +SHARED_LIBVERSION=$(FPC_VERSION) +endif +ifndef SHARED_LIBNAME +SHARED_LIBNAME=$(PACKAGE_NAME) +endif +ifndef SHARED_FULLNAME +SHARED_FULLNAME=$(SHAREDLIBPREFIX)$(SHARED_LIBNAME)-$(SHARED_LIBVERSION)$(SHAREDLIBEXT) +endif +ifndef SHARED_LIBUNITS +SHARED_LIBUNITS:=$(TARGET_UNITS) $(TARGET_IMPLICITUNITS) +override SHARED_LIBUNITS:=$(filter-out $(INSTALL_BUILDUNIT),$(SHARED_LIBUNITS)) +endif +fpc_shared: +ifdef HASSHAREDLIB + $(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1 +ifneq ($(SHARED_BUILD),n) + $(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGETDIR) -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR) +endif +else + @$(ECHO) Shared Libraries not supported +endif +fpc_shared_install: +ifneq ($(SHARED_BUILD),n) +ifneq ($(SHARED_LIBUNITS),) +ifneq ($(wildcard $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME)),) + $(INSTALL) $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME) $(INSTALL_SHAREDDIR) +endif +endif +endif +.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))) $(addprefix $(IMPORTLIBPREFIX),$(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_distinstall +fpc_distinstall: install exampleinstall +.PHONY: fpc_zipinstall fpc_zipsourceinstall fpc_zipexampleinstall +ifndef PACKDIR +ifndef inUnix +PACKDIR=$(BASEDIR)/../fpc-pack +else +PACKDIR=/tmp/fpc-pack +endif +endif +ifndef ZIPNAME +ifdef DIST_ZIPNAME +ZIPNAME=$(DIST_ZIPNAME) +else +ZIPNAME=$(PACKAGE_NAME) +endif +endif +ifndef FULLZIPNAME +FULLZIPNAME=$(ZIPCROSSPREFIX)$(ZIPPREFIX)$(ZIPNAME)$(ZIPSUFFIX) +endif +ifndef ZIPTARGET +ifdef DIST_ZIPTARGET +ZIPTARGET=DIST_ZIPTARGET +else +ZIPTARGET=install +endif +endif +ifndef USEZIP +ifdef inUnix +USETAR=1 +endif +endif +ifndef inUnix +USEZIPWRAPPER=1 +endif +ifdef USEZIPWRAPPER +ZIPPATHSEP=$(PATHSEP) +ZIPWRAPPER=$(subst /,$(PATHSEP),$(DIST_DESTDIR)/fpczip$(SRCBATCHEXT)) +else +ZIPPATHSEP=/ +endif +ZIPCMD_CDPACK:=cd $(subst /,$(ZIPPATHSEP),$(PACKDIR)) +ZIPCMD_CDBASE:=cd $(subst /,$(ZIPPATHSEP),$(BASEDIR)) +ifdef USETAR +ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(TAREXT) +ZIPCMD_ZIP:=$(TARPROG) cf$(TAROPT) $(ZIPDESTFILE) * +else +ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(ZIPEXT) +ZIPCMD_ZIP:=$(subst /,$(ZIPPATHSEP),$(ZIPPROG)) -Dr $(ZIPOPT) $(ZIPDESTFILE) * +endif +fpc_zipinstall: + $(MAKE) $(ZIPTARGET) INSTALL_PREFIX=$(PACKDIR) ZIPINSTALL=1 + $(MKDIR) $(DIST_DESTDIR) + $(DEL) $(ZIPDESTFILE) +ifdef USEZIPWRAPPER +ifneq ($(ECHOREDIR),echo) + $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDPACK))" > $(ZIPWRAPPER) + $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_ZIP))" >> $(ZIPWRAPPER) + $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDBASE))" >> $(ZIPWRAPPER) +else + echo $(ZIPCMD_CDPACK) > $(ZIPWRAPPER) + echo $(ZIPCMD_ZIP) >> $(ZIPWRAPPER) + echo $(ZIPCMD_CDBASE) >> $(ZIPWRAPPER) +endif +ifdef inUnix + /bin/sh $(ZIPWRAPPER) +else + $(ZIPWRAPPER) +endif + $(DEL) $(ZIPWRAPPER) +else + $(ZIPCMD_CDPACK) ; $(ZIPCMD_ZIP) ; $(ZIPCMD_CDBASE) +endif + $(DELTREE) $(PACKDIR) +fpc_zipsourceinstall: + $(MAKE) fpc_zipinstall ZIPTARGET=sourceinstall ZIPSUFFIX=$(ZIPSOURCESUFFIX) +fpc_zipexampleinstall: +ifdef HASEXAMPLES + $(MAKE) fpc_zipinstall ZIPTARGET=exampleinstall ZIPSUFFIX=$(ZIPEXAMPLESUFFIX) +endif +fpc_zipdistinstall: + $(MAKE) fpc_zipinstall ZIPTARGET=distinstall +.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))) $(addprefix $(IMPORTLIBPREFIX),$(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 +all: fpc_all +debug: fpc_debug +smart: fpc_smart +release: fpc_release +units: fpc_units +examples: +shared: fpc_shared +install: fpc_install +sourceinstall: fpc_sourceinstall +exampleinstall: fpc_exampleinstall +distinstall: fpc_distinstall +zipinstall: fpc_zipinstall +zipsourceinstall: fpc_zipsourceinstall +zipexampleinstall: fpc_zipexampleinstall +zipdistinstall: fpc_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 +.NOTPARALLEL: +jsonparser$(PPUEXT): jsonparser.pp fpjson$(PPUEXT) jsonscanner$(PPUEXT) diff --git a/packages/fcl-json/Makefile.fpc b/packages/fcl-json/Makefile.fpc new file mode 100644 index 0000000000..68de666016 --- /dev/null +++ b/packages/fcl-json/Makefile.fpc @@ -0,0 +1,29 @@ +# +# Makefile.fpc for XML for FCL +# + +[package] +name=fcl-json +version=2.2.0 + +[target] +units=fpjson jsonscanner jsonparser +rsts=fpjson jsonscanner jsonparser + +[require] +packages=fcl-base + +[compiler] +options=-S2h +sourcedir=src + +[install] +fpcpackage=y + +[default] +fpcdir=../.. + +[rules] +.NOTPARALLEL: + +jsonparser$(PPUEXT): jsonparser.pp fpjson$(PPUEXT) jsonscanner$(PPUEXT) diff --git a/packages/fcl-json/src/fpjson.pp b/packages/fcl-json/src/fpjson.pp new file mode 100644 index 0000000000..45ff2c78a3 --- /dev/null +++ b/packages/fcl-json/src/fpjson.pp @@ -0,0 +1,1448 @@ +{$mode objfpc} +{$h+} +unit fpjson; + +interface + +uses + variants, + SysUtils, + classes, + contnrs; + +type + + TJSONtype = (jtUnknown, jtNumber, jtString, jtBoolean, jtNull, jtArray, jtObject); + TJSONFloat = Extended; + TJSONStringType = AnsiString; + + { TJSONData } + + TJSONData = class(TObject) + protected + function GetAsBoolean: Boolean; virtual; abstract; + function GetAsFloat: TJSONFloat; virtual; abstract; + function GetAsInteger: Integer; virtual; abstract; + function GetIsNull: Boolean; virtual; + procedure SetAsBoolean(const AValue: Boolean); virtual; abstract; + procedure SetAsFloat(const AValue: TJSONFloat); virtual; abstract; + procedure SetAsInteger(const AValue: Integer); virtual; abstract; + function GetAsJSON: TJSONStringType; virtual; abstract; + function GetAsString: TJSONStringType; virtual; abstract; + procedure SetAsString(const AValue: TJSONStringType); virtual; abstract; + function GetValue: variant; virtual; abstract; + procedure SetValue(const AValue: variant); virtual; abstract; + function GetItem(Index : Integer): TJSONData; virtual; + procedure SetItem(Index : Integer; const AValue: TJSONData); virtual; + function GetCount: Integer; virtual; + public + Class function JSONType: TJSONType; virtual; + property Count: Integer read GetCount; + property Items[Index: Integer]: TJSONData read GetItem write SetItem; + property Value: variant read GetValue write SetValue; + Property AsString : TJSONStringType Read GetAsString Write SetAsString; + Property AsFloat : TJSONFloat Read GetAsFloat Write SetAsFloat; + Property AsInteger : Integer Read GetAsInteger Write SetAsInteger; + Property AsBoolean : Boolean Read GetAsBoolean Write SetAsBoolean; + Property IsNull : Boolean Read GetIsNull; + Property AsJSON : String Read GetAsJSON; + end; + + TJSONNumberType = (ntFloat,ntInteger); + + TJSONNumber = class(TJSONData) + protected + public + class function JSONType: TJSONType; override; + class function NumberType : TJSONNumberType; virtual; abstract; + end; + + { TJSONFloatNumber } + + TJSONFloatNumber = class(TJSONNumber) + Private + FValue : TJSONFloat; + protected + function GetAsBoolean: Boolean; override; + function GetAsFloat: TJSONFloat; override; + function GetAsInteger: Integer; override; + procedure SetAsBoolean(const AValue: Boolean); override; + procedure SetAsFloat(const AValue: TJSONFloat); override; + procedure SetAsInteger(const AValue: Integer); override; + function GetAsJSON: TJSONStringType; override; + function GetAsString: TJSONStringType; override; + procedure SetAsString(const AValue: TJSONStringType); override; + function GetValue: variant; override; + procedure SetValue(const AValue: variant); override; + public + Constructor Create(AValue : TJSONFloat); + class function NumberType : TJSONNumberType; override; + end; + + { TJSONIntegerNumber } + + TJSONIntegerNumber = class(TJSONNumber) + Private + FValue : Integer; + protected + function GetAsBoolean: Boolean; override; + function GetAsFloat: TJSONFloat; override; + function GetAsInteger: Integer; override; + procedure SetAsBoolean(const AValue: Boolean); override; + procedure SetAsFloat(const AValue: TJSONFloat); override; + procedure SetAsInteger(const AValue: Integer); override; + function GetAsJSON: TJSONStringType; override; + function GetAsString: TJSONStringType; override; + procedure SetAsString(const AValue: TJSONStringType); override; + function GetValue: variant; override; + procedure SetValue(const AValue: variant); override; + public + Constructor Create(AValue : Integer); + class function NumberType : TJSONNumberType; override; + end; + + { TJSONString } + + TJSONString = class(TJSONData) + Private + FValue: TJSONStringType; + protected + function GetValue: Variant; override; + procedure SetValue(const AValue: Variant); override; + function GetAsBoolean: Boolean; override; + function GetAsFloat: TJSONFloat; override; + function GetAsInteger: Integer; override; + procedure SetAsBoolean(const AValue: Boolean); override; + procedure SetAsFloat(const AValue: TJSONFloat); override; + procedure SetAsInteger(const AValue: Integer); override; + function GetAsJSON: TJSONStringType; override; + function GetAsString: TJSONStringType; override; + procedure SetAsString(const AValue: TJSONStringType); override; + public + Constructor Create(AValue : TJSONStringType); + class function JSONType: TJSONType; override; + end; + + { TJSONboolean } + + TJSONBoolean = class(TJSONData) + Private + FValue: Boolean; + protected + function GetValue: Variant; override; + procedure SetValue(const AValue: Variant); override; + function GetAsBoolean: Boolean; override; + function GetAsFloat: TJSONFloat; override; + function GetAsInteger: Integer; override; + procedure SetAsBoolean(const AValue: Boolean); override; + procedure SetAsFloat(const AValue: TJSONFloat); override; + procedure SetAsInteger(const AValue: Integer); override; + function GetAsJSON: TJSONStringType; override; + function GetAsString: TJSONStringType; override; + procedure SetAsString(const AValue: TJSONStringType); override; + public + Constructor Create(AValue : Boolean); + class function JSONType: TJSONType; override; + end; + + { TJSONnull } + + TJSONNull = class(TJSONData) + protected + Procedure Converterror(From : Boolean); + function GetAsBoolean: Boolean; override; + function GetAsFloat: TJSONFloat; override; + function GetAsInteger: Integer; override; + function GetIsNull: Boolean; override; + procedure SetAsBoolean(const AValue: Boolean); override; + procedure SetAsFloat(const AValue: TJSONFloat); override; + procedure SetAsInteger(const AValue: Integer); override; + function GetAsJSON: TJSONStringType; override; + function GetAsString: TJSONStringType; override; + procedure SetAsString(const AValue: TJSONStringType); override; + function GetValue: variant; override; + procedure SetValue(const AValue: variant); override; + public + class function JSONType: TJSONType; override; + end; + + TJSONArrayIterator = procedure(Item: TJSONData; Data: TObject; var Continue: Boolean) of object; + + { TJSONArray } + TJSONObject = Class; + + TJSONArray = class(TJSONData) + Private + FList : TFPObjectList; + function GetArrays(Index : Integer): TJSONArray; + function GetBooleans(Index : Integer): Boolean; + function GetFloats(Index : Integer): TJSONFloat; + function GetIntegers(Index : Integer): Integer; + function GetNulls(Index : Integer): Boolean; + function GetObjects(Index : Integer): TJSONObject; + function GetStrings(Index : Integer): TJSONStringType; + function GetTypes(Index : Integer): TJSONType; + procedure SetArrays(Index : Integer; const AValue: TJSONArray); + procedure SetBooleans(Index : Integer; const AValue: Boolean); + procedure SetFloats(Index : Integer; const AValue: TJSONFloat); + procedure SetIntegers(Index : Integer; const AValue: Integer); + procedure SetObjects(Index : Integer; const AValue: TJSONObject); + procedure SetStrings(Index : Integer; const AValue: TJSONStringType); + protected + Procedure Converterror(From : Boolean); + function GetAsBoolean: Boolean; override; + function GetAsFloat: TJSONFloat; override; + function GetAsInteger: Integer; override; + procedure SetAsBoolean(const AValue: Boolean); override; + procedure SetAsFloat(const AValue: TJSONFloat); override; + procedure SetAsInteger(const AValue: Integer); override; + function GetAsJSON: TJSONStringType; override; + function GetAsString: TJSONStringType; override; + procedure SetAsString(const AValue: TJSONStringType); override; + function GetValue: variant; override; + procedure SetValue(const AValue: variant); override; + function GetCount: Integer; override; + function GetItem(Index : Integer): TJSONData; override; + procedure SetItem(Index : Integer; const AValue: TJSONData); override; + public + Constructor Create; overload; + Constructor Create(const Elements : Array of Const); overload; + Destructor Destroy; override; + class function JSONType: TJSONType; override; + // Examine + procedure Iterate(Iterator : TJSONArrayIterator; Data: TObject); + function IndexOf(obj: TJSONData): Integer; + // Manipulate + function Add(Item : TJSONData): Integer; + function Add(I : Integer): Integer; + function Add(S : String): Integer; + function Add: Integer; + function Add(F : TJSONFloat): Integer; + function Add(B : Boolean): Integer; + function Add(AnArray : TJSONArray): Integer; + function Add(AnObject: TJSONObject): Integer; + Procedure Delete(Index : Integer); + Procedure Remove(Item : TJSONData); + // Easy Access Properties. + property Items;default; + Property Types[Index : Integer] : TJSONType Read GetTypes; + Property Nulls[Index : Integer] : Boolean Read GetNulls; + Property Integers[Index : Integer] : Integer Read GetIntegers Write SetIntegers; + Property Strings[Index : Integer] : TJSONStringType Read GetStrings Write SetStrings; + Property Floats[Index : Integer] : TJSONFloat Read GetFloats Write SetFloats; + Property Booleans[Index : Integer] : Boolean Read GetBooleans Write SetBooleans; + Property Arrays[Index : Integer] : TJSONArray Read GetArrays Write SetArrays; + Property Objects[Index : Integer] : TJSONObject Read GetObjects Write SetObjects; + end; + + TJSONObjectIterator = procedure(Const AName : TJSONStringType; Item: TJSONData; Data: TObject; var Continue: Boolean) of object; + + { TJSONObject } + + TJSONObject = class(TJSONData) + private + FHash : TFPHashObjectList; // Careful : Names limited to 255 chars. + function GetArrays(AName : String): TJSONArray; + function GetBooleans(AName : String): Boolean; + function GetElements(AName: string): TJSONData; + function GetFloats(AName : String): TJSONFloat; + function GetIntegers(AName : String): Integer; + function GetIsNull(AName : String): Boolean; + function GetNameOf(Index : Integer): TJSONStringType; + function GetObjects(AName : String): TJSONObject; + function GetStrings(AName : String): TJSONStringType; + function GetTypes(AName : String): TJSONType; + procedure SetArrays(AName : String; const AValue: TJSONArray); + procedure SetBooleans(AName : String; const AValue: Boolean); + procedure SetElements(AName: string; const AValue: TJSONData); + procedure SetFloats(AName : String; const AValue: TJSONFloat); + procedure SetIntegers(AName : String; const AValue: Integer); + procedure SetIsNull(AName : String; const AValue: Boolean); + procedure SetObjects(AName : String; const AValue: TJSONObject); + procedure SetStrings(AName : String; const AValue: TJSONStringType); + protected + Procedure Converterror(From : Boolean); + function GetAsBoolean: Boolean; override; + function GetAsFloat: TJSONFloat; override; + function GetAsInteger: Integer; override; + procedure SetAsBoolean(const AValue: Boolean); override; + procedure SetAsFloat(const AValue: TJSONFloat); override; + procedure SetAsInteger(const AValue: Integer); override; + function GetAsJSON: TJSONStringType; override; + function GetAsString: TJSONStringType; override; + procedure SetAsString(const AValue: TJSONStringType); override; + function GetValue: variant; override; + procedure SetValue(const AValue: variant); override; + function GetCount: Integer; override; + function GetItem(Index : Integer): TJSONData; override; + procedure SetItem(Index : Integer; const AValue: TJSONData); override; + public + constructor Create; + Constructor Create(const Elements : Array of Const); overload; + destructor Destroy; override; + class function JSONType: TJSONType; override; + // Examine + procedure Iterate(Iterator : TJSONObjectIterator; Data: TObject); + function IndexOf(Item: TJSONData): Integer; + Function IndexOfName(const AName: TJSONStringType): Integer; + // Manipulate + function Add(const AName: TJSONStringType; AValue: TJSONData): Integer; overload; + function Add(const AName: TJSONStringType; AValue: Boolean): Integer; overload; + function Add(const AName: TJSONStringType; AValue: TJSONFloat): Integer; overload; + function Add(const AName: TJSONStringType; AValue: TJSONStringType): Integer; overload; + function Add(const AName: TJSONStringType; Avalue: Integer): Integer; overload; + function Add(const AName: TJSONStringType): Integer; overload; + function Add(const AName: TJSONStringType; AValue : TJSONArray): Integer; overload; + procedure Delete(Index : Integer); + procedure Remove(Item : TJSONData); + + // Easy access properties. + property Names[Index : Integer] : TJSONStringType read GetNameOf; + property Elements[AName: string] : TJSONData read GetElements write SetElements; default; + + Property Types[AName : String] : TJSONType Read GetTypes; + Property Nulls[AName : String] : Boolean Read GetIsNull Write SetIsNull; + Property Floats[AName : String] : TJSONFloat Read GetFloats Write SetFloats; + Property Integers[AName : String] : Integer Read GetIntegers Write SetIntegers; + Property Strings[AName : String] : TJSONStringType Read GetStrings Write SetStrings; + Property Booleans[AName : String] : Boolean Read GetBooleans Write SetBooleans; + Property Arrays[AName : String] : TJSONArray Read GetArrays Write SetArrays; + Property Objects[AName : String] : TJSONObject Read GetObjects Write SetObjects; + end; + + EJSON = Class(Exception); + +Function StringToJSONString(S : TJSONStringType) : TJSONStringType; +Function JSONStringToString(S : TJSONStringType) : TJSONStringType; + + + +implementation + +Resourcestring + SErrCannotConvertFromNull = 'Cannot convert data from Null value'; + SErrCannotConvertToNull = 'Cannot convert data to Null value'; + SErrCannotConvertFromArray = 'Cannot convert data from array value'; + SErrCannotConvertToArray = 'Cannot convert data to array value'; + SErrCannotConvertFromObject = 'Cannot convert data from object value'; + SErrCannotConvertToObject = 'Cannot convert data to object value'; + SErrInvalidFloat = 'Invalid float value : %s'; + SErrInvalidInteger = 'Invalid float value : %s'; + SErrCannotSetNotIsNull = 'IsNull cannot be set to False'; + SErrCannotAddArrayTwice = 'Adding an array object to an array twice is not allowed'; + SErrCannotAddObjectTwice = 'Adding an object to an array twice is not allowed'; + SErrUnknownTypeInConstructor = 'Unknown type in JSON%s constructor: %d'; + SErrNotJSONData = 'Cannot add object of type %s to TJSON%s'; + SErrPointerNotNil = 'Cannot add non-nil pointer to JSON%s'; + SErrOddNumber = 'TJSONObject must be constructed with name,value pairs'; + SErrNameMustBeString = 'TJSONObject constructor element name at pos %d is not a string'; + + +Function StringToJSONString(S : TJSONStringType) : TJSONStringType; + +Var + I,J,L : Integer; + P : Pchar; + +begin + I:=1; + J:=1; + Result:=''; + L:=Length(S); + P:=PChar(S); + While I<=L do + begin + if (P^ in ['"','/','\',#8,#9,#10,#12,#13]) then + begin + Result:=Result+Copy(S,J,I-J); + Case P^ of + '\' : Result:=Result+'\\'; + '/' : Result:=Result+'\/'; + '"' : Result:=Result+'\"'; + #8 : Result:=Result+'\b'; + #9 : Result:=Result+'\t'; + #10 : Result:=Result+'\n'; + #12 : Result:=Result+'\f'; + #13 : Result:=Result+'\r'; + end; + J:=I+1; + end; + Inc(I); + Inc(P); + end; + Result:=Result+Copy(S,J,I-1); +end; + +Function JSONStringToString(S : TJSONStringType) : TJSONStringType; + +Var + I,J,L : Integer; + P : PChar; + w : String; + +begin + I:=1; + J:=1; + L:=Length(S); + Result:=''; + P:=PChar(S); + While (I<=L) do + begin + if (P^='\') then + begin + Result:=Result+Copy(S,J,I-J); + Inc(P); + If (P^<>#0) then + begin + Inc(I); + Case P^ of + '\','"','/' + : Result:=Result+P^; + 'b' : Result:=Result+#8; + 't' : Result:=Result+#9; + 'n' : Result:=Result+#10; + 'f' : Result:=Result+#12; + 'r' : Result:=Result+#13; + 'u' : begin + W:=Copy(S,I+1,4); + Inc(I,4); + Inc(P,4); + Result:=Result+WideChar(StrToInt('$'+W)); + end; + end; + end; + J:=I+1; + end; + Inc(I); + Inc(P); + end; + Result:=Result+Copy(S,J,I-J+1); +end; + + + +{ TJSONData } + + +function TJSONData.GetItem(Index : Integer): TJSONData; +begin + Result:=nil; +end; + +function TJSONData.GetCount: Integer; +begin + Result:=0; +end; + +function TJSONData.GetIsNull: Boolean; +begin + Result:=False; +end; + +class function TJSONData.JSONType: TJSONType; +begin + JSONType:=jtUnknown; +end; + +procedure TJSONData.SetItem(Index : Integer; const AValue: + TJSONData); +begin + // Do Nothing +end; + +{ TJSONnumber } + +class function TJSONnumber.JSONType: TJSONType; +begin + Result:=jtNumber; +end; + + +{ TJSONstring } + +class function TJSONstring.JSONType: TJSONType; +begin + Result:=jtString; +end; + +function TJSONstring.GetValue: Variant; +begin + Result:=FValue; +end; + +procedure TJSONstring.SetValue(const AValue: Variant); +begin + FValue:=AValue; +end; + + +function TJSONstring.GetAsBoolean: Boolean; +begin + Result:=StrToBool(FValue); +end; + +function TJSONstring.GetAsFloat: TJSONFloat; + +Var + C : Integer; + +begin + Val(FValue,Result,C); + If (C<>0) then + If Not TryStrToFloat(FValue,Result) then + Raise EConvertError.CreateFmt(SErrInvalidFloat,[FValue]); +end; + +function TJSONstring.GetAsInteger: Integer; +begin + Result:=StrToInt(FValue); +end; + +procedure TJSONstring.SetAsBoolean(const AValue: Boolean); +begin + FValue:=BoolToStr(AValue); +end; + +procedure TJSONstring.SetAsFloat(const AValue: TJSONFloat); +begin + FValue:=FloatToStr(AValue); +end; + +procedure TJSONstring.SetAsInteger(const AValue: Integer); +begin + FValue:=IntToStr(AValue); +end; + +function TJSONstring.GetAsJSON: TJSONStringType; +begin + Result:='"'+StringToJSONString(FValue)+'"'; +end; + +function TJSONstring.GetAsString: TJSONStringType; +begin + Result:=FValue; +end; + +procedure TJSONstring.SetAsString(const AValue: TJSONStringType); +begin + FValue:=AValue; +end; + +constructor TJSONstring.Create(AValue: TJSONStringType); +begin + FValue:=AValue; +end; + +{ TJSONboolean } + + +function TJSONboolean.GetValue: Variant; +begin + Result:=FValue; +end; + +class function TJSONboolean.JSONType: TJSONType; +begin + Result:=jtBoolean; +end; + + +procedure TJSONboolean.SetValue(const AValue: Variant); +begin + FValue:=boolean(AValue); +end; + +function TJSONboolean.GetAsBoolean: Boolean; +begin + Result:=FValue; +end; + +function TJSONboolean.GetAsFloat: TJSONFloat; +begin + Result:=Ord(FValue); +end; + +function TJSONboolean.GetAsInteger: Integer; +begin + Result:=Ord(FValue); +end; + + +procedure TJSONboolean.SetAsBoolean(const AValue: Boolean); +begin + FValue:=AValue; +end; + +procedure TJSONboolean.SetAsFloat(const AValue: TJSONFloat); +begin + FValue:=(AValue<>0) +end; + +procedure TJSONboolean.SetAsInteger(const AValue: Integer); +begin + FValue:=(AValue<>0) +end; + +function TJSONboolean.GetAsJSON: TJSONStringType; +begin + If FValue then + Result:='True' + else + Result:='False'; +end; + +function TJSONboolean.GetAsString: TJSONStringType; +begin + Result:=BoolToStr(FValue); +end; + +procedure TJSONboolean.SetAsString(const AValue: TJSONStringType); +begin + FValue:=StrToBool(AValue); +end; + +constructor TJSONboolean.Create(AValue: Boolean); +begin + FValue:=AValue; +end; + +{ TJSONnull } + +procedure TJSONnull.Converterror(From : Boolean); +begin + If From then + Raise EJSON.Create(SErrCannotConvertFromNull) + else + Raise EJSON.Create(SErrCannotConvertToNull); +end; + +function TJSONnull.GetAsBoolean: Boolean; +begin + ConvertError(True); +end; + +function TJSONnull.GetAsFloat: TJSONFloat; +begin + ConvertError(True); +end; + +function TJSONnull.GetAsInteger: Integer; +begin + ConvertError(True); +end; + +function TJSONnull.GetIsNull: Boolean; +begin + Result:=True; +end; + +procedure TJSONnull.SetAsBoolean(const AValue: Boolean); +begin + ConvertError(False); +end; + +procedure TJSONnull.SetAsFloat(const AValue: TJSONFloat); +begin + ConvertError(False); +end; + +procedure TJSONnull.SetAsInteger(const AValue: Integer); +begin + ConvertError(False); +end; + +function TJSONnull.GetAsJSON: TJSONStringType; +begin + Result:='Null'; +end; + +function TJSONnull.GetAsString: TJSONStringType; +begin + ConvertError(True); +end; + +procedure TJSONnull.SetAsString(const AValue: TJSONStringType); +begin + ConvertError(True); +end; + +function TJSONnull.GetValue: Variant; +begin + Result:=variants.Null; +end; + +procedure TJSONnull.SetValue(const AValue: variant); +begin + ConvertError(False); +end; + +class function TJSONnull.JSONType: TJSONType; +begin + Result:=jtNull; +end; + + + +{ TJSONFloatNumber } + +function TJSONFloatNumber.GetAsBoolean: Boolean; +begin + Result:=(FValue<>0); +end; + +function TJSONFloatNumber.GetAsFloat: TJSONFloat; +begin + Result:=FValue; +end; + +function TJSONFloatNumber.GetAsInteger: Integer; +begin + Result:=Round(FValue); +end; + +procedure TJSONFloatNumber.SetAsBoolean(const AValue: Boolean); +begin + FValue:=Ord(AValue); +end; + +procedure TJSONFloatNumber.SetAsFloat(const AValue: TJSONFloat); +begin + FValue:=AValue; +end; + +procedure TJSONFloatNumber.SetAsInteger(const AValue: Integer); +begin + FValue:=AValue; +end; + +function TJSONFloatNumber.GetAsJSON: TJSONStringType; +begin + Result:=AsString; +end; + +function TJSONFloatNumber.GetAsString: TJSONStringType; +begin + Str(FValue,Result); +end; + +procedure TJSONFloatNumber.SetAsString(const AValue: TJSONStringType); + +Var + C : Integer; + +begin + Val(AValue,FValue,C); + If (C<>0) then + Raise EConvertError.CreateFmt(SErrInvalidFloat,[AValue]); +end; + +function TJSONFloatNumber.GetValue: variant; +begin + Result:=FValue; +end; + +procedure TJSONFloatNumber.SetValue(const AValue: variant); +begin + FValue:=AValue; +end; + +constructor TJSONFloatNumber.Create(AValue: TJSONFloat); +begin + FValue:=AValue; +end; + +class function TJSONFloatNumber.NumberType: TJSONNumberType; +begin + Result:=ntFloat; +end; + +{ TJSONIntegerNumber } + +function TJSONIntegerNumber.GetAsBoolean: Boolean; +begin + Result:=FValue<>0; +end; + +function TJSONIntegerNumber.GetAsFloat: TJSONFloat; +begin + Result:=Ord(FValue); +end; + +function TJSONIntegerNumber.GetAsInteger: Integer; +begin + Result:=FValue; +end; + +procedure TJSONIntegerNumber.SetAsBoolean(const AValue: Boolean); +begin + FValue:=Ord(AValue); +end; + +procedure TJSONIntegerNumber.SetAsFloat(const AValue: TJSONFloat); +begin + FValue:=Round(AValue); +end; + +procedure TJSONIntegerNumber.SetAsInteger(const AValue: Integer); +begin + FValue:=AValue; +end; + +function TJSONIntegerNumber.GetAsJSON: TJSONStringType; +begin + Result:=AsString; +end; + +function TJSONIntegerNumber.GetAsString: TJSONStringType; +begin + Result:=IntToStr(FValue) +end; + +procedure TJSONIntegerNumber.SetAsString(const AValue: TJSONStringType); +begin + FValue:=StrToInt(AValue); +end; + +function TJSONIntegerNumber.GetValue: variant; +begin + Result:=FValue; +end; + +procedure TJSONIntegerNumber.SetValue(const AValue: variant); +begin + FValue:=AValue; +end; + +constructor TJSONIntegerNumber.Create(AValue: Integer); +begin + FValue:=AValue; +end; + +class function TJSONIntegerNumber.NumberType: TJSONNumberType; +begin + Result:=ntInteger; +end; + + +{ TJSONArray } + +function TJSONArray.GetBooleans(Index : Integer): Boolean; +begin + Result:=Items[Index].AsBoolean; +end; + +function TJSONArray.GetArrays(Index : Integer): TJSONArray; +begin + Result:=Items[Index] as TJSONArray; +end; + +function TJSONArray.GetFloats(Index : Integer): TJSONFloat; +begin + Result:=Items[Index].AsFloat; +end; + +function TJSONArray.GetIntegers(Index : Integer): Integer; +begin + Result:=Items[Index].AsInteger; +end; + +function TJSONArray.GetNulls(Index : Integer): Boolean; +begin + Result:=Items[Index].IsNull; +end; + +function TJSONArray.GetObjects(Index : Integer): TJSONObject; +begin + Result:=Items[Index] as TJSONObject; +end; + +function TJSONArray.GetStrings(Index : Integer): TJSONStringType; +begin + Result:=Items[Index].AsString; +end; + +function TJSONArray.GetTypes(Index : Integer): TJSONType; +begin + Result:=Items[Index].JSONType; +end; + +procedure TJSONArray.SetArrays(Index : Integer; const AValue: TJSONArray); +begin + Items[Index]:=AValue; +end; + +procedure TJSONArray.SetBooleans(Index : Integer; const AValue: Boolean); + +begin + Items[Index]:=TJSonBoolean.Create(AValue); +end; + +procedure TJSONArray.SetFloats(Index : Integer; const AValue: TJSONFloat); +begin + Items[Index]:=TJSONFloatNumber.Create(AValue); +end; + +procedure TJSONArray.SetIntegers(Index : Integer; const AValue: Integer); +begin + Items[Index]:=TJSONIntegerNumber.Create(AValue); +end; + +procedure TJSONArray.SetObjects(Index : Integer; const AValue: TJSONObject); +begin + Items[Index]:=AValue; +end; + +procedure TJSONArray.SetStrings(Index : Integer; const AValue: TJSONStringType); +begin + Items[Index]:=TJSONString.Create(AValue); +end; + +procedure TJSONArray.Converterror(From: Boolean); +begin + If From then + Raise EJSON.Create(SErrCannotConvertFromArray) + else + Raise EJSON.Create(SErrCannotConvertToArray); +end; + +function TJSONArray.GetAsBoolean: Boolean; +begin + ConvertError(True); +end; + +function TJSONArray.GetAsFloat: TJSONFloat; +begin + ConvertError(True); +end; + +function TJSONArray.GetAsInteger: Integer; +begin + ConvertError(True); +end; + +procedure TJSONArray.SetAsBoolean(const AValue: Boolean); +begin + ConvertError(False); +end; + +procedure TJSONArray.SetAsFloat(const AValue: TJSONFloat); +begin + ConvertError(False); +end; + +procedure TJSONArray.SetAsInteger(const AValue: Integer); +begin + ConvertError(False); +end; + +function TJSONArray.GetAsJSON: TJSONStringType; + +Var + I : Integer; + +begin + Result:='['; + For I:=0 to Count-1 do + begin + Result:=Result+Items[i].AsJSON; + If (I<Count-1) then + Result:=Result+', ' + end; + Result:=Result+']'; +end; + +function TJSONArray.GetAsString: TJSONStringType; +begin + ConvertError(True); +end; + +procedure TJSONArray.SetAsString(const AValue: TJSONStringType); +begin + ConvertError(False); +end; + +function TJSONArray.GetValue: variant; +begin + ConvertError(True); +end; + +procedure TJSONArray.SetValue(const AValue: variant); +begin + ConvertError(False); +end; + +function TJSONArray.GetCount: Integer; +begin + Result:=Flist.Count; +end; + +function TJSONArray.GetItem(Index: Integer): TJSONData; +begin + Result:=FList[Index] as TJSONData; +end; + +procedure TJSONArray.SetItem(Index: Integer; const AValue: TJSONData); +begin + If (Index=FList.Count) then + FList.Add(AValue) + else + FList[Index]:=AValue; +end; + +constructor TJSONArray.Create; +begin + Flist:=TFPObjectList.Create(True); +end; + +Function VarRecToJSON(Const Element : TVarRec; SourceType : String) : TJSONData; + +begin + Result:=Nil; + With Element do + case VType of + vtInteger : Result:=TJSONIntegerNumber.Create(VInteger); + vtBoolean : Result:=TJSONBoolean.Create(VBoolean); + vtChar : Result:=TJSONString.Create(VChar); + vtExtended : Result:=TJSONFloatNumber.Create(VExtended^); + vtString : Result:=TJSONString.Create(vString^); + vtAnsiString : Result:=TJSONString.Create(AnsiString(vAnsiString)); + vtPChar : Result:=TJSONString.Create(StrPas(VPChar)); + vtPointer : If (VPointer<>Nil) then + Raise EJSON.CreateFmt(SErrPointerNotNil,[SourceType]) + else + Result:=TJSONNull.Create; + vtCurrency : Result:=TJSONFloatNumber.Create(vCurrency^); + vtInt64 : Result:=TJSONFloatNumber.Create(vInt64^); + vtObject : if (VObject is TJSONData) then + Result:=TJSONData(VObject) + else + Raise EJSON.CreateFmt(SErrNotJSONData,[SourceType,VObject.ClassName]); + //vtVariant : + else + Raise EJSON.CreateFmt(SErrUnknownTypeInConstructor,[SourceType,VType]) + end; +end; + +constructor TJSONArray.Create(Const Elements: array of const); + +Var + I : integer; + J : TJSONData; + +begin + Create; + For I:=Low(Elements) to High(Elements) do + begin + J:=VarRecToJSON(Elements[i],'Array'); + Add(J); + end; +end; + +Destructor TJSONArray.Destroy; +begin + FreeAndNil(FList); + inherited Destroy; +end; + +class function TJSONArray.JSONType: TJSONType; +begin + Result:=jtArray; +end; + +procedure TJSONArray.Iterate(Iterator: TJSONArrayIterator; Data: TObject); + +Var + I : Integer; + Cont : Boolean; + +begin + I:=0; + Cont:=True; + While (I<FList.Count) and cont do + begin + Iterator(Items[i],Data,Cont); + Inc(I); + end; +end; + +function TJSONArray.IndexOf(obj: TJSONData): Integer; +begin + Result:=FList.IndexOf(Obj); +end; + +function TJSONArray.Add(Item: TJSONData): Integer; +begin + Result:=FList.Add(Item); +end; + +function TJSONArray.Add(I: Integer): Integer; +begin + Result:=Add(TJSONIntegerNumber.Create(I)); +end; + +function TJSONArray.Add(S: String): Integer; +begin + Result:=Add(TJSONString.Create(S)); +end; + +function TJSONArray.Add: Integer; +begin + Result:=Add(TJSONNull.Create); +end; + +function TJSONArray.Add(F: TJSONFloat): Integer; +begin + Result:=Add(TJSONFloatNumber.Create(F)); +end; + +function TJSONArray.Add(B: Boolean): Integer; +begin + Result:=Add(TJSONBoolean.Create(B)); +end; + +function TJSONArray.Add(AnArray: TJSONArray): Integer; +begin + If (IndexOf(AnArray)<>-1) then + Raise EJSON.Create(SErrCannotAddArrayTwice); + Result:=Add(TJSONData(AnArray)); +end; + +function TJSONArray.Add(AnObject: TJSONObject): Integer; +begin + If (IndexOf(AnObject)<>-1) then + Raise EJSON.Create(SErrCannotAddObjectTwice); + Result:=Add(TJSONData(AnObject)); +end; + +procedure TJSONArray.Delete(Index: Integer); +begin + FList.Delete(Index); +end; + +procedure TJSONArray.Remove(Item: TJSONData); +begin + FList.Remove(Item); +end; + +{ TJSONObject } + +function TJSONObject.GetArrays(AName : String): TJSONArray; +begin + Result:=GetElements(AName) as TJSONArray; +end; + +function TJSONObject.GetBooleans(AName : String): Boolean; +begin + Result:=GetElements(AName).AsBoolean; +end; + +function TJSONObject.GetElements(AName: string): TJSONData; +begin + Result:=TJSONData(FHash.Find(AName)); +end; + +function TJSONObject.GetFloats(AName : String): TJSONFloat; +begin + Result:=GetElements(AName).AsFloat; +end; + +function TJSONObject.GetIntegers(AName : String): Integer; +begin + Result:=GetElements(AName).AsInteger; +end; + +function TJSONObject.GetIsNull(AName : String): Boolean; +begin + Result:=GetElements(AName).IsNull; +end; + +function TJSONObject.GetNameOf(Index: Integer): TJSONStringType; +begin + Result:=FHash.NameOfIndex(Index); +end; + +function TJSONObject.GetObjects(AName : String): TJSONObject; +begin + Result:=GetElements(AName) as TJSONObject; +end; + +function TJSONObject.GetStrings(AName : String): TJSONStringType; +begin + Result:=GetElements(AName).AsString; +end; + +function TJSONObject.GetTypes(AName : String): TJSONType; +begin + Result:=Getelements(Aname).JSONType; +end; + +procedure TJSONObject.SetArrays(AName : String; const AValue: TJSONArray); + +begin + SetElements(AName,AVAlue); +end; + +procedure TJSONObject.SetBooleans(AName : String; const AValue: Boolean); +begin + SetElements(AName,TJSONBoolean.Create(AVAlue)); +end; + +procedure TJSONObject.SetElements(AName: string; const AValue: TJSONData); +Var + Index : Integer; + +begin + Index:=FHash.FindIndexOf(AName); + If (Index=-1) then + FHash.Add(AName,AValue) + else + FHash.Items[Index]:=AValue; // Will free the previous value. +end; + +procedure TJSONObject.SetFloats(AName : String; const AValue: TJSONFloat); +begin + SetElements(AName,TJSONFloatNumber.Create(AVAlue)); +end; + +procedure TJSONObject.SetIntegers(AName : String; const AValue: Integer); +begin + SetElements(AName,TJSONIntegerNumber.Create(AVAlue)); +end; + +procedure TJSONObject.SetIsNull(AName : String; const AValue: Boolean); +begin + If Not AValue then + Raise EJSON.Create(SErrCannotSetNotIsNull); + SetElements(AName,TJSONNull.Create); +end; + +procedure TJSONObject.SetObjects(AName : String; const AValue: TJSONObject); +begin + SetElements(AName,AValue); +end; + +procedure TJSONObject.SetStrings(AName : String; const AValue: TJSONStringType); +begin + SetElements(AName,TJSONString.Create(AVAlue)); +end; + +procedure TJSONObject.Converterror(From: Boolean); +begin + If From then + Raise EJSON.Create(SErrCannotConvertFromObject) + else + Raise EJSON.Create(SErrCannotConvertToObject); +end; + +function TJSONObject.GetAsBoolean: Boolean; +begin + ConvertError(True); +end; + +function TJSONObject.GetAsFloat: TJSONFloat; +begin + ConvertError(True); +end; + +function TJSONObject.GetAsInteger: Integer; +begin + ConvertError(True); +end; + +procedure TJSONObject.SetAsBoolean(const AValue: Boolean); +begin + ConvertError(False); +end; + +procedure TJSONObject.SetAsFloat(const AValue: TJSONFloat); +begin + ConvertError(False); +end; + +procedure TJSONObject.SetAsInteger(const AValue: Integer); +begin + ConvertError(False); +end; + +function TJSONObject.GetAsJSON: TJSONStringType; + +Var + I : Integer; + +begin + Result:=''; + For I:=0 to Count-1 do + begin + If (Result<>'') then + Result:=Result+', '; + Result:=Result+'"'+StringToJSONString(Names[i])+'" : '+Items[I].AsJSON; + end; + If (Result<>'') then + Result:='{ '+Result+' }' + else + Result:='{}'; +end; + +function TJSONObject.GetAsString: TJSONStringType; +begin + ConvertError(True); +end; + +procedure TJSONObject.SetAsString(const AValue: TJSONStringType); +begin + ConvertError(False); +end; + +function TJSONObject.GetValue: variant; +begin + ConvertError(True); +end; + +procedure TJSONObject.SetValue(const AValue: variant); +begin + ConvertError(False); +end; + +function TJSONObject.GetCount: Integer; +begin + Result:=FHash.Count; +end; + +function TJSONObject.GetItem(Index: Integer): TJSONData; +begin + Result:=TJSONData(FHash.Items[Index]); +end; + +procedure TJSONObject.SetItem(Index: Integer; const AValue: TJSONData); +begin + FHash.Items[Index]:=AValue; +end; + +constructor TJSONObject.Create; +begin + FHash:=TFPHashObjectList.Create(True); +end; + + + +constructor TJSONObject.Create(const Elements: array of const); + +Var + I : integer; + F : TJSONFloat; + AName : String; + J : TJSONData; + +begin + Create; + If ((High(Elements)-Low(Elements)) mod 2)=0 then + Raise EJSON.Create(SErrOddNumber); + I:=Low(Elements); + While I<=High(Elements) do + begin + With Elements[i] do + Case VType of + vtChar : AName:=VChar; + vtString : AName:=vString^; + vtAnsiString : AName:=(AnsiString(vAnsiString)); + vtPChar : AName:=StrPas(VPChar); + else + Raise EJSON.CreateFmt(SErrNameMustBeString,[I+1]); + end; + If (ANAme='') then + Raise EJSON.CreateFmt(SErrNameMustBeString,[I+1]); + Inc(I); + J:=VarRecToJSON(Elements[i],'Object'); + Add(AName,J); + Inc(I); + end; +end; + + +destructor TJSONObject.Destroy; +begin + FreeAndNil(FHash); + inherited Destroy; +end; + +class function TJSONObject.JSONType: TJSONType; +begin + Result:=jtObject; +end; + +procedure TJSONObject.Iterate(Iterator: TJSONObjectIterator; Data: TObject); + +Var + I : Integer; + Cont : Boolean; + +begin + I:=0; + Cont:=True; + While (I<FHash.Count) and cont do + begin + Iterator(Names[I],Items[i],Data,Cont); + Inc(I); + end; +end; + +function TJSONObject.IndexOf(Item: TJSONData): Integer; +begin + +end; + +function TJSONObject.IndexOfName(const AName: TJSONStringType): Integer; +begin + +end; + +function TJSONObject.Add(const AName: TJSONStringType; AValue: TJSONData + ): Integer; +begin + Result:=FHash.Add(AName,AValue); +end; + +function TJSONObject.Add(const AName: TJSONStringType; AValue: Boolean + ): Integer; +begin + Result:=Add(AName,TJSONBoolean.Create(AValue)); +end; + +function TJSONObject.Add(const AName: TJSONStringType; AValue: TJSONFloat): Integer; +begin + Result:=Add(AName,TJSONFloatNumber.Create(AValue)); +end; + +function TJSONObject.Add(const AName: TJSONStringType; AValue: TJSONStringType): Integer; +begin + Result:=Add(AName,TJSONString.Create(AValue)); +end; + +function TJSONObject.Add(const AName: TJSONStringType; Avalue: Integer): Integer; +begin + Result:=Add(AName,TJSONIntegerNumber.Create(AValue)); +end; + +function TJSONObject.Add(const AName: TJSONStringType): Integer; +begin + Result:=Add(AName,TJSONNull.Create); +end; + +function TJSONObject.Add(const AName: TJSONStringType; AValue: TJSONArray + ): Integer; +begin + Result:=Add(AName,TJSONData(AValue)); +end; + +procedure TJSONObject.Delete(Index: Integer); +begin + FHash.Delete(Index); +end; + +procedure TJSONObject.Remove(Item: TJSONData); +begin + FHash.Remove(Item); +end; + +end. + diff --git a/packages/fcl-json/src/jsonparser.pp b/packages/fcl-json/src/jsonparser.pp new file mode 100644 index 0000000000..33bdac5dc1 --- /dev/null +++ b/packages/fcl-json/src/jsonparser.pp @@ -0,0 +1,237 @@ +unit jsonparser; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, fpJSON, jsonscanner; + +Type + + { TJSONParser } + + TJSONParser = Class(TObject) + Private + FScanner : TJSONScanner; + function ParseNumber: TJSONNumber; + Protected + procedure DoError(Msg: String); + function DoParse(AtCurrent,AllowEOF: Boolean): TJSONData; + function GetNextToken: TJSONToken; + function CurrentTokenString: String; + function CurrentToken: TJSONToken; + function ParseArray: TJSONArray; + function ParseObject: TJSONObject; + Public + function Parse: TJSONData; + Constructor Create(Source : TStream); overload; + Constructor Create(Source : TJSONStringType); overload; + end; + + EJSONScanner = Class(Exception); + +implementation + +Resourcestring + SErrUnexpectedEOF = 'Unexpected EOF encountered.'; + SErrUnexpectedToken = 'Unexpected token (%s) encountered.'; + SErrExpectedColon = 'Expected colon (:), got token "%s".'; + SErrUnexpectedComma = 'Invalid comma encountered.'; + SErrEmptyElement = 'Empty element encountered.'; + SErrExpectedElementName = 'Expected element name, got token "%s"'; + SExpectedCommaorBraceClose = 'Expected , or ], got token "%s".'; + SErrInvalidNumber = 'Number is not an integer or real number: %s'; + +{ TJSONParser } + +Function TJSONParser.Parse : TJSONData; + +begin + Result:=DoParse(False,True); +end; + +{ + Consume next token and convert to JSON data structure. + If AtCurrent is true, the current token is used. If false, + a token is gotten from the scanner. + If AllowEOF is false, encountering a tkEOF will result in an exception. +} + +Function TJSONParser.CurrentToken : TJSONToken; + +begin + Result:=FScanner.CurToken; +end; + +Function TJSONParser.CurrentTokenString : String; + +begin + If CurrentToken in [tkString,tkNumber] then + Result:=FScanner.CurTokenString + else + Result:=TokenInfos[CurrentToken]; +end; + +Function TJSONParser.DoParse(AtCurrent,AllowEOF : Boolean) : TJSONData; + +var + T : TJSONToken; + +begin + Result:=nil; + try + If not AtCurrent then + T:=GetNextToken + else + T:=FScanner.CurToken; + Case T of + tkEof : If Not AllowEof then + DoError(SErrUnexpectedEOF); + tkNull : Result:=TJSONNull.Create; + tkTrue, + tkFalse : Result:=TJSONBoolean.Create(t=tkTrue); + tkString : Result:=TJSONString.Create(CurrentTokenString); + tkCurlyBraceOpen : Result:=ParseObject; + tkCurlyBraceClose : DoError(SErrUnexpectedToken); + tkSQuaredBraceOpen : Result:=ParseArray; + tkSQuaredBraceClose : DoError(SErrUnexpectedToken); + tkNumber : Result:=ParseNumber; + tkComma : DoError(SErrUnexpectedToken); + end; + except + if assigned(Result) then + FreeAndNil(Result); + Raise; + end; +end; + + +// Creates the correct JSON number type, based on the current token. +Function TJSONParser.ParseNumber : TJSONNumber; + +Var + I : Integer; + F : TJSONFloat; + S : String; + +begin + S:=CurrentTokenString; + I:=0; + If TryStrToInt(S,I) then + Result:=TJSONIntegerNumber.Create(I) + else + begin + I:=0; + Val(S,F,I); + If (I<>0) then + DoError(SErrInvalidNumber); + Result:=TJSONFloatNumber.Create(F); + end; +end; + +// Current token is {, on exit current token is } +Function TJSONParser.ParseObject : TJSONObject; + +Var + T : TJSONtoken; + E : TJSONData; + N : String; + +begin + Result:=TJSONObject.Create; + Try + T:=GetNextToken; + While T<>tkCurlyBraceClose do + begin + If T<>tkString then + DoError(SErrExpectedElementName); + N:=CurrentTokenString; + T:=GetNextToken; + If (T<>tkColon) then + DoError(SErrExpectedColon); + Writeln('Getting element'); + E:=DoParse(False,False); + Result.Add(N,E); + T:=GetNextToken; + If Not (T in [tkComma,tkCurlyBraceClose]) then + DoError(SExpectedCommaorBraceClose); + If T=tkComma then + T:=GetNextToken; + end; + Except + FreeAndNil(Result); + Raise; + end; +end; + +// Current token is [, on exit current token is ] +Function TJSONParser.ParseArray : TJSONArray; + +Var + T : TJSONtoken; + E : TJSONData; + LastComma : Boolean; + +begin + Result:=TJSONArray.Create; + LastComma:=False; + Try + Repeat + T:=GetNextToken; + If (T<>tkSquaredBraceClose) then + begin + E:=DoParse(True,False); + If (E<>Nil) then + Result.Add(E) + else if (Result.Count>0) then + DoError(SErrEmptyElement); + T:=GetNextToken; + If Not (T in [tkComma,tkSquaredBraceClose]) then + DoError(SExpectedCommaorBraceClose); + LastComma:=(t=TkComma); + end; + Until (T=tkSquaredBraceClose); + If LastComma then // Test for ,] case + DoError(SErrUnExpectedToken); + Except + FreeAndNil(Result); + Raise; + end; +end; + +// Get next token, discarding whitespace +Function TJSONParser.GetNextToken : TJSONToken ; + +begin + Repeat + Result:=FScanner.FetchToken; + Until (Result<>tkWhiteSpace); + Writeln('GetNextToken : ',CurrentTokenString); +end; + +Procedure TJSONParser.DoError(Msg : String); + +Var + S : String; + +begin + S:=Format(Msg,[CurrentTokenString]); + S:=Format('Error at line %d, Pos %d:',[FScanner.CurRow,FSCanner.CurColumn])+S; + Raise EJSONScanner.Create(S); +end; + +constructor TJSONParser.Create(Source: TStream); +begin + Inherited Create; + FScanner:=TJSONScanner.Create(Source); +end; + +constructor TJSONParser.Create(Source: TJSONStringType); +begin + Inherited Create; + FScanner:=TJSONScanner.Create(Source); +end; + +end. + diff --git a/packages/fcl-json/src/jsonscanner.pp b/packages/fcl-json/src/jsonscanner.pp new file mode 100644 index 0000000000..52686fb7a6 --- /dev/null +++ b/packages/fcl-json/src/jsonscanner.pp @@ -0,0 +1,355 @@ +{ + This file is part of the Free Component Library + + JSON source lexical scanner + Copyright (c) 2007 by Michael Van Canneyt michael@freepascal.org + + 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} +{$h+} + +unit jsonscanner; + +interface + +uses SysUtils, Classes; + +resourcestring + SErrInvalidCharacter = 'Invalid character ''%s'''; + SErrOpenString = 'string exceeds end of line'; + +type + + TJSONToken = ( + tkEOF, + tkWhitespace, + tkString, + tkNumber, + tkTrue, + tkFalse, + tkNull, + // Simple (one-character) tokens + tkComma, // ',' + tkColon, // ':' + tkCurlyBraceOpen, // '{' + tkCurlyBraceClose, // '}' + tkSquaredBraceOpen, // '[' + tkSquaredBraceClose, // ']' + tkUnknown + ); + + EScannerError = class(Exception); + + + TJSONScanner = class + private + FSource : TStringList; + FCurRow: Integer; + FCurToken: TJSONToken; + FCurTokenString: string; + FCurLine: string; + TokenStr: PChar; + function GetCurColumn: Integer; + protected + procedure Error(const Msg: string);overload; + procedure Error(const Msg: string; Args: array of Const);overload; + function DoFetchToken: TJSONToken; + public + constructor Create(Source : TStream); overload; + constructor Create(Source : String); overload; + destructor Destroy; override; + function FetchToken: TJSONToken; + + + property CurLine: string read FCurLine; + property CurRow: Integer read FCurRow; + property CurColumn: Integer read GetCurColumn; + + property CurToken: TJSONToken read FCurToken; + property CurTokenString: string read FCurTokenString; + end; + +const + TokenInfos: array[TJSONToken] of string = ( + 'EOF', + 'Whitespace', + 'String', + 'Number', + 'True', + 'False', + 'Null', + ',', + ':', + '{', + '}', + '[', + ']', + '' + ); + + +implementation + +constructor TJSONScanner.Create(Source : TStream); + +begin + FSource:=TStringList.Create; + FSource.LoadFromStream(Source); +end; + +constructor TJSONScanner.Create(Source : String); +begin + FSource:=TStringList.Create; + FSource.Text:=Source; +end; + +destructor TJSONScanner.Destroy; +begin + FreeAndNil(FSource); + Inherited; +end; + + +function TJSONScanner.FetchToken: TJSONToken; + +begin + Result:=DoFetchToken; +end; + +procedure TJSONScanner.Error(const Msg: string); +begin + raise EScannerError.Create(Msg); +end; + +procedure TJSONScanner.Error(const Msg: string; Args: array of Const); +begin + raise EScannerError.CreateFmt(Msg, Args); +end; + +function TJSONScanner.DoFetchToken: TJSONToken; + + function FetchLine: Boolean; + begin + Result:=FCurRow<FSource.Count; + if Result then + begin + FCurLine:=FSource[FCurRow]; + TokenStr:=PChar(FCurLine); + Inc(FCurRow); + end + else + begin + FCurLine:=''; + TokenStr:=nil; + end; + end; + +var + TokenStart, CurPos: PChar; + it : TJSONToken; + I : Integer; + OldLength, SectionLength, Index: Integer; + S : String; + +begin + if TokenStr = nil then + if not FetchLine then + begin + Result := tkEOF; + FCurToken := Result; + exit; + end; + + FCurTokenString := ''; + + case TokenStr[0] of + #0: // Empty line + begin + FetchLine; + Result := tkWhitespace; + end; + #9, ' ': + begin + Result := tkWhitespace; + repeat + Inc(TokenStr); + if TokenStr[0] = #0 then + if not FetchLine then + begin + FCurToken := Result; + exit; + end; + until not (TokenStr[0] in [#9, ' ']); + end; + '"': + begin + Inc(TokenStr); + TokenStart := TokenStr; + OldLength := 0; + FCurTokenString := ''; + + while not (TokenStr[0] in [#0,'"']) do + begin + if (TokenStr[0]='\') then + begin + // Save length + SectionLength := TokenStr - TokenStart; + Inc(TokenStr); + // Read escaped token + Case TokenStr[0] of + '"' : S:='"'; + 't' : S:=#9; + 'b' : S:=#8; + 'n' : S:=#10; + 'r' : S:=#13; + 'f' : S:=#12; + '\' : S:='\'; + '/' : S:='/'; + 'u' : begin + S:='0000'; + For I:=1 to 4 do + begin + Inc(TokenStr); + Case TokenStr[0] of + '0'..'9','A'..'F','a'..'f' : + S[i]:=Upcase(TokenStr[0]); + else + Error(SErrInvalidCharacter, [TokenStr[0]]); + end; + end; + // Takes care of conversion... + S:=WideChar(StrToInt('$'+S)); + end; + #0 : Error(SErrOpenString); + else + Error(SErrInvalidCharacter, [TokenStr[0]]); + end; + SetLength(FCurTokenString, OldLength + SectionLength+1+Length(S)); + if SectionLength > 0 then + Move(TokenStart^, FCurTokenString[OldLength + 1], SectionLength); + Move(S[1],FCurTokenString[OldLength + SectionLength+1],Length(S)); + Inc(OldLength, SectionLength+Length(S)); + // Next char + // Inc(TokenStr); + TokenStart := TokenStr+1; + end; + if TokenStr[0] = #0 then + Error(SErrOpenString); + Inc(TokenStr); + end; + if TokenStr[0] = #0 then + Error(SErrOpenString); + SectionLength := TokenStr - TokenStart; + SetLength(FCurTokenString, OldLength + SectionLength); + if SectionLength > 0 then + Move(TokenStart^, FCurTokenString[OldLength + 1], SectionLength); + Inc(TokenStr); + Result := tkString; + end; + ',': + begin + Inc(TokenStr); + Result := tkComma; + end; + '0'..'9','-': + begin + TokenStart := TokenStr; + while true do + begin + Inc(TokenStr); + case TokenStr[0] of + '.': + begin + if TokenStr[1] in ['0'..'9', 'e', 'E'] then + begin + Inc(TokenStr); + repeat + Inc(TokenStr); + until not (TokenStr[0] in ['0'..'9', 'e', 'E','-','+']); + end; + break; + end; + '0'..'9': ; + 'e', 'E': + begin + Inc(TokenStr); + if TokenStr[0] in ['-','+'] then + Inc(TokenStr); + while TokenStr[0] in ['0'..'9'] do + Inc(TokenStr); + break; + end; + else + break; + end; + end; + SectionLength := TokenStr - TokenStart; + SetLength(FCurTokenString, SectionLength); + if SectionLength > 0 then + Move(TokenStart^, FCurTokenString[1], SectionLength); + Result := tkNumber; + end; + ':': + begin + Inc(TokenStr); + Result := tkColon; + end; + '{': + begin + Inc(TokenStr); + Result := tkCurlyBraceOpen; + end; + '}': + begin + Inc(TokenStr); + Result := tkCurlyBraceClose; + end; + '[': + begin + Inc(TokenStr); + Result := tkSquaredBraceOpen; + end; + ']': + begin + Inc(TokenStr); + Result := tkSquaredBraceClose; + end; + 'T','t','F','f','N','n' : + begin + TokenStart := TokenStr; + repeat + Inc(TokenStr); + until not (TokenStr[0] in ['A'..'Z', 'a'..'z', '0'..'9', '_']); + SectionLength := TokenStr - TokenStart; + SetLength(FCurTokenString, SectionLength); + if SectionLength > 0 then + Move(TokenStart^, FCurTokenString[1], SectionLength); + for it := tkTrue to tkNull do + if CompareText(CurTokenString, TokenInfos[it]) = 0 then + begin + Result := it; + FCurToken := Result; + exit; + end; + Error(SErrInvalidCharacter, [TokenStart[0]]); + end; + else + Error(SErrInvalidCharacter, [TokenStr[0]]); + end; + + FCurToken := Result; +end; + +function TJSONScanner.GetCurColumn: Integer; +begin + Result := TokenStr - PChar(CurLine); +end; + +end. diff --git a/packages/fcl-json/tests/testjson.lpi b/packages/fcl-json/tests/testjson.lpi new file mode 100644 index 0000000000..38247f31d1 --- /dev/null +++ b/packages/fcl-json/tests/testjson.lpi @@ -0,0 +1,65 @@ +<?xml version="1.0"?> +<CONFIG> + <ProjectOptions> + <PathDelim Value="/"/> + <Version Value="5"/> + <General> + <SessionStorage Value="InProjectDir"/> + <MainUnit Value="0"/> + <IconPath Value="./"/> + <TargetFileExt Value=""/> + </General> + <VersionInfo> + <ProjectVersion Value=""/> + </VersionInfo> + <PublishOptions> + <Version Value="2"/> + <IgnoreBinaries Value="False"/> + <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> + <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> + </local> + </RunParams> + <RequiredPackages Count="3"> + <Item1> + <PackageName Value="LCL"/> + </Item1> + <Item2> + <PackageName Value="FPCUnitTestRunner"/> + </Item2> + <Item3> + <PackageName Value="FCL"/> + </Item3> + </RequiredPackages> + <Units Count="3"> + <Unit0> + <Filename Value="testjson.pp"/> + <IsPartOfProject Value="True"/> + <UnitName Value="testjson"/> + </Unit0> + <Unit1> + <Filename Value="testjsonparser.pp"/> + <IsPartOfProject Value="True"/> + <UnitName Value="testjsonparser"/> + </Unit1> + <Unit2> + <Filename Value="testjsondata.pp"/> + <IsPartOfProject Value="True"/> + <UnitName Value="testjsondata"/> + </Unit2> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="5"/> + <CodeGeneration> + <Generate Value="Faster"/> + </CodeGeneration> + <Other> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> +</CONFIG> diff --git a/packages/fcl-json/tests/testjson.pp b/packages/fcl-json/tests/testjson.pp new file mode 100644 index 0000000000..aa49a5c770 --- /dev/null +++ b/packages/fcl-json/tests/testjson.pp @@ -0,0 +1,21 @@ +program testjson; + +{$mode objfpc}{$H+} + +uses + Classes, consoletestrunner, testjsondata, testjsonparser; +type + { TLazTestRunner } + TMyTestRunner = class(TTestRunner) + protected + // override the protected methods of TTestRunner to customize its behavior + end; + +var + Application: TMyTestRunner; +begin + Application := TMyTestRunner.Create(nil); + Application.Initialize; + Application.Run; + Application.Free; +end. diff --git a/packages/fcl-json/tests/testjsondata.pp b/packages/fcl-json/tests/testjsondata.pp new file mode 100644 index 0000000000..be87d1cdef --- /dev/null +++ b/packages/fcl-json/tests/testjsondata.pp @@ -0,0 +1,1786 @@ +unit testjsondata; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, fpcunit, testutils, testregistry, fpjson; + +type + + + { TTestJSONString } + + TTestJSONString = Class(TTestCase) + Private + Procedure TestTo(Const Src,Dest : String); + Procedure TestFrom(Const Src,Dest : String); + Published + Procedure TestJSONStringToString; + Procedure TestStringToJSONString; + end; + + { TTestJSON } + + TTestJSON = Class(TTestCase) + Protected + Procedure TestItemCount(J : TJSONData;Expected : Integer); + Procedure TestJSONType(J : TJSONData;Expected : TJSONType); + Procedure TestJSON(J : TJSONData;Expected : String); + Procedure TestIsNull(J : TJSONData;Expected : Boolean); + Procedure TestAsBoolean(J : TJSONData;Expected : Boolean; ExpectError : boolean = False); + Procedure TestAsInteger(J : TJSONData; Expected : Integer; ExpectError : boolean = False); + Procedure TestAsString(J : TJSONData; Expected : String; ExpectError : boolean = False); + Procedure TestAsFloat(J : TJSONData; Expected : TJSONFloat; ExpectError : boolean = False); + end; + + { TTestNull } + + TTestNull = class(TTestJSON) + published + procedure TestNull; + end; + + { TTestBoolean } + + TTestBoolean = class(TTestJSON) + published + procedure TestTrue; + procedure TestFalse; + end; + + { TTestInteger } + + TTestInteger = class(TTestJSON) + Private + Procedure DoTest(I : Integer); + published + procedure TestPositive; + procedure TestNegative; + procedure TestZero; + end; + + { TTestFloat } + + TTestFloat = class(TTestJSON) + Private + Procedure DoTest(F : TJSONFloat); + published + procedure TestPositive; + procedure TestNegative; + procedure TestZero; + end; + + { TTestString } + + TTestString = class(TTestJSON) + private + procedure DoTestFloat(F: TJSOnFloat; S: String; OK: Boolean); + published + procedure TestString; + procedure TestInteger; + procedure TestNegativeInteger; + procedure TestFloat; + procedure TestNegativeFloat; + Procedure TestBooleanTrue; + Procedure TestBooleanFalse; + end; + + { TTestArray } + + TTestArray = class(TTestJSON) + private + procedure TestAddBoolean(B : Boolean); + published + Procedure TestCreate; + Procedure TestCreateString; + Procedure TestCreatePchar; + procedure TestCreateStrings; + procedure TestCreateInteger; + procedure TestCreateInt64; + procedure TestCreateFloat; + procedure TestCreateBoolean; + procedure TestCreateObject; + procedure TestCreateJSONString; + procedure TestCreateJSONObject; + procedure TestCreateNilPointer; + procedure TestCreatePointer; + procedure TestAddInteger; + procedure TestAddFloat; + procedure TestAddBooleanTrue; + procedure TestAddBooleanFalse; + procedure TestAddString; + procedure TestAddNull; + procedure TestAddObject; + procedure TestAddArray; + procedure TestDelete; + procedure TestRemove; + end; + + { TTestObject } + + TTestObject = class(TTestJSON) + private + procedure TestAddBoolean(B : Boolean); + published + Procedure TestCreate; + Procedure TestCreateString; + Procedure TestCreatePchar; + procedure TestCreateStrings; + procedure TestCreateInteger; + procedure TestCreateInt64; + procedure TestCreateFloat; + procedure TestCreateBoolean; + procedure TestCreateObject; + procedure TestCreateJSONString; + procedure TestCreateJSONObject; + procedure TestCreateNilPointer; + procedure TestCreatePointer; + procedure TestAddInteger; + procedure TestAddFloat; + procedure TestAddBooleanTrue; + procedure TestAddBooleanFalse; + procedure TestAddString; + procedure TestAddNull; + procedure TestAddObject; + procedure TestAddArray; + procedure TestDelete; + procedure TestRemove; + end; + + +implementation + +{ TTestJSON } + +procedure TTestJSON.TestItemCount(J: TJSONData; Expected: Integer); +begin + AssertEquals(J.ClassName+'.ItemCount',Expected,J.Count); +end; + +procedure TTestJSON.TestJSONType(J: TJSONData; Expected: TJSONType); +begin + AssertEquals(J.ClassName+'.JSONType',Ord(Expected),Ord(J.JSONType)); +end; + +procedure TTestJSON.TestJSON(J: TJSONData; Expected: String); +begin + AssertEquals(J.ClassName+'.AsJSON',Expected,J.AsJSON); +end; + +procedure TTestJSON.TestIsNull(J: TJSONData; Expected: Boolean); +begin + AssertEquals(J.ClassName+'.IsNull',Expected,J.IsNull); +end; + +procedure TTestJSON.TestAsBoolean(J: TJSONData; Expected: Boolean; ExpectError: boolean = False); + +Var + B : Boolean; + AssignOK : Boolean; + Msg : String; + +begin + AssignOK:=False; + Try + B:=J.AsBoolean; + AssignOK:=True; + If Not ExpectError then + AssertEquals(J.Classname+'.AsBoolean',Expected,B); + except + On E : Exception do + begin + AssignOK:=False; + Msg:=E.Message; + end; + end; + If ExpectError then + begin + If AssignOK then + Fail(J.ClassName+'.AsBoolean must raise error'); + end + else + begin + If not AssignOK then + Fail(J.ClassName+'.AsBoolean raised unexpected exception: '+Msg) + end; +end; + +procedure TTestJSON.TestAsInteger(J: TJSONData; Expected: Integer; + ExpectError: boolean); + +Var + I : Integer; + AssignOK : Boolean; + Msg : String; + +begin + AssignOK:=False; + Try + I:=J.AsInteger; + AssignOK:=True; + If Not ExpectError then + AssertEquals(J.Classname+'.AsInteger',Expected,I); + except + On E : Exception do + begin + AssignOK:=False; + Msg:=E.Message; + end; + end; + If ExpectError then + begin + If AssignOK then + Fail(J.ClassName+'.AsInteger must raise error'); + end + else + begin + If not AssignOK then + Fail(J.ClassName+'.AsInteger raised unexpected exception: '+Msg) + end; +end; + +procedure TTestJSON.TestAsString(J: TJSONData; Expected: String; + ExpectError: boolean); + +Var + S : String; + AssignOK : Boolean; + Msg : String; + +begin + AssignOK:=False; + Try + S:=J.AsString; + AssignOK:=True; + If Not ExpectError then + AssertEquals(J.Classname+'.AsString',Expected,S); + except + On E : Exception do + begin + AssignOK:=False; + Msg:=E.Message; + end; + end; + If ExpectError then + begin + If AssignOK then + Fail(J.ClassName+'.AsString must raise error'); + end + else + begin + If not AssignOK then + Fail(J.ClassName+'.AsString raised unexpected exception: '+Msg) + end; +end; + +procedure TTestJSON.TestAsFloat(J: TJSONData; Expected: TJSONFloat; + ExpectError: boolean); + +Var + F : TJSONFloat; + AssignOK : Boolean; + Msg : String; + +begin + AssignOK:=False; + Try + F:=J.AsFloat; + AssignOK:=True; + If Not ExpectError then + AssertEquals(J.Classname+'.AsFloat',Expected,F); + except + On E : Exception do + begin + AssignOK:=False; + Msg:=E.Message; + end; + end; + If ExpectError then + begin + If AssignOK then + Fail(J.ClassName+'.AsFloat must raise error'); + end + else + begin + If not AssignOK then + Fail(J.ClassName+'.AsFloat raised unexpected exception: '+Msg) + end; +end; + +{ TTestBoolean } + +procedure TTestBoolean.TestTrue; + +Var + J : TJSONBoolean; + +begin + J:=TJSONBoolean.Create(True); + try + TestJSONType(J,jtBoolean); + TestItemCount(J,0); + TestJSON(J,'True'); + TestIsNull(J,False); + TestAsBoolean(J,True); + TestAsInteger(J,1); + TestAsString(J,BoolToStr(True)); + TestAsFloat(J,1.0); + finally + FreeAndNil(J); + end; +end; + +procedure TTestBoolean.TestFalse; + +Var + J : TJSONBoolean; + +begin + J:=TJSONBoolean.Create(False); + try + TestJSONType(J,jtBoolean); + TestItemCount(J,0); + TestJSON(J,'False'); + TestIsNull(J,False); + TestAsBoolean(J,False); + TestAsInteger(J,0); + TestAsString(J,BoolToStr(False)); + TestAsFloat(J,0.0); + finally + FreeAndNil(J); + end; +end; + + + +{ TTestNull } + +procedure TTestNull.TestNull; + +Var + J : TJSONNull; + +begin + J:=TJSONNull.Create; + try + TestJSONType(J,jtNull); + TestItemCount(J,0); + TestJSON(J,'Null'); + TestIsNull(J,True); + TestAsBoolean(J,False,True); + TestAsInteger(J,0,true); + TestAsString(J,BoolToStr(False),true); + TestAsFloat(J,0.0,true); + finally + FreeAndNil(J); + end; +end; + + +{ TTestString } + +procedure TTestString.TestString; + +Const + S = 'A string'; + +Var + J : TJSONString; + +begin + J:=TJSONString.Create(S); + try + TestJSONType(J,jtString); + TestItemCount(J,0); + TestJSON(J,'"'+S+'"'); + TestIsNull(J,False); + TestAsBoolean(J,False,True); + TestAsInteger(J,0,true); + TestAsString(J,S); + TestAsFloat(J,0.0,true); + finally + FreeAndNil(J); + end; +end; + +procedure TTestString.TestInteger; + +Const + S = '1'; + +Var + J : TJSONString; + +begin + J:=TJSONString.Create(S); + try + TestJSONType(J,jtString); + TestItemCount(J,0); + TestJSON(J,'"'+S+'"'); + TestIsNull(J,False); + TestAsBoolean(J,True,False); + TestAsInteger(J,1,False); + TestAsString(J,S); + TestAsFloat(J,1.0,False); + finally + FreeAndNil(J); + end; +end; + +procedure TTestString.TestNegativeInteger; + +Const + S = '-1'; + +Var + J : TJSONString; + +begin + J:=TJSONString.Create(S); + try + TestJSONType(J,jtString); + TestItemCount(J,0); + TestJSON(J,'"'+S+'"'); + TestIsNull(J,False); + TestAsBoolean(J,True,False); + TestAsInteger(J,-1,False); + TestAsString(J,S); + TestAsFloat(J,-1.0,False); + finally + FreeAndNil(J); + end; +end; + +procedure TTestString.TestFloat; + +begin + DoTestFloat(1.0,'1.0',True); + DoTestFloat(1.0,'1',True); + DoTestFloat(1.0,'1e0',True); + DoTestFloat(1.2,'1.2',True); + DoTestFloat(12.0,'1.2e1',True); +end; + +procedure TTestString.TestNegativeFloat; +begin + DoTestFloat(-1.0,'-1.0',True); + DoTestFloat(-1.0,'-1',True); + DoTestFloat(-1.0,'-1e0',True); + DoTestFloat(-1.2,'-1.2',True); + DoTestFloat(-12.0,'-1.2e1',True); +end; + +procedure TTestString.TestBooleanTrue; + +Const + S = 'True'; + +Var + J : TJSONString; + +begin + J:=TJSONString.Create(S); + try + TestJSONType(J,jtString); + TestItemCount(J,0); + TestJSON(J,'"'+S+'"'); + TestIsNull(J,False); + TestAsBoolean(J,True,False); + TestAsInteger(J,-1,True); + TestAsString(J,S); + TestAsFloat(J,-1.0,True); + finally + FreeAndNil(J); + end; +end; + +procedure TTestString.TestBooleanFalse; + +Const + S = 'False'; + +Var + J : TJSONString; + +begin + J:=TJSONString.Create(S); + try + TestJSONType(J,jtString); + TestItemCount(J,0); + TestJSON(J,'"'+S+'"'); + TestIsNull(J,False); + TestAsBoolean(J,False,False); + TestAsInteger(J,0,True); + TestAsString(J,S); + TestAsFloat(J,0,True); + finally + FreeAndNil(J); + end; +end; + +procedure TTestString.DoTestFloat(F : TJSOnFloat;S : String; OK : Boolean); + +Var + J : TJSONString; + +begin + J:=TJSONString.Create(S); + try + TestJSONType(J,jtString); + TestItemCount(J,0); + TestJSON(J,'"'+S+'"'); + TestIsNull(J,False); + TestAsBoolean(J,(F<>0),Not OK); + TestAsInteger(J,Round(F),(Pos('.',S)<>0) or (Pos('E',UpperCase(S))<>0)); + TestAsString(J,S); + TestAsFloat(J,F,Not OK); + finally + FreeAndNil(J); + end; +end; + + +{ TTestInteger } + +procedure TTestInteger.DoTest(I: Integer); + +Var + J : TJSONIntegerNumber; + +begin + J:=TJSONIntegerNumber.Create(I); + try + TestJSONType(J,jtNumber); + TestItemCount(J,0); + AssertEquals('Numbertype is ntInteger',ord(ntInteger),Ord(J.NumberType)); + TestJSON(J,IntToStr(i)); + TestIsNull(J,False); + TestAsBoolean(J,(I<>0)); + TestAsInteger(J,I); + TestAsString(J,IntToStr(I)); + TestAsFloat(J,I); + finally + FreeAndNil(J); + end; +end; + +procedure TTestInteger.TestPositive; + +begin + DoTest(1); +end; + +procedure TTestInteger.TestNegative; +begin + DoTest(-1); +end; + +procedure TTestInteger.TestZero; +begin + DoTest(0); +end; + +{ TTestFloat } + +procedure TTestFloat.DoTest(F: TJSONFloat); + +Var + J : TJSONFloatNumber; + S : String; + +begin + Str(F,S); + J:=TJSONFloatNumber.Create(F); + try + TestJSONType(J,jtNumber); + TestItemCount(J,0); + AssertEquals('Numbertype is ntFloat',ord(ntFloat),Ord(J.NumberType)); + TestJSON(J,S); + TestIsNull(J,False); + TestAsBoolean(J,(F<>0)); + TestAsInteger(J,Round(F)); + TestAsString(J,S); + TestAsFloat(J,F); + finally + FreeAndNil(J); + end; +end; + +procedure TTestFloat.TestPositive; +begin + DoTest(1.0); + DoTest(1.2); + DoTest(1.2e1); + DoTest(1.2e-1); + DoTest(1.2e10); + DoTest(1.2e-10); +end; + +procedure TTestFloat.TestNegative; +begin + DoTest(-1.0); + DoTest(-1.2); + DoTest(-1.2e1); + DoTest(-1.2e-1); + DoTest(-1.2e10); + DoTest(-1.2e-10); +end; + +procedure TTestFloat.TestZero; +begin + DoTest(0.0); +end; + +{ TTestArray } + +procedure TTestArray.TestCreate; + +Var + J : TJSONArray; + +begin + J:=TJSonArray.Create; + try + TestJSONType(J,jtArray); + TestItemCount(J,0); + TestJSON(J,'[]'); + TestIsNull(J,False); + TestAsBoolean(J,False,True); + TestAsInteger(J,1,True); + TestAsString(J,'',True); + TestAsFloat(J,0.0,True); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestCreateString; + +Const + S = 'A string'; + +Var + J : TJSONArray; + +begin + J:=TJSonArray.Create([S]); + try + TestJSONType(J,jtArray); + TestItemCount(J,1); + TestJSONType(J[0],jtString); + TestJSON(J,'["'+S+'"]'); + TestIsNull(J,False); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestCreatePChar; + +Const + S = 'A string'; + +Var + J : TJSONArray; + +begin + J:=TJSonArray.Create([Pchar(S)]); + try + TestJSONType(J,jtArray); + TestItemCount(J,1); + TestJSONType(J[0],jtString); + TestJSON(J,'["'+S+'"]'); + TestIsNull(J,False); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestCreateStrings; + +Const + S = 'A string'; + T = 'B string'; + +Var + J : TJSONArray; + +begin + J:=TJSONArray.Create([S,T]); + try + TestJSONType(J,jtArray); + TestItemCount(J,2); + TestJSONType(J[0],jtString); + TestJSONType(J[1],jtString); + TestJSON(J,'["'+S+'", "'+T+'"]'); + TestIsNull(J,False); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestCreateInteger; + +Const + S = 3; + +Var + J : TJSONArray; + +begin + J:=TJSonArray.Create([S]); + try + TestJSONType(J,jtArray); + TestItemCount(J,1); + TestJSONType(J[0],jtNumber); + TestJSON(J,'[3]'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestCreateFloat; + +Const + S = 1.2; + +Var + J : TJSONArray; + r : String; + +begin + J:=TJSonArray.Create([S]); + try + TestJSONType(J,jtArray); + TestItemCount(J,1); + TestJSONType(J[0],jtNumber); + Str(S,R); + TestJSON(J,'['+R+']'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestCreateInt64; + +Const + S : Int64 = $FFFFFF; + +Var + J : TJSONArray; + r : String; + F : TJSONFloat; + +begin + J:=TJSonArray.Create([S]); + try + TestJSONType(J,jtArray); + TestItemCount(J,1); + TestJSONType(J[0],jtNumber); + F:=S; + Str(F,R); + TestJSON(J,'['+R+']'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestCreateBoolean; + +Const + S = True; + +Var + J : TJSONArray; + +begin + J:=TJSonArray.Create([S]); + try + TestJSONType(J,jtArray); + TestItemCount(J,1); + TestJSONType(J[0],jtBoolean); + TestJSON(J,'[True]'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestCreateJSONObject; + +Var + J : TJSONArray; + +begin + J:=TJSonArray.Create([TJSONObject.Create]); + try + TestItemCount(J,1); + TestJSONType(J[0],jtObject); + TestJSON(J,'[{}]'); + finally + FreeAndNil(J); + end; +end; +procedure TTestArray.TestCreateJSONString; + +Const + S = 'A string'; + +Var + J : TJSONArray; + +begin + J:=TJSonArray.Create([TJSONString.Create(S)]); + try + TestItemCount(J,1); + TestJSONType(J[0],jtString); + TestJSON(J,'["'+S+'"]'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestCreateObject; + +Var + J : TJSONArray; + +begin + J:=Nil; + try + Try + J:=TJSONArray.Create([TObject.Create]); + Fail('Array constructor accepts only TJSONData'); + finally + FreeAndNil(J); + end; + except + // Should be OK. + end; +end; + +procedure TTestArray.TestCreateNilPointer; + +Var + J : TJSONArray; + P : Pointer; + +begin + J:=Nil; + P:=Nil; + Try + J:=TJSONArray.Create([P]); + TestJSONType(J[0],jtNull); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestCreatePointer; + +Var + J : TJSONArray; + P : Pointer; + +begin + J:=Nil; + P:=@Self; + try + Try + J:=TJSONArray.Create([P]); + Fail('Array constructor accepts only NIL pointers'); + finally + FreeAndNil(J); + end; + except + // Should be OK. + end; +end; + +procedure TTestArray.TestAddInteger; + +Var + J : TJSONArray; + +begin + J:=TJSonArray.Create; + try + J.Add(0); + TestItemCount(J,1); + TestJSONType(J[0],jtNumber); + AssertEquals('J[0] is TJSONIntegerNumber',J[0].ClassType,TJSONIntegerNumber); + AssertEquals('j.Types[0]=jtNumber',ord(J.Types[0]),Ord(jtNumber)); + AssertEquals('J.Integers[0]=0',0,J.integers[0]); + TestAsInteger(J[0],0); + TestJSON(J,'[0]'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestAddFloat; + +Var + J : TJSONArray; + S : String; + F : TJSONFloat; +begin + F:=1.2; + J:=TJSonArray.Create; + try + J.Add(F); + TestItemCount(J,1); + TestJSONType(J[0],jtNumber); + AssertEquals('J[0] is TJSONFloatNumber',TJSONfloatNumber,J[0].ClassType); + AssertEquals('j.Types[0]=jtNumber',Ord(jtNumber),ord(J.Types[0])); + AssertEquals('J.Floats[0]='+FloatToStr(F),F,J.Floats[0]); + TestAsFloat(J[0],F); + Str(F,S); + TestJSON(J,'['+S+']'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestAddBoolean(B : Boolean); + +Var + J : TJSONArray; + +begin + B:=True; + J:=TJSonArray.Create; + try + J.Add(B); + TestItemCount(J,1); + TestJSONType(J[0],jtBoolean); + AssertEquals('J[0] is TJSONBoolean',TJSONBoolean,J[0].ClassType); + TestAsBoolean(J[0],B); + AssertEquals('J.Booleans[0]='+BoolToStr(B)+'"',B,J.Booleans[0]); + If B then + TestJSON(J,'[True]') + else + TestJSON(J,'[False]'); + finally + FreeAndNil(J); + end; + +end; + +procedure TTestArray.TestAddBooleanTrue; + +begin + TestAddBoolean(True); +end; + +procedure TTestArray.TestAddBooleanFalse; + +begin + TestAddBoolean(False); +end; + +procedure TTestArray.TestAddString; + +Var + J : TJSONArray; + S : String; + F : TJSONFloat; + +begin + S:='A string'; + J:=TJSonArray.Create; + try + J.Add(S); + TestItemCount(J,1); + TestJSONType(J[0],jtString); + AssertEquals('J[0] is TJSONString',TJSONString,J[0].ClassType); + TestAsString(J[0],S); + AssertEquals('J.Strings[0]="'+S+'"',S,J.Strings[0]); + TestJSON(J,'["'+StringToJSONString(S)+'"]'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestAddNull; + +Var + J : TJSONArray; + S : String; + F : TJSONFloat; + +begin + J:=TJSonArray.Create; + try + J.Add; + TestItemCount(J,1); + TestJSONType(J[0],jtNull); + AssertEquals('J[0] is TJSONNull',TJSONNull,J[0].ClassType); + AssertEquals('J.Nulls[0]=True',True,J.Nulls[0]); + TestIsNull(J[0],true); + TestJSON(J,'[Null]'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestAddArray; + +Var + J,J2 : TJSONArray; + +begin + J:=TJSonArray.Create; + try + J2:=TJSonArray.Create; + J2.Add(0); + J2.Add(1); + J.Add(J2); + TestItemCount(J,1); + TestJSONType(J[0],jtArray); + AssertEquals('J[0] is TJSONArray',TJSONArray,J[0].ClassType); + AssertEquals('J.Arrays[0] is TJSONArray',TJSONArray,J.Arrays[0].ClassType); + TestAsInteger(J.Arrays[0][0],0); + TestAsInteger(J.Arrays[0][1],1); + TestJSON(J,'[[0, 1]]'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestAddObject; + +Const + A = 'a'; + B = 'b'; + +Var + J : TJSONArray; + J2 : TJSONObject; + +begin + J:=TJSonArray.Create; + try + J2:=TJSonObject.Create; + J2.Add(A,0); + J2.Add(B,1); + J.Add(J2); + TestItemCount(J,1); + TestJSONType(J[0],jtObject); + AssertEquals('J[0] is TJSONObject',TJSONObject,J[0].ClassType); + AssertEquals('J.Objects[0] is TJSONObject',TJSONObject,J.Objects[0].ClassType); + TestAsInteger(J.Objects[0][A],0); + TestAsInteger(J.Objects[0][B],1); + TestJSON(J,'[{ "a" : 0, "b" : 1 }]'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestDelete; + +Var + J : TJSONArray; + +begin + J:=TJSonArray.Create; + try + J.Add(0); + J.Add(1); + TestItemCount(J,2); + TestJSONType(J[0],jtNumber); + TestJSONType(J[1],jtNumber); + TestJSON(J,'[0, 1]'); + J.Delete(1); + TestItemCount(J,1); + J.Delete(0); + TestItemCount(J,0); + finally + FreeAndNil(J); + end; +end; + +procedure TTestArray.TestRemove; + +Var + J : TJSONArray; + I : TJSONData; + +begin + J:=TJSonArray.Create; + try + J.Add(0); + J.Add(1); + J.Add(2); + TestItemCount(J,3); + TestJSONType(J[0],jtNumber); + TestJSONType(J[1],jtNumber); + TestJSONType(J[2],jtNumber); + TestJSON(J,'[0, 1, 2]'); + I:=J[1]; + J.Remove(I); + TestItemCount(J,2); + TestAsInteger(J[0],0); + TestAsInteger(J[1],2); + finally + FreeAndNil(J); + end; +end; + +{ TTestObject } + +procedure TTestObject.TestCreate; + +Var + J : TJSONObject; + +begin + J:=TJSONObject.Create; + try + TestJSONType(J,jtObject); + TestItemCount(J,0); + TestJSON(J,'{}'); + TestIsNull(J,False); + TestAsBoolean(J,False,True); + TestAsInteger(J,1,True); + TestAsString(J,'',True); + TestAsFloat(J,0.0,True); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestAddInteger; + +Const + A = 'a'; + +Var + J : TJSONObject; + +begin + J:=TJSonObject.Create; + try + J.Add(A,0); + TestItemCount(J,1); + TestJSONType(J[A],jtNumber); + AssertEquals('J[''a''] is TJSONIntegerNumber',J[A].ClassType,TJSONIntegerNumber); + AssertEquals('j.Types[''a'']=jtNumber',ord(J.Types[A]),Ord(jtNumber)); + AssertEquals('J.Integers[''a'']=0',0,J.integers[A]); + TestAsInteger(J[A],0); + TestJSON(J,'{ "'+A+'" : 0 }'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestAddFloat; + +Const + A = 'a'; + +Var + J : TJSONObject; + S : String; + F : TJSONFloat; +begin + F:=1.2; + J:=TJSonObject.Create; + try + J.Add(A,F); + TestItemCount(J,1); + TestJSONType(J[A],jtNumber); + AssertEquals('J[''a''] is TJSONFloatNumber',TJSONfloatNumber,J[a].ClassType); + AssertEquals('j.Types[''a'']=jtNumber',Ord(jtNumber),ord(J.Types[a])); + AssertEquals('J.Floats[''a'']='+FloatToStr(F),F,J.Floats[a]); + TestAsFloat(J[A],F); + Str(F,S); + TestJSON(J,'{ "'+a+'" : '+S+' }'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestAddBoolean(B : Boolean); + +Const + A = 'a'; + +Var + J : TJSONObject; + +begin + B:=True; + J:=TJSonObject.Create; + try + J.Add(A,B); + TestItemCount(J,1); + TestJSONType(J[A],jtBoolean); + AssertEquals('J[''a''] is TJSONBoolean',TJSONBoolean,J[a].ClassType); + TestAsBoolean(J[a],B); + AssertEquals('J.Booleans[''a'']='+BoolToStr(B)+'"',B,J.Booleans[a]); + If B then + TestJSON(J,'{ "'+a+'" : True }') + else + TestJSON(J,'{ "'+a+'" : False }'); + finally + FreeAndNil(J); + end; + +end; + +procedure TTestObject.TestAddBooleanTrue; + +begin + TestAddBoolean(True); +end; + +procedure TTestObject.TestAddBooleanFalse; + +begin + TestAddBoolean(False); +end; + +procedure TTestObject.TestAddString; + +Const + A = 'a'; + +Var + J : TJSONObject; + S : String; + F : TJSONFloat; + +begin + S:='A string'; + J:=TJSonObject.Create; + try + J.Add(A,S); + TestItemCount(J,1); + TestJSONType(J[a],jtString); + AssertEquals('J[''a''] is TJSONString',TJSONString,J[A].ClassType); + TestAsString(J[a],S); + AssertEquals('J.Strings[''a'']="'+S+'"',S,J.Strings[A]); + TestJSON(J,'{ "'+a+'" : "'+StringToJSONString(S)+'" }'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestAddNull; + +Const + A = 'a'; + +Var + J : TJSONObject; + S : String; + F : TJSONFloat; + +begin + J:=TJSonObject.Create; + try + J.Add(a); + TestItemCount(J,1); + TestJSONType(J[a],jtNull); + AssertEquals('J[''a''] is TJSONNull',TJSONNull,J[A].ClassType); + AssertEquals('J.Nulls[''a'']=True',True,J.Nulls[A]); + TestIsNull(J[a],true); + TestJSON(J,'{ "'+a+'" : Null }'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestAddObject; + +Const + A = 'a'; + B = 'b'; + C = 'c'; + +Var + J,J2 : TJSONObject; + +begin + J:=TJSonObject.Create; + try + J2:=TJSonObject.Create; + J2.Add(B,0); + J2.Add(C,1); + J.Add(A,J2); + TestItemCount(J,1); + TestJSONType(J[A],jtObject); + AssertEquals('J[''a''] is TJSONObject',TJSONObject,J[A].ClassType); + AssertEquals('J.Objects[''a''] is TJSONObject',TJSONObject,J.Objects[A].ClassType); + TestAsInteger(J.Objects[A][B],0); + TestAsInteger(J.Objects[A][C],1); + TestJSON(J,'{ "a" : { "b" : 0, "c" : 1 } }'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestAddArray; + +Const + A = 'a'; + +Var + J : TJSONObject; + J2 : TJSONArray; + +begin + J:=TJSONObject.Create; + try + J2:=TJSonArray.Create; + J2.Add(0); + J2.Add(1); + J.Add(A,J2); + TestItemCount(J,1); + TestJSONType(J[A],jtArray); + AssertEquals('J[''a''] is TJSONArray',TJSONArray,J[A].ClassType); + AssertEquals('J.Arrays[0] is TJSONArray',TJSONArray,J.Arrays[A].ClassType); + TestAsInteger(J.Arrays[A][0],0); + TestAsInteger(J.Arrays[A][1],1); + TestJSON(J,'{ "a" : [0, 1] }'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestDelete; + +Const + A = 'a'; + B = 'b'; + +Var + J : TJSONObject; + +begin + J:=TJSonObject.Create; + try + J.Add(A,0); + J.Add(B,1); + TestItemCount(J,2); + TestJSONType(J[A],jtNumber); + TestJSONType(J[A],jtNumber); + TestJSON(J,'{ "a" : 0, "b" : 1 }'); + J.Delete(1); + TestItemCount(J,1); + J.Delete(0); + TestItemCount(J,0); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestRemove; + +Const + A = 'a'; + B = 'b'; + C = 'c'; + +Var + J : TJSONObject; + I : TJSONData; + +begin + J:=TJSonObject.Create; + try + J.Add(A,1); + J.Add(B,2); + J.Add(C,3); + TestItemCount(J,3); + TestJSONType(J[A],jtNumber); + TestJSONType(J[B],jtNumber); + TestJSONType(J[C],jtNumber); + TestJSON(J,'{ "a" : 1, "b" : 2, "c" : 3 }'); + I:=J[b]; + J.Remove(I); + TestItemCount(J,2); + TestAsInteger(J[a],1); + TestAsInteger(J[c],3); + finally + FreeAndNil(J); + end; +end; + + +procedure TTestObject.TestCreateString; + +Const + A = 'A'; + S = 'A string'; + +Var + J : TJSONObject; + +begin + J:=TJSONObject.Create([A,S]); + try + TestJSONType(J,jtObject); + TestItemCount(J,1); + TestJSONType(J[A],jtString); + TestJSON(J,'{ "A" : "'+S+'" }'); + TestIsNull(J,False); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestCreatePChar; + +Const + A = 'A'; + S = 'A string'; + +Var + J : TJSONObject; + +begin + J:=TJSONObject.Create([A,Pchar(S)]); + try + TestJSONType(J,jtObject); + TestItemCount(J,1); + TestJSONType(J[A],jtString); + TestJSON(J,'{ "A" : "'+S+'" }'); + TestIsNull(J,False); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestCreateStrings; + +Const + A = 'A'; + B = 'B'; + S = 'A string'; + T = 'B string'; + +Var + J : TJSONObject; + +begin + J:=TJSONObject.Create([A,S,B,T]); + try + TestJSONType(J,jtObject); + TestItemCount(J,2); + TestJSONType(J[A],jtString); + TestJSONType(J[B],jtString); + TestJSON(J,'{ "A" : "'+S+'", "B" : "'+T+'" }'); + TestIsNull(J,False); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestCreateInteger; + +Const + A = 'A'; + S = 3; + +Var + J : TJSONObject; + +begin + J:=TJSONObject.Create([A,S]); + try + TestJSONType(J,jtObject); + TestItemCount(J,1); + TestJSONType(J[A],jtNumber); + TestJSON(J,'{ "A" : 3 }'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestCreateFloat; + +Const + A = 'A'; + S = 1.2; + +Var + J : TJSONObject; + r : String; + +begin + J:=TJSONObject.Create([A,S]); + try + TestJSONType(J,jtObject); + TestItemCount(J,1); + TestJSONType(J[A],jtNumber); + Str(S,R); + TestJSON(J,'{ "A" : '+R+' }'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestCreateInt64; + +Const + A = 'A'; + S : Int64 = $FFFFFF; + +Var + J : TJSONObject; + r : String; + F : TJSONFloat; + +begin + J:=TJSONObject.Create([A,S]); + try + TestJSONType(J,jtObject); + TestItemCount(J,1); + TestJSONType(J[A],jtNumber); + F:=S; + Str(F,R); + TestJSON(J,'{ "A" : '+R+' }'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestCreateBoolean; + +Const + A = 'A'; + S = True; + +Var + J : TJSONObject; + +begin + J:=TJSONObject.Create([A,S]); + try + TestJSONType(J,jtObject); + TestItemCount(J,1); + TestJSONType(J[A],jtBoolean); + TestJSON(J,'{ "A" : True }'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestCreateJSONObject; + +Const + A = 'A'; + +Var + J : TJSONObject; + +begin + J:=TJSONObject.Create([A,TJSONObject.Create]); + try + TestItemCount(J,1); + TestJSONType(J[A],jtObject); + TestJSON(J,'{ "A" : {} }'); + finally + FreeAndNil(J); + end; +end; +procedure TTestObject.TestCreateJSONString; + +Const + A = 'A'; + S = 'A string'; + +Var + J : TJSONObject; + +begin + J:=TJSONObject.Create([A,TJSONString.Create(S)]); + try + TestItemCount(J,1); + TestJSONType(J[A],jtString); + TestJSON(J,'{ "A" : "'+S+'" }'); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestCreateObject; + +Const + A = 'A'; + +Var + J : TJSONObject; + +begin + J:=Nil; + try + Try + J:=TJSONObject.Create([A,TObject.Create]); + Fail('Array constructor accepts only TJSONData'); + finally + FreeAndNil(J); + end; + except + // Should be OK. + end; +end; + +procedure TTestObject.TestCreateNilPointer; + +Const + A = 'A'; + +Var + J : TJSONObject; + P : Pointer; + +begin + J:=Nil; + P:=Nil; + Try + J:=TJSONObject.Create([A,P]); + TestJSONType(J[A],jtNull); + finally + FreeAndNil(J); + end; +end; + +procedure TTestObject.TestCreatePointer; + +Const + A = 'A'; + +Var + J : TJSONObject; + P : Pointer; + +begin + J:=Nil; + P:=@Self; + try + Try + J:=TJSONObject.Create([A,P]); + Fail('Array constructor accepts only NIL pointers'); + finally + FreeAndNil(J); + end; + except + // Should be OK. + end; +end; + +{ TTestJSONString } + +procedure TTestJSONString.TestTo(const Src, Dest: String); + +Var + S : String; + +begin + S:='StringToJSONString('''+Src+''')='''+Dest+''''; + AssertEquals(S,Dest,StringToJSONString(Src)); +end; + +procedure TTestJSONString.TestFrom(const Src, Dest: String); + +Var + S : String; + +begin + S:='JSONStringToString('''+Src+''')='''+Dest+''''; + AssertEquals(S,Dest,JSONStringToString(Src)); +end; + +procedure TTestJSONString.TestJSONStringToString; +begin + TestFrom('',''); + TestFrom('A','A'); + TestFrom('AB','AB'); + TestFrom('ABC','ABC'); + TestFrom('\\','\'); + TestFrom('\/','/'); + TestFrom('\"','"'); + TestFrom('\b',#8); + TestFrom('\t',#9); + TestFrom('\n',#10); + TestFrom('\f',#12); + TestFrom('\r',#13); + TestFrom('\bBC',#8'BC'); + TestFrom('\tBC',#9'BC'); + TestFrom('\nBC',#10'BC'); + TestFrom('\fBC',#12'BC'); + TestFrom('\rBC',#13'BC'); + TestFrom('A\b','A'#8); + TestFrom('A\t','A'#9); + TestFrom('A\n','A'#10); + TestFrom('A\f','A'#12); + TestFrom('A\r','A'#13); + TestFrom('A\bBC','A'#8'BC'); + TestFrom('A\tBC','A'#9'BC'); + TestFrom('A\nBC','A'#10'BC'); + TestFrom('A\fBC','A'#12'BC'); + TestFrom('A\rBC','A'#13'BC'); + TestFrom('\\\\','\\'); + TestFrom('\/\/','//'); + TestFrom('\"\"','""'); + TestFrom('\b\b',#8#8); + TestFrom('\t\t',#9#9); + TestFrom('\n\n',#10#10); + TestFrom('\f\f',#12#12); + TestFrom('\r\r',#13#13); +end; + +procedure TTestJSONString.TestStringToJSONString; +begin + TestTo('',''); + TestTo('A','A'); + TestTo('AB','AB'); + TestTo('ABC','ABC'); + TestTo('\','\\'); + TestTo('/','\/'); + TestTo('"','\"'); + TestTo(#8,'\b'); + TestTo(#9,'\t'); + TestTo(#10,'\n'); + TestTo(#12,'\f'); + TestTo(#13,'\r'); + TestTo(#8'BC','\bBC'); + TestTo(#9'BC','\tBC'); + TestTo(#10'BC','\nBC'); + TestTo(#12'BC','\fBC'); + TestTo(#13'BC','\rBC'); + TestTo('A'#8,'A\b'); + TestTo('A'#9,'A\t'); + TestTo('A'#10,'A\n'); + TestTo('A'#12,'A\f'); + TestTo('A'#13,'A\r'); + TestTo('A'#8'BC','A\bBC'); + TestTo('A'#9'BC','A\tBC'); + TestTo('A'#10'BC','A\nBC'); + TestTo('A'#12'BC','A\fBC'); + TestTo('A'#13'BC','A\rBC'); + TestTo('\\','\\\\'); + TestTo('//','\/\/'); + TestTo('""','\"\"'); + TestTo(#8#8,'\b\b'); + TestTo(#9#9,'\t\t'); + TestTo(#10#10,'\n\n'); + TestTo(#12#12,'\f\f'); + TestTo(#13#13,'\r\r'); +end; + +initialization + RegisterTest(TTestJSONString); + RegisterTest(TTestNull); + RegisterTest(TTestBoolean); + RegisterTest(TTestInteger); + RegisterTest(TTestFloat); + RegisterTest(TTestString); + RegisterTest(TTestArray); + RegisterTest(TTestObject); +end. + diff --git a/packages/fcl-json/tests/testjsonparser.pp b/packages/fcl-json/tests/testjsonparser.pp new file mode 100644 index 0000000000..070bc2e73f --- /dev/null +++ b/packages/fcl-json/tests/testjsonparser.pp @@ -0,0 +1,364 @@ +unit testjsonparser; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, fpcunit, testutils, testregistry,fpjson, + jsonParser,testjsondata; + +type + + { TTestParser } + + TTestParser= class(TTestJSON) + private + procedure DoTestError(S: String); + procedure DoTestFloat(F: TJSONFloat); overload; + procedure DoTestFloat(F: TJSONFloat; S: String); overload; + procedure DoTestObject(S: String; const ElNames: array of String); + procedure DoTestString(S : String); + procedure DoTestArray(S: String; ACount: Integer); + published + procedure TestEmpty; + procedure TestNull; + procedure TestTrue; + procedure TestFalse; + procedure TestFloat; + procedure TestInteger; + procedure TestString; + procedure TestArray; + procedure TestObject; + procedure TestMixed; + procedure TestErrors; + end; + +implementation + +procedure TTestParser.TestEmpty; + +Var + P : TJSONParser; + J : TJSONData; + +begin + P:=TJSONParser.Create(''); + Try + J:=P.Parse; + If (J<>Nil) then + Fail('Empty returns Nil'); + Finally + FreeAndNil(J); + FreeAndNil(P); + end; +end; + +procedure TTestParser.TestInteger; + +Var + P : TJSONParser; + J : TJSONData; + +begin + P:=TJSONParser.Create('1'); + Try + J:=P.Parse; + If (J=Nil) then + Fail('Parse of 1 fails'); + TestJSONType(J,jtNumber); + TestAsInteger(J,1); + Finally + FreeAndNil(J); + FreeAndNil(P); + end; +end; + +procedure TTestParser.TestNull; + +Var + P : TJSONParser; + J : TJSONData; + +begin + P:=TJSONParser.Create('Null'); + Try + J:=P.Parse; + If (J=Nil) then + Fail('Parse of Null fails'); + TestJSONType(J,jtNull); + Finally + FreeAndNil(J); + FreeAndNil(P); + end; +end; + +procedure TTestParser.TestTrue; + +Var + P : TJSONParser; + J : TJSONData; + +begin + P:=TJSONParser.Create('True'); + Try + J:=P.Parse; + If (J=Nil) then + Fail('Parse of True fails'); + TestJSONType(J,jtBoolean); + TestAsBoolean(J,True); + Finally + FreeAndNil(J); + FreeAndNil(P); + end; +end; + +procedure TTestParser.TestFalse; + +Var + P : TJSONParser; + J : TJSONData; + +begin + P:=TJSONParser.Create('False'); + Try + J:=P.Parse; + If (J=Nil) then + Fail('Parse of False fails'); + TestJSONType(J,jtBoolean); + TestAsBoolean(J,False); + Finally + FreeAndNil(J); + FreeAndNil(P); + end; +end; + +procedure TTestParser.TestFloat; + + +begin + DoTestFloat(1.2); + DoTestFloat(-1.2); + DoTestFloat(0); + DoTestFloat(1.2e1); + DoTestFloat(-1.2e1); + DoTestFloat(0); + DoTestFloat(1.2,'1.2'); + DoTestFloat(-1.2,'-1.2'); + DoTestFloat(0,'0.0'); +end; + +procedure TTestParser.TestString; + +begin + DoTestString('A string'); + DoTestString(''); + DoTestString('\"'); +end; + + +procedure TTestParser.TestArray; + +Var + S1,S2,S3 : String; + + +begin + DoTestArray('[]',0); + DoTestArray('[Null]',1); + DoTestArray('[True]',1); + DoTestArray('[False]',1); + DoTestArray('[1]',1); + DoTestArray('[1, 2]',2); + DoTestArray('[1, 2, 3]',3); + Str(1.2,S1); + Str(2.3,S2); + Str(3.4,S3); + DoTestArray('['+S1+']',1); + DoTestArray('['+S1+', '+S2+']',2); + DoTestArray('['+S1+', '+S2+', '+S3+']',3); + DoTestArray('["A string"]',1); + DoTestArray('["A string", "Another string"]',2); + DoTestArray('["A string", "Another string", "Yet another string"]',3); + DoTestArray('[Null, False]',2); + DoTestArray('[True, False]',2); + DoTestArray('[Null, 1]',2); + DoTestArray('[1, "A string"]',2); + DoTestArray('[1, []]',2); + DoTestArray('[1, [1, 2]]',2); +end; + +procedure TTestParser.TestMixed; + +begin + DoTestArray('[1, {}]',2); + DoTestArray('[1, { "a" : 1 }]',2); + DoTestArray('[1, { "a" : 1 }, 1]',3); + DoTestObject('{ "a" : [1, 2] }',['a']); + DoTestObject('{ "a" : [1, 2], "B" : { "c" : "d" } }',['a','B']); +end; + +procedure TTestParser.TestObject; +begin + DoTestObject('{}',[]); + DoTestObject('{ "a" : 1 }',['a']); + DoTestObject('{ "a" : 1, "B" : "String" }',['a','B']); + DoTestObject('{ "a" : 1, "B" : {} }',['a','B']); + DoTestObject('{ "a" : 1, "B" : { "c" : "d" } }',['a','B']); +end; + + +procedure TTestParser.DoTestObject(S : String; Const ElNames : Array of String); + +Var + P : TJSONParser; + J : TJSONData; + O : TJSONObject; + I : Integer; + +begin + P:=TJSONParser.Create(S); + Try + J:=P.Parse; + If (J=Nil) then + Fail('Parse of object "'+S+'" fails'); + TestJSONType(J,jtObject); + TestItemCount(J,High(ElNames)-Low(ElNames)+1); + O:=TJSONObject(J); + For I:=Low(ElNames) to High(ElNames) do + AssertEquals(Format('Element %d name',[I-Low(Elnames)]) + ,ElNames[i], O.Names[I-Low(ElNames)]); + TestJSON(J,S); + Finally + FreeAndNil(J); + FreeAndNil(P); + end; +end; + + +procedure TTestParser.DoTestArray(S : String; ACount : Integer); + +Var + P : TJSONParser; + J : TJSONData; + +begin + P:=TJSONParser.Create(S); + Try + J:=P.Parse; + If (J=Nil) then + Fail('Parse of array "'+S+'" fails'); + TestJSONType(J,jtArray); + TestItemCount(J,ACount); + TestJSON(J,S); + Finally + FreeAndNil(J); + FreeAndNil(P); + end; +end; + +procedure TTestParser.TestErrors; + +begin + DoTestError('a'); + DoTestError('"b'); + DoTestError('1Tru'); + DoTestError('b"'); + DoTestError('{"a" : }'); + DoTestError('{"a" : ""'); + DoTestError('{"a : ""'); + DoTestError('[1,]'); + DoTestError('[,]'); + DoTestError('[,,]'); + DoTestError('[1,,]'); +end; + +procedure TTestParser.DoTestError(S : String); + +Var + P : TJSONParser; + J : TJSONData; + ParseOK : Boolean; + N : String; + +begin + ParseOK:=False; + P:=TJSONParser.Create(S); + J:=Nil; + Try + Try + Repeat + FreeAndNil(J); + J:=P.Parse; + ParseOK:=True; + If (J<>Nil) then + N:=J.ClassName; + Until (J=Nil) + Finally + FreeAndNil(J); + FreeAndNil(P); + end; + except + ParseOk:=False; + end; + If ParseOK then + Fail('Parse of JSON string "'+S+'" should fail, but returned '+N); +end; + +procedure TTestParser.DoTestString(S: String); + +Var + P : TJSONParser; + J : TJSONData; + +begin + P:=TJSONParser.Create('"'+S+'"'); + Try + J:=P.Parse; + If (J=Nil) then + Fail('Parse of string "'+S+'" fails'); + TestJSONType(J,jtString); + TestAsString(J,JSONStringToString(S)); + TestJSON(J,'"'+S+'"'); + Finally + FreeAndNil(J); + FreeAndNil(P); + end; + +end; + +procedure TTestParser.DoTestFloat(F : TJSONFloat); + +Var + S : String; + +begin + Str(F,S); + DoTestFloat(F,S); +end; + +procedure TTestParser.DoTestFloat(F : TJSONFloat; S : String); + +Var + P : TJSONParser; + J : TJSONData; + +begin + P:=TJSONParser.Create(S); + Try + J:=P.Parse; + If (J=Nil) then + Fail('Parse of float '+S+' fails'); + TestJSONType(J,jtNumber); + TestAsFloat(J,F); + Finally + FreeAndNil(J); + FreeAndNil(P); + end; +end; + + +initialization + RegisterTest(TTestParser); +end. + |
