Jelajahi Sumber

* Added webdata

git-svn-id: trunk@15334 -
michael 15 tahun lalu
induk
melakukan
81648b6fbf

+ 8 - 0
.gitattributes

@@ -2259,6 +2259,14 @@ packages/fcl-web/src/base/httpdefs.pp svneol=native#text/plain
 packages/fcl-web/src/base/webpage.pp svneol=native#text/plain
 packages/fcl-web/src/base/websession.pp svneol=native#text/plain
 packages/fcl-web/src/base/webutil.pp svneol=native#text/plain
+packages/fcl-web/src/webdata/Makefile svneol=native#text/plain
+packages/fcl-web/src/webdata/Makefile.fpc svneol=native#text/plain
+packages/fcl-web/src/webdata/extjsjson.pp svneol=native#text/plain
+packages/fcl-web/src/webdata/extjsxml.pp svneol=native#text/plain
+packages/fcl-web/src/webdata/fpextjs.pp svneol=native#text/plain
+packages/fcl-web/src/webdata/fpwebdata.pp svneol=native#text/plain
+packages/fcl-web/src/webdata/sqldbwebdata.pp svneol=native#text/plain
+packages/fcl-web/src/webdata/webdata.txt svneol=native#text/plain
 packages/fcl-web/tests/cgigateway.lpi svneol=native#text/plain
 packages/fcl-web/tests/cgigateway.pp svneol=native#text/plain
 packages/fcl-web/tests/testcgiapp.lpi svneol=native#text/plain

+ 2904 - 0
packages/fcl-web/src/webdata/Makefile

@@ -0,0 +1,2904 @@
+#
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2009/11/05]
+#
+default: all
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku 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-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded avr-embedded armeb-linux armeb-embedded
+BSDs = freebsd netbsd openbsd darwin
+UNIXs = linux $(BSDs) solaris qnx
+LIMIT83fs = go32v2 os2 emx watcom
+OSNeedsComspecToRunBatch = go32v2 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 COMSPEC
+ifneq ($(findstring $(OS_SOURCE),$(OSNeedsComspecToRunBatch)),)
+RUNBATCH=$(COMSPEC) /C
+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))
+ifneq ($(CPU_TARGET),)
+FPC:=$(shell $(FPCPROG) -P$(CPU_TARGET) -PB)
+else
+FPC:=$(shell $(FPCPROG) -PB)
+endif
+ifneq ($(findstring Error,$(FPC)),)
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+else
+ifeq ($(strip $(wildcard $(FPC))),)
+FPC:=$(firstword $(FPCPROG))
+endif
+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)
+ifeq ($(CPU_TARGET),armeb)
+ARCH=arm
+override FPCOPT+=-Cb
+else
+ifeq ($(CPU_TARGET),armel)
+ARCH=arm
+override FPCOPT+=-CaEABI
+else
+ARCH=$(CPU_TARGET)
+endif
+endif
+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 ARCH 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
+ifeq ($(OS_TARGET),darwin)
+ifeq ($(OS_SOURCE),darwin)
+DARWIN2DARWIN=1
+endif
+endif
+ifndef BINUTILSPREFIX
+ifndef CROSSBINDIR
+ifdef CROSSCOMPILE
+ifndef DARWIN2DARWIN
+BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+endif
+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-web
+override PACKAGE_VERSION=2.5.1
+PACKAGEDIR_MAIN:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-web/Makefile.fpc,$(PACKAGESDIR))))))
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+override TARGET_UNITS+=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+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-haiku)
+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-darwin)
+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-darwin)
+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),avr-embedded)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+override COMPILER_OPTIONS+=-S2h
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+override COMPILER_OPTIONS+=-S2h
+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
+ifeq ($(OS_SOURCE),linux)
+ifndef GCCLIBDIR
+ifeq ($(CPU_TARGET),i386)
+ifneq ($(findstring x86_64,$(shell uname -a)),)
+ifeq ($(BINUTILSPREFIX),)
+GCCLIBDIR:=$(shell dirname `gcc -m32 -print-libgcc-file-name`)
+endif
+endif
+endif
+ifeq ($(CPU_TARGET),powerpc64)
+ifeq ($(BINUTILSPREFIX),)
+GCCLIBDIR:=$(shell dirname `gcc -m64 -print-libgcc-file-name`)
+endif
+endif
+endif
+ifndef GCCLIBDIR
+CROSSGCC=$(strip $(wildcard $(addsuffix /$(BINUTILSPREFIX)gcc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(CROSSGCC),)
+GCCLIBDIR:=$(shell dirname `$(CROSSGCC) -print-libgcc-file-name`)
+endif
+endif
+ifndef OTHERLIBDIR
+OTHERLIBDIR:=$(shell grep -v "^\#" /etc/ld.so.conf | awk '{ ORS=" "; print $1 }')
+endif
+endif
+ifdef inUnix
+ifeq ($(OS_SOURCE),netbsd)
+OTHERLIBDIR+=/usr/pkg/lib
+endif
+export GCCLIBDIR OTHERLIB
+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
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+OEXT=.obj
+ASMEXT=.asm
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=wat
+IMPORTLIBPREFIX=
+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
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),emx)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=emx
+ECHO=echo
+IMPORTLIBPREFIX=
+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),haiku)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=hai
+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
+IMPORTLIBPREFIX=imp
+endif
+ifeq ($(OS_TARGET),netwlibc)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nwl
+IMPORTLIBPREFIX=imp
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+IMPORTLIBPREFIX=imp
+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
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+IMPORTLIBPREFIX=
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+SHORTSUFFIX=wat
+IMPORTLIBPREFIX=
+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
+IMPORTLIBPREFIX=
+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
+IMPORTLIBPREFIX=imp
+endif
+ifeq ($(OS_TARGET),netwlibc)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nwl
+IMPORTLIBPREFIX=imp
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+IMPORTLIBPREFIX=imp
+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 fcl-xml fcl-db fcl-json
+ifeq ($(FULL_TARGET),i386-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),i386-haiku)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_SQLITE=1
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_UNIVINT=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_UNIVINT=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_SQLITE=1
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_UNIVINT=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_SQLITE=1
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),arm-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_UNIVINT=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_UNIVINT=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),avr-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+endif
+ifeq ($(FULL_TARGET),armeb-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_ICONVENC=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=1
+REQUIRE_PACKAGES_IBASE=1
+REQUIRE_PACKAGES_POSTGRES=1
+REQUIRE_PACKAGES_MYSQL=1
+REQUIRE_PACKAGES_ODBC=1
+REQUIRE_PACKAGES_ORACLE=1
+REQUIRE_PACKAGES_SQLITE=1
+REQUIRE_PACKAGES_PXLIB=1
+endif
+ifeq ($(FULL_TARGET),armeb-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FCL-BASE=1
+REQUIRE_PACKAGES_FCL-XML=1
+REQUIRE_PACKAGES_FCL-DB=1
+REQUIRE_PACKAGES_FCL-JSON=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_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_ICONVENC
+PACKAGEDIR_ICONVENC:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /iconvenc/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_ICONVENC),)
+ifneq ($(wildcard $(PACKAGEDIR_ICONVENC)/units/$(TARGETSUFFIX)),)
+UNITDIR_ICONVENC=$(PACKAGEDIR_ICONVENC)/units/$(TARGETSUFFIX)
+else
+UNITDIR_ICONVENC=$(PACKAGEDIR_ICONVENC)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_ICONVENC)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_ICONVENC) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_ICONVENC)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_ICONVENC=
+UNITDIR_ICONVENC:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /iconvenc/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_ICONVENC),)
+UNITDIR_ICONVENC:=$(firstword $(UNITDIR_ICONVENC))
+else
+UNITDIR_ICONVENC=
+endif
+endif
+ifdef UNITDIR_ICONVENC
+override COMPILER_UNITDIR+=$(UNITDIR_ICONVENC)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FCL-XML
+PACKAGEDIR_FCL-XML:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-xml/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FCL-XML),)
+ifneq ($(wildcard $(PACKAGEDIR_FCL-XML)/units/$(TARGETSUFFIX)),)
+UNITDIR_FCL-XML=$(PACKAGEDIR_FCL-XML)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FCL-XML=$(PACKAGEDIR_FCL-XML)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FCL-XML)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FCL-XML) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-XML)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FCL-XML=
+UNITDIR_FCL-XML:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-xml/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FCL-XML),)
+UNITDIR_FCL-XML:=$(firstword $(UNITDIR_FCL-XML))
+else
+UNITDIR_FCL-XML=
+endif
+endif
+ifdef UNITDIR_FCL-XML
+override COMPILER_UNITDIR+=$(UNITDIR_FCL-XML)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FCL-DB
+PACKAGEDIR_FCL-DB:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-db/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FCL-DB),)
+ifneq ($(wildcard $(PACKAGEDIR_FCL-DB)/units/$(TARGETSUFFIX)),)
+UNITDIR_FCL-DB=$(PACKAGEDIR_FCL-DB)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FCL-DB=$(PACKAGEDIR_FCL-DB)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FCL-DB)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FCL-DB) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-DB)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FCL-DB=
+UNITDIR_FCL-DB:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-db/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FCL-DB),)
+UNITDIR_FCL-DB:=$(firstword $(UNITDIR_FCL-DB))
+else
+UNITDIR_FCL-DB=
+endif
+endif
+ifdef UNITDIR_FCL-DB
+override COMPILER_UNITDIR+=$(UNITDIR_FCL-DB)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FCL-JSON
+PACKAGEDIR_FCL-JSON:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fcl-json/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FCL-JSON),)
+ifneq ($(wildcard $(PACKAGEDIR_FCL-JSON)/units/$(TARGETSUFFIX)),)
+UNITDIR_FCL-JSON=$(PACKAGEDIR_FCL-JSON)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FCL-JSON=$(PACKAGEDIR_FCL-JSON)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FCL-JSON)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_FCL-JSON) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FCL-JSON)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FCL-JSON=
+UNITDIR_FCL-JSON:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fcl-json/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FCL-JSON),)
+UNITDIR_FCL-JSON:=$(firstword $(UNITDIR_FCL-JSON))
+else
+UNITDIR_FCL-JSON=
+endif
+endif
+ifdef UNITDIR_FCL-JSON
+override COMPILER_UNITDIR+=$(UNITDIR_FCL-JSON)
+endif
+endif
+ifdef REQUIRE_PACKAGES_IBASE
+PACKAGEDIR_IBASE:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /ibase/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_IBASE),)
+ifneq ($(wildcard $(PACKAGEDIR_IBASE)/units/$(TARGETSUFFIX)),)
+UNITDIR_IBASE=$(PACKAGEDIR_IBASE)/units/$(TARGETSUFFIX)
+else
+UNITDIR_IBASE=$(PACKAGEDIR_IBASE)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_IBASE)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_IBASE) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_IBASE)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_IBASE=
+UNITDIR_IBASE:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /ibase/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_IBASE),)
+UNITDIR_IBASE:=$(firstword $(UNITDIR_IBASE))
+else
+UNITDIR_IBASE=
+endif
+endif
+ifdef UNITDIR_IBASE
+override COMPILER_UNITDIR+=$(UNITDIR_IBASE)
+endif
+endif
+ifdef REQUIRE_PACKAGES_POSTGRES
+PACKAGEDIR_POSTGRES:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /postgres/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_POSTGRES),)
+ifneq ($(wildcard $(PACKAGEDIR_POSTGRES)/units/$(TARGETSUFFIX)),)
+UNITDIR_POSTGRES=$(PACKAGEDIR_POSTGRES)/units/$(TARGETSUFFIX)
+else
+UNITDIR_POSTGRES=$(PACKAGEDIR_POSTGRES)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_POSTGRES)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_POSTGRES) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_POSTGRES)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_POSTGRES=
+UNITDIR_POSTGRES:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /postgres/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_POSTGRES),)
+UNITDIR_POSTGRES:=$(firstword $(UNITDIR_POSTGRES))
+else
+UNITDIR_POSTGRES=
+endif
+endif
+ifdef UNITDIR_POSTGRES
+override COMPILER_UNITDIR+=$(UNITDIR_POSTGRES)
+endif
+endif
+ifdef REQUIRE_PACKAGES_MYSQL
+PACKAGEDIR_MYSQL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /mysql/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_MYSQL),)
+ifneq ($(wildcard $(PACKAGEDIR_MYSQL)/units/$(TARGETSUFFIX)),)
+UNITDIR_MYSQL=$(PACKAGEDIR_MYSQL)/units/$(TARGETSUFFIX)
+else
+UNITDIR_MYSQL=$(PACKAGEDIR_MYSQL)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_MYSQL)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_MYSQL) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_MYSQL)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_MYSQL=
+UNITDIR_MYSQL:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /mysql/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_MYSQL),)
+UNITDIR_MYSQL:=$(firstword $(UNITDIR_MYSQL))
+else
+UNITDIR_MYSQL=
+endif
+endif
+ifdef UNITDIR_MYSQL
+override COMPILER_UNITDIR+=$(UNITDIR_MYSQL)
+endif
+endif
+ifdef REQUIRE_PACKAGES_ODBC
+PACKAGEDIR_ODBC:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /odbc/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_ODBC),)
+ifneq ($(wildcard $(PACKAGEDIR_ODBC)/units/$(TARGETSUFFIX)),)
+UNITDIR_ODBC=$(PACKAGEDIR_ODBC)/units/$(TARGETSUFFIX)
+else
+UNITDIR_ODBC=$(PACKAGEDIR_ODBC)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_ODBC)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_ODBC) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_ODBC)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_ODBC=
+UNITDIR_ODBC:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /odbc/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_ODBC),)
+UNITDIR_ODBC:=$(firstword $(UNITDIR_ODBC))
+else
+UNITDIR_ODBC=
+endif
+endif
+ifdef UNITDIR_ODBC
+override COMPILER_UNITDIR+=$(UNITDIR_ODBC)
+endif
+endif
+ifdef REQUIRE_PACKAGES_ORACLE
+PACKAGEDIR_ORACLE:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /oracle/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_ORACLE),)
+ifneq ($(wildcard $(PACKAGEDIR_ORACLE)/units/$(TARGETSUFFIX)),)
+UNITDIR_ORACLE=$(PACKAGEDIR_ORACLE)/units/$(TARGETSUFFIX)
+else
+UNITDIR_ORACLE=$(PACKAGEDIR_ORACLE)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_ORACLE)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_ORACLE) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_ORACLE)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_ORACLE=
+UNITDIR_ORACLE:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /oracle/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_ORACLE),)
+UNITDIR_ORACLE:=$(firstword $(UNITDIR_ORACLE))
+else
+UNITDIR_ORACLE=
+endif
+endif
+ifdef UNITDIR_ORACLE
+override COMPILER_UNITDIR+=$(UNITDIR_ORACLE)
+endif
+endif
+ifdef REQUIRE_PACKAGES_SQLITE
+PACKAGEDIR_SQLITE:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /sqlite/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_SQLITE),)
+ifneq ($(wildcard $(PACKAGEDIR_SQLITE)/units/$(TARGETSUFFIX)),)
+UNITDIR_SQLITE=$(PACKAGEDIR_SQLITE)/units/$(TARGETSUFFIX)
+else
+UNITDIR_SQLITE=$(PACKAGEDIR_SQLITE)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_SQLITE)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_SQLITE) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_SQLITE)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_SQLITE=
+UNITDIR_SQLITE:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /sqlite/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_SQLITE),)
+UNITDIR_SQLITE:=$(firstword $(UNITDIR_SQLITE))
+else
+UNITDIR_SQLITE=
+endif
+endif
+ifdef UNITDIR_SQLITE
+override COMPILER_UNITDIR+=$(UNITDIR_SQLITE)
+endif
+endif
+ifdef REQUIRE_PACKAGES_PXLIB
+PACKAGEDIR_PXLIB:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /pxlib/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_PXLIB),)
+ifneq ($(wildcard $(PACKAGEDIR_PXLIB)/units/$(TARGETSUFFIX)),)
+UNITDIR_PXLIB=$(PACKAGEDIR_PXLIB)/units/$(TARGETSUFFIX)
+else
+UNITDIR_PXLIB=$(PACKAGEDIR_PXLIB)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_PXLIB)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_PXLIB) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_PXLIB)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_PXLIB=
+UNITDIR_PXLIB:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /pxlib/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_PXLIB),)
+UNITDIR_PXLIB:=$(firstword $(UNITDIR_PXLIB))
+else
+UNITDIR_PXLIB=
+endif
+endif
+ifdef UNITDIR_PXLIB
+override COMPILER_UNITDIR+=$(UNITDIR_PXLIB)
+endif
+endif
+ifdef REQUIRE_PACKAGES_UNIVINT
+PACKAGEDIR_UNIVINT:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /univint/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_UNIVINT),)
+ifneq ($(wildcard $(PACKAGEDIR_UNIVINT)/units/$(TARGETSUFFIX)),)
+UNITDIR_UNIVINT=$(PACKAGEDIR_UNIVINT)/units/$(TARGETSUFFIX)
+else
+UNITDIR_UNIVINT=$(PACKAGEDIR_UNIVINT)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_UNIVINT)/$(FPCMADE):
+	$(MAKE) -C $(PACKAGEDIR_UNIVINT) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_UNIVINT)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_UNIVINT=
+UNITDIR_UNIVINT:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /univint/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_UNIVINT),)
+UNITDIR_UNIVINT:=$(firstword $(UNITDIR_UNIVINT))
+else
+UNITDIR_UNIVINT=
+endif
+endif
+ifdef UNITDIR_UNIVINT
+override COMPILER_UNITDIR+=$(UNITDIR_UNIVINT)
+endif
+endif
+ifndef NOCPUDEF
+override FPCOPTDEF=$(ARCH)
+endif
+ifneq ($(OS_TARGET),$(OS_SOURCE))
+override FPCOPT+=-T$(OS_TARGET)
+endif
+ifneq ($(CPU_TARGET),$(CPU_SOURCE))
+override FPCOPT+=-P$(ARCH)
+endif
+ifeq ($(OS_SOURCE),openbsd)
+override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
+endif
+ifndef CROSSBOOTSTRAP
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-XP$(BINUTILSPREFIX)
+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 GCCLIBDIR
+override FPCOPT+=-Fl$(GCCLIBDIR)
+endif
+ifdef OTHERLIBDIR
+override FPCOPT+=$(addprefix -Fl,$(OTHERLIBDIR))
+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))
+ifdef RUNBATCH
+EXECPPAS:=@$(RUNBATCH) $(PPAS)
+else
+EXECPPAS:=@$(PPAS)
+endif
+endif
+endif
+.PHONY: fpc_units
+ifneq ($(TARGET_UNITS)$(TARGET_IMPLICITUNITS),)
+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 %.inc $(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_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:
+zipinstall:
+zipsourceinstall:
+zipexampleinstall:
+zipdistinstall:
+clean: fpc_clean
+distclean: fpc_distclean
+cleanall: fpc_cleanall
+info: fpc_info
+makefiles: fpc_makefiles
+.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+ifneq ($(wildcard fpcmake.loc),)
+include fpcmake.loc
+endif
+.NOTPARALLEL:

+ 26 - 0
packages/fcl-web/src/webdata/Makefile.fpc

@@ -0,0 +1,26 @@
+#
+#   Makefile.fpc for FCL Web components
+#
+
+[package]
+main=fcl-web
+version=2.5.1
+
+[target]
+units=fpwebdata sqldbwebdata fpextjs extjsjson extjsxml
+
+[require]
+packages=fcl-base fcl-xml fcl-db fcl-json
+
+[compiler]
+options=-S2h
+
+[install]
+fpcpackage=y
+
+[default]
+fpcdir=../../../..
+
+
+[rules]
+.NOTPARALLEL:

+ 362 - 0
packages/fcl-web/src/webdata/extjsjson.pp

@@ -0,0 +1,362 @@
+unit extjsjson;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, httpdefs, fphttp,fpwebdata, fpextjs, fpjson, db, jsonparser;
+
+type
+
+  { TExtJSJSonWebdataInputAdaptor }
+
+  TExtJSJSonWebdataInputAdaptor = CLass(TCustomWebdataInputAdaptor)
+  private
+    FRows : TJSONArray;
+    FCurrentRow : TJSONObject;
+    FIDValue : TJSONData;
+    FRowIndex : integer;
+    function CheckData: Boolean;
+  Public
+    Function GetNextBatch : Boolean; override;
+    Function TryFieldValue(Const AFieldName : String; out AValue : String) : Boolean; override;
+    Destructor destroy; override;
+  end;
+  { TExtJSJSONDataFormatter }
+
+  TExtJSJSONDataFormatter = Class(TExtJSDataFormatter)
+  private
+    procedure SendSuccess(ResponseContent: TStream; AddIDValue : Boolean = False);
+  protected
+    Function CreateAdaptor(ARequest : TRequest) : TCustomWebdataInputAdaptor; override;
+    Function AddFieldToJSON(O: TJSONObject; AFieldName: String; F: TField): TJSONData;
+    function GetDataContentType: String; override;
+    Function GetJSONMetaData: TJSONObject;
+    function RowToJSON: TJSONObject;
+    procedure DatasetToStream(Stream: TStream); override;
+    Procedure DoExceptionToStream(E : Exception; ResponseContent : TStream); override;
+    Procedure DoInsertRecord(ResponseContent : TStream); override;
+    Procedure DoUpdateRecord(ResponseContent : TStream); override;
+    Procedure DoDeleteRecord(ResponseContent : TStream); override;
+  end;
+
+implementation
+{ $define wmdebug}
+{$ifdef wmdebug}
+uses dbugintf;
+{$endif wmdebug}
+
+Resourcestring
+  SErrWrongDataFormat = 'Post ROWS data has wrong value type. Expected array or object, got : %s.';
+  SerrNoExceptionMessage = 'No exception to take error message from.';
+
+Const
+  // Do not localize these strings
+  SDefMetaDataProperty  = 'metaData';
+  SDefFieldsProperty    = 'fields';
+  SDefFieldProperty     = 'field';
+  SDefFieldNameProperty = 'name';
+  SDefDirectionProperty = 'direction';
+  SDefSortInfoProperty  = 'sortInfo';
+  SDefAscDesc : Array[Boolean] of string = ('ASC','DESC');
+
+function TExtJSJSONDataFormatter.GetDataContentType: String;
+begin
+  Result:='text/html';
+end;
+
+function TExtJSJSONDataFormatter.CreateAdaptor(ARequest: TRequest
+  ): TCustomWebdataInputAdaptor;
+begin
+  Result:=TExtJSJSonWebdataInputAdaptor.Create(Self);
+  Result.Request:=ARequest;
+end;
+
+function TExtJSJSONDataFormatter.AddFieldToJSON(O : TJSONObject; AFieldName : String; F : TField): TJSONData;
+
+begin
+  Case F.DataType of
+    ftSmallint,
+    ftInteger,
+    ftAutoInc,
+    ftWord:
+      Result:=O.Items[O.Add(AFieldName,F.AsInteger)];
+    ftBoolean:
+      Result:=O.Items[O.Add(AFieldName,F.AsBoolean)];
+    ftLargeint:
+      Result:=O.Items[O.Add(AFieldName,F.AsLargeInt)];
+  else
+    Result:=O.Items[O.Add(AFieldName,F.DisplayText)];
+  end;
+end;
+
+function TExtJSJSONDataFormatter.RowToJSON: TJSONObject;
+
+Var
+  F : TField;
+  I : Integer;
+
+
+begin
+  Result:=TJSONObject.Create();
+  For I:=0 to Dataset.Fields.Count-1 do
+    begin
+    F:=Dataset.Fields[I];
+    AddFieldToJSON(Result,F.FieldName,F);
+    end;
+end;
+
+Function TExtJSJSONDataFormatter.GetJSONMetaData: TJSONObject;
+
+Var
+  F : TJSONArray;
+  Fi : TField;
+  I : Integer;
+  O : TJSONObject;
+  SF : String;
+
+begin
+  If (SortField='') then
+    SF:=Dataset.Fields[0].FieldName
+  else
+    SF:=SortField;
+  Result:=TJSonObject.Create;
+  try
+    F:=TJSONArray.Create;
+    Result.add(SDefFieldsProperty,F);
+    For I:=0 to Dataset.Fields.Count-1 do
+      begin
+      Fi:=Dataset.Fields[i];
+      O:=TJSONObject.Create();
+      O.Add(SDefFieldNameProperty,Fi.FieldName);
+      F.Add(O);
+      end;
+    O:=TJSONObject.Create();
+    O.Add(SDefFieldProperty,SF);
+    O.Add(SDefDirectionProperty,SDefAscDesc[SortDescending]);
+    Result.Add(SDefSortInfoProperty,O);
+  except
+    Result.free;
+    Raise;
+  end;
+end;
+
+procedure TExtJSJSONDataFormatter.DatasetToStream(Stream: TStream);
+
+Var
+  Rows : TJSONArray;
+  Meta,Resp : TJSONObject;
+  L : String;
+  DS : TDataset;
+  i,RCount,ACount : Integer;
+
+begin
+  Rows:=Nil;
+  Resp:=TJSONObject.Create;
+  try
+    Rows:=TJSONArray.Create();
+    DS:=Dataset;
+    DS.First;
+    RCount:=0;
+    If MetaData then
+      begin
+      Meta:=GetJSONMetaData;
+      Resp.Add(SDefMetaDataProperty,Meta);
+      end;
+    // Go to start
+    ACount:=PageStart;
+    While (Not DS.EOF) and (ACount>0) do
+      begin
+      DS.Next;
+      Dec(ACount);
+      Inc(RCount);
+      end;
+    ACount:=PageSize;
+    While (not DS.EOF) and ((PageSize=0) or (ACount>0)) do
+      begin
+      Inc(RCount);
+      Dec(ACount);
+      Rows.Add(RowToJSON);
+      DS.Next;
+      end;
+    If (PageSize>0) then
+      While (not DS.EOF) do
+        begin
+        Inc(RCount);
+        DS.Next;
+        end;
+    Resp.Add(RowsProperty,Rows);
+    Resp.Add(SuccessProperty,True);
+    If (PageSize>0) then
+       Resp.Add(TotalProperty,RCount);
+    L:=Resp.AsJSON;
+    Stream.WriteBuffer(L[1],Length(L));
+  finally
+    Resp.Free;
+  end;
+end;
+
+procedure TExtJSJSONDataFormatter.DoExceptionToStream(E: Exception;
+  ResponseContent: TStream);
+
+Var
+   Resp : TJSonObject;
+   L : String;
+
+begin
+  Resp:=tjsonObject.Create();
+  try
+    Resp.Add(SuccessProperty,False);
+    If Assigned(E) then
+      Resp.Add(MessageProperty,E.Message)
+    else
+      Resp.Add(MessageProperty,SerrNoExceptionMessage);
+    L:=Resp.AsJSON;
+    If Length(L)>0 then
+      ResponseContent.WriteBuffer(L[1],Length(L));
+  finally
+    Resp.Free;
+  end;
+end;
+
+procedure TExtJSJSONDataFormatter.SendSuccess(ResponseContent: TStream; AddIDValue : Boolean = False);
+
+Var
+   Resp : TJSonObject;
+   L : String;
+
+begin
+  try
+    Resp:=TJsonObject.Create;
+    Resp.Add(SuccessProperty,True);
+    Resp.Add(Provider.IDFieldName,Provider.IDFieldValue);
+    L:=Resp.AsJSON;
+    ResponseContent.WriteBuffer(L[1],Length(L));
+  finally
+    Resp.Free;
+  end;
+end;
+
+procedure TExtJSJSONDataFormatter.DoInsertRecord(ResponseContent: TStream);
+
+begin
+  Inherited;
+  SendSuccess(ResponseContent,True);
+end;
+
+procedure TExtJSJSONDataFormatter.DoUpdateRecord(ResponseContent: TStream);
+begin
+  inherited DoUpdateRecord(ResponseContent);
+  SendSuccess(ResponseContent,False);
+end;
+
+procedure TExtJSJSONDataFormatter.DoDeleteRecord(ResponseContent: TStream);
+begin
+  inherited DoDeleteRecord(ResponseContent);
+  SendSuccess(ResponseContent,False);
+end;
+
+{ TExtJSJSonWebdataInputAdaptor }
+
+function TExtJSJSonWebdataInputAdaptor.CheckData : Boolean;
+
+Var
+  D : TJSONData;
+  P : TJSONParser;
+  S : String;
+
+begin
+  Result:=Assigned(FCurrentRow);
+  If Not (Result) and TryParamValue('rows',S) then
+    begin
+    {$ifdef wmdebug}senddebug('Check data: '+GetParamValue('rows'));{$endif}
+    P:=TJSONParser.Create(S);
+    try
+      D:=P.Parse;
+      {$ifdef wmdebug}senddebug('Classname : '+D.ClassName);{$endif}
+      If D is TJSONArray then
+        begin
+        FRows:=TJSONArray(D);
+        FRowIndex:=0;
+        FCurrentRow:=FRows.Items[0] as TJSONObject;
+        end
+      else If D is TJSONObject then
+        begin
+        FRows:=Nil;
+        FCurrentRow:=TJSONObject(D);
+        end
+      else if D is TJSONInt64Number then
+        FIDValue:=D
+      else
+        begin
+        FreeAndNil(D);
+        Raise EFPHTTPError.CreateFmt(SErrWrongDataFormat,[D.ClassName]);
+        end;
+      Result:=True;
+    finally
+      P.Free;
+    end;
+    end;
+end;
+
+function TExtJSJSonWebdataInputAdaptor.GetNextBatch: Boolean;
+begin
+  If (FRows=Nil) then
+    Result:=inherited GetNextBatch
+  else
+    begin
+    Result:=FRowindex<FRows.Count-1;
+    Inc(FRowIndex);
+    If Result then
+      FCurrentRow:=FRows.Items[FRowIndex] as TJSONObject
+    else
+      FCurrentRow:=Nil;
+    end;
+end;
+
+function TExtJSJSonWebdataInputAdaptor.TryFieldValue(const AFieldName: String;
+  out AValue: String): Boolean;
+
+Var
+  I : Integer;
+
+begin
+  Result:=False;
+  if CheckData then
+    begin
+    If Assigned(FIDValue) and (0=CompareText(AFieldName,'ID')) then
+      begin
+      AValue:=FIDValue.AsString;
+      Result:=True;
+      end
+    else
+      begin
+      I:=FCurrentRow.IndexOfName(AFieldName);
+      Result:=I<>-1;
+      if result then
+        AValue:=FCurrentRow.Items[I].AsString;
+      end;
+    end;
+end;
+
+destructor TExtJSJSonWebdataInputAdaptor.destroy;
+begin
+  If Assigned(FRows) then
+    FreeAndNil(FRows)
+  else if assigned(FCurrentRow) then
+    FreeAndNil(FCurrentRow)
+  else if Assigned(FIDValue) then
+    FreeAndNil(FIDValue);
+  inherited destroy;
+end;
+
+initialization
+  WebDataProviderManager.RegisterInputAdaptor('ExtJS - JSON',TExtJSJSONWebdataInputAdaptor);
+  WebDataProviderManager.RegisterDataProducer('ExtJS - JSON',TExtJSJSONDataFormatter);
+
+finalization
+  WebDataProviderManager.UnRegisterInputAdaptor('ExtJS - JSON');
+  WebDataProviderManager.UnRegisterDataProducer('ExtJS - JSON')
+end.
+

+ 362 - 0
packages/fcl-web/src/webdata/extjsxml.pp

@@ -0,0 +1,362 @@
+unit extjsxml;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, httpdefs, fpextjs, dom, xmlread, xmlwrite, fpwebdata, db;
+
+Type
+
+  { TExtJSXMLWebdataInputAdaptor }
+
+  TExtJSXMLWebdataInputAdaptor = CLass(TCustomWebdataInputAdaptor)
+  private
+    FDE: String;
+    FRE: String;
+    FREEL: String;
+    FXML : TXMLDocument;
+    FDocRoot : TDOMElement;
+    FRoot : TDOMElement;
+    FCurrentRow : TDOMElement;
+    FIDValue : TDOMElement;
+    function isDocumentStored: boolean;
+    function IsRecordStored: boolean;
+    function isRootStored: boolean;
+    function CheckData: Boolean;
+  protected
+  Public
+    Constructor Create(AOwner : TComponent); override;
+    Destructor destroy; override;
+    Function TryFieldValue(Const AFieldName : String; out AValue : String) : Boolean; override;
+    Property DocumentElement : String Read FDE Write FDE stored isDocumentStored;
+    Property RootElement : String Read FRE Write FRE stored isRootStored;
+    Property RecordElement : String Read FREEL Write FREEL stored IsRecordStored;
+  end;
+  { TExtJSJSONDataFormatter }
+
+  { TExtJSXMLDataFormatter }
+
+  TExtJSXMLDataFormatter = Class(TExtJSDataFormatter)
+  private
+    FDP: String;
+    FReP: String;
+    FRP: String;
+    function IsDocumentStored: boolean;
+    function IsRecordStored: boolean;
+    function IsRootStored: boolean;
+  protected
+    Function CreateAdaptor(ARequest : TRequest) : TCustomWebdataInputAdaptor; override;
+    Procedure DoExceptionToStream(E : Exception; ResponseContent : TStream); override;
+    Function GetDataContentType : String; override;
+    function RowToXML(Doc: TXMLDocument): TDOMelement;
+    procedure DatasetToStream(Stream: TStream); override;
+  public
+    Constructor Create(AOwner : TComponent); override;
+  published
+    Property RootProperty : String Read FRP Write FRP Stored IsRootStored;
+    Property RecordProperty : String Read FReP Write FReP Stored IsRecordStored;
+    Property DocumentProperty : String Read FDP Write FDP Stored IsDocumentStored;
+  end;
+
+implementation
+{ $define wmdebug}
+{$ifdef wmdebug}
+uses dbugintf;
+{$endif wmdebug}
+
+Resourcestring
+  SerrNoExceptionMessage = 'No exception to take error message from.';
+
+Const
+  // For TExtJSXMLDataFormatter.
+  SDefDocumentProperty = 'xrequest';
+  SDefRecordProperty   = 'row';
+  SDefRootProperty     = 'dataset';
+
+  // Fpr TExtJSXMLWebdataInputAdaptor
+  SDefRootElement     = SDefRootProperty;
+  SDefRecordElement   = SDefRecordProperty;
+  SDefDocumentElement = SDefDocumentProperty;
+
+function TExtJSXMLDataFormatter.IsRootStored: boolean;
+begin
+  Result:=RootProperty<>SDefRootProperty;
+end;
+
+function TExtJSXMLDataFormatter.CreateAdaptor(ARequest: TRequest
+  ): TCustomWebdataInputAdaptor;
+
+Var
+  R : TExtJSXMLWebdataInputAdaptor;
+
+begin
+  R:=TExtJSXMLWebdataInputAdaptor.Create(Self);
+  R.Request:=ARequest;
+  R.DocumentElement:=Self.DocumentProperty;
+  R.RootElement:=Self.RootProperty;
+  R.RecordElement:=Self.RecordProperty;
+  Result:=R;
+end;
+
+function TExtJSXMLDataFormatter.IsRecordStored: boolean;
+begin
+  Result:=RecordProperty<>SDefRecordProperty;
+end;
+
+function TExtJSXMLDataFormatter.IsDocumentStored: boolean;
+begin
+  Result:=DocumentProperty<>SDefDocumentProperty
+end;
+
+procedure TExtJSXMLDataFormatter.DoExceptionToStream(E: Exception;
+  ResponseContent: TStream);
+
+Var
+  Xml : TXMLDocument;
+  El,C : TDOMElement;
+
+begin
+  XML:=TXMLDocument.Create;
+  try
+    El:=XML.CreateElement(RootProperty);
+    XML.AppendChild(El);
+    El[SuccessProperty]:='false';
+    C:=XML.CreateElement(SuccessProperty);
+    C.AppendChild(XML.CreateTextNode('false'));
+    El.AppendChild(c);
+    C:=XML.CreateElement(MessageProperty);
+    El.AppendChild(C);
+    If Assigned(E) then
+      C.AppendChild(XML.CreateTextNode(E.Message))
+    else
+      C.AppendChild(XML.CreateTextNode(SerrNoExceptionMessage));
+    WriteXMLFile(XML,ResponseContent);
+  Finally
+    XML.Free;
+  end;
+end;
+
+function TExtJSXMLDataFormatter.GetDataContentType: String;
+begin
+  Result:='text/xml';
+end;
+
+Function TExtJSXMLDataFormatter.RowToXML(Doc : TXMLDocument) : TDOMelement;
+
+Var
+  E : TDOMElement;
+  F : TField;
+  I : Integer;
+begin
+  Result:=Doc.CreateElement(RecordProperty);
+  For I:=0 to Dataset.Fields.Count-1 do
+    begin
+    F:=Dataset.Fields[i];
+    E:=Doc.CreateElement(F.FieldName);
+    E.AppendChild(Doc.CreateTextNode(F.DisplayText));
+    Result.AppendChild(E);
+    end;
+end;
+
+procedure TExtJSXMLDataFormatter.DatasetToStream(Stream: TStream);
+
+Var
+  Xml : TXMLDocument;
+  E,C : TDOMElement;
+  i,RCount,ACount : Integer;
+  DS : TDataset;
+
+begin
+  RCount:=0;
+  ACount:=0;
+  DS:=Dataset;
+   XML:=TXMLDocument.Create;
+   try
+     E:=XML.CreateElement(RootProperty);
+     XML.AppendChild(E);
+     // Go to start
+     ACount:=PageStart;
+     While (Not DS.EOF) and (ACount>0) do
+       begin
+       DS.Next;
+       Dec(ACount);
+       Inc(RCount);
+       end;
+     ACount:=PageSize;
+     While (not DS.EOF) and ((PageSize=0) or (ACount>0)) do
+       begin
+       Inc(RCount);
+       Dec(ACount);
+       E.AppendChild(RowToXML(XML));
+       DS.Next;
+       end;
+     If (PageSize>0) then
+       While (not DS.EOF) do
+         begin
+         Inc(RCount);
+         DS.Next;
+         end;
+     C:=XML.CreateElement(TotalProperty);
+     C.AppendChild(XML.CreateTextNode(IntToStr(RCount)));
+     E.AppendChild(C);
+     C:=XML.CreateElement(SuccessProperty);
+     C.AppendChild(XML.CreateTextNode('true'));
+     E.AppendChild(C);
+     WriteXMLFile(XML,Stream);
+
+   finally
+     XML.Free;
+   end;
+end;
+
+constructor TExtJSXMLDataFormatter.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  RootProperty:=SDefRootProperty;
+  RecordProperty:=SDefRecordProperty;
+  DocumentProperty:=SDefDocumentProperty
+end;
+
+{ TExtJSXMLWebdataInputAdaptor }
+
+
+function TExtJSXMLWebdataInputAdaptor.isDocumentStored: boolean;
+begin
+  Result:=DocumentElement<>SDefDocumentElement;
+end;
+
+function TExtJSXMLWebdataInputAdaptor.IsRecordStored: boolean;
+begin
+  Result:=RecordElement<>SDefRecordElement;
+end;
+
+function TExtJSXMLWebdataInputAdaptor.isRootStored: boolean;
+begin
+  Result:=RootElement<>SDefRootElement;
+end;
+
+function TExtJSXMLWebdataInputAdaptor.CheckData: Boolean;
+
+Var
+  S : String;
+  T : TStringSTream;
+  E : TDomElement;
+  P : Integer;
+
+begin
+  {$ifdef wmdebug}senddebug('Check data: '+Request.Content);{$endif}
+  Result:=Assigned(FXML);
+  If Not (Result)  then
+    begin
+    S:=Request.ContentType;
+    P:=Pos(';',S);
+    If (P<>0) then
+      S:=Copy(S,1,P-1);
+   {$ifdef wmdebug}senddebug('Check data: '+S);{$endif}
+    Result:=CompareText(S,'application/x-www-form-urlencoded')=0;
+    If not Result then
+      begin
+      T:=TStringStream.Create(Request.Content);
+      try
+        XmlRead.ReadXMLFile(FXML,T);
+        If (DocumentElement<>'') and (FXML.DocumentElement.NodeName=DocumentElement) then
+          begin
+          {$ifdef wmdebug}senddebug('Document element is ExtJS DocumentElement');{$endif}
+          FDocRoot:=FXML.DocumentElement;
+          E:=FDocRoot;
+          end
+        else if (DocumentElement<>'') then
+          begin
+          //FXML.
+          {$ifdef wmdebug}senddebug('Looking for ExtJS Documentelement "'+DocumentElement+'" in XML.DocumentElement');{$endif}
+          FDocRoot:=FXML.DocumentElement.FindNode(DocumentElement) as TDOMElement;
+          E:=FDocRoot;
+          end;
+        {$ifdef wmdebug}senddebug('Looking for DocRoot element "'+RootElement+'" in FDocRoot');{$endif}
+        If Assigned(FDocRoot) then
+          FRoot:=FDocRoot
+        else
+          FRoot:=FXML.FindNode(RootElement) as TDomElement;
+        {$ifdef wmdebug}senddebug('Looking for current record element "'+RecordElement+'" in FRoot');{$endif}
+        If Assigned(FRoot) then
+          begin
+          FCurrentRow:=FRoot.FindNode(RecordElement) as TDomElement;
+          If Not Assigned(FCurrentRow) then
+            FIDValue:=FRoot.FindNode('ID') as TDomElement;
+          end
+        else
+          begin
+          {$ifdef wmdebug}senddebug('Looking for current record element "'+RecordElement+'" in document');{$endif}
+          FCurrentRow:=FXML.FindNode(RecordElement) as TDomElement;
+          end;
+        If (FCurrentRow=Nil) and (FXML.DocumentElement.NodeName=RecordElement) then
+          begin
+          {$ifdef wmdebug}senddebug('Documentelement is  record element "'+RecordElement+'"');{$endif}
+          FCurrentRow:=FXML.DocumentElement;
+          end;
+        {$ifdef wmdebug}senddebug('Have current row: "'+IntToStr(Ord(Assigned(FCurrentRow)))+'"');{$endif}
+        Result:=True;
+      finally
+        T.free;
+      end;
+      end;
+    end;
+
+end;
+
+function TExtJSXMLWebdataInputAdaptor.TryFieldValue(const AFieldName: String;
+  out AValue: String): Boolean;
+
+Var
+  I : Integer;
+  E : TDOMElement;
+  N : TDOMNode;
+
+begin
+  Result:=False;
+  if CheckData then
+    begin
+    If Assigned(FIDValue) and (0=CompareText(AFieldName,'ID')) then
+      begin
+      AValue:=FIDValue.NodeValue;
+      Result:=True;
+      end
+    else if Assigned(FCurrentRow) then
+      begin
+      E:=FCurrentRow.FindNode(AFieldName) as TDomElement;
+      Result:=Assigned(E);
+      if result then
+        begin
+        N:=E.FirstChild;
+        If Assigned(N) then
+          AValue:=N.NodeValue;
+        end;
+      end;
+    end;
+end;
+
+constructor TExtJSXMLWebdataInputAdaptor.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  RootElement:=SDefRootElement;
+  RecordElement:=SDefRecordElement;
+  DocumentElement:=SDefDocumentElement;
+end;
+
+destructor TExtJSXMLWebdataInputAdaptor.destroy;
+begin
+  FreeAndNil(FXML);
+  inherited destroy;
+end;
+
+initialization
+  WebDataProviderManager.RegisterInputAdaptor('ExtJS - XML',TExtJSXMLWebdataInputAdaptor);
+  WebDataProviderManager.RegisterDataProducer('ExtJS - XML',TExtJSXMLDataFormatter);
+
+finalization
+  WebDataProviderManager.UnRegisterInputAdaptor('ExtJS - XML');
+  WebDataProviderManager.UnRegisterDataProducer('ExtJS - XML')
+end.
+

+ 143 - 0
packages/fcl-web/src/webdata/fpextjs.pp

@@ -0,0 +1,143 @@
+unit fpextjs;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fphttp, db, httpdefs, fpwebdata;
+
+Type
+
+
+  { TExtJSDataFormatter }
+
+  TExtJSDataFormatter = Class(TCustomHTTPDataContentProducer)
+  private
+    FMP: String;
+    FPLP: String;
+    FPSP: String;
+    FRP: String;
+    FSP: String;
+    FTP: String;
+    function IsMessageStored: boolean;
+    function IsPageLimitStored: boolean;
+    function IsPageStartStored: boolean;
+    function IsRowsStored: boolean;
+    Function IsSuccessStored : Boolean;
+    function IsTotalStored: boolean;
+  Public
+    Constructor Create(AOwner : TComponent); override;
+    Procedure DoReadRecords(Stream : TStream); override;
+    Function ProduceContent : String; override;
+    Property SuccessProperty : String Read FSP Write FSP stored IsSuccessStored;
+    Property PageStartProperty : String Read FPSP Write FPSP stored IsPageStartStored;
+    Property PageLimitProperty : String Read FPLP Write FPLP stored IsPageLimitStored;
+    Property RowsProperty : String Read FRP Write FRP stored IsRowsStored;
+    Property MessageProperty : String Read FMP Write FMP stored IsMessageStored;
+    Property TotalProperty : String Read FTP Write FTP stored IsTotalStored;
+  end;
+
+Const
+  // Do not localize these constants.
+  DefRowsProperty      = 'rows';
+  DefPageLimitProperty = 'limit';
+  DefPageStartProperty = 'start';
+  DefSuccessProperty   = 'success';
+  DefMessageProperty   = 'message';
+  DefTotalProperty     = 'total';
+
+implementation
+
+Resourcestring
+  SErrNoAdaptor = 'No adaptor available';
+
+{ TExtJSDataFormatter }
+
+function TExtJSDataFormatter.IsSuccessStored: Boolean;
+begin
+  Result:=(SuccessProperty<>DefSuccessProperty);
+end;
+
+function TExtJSDataFormatter.IsTotalStored: boolean;
+begin
+  Result:=(TotalProperty<>DefTotalProperty);
+end;
+
+function TExtJSDataFormatter.IsMessageStored: boolean;
+begin
+  Result:=(MessageProperty<>DefMessageProperty);
+end;
+
+function TExtJSDataFormatter.IsPageLimitStored: boolean;
+begin
+  Result:=(PageLimitProperty<>DefPageLimitProperty);
+end;
+
+function TExtJSDataFormatter.IsPageStartStored: boolean;
+begin
+  Result:=(PageStartProperty<>DefPageStartProperty);
+end;
+
+function TExtJSDataFormatter.IsRowsStored: boolean;
+begin
+  Result:=(RowsProperty<>DefRowsProperty);
+end;
+
+constructor TExtJSDataFormatter.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  RowsProperty:=DefRowsProperty;
+  PageLimitProperty:=DefPageLimitProperty;
+  PageStartProperty:=DefPageStartProperty;
+  SuccessProperty:=DefSuccessProperty;
+  MessageProperty:=DefMessageProperty;
+  TotalProperty:=DefTotalProperty;
+end;
+
+procedure TExtJSDataFormatter.DoReadRecords(Stream: TStream);
+
+Var
+  I : Integer;
+  L : TStrings;
+  S : String;
+begin
+
+  If AllowPageSize then
+    begin
+    If Not Assigned(Adaptor) then
+      Raise EFPHTTPError.Create(SErrNoAdaptor);
+    if Adaptor.TryFieldValue(PageStartProperty,S) then
+      begin
+      I:=StrToIntDef(S,-1);
+      If I<>-1 then
+        PageStart:=I;
+      end;
+    if Adaptor.TryFieldValue(PageLimitProperty,S) then
+      begin
+      I:=StrToIntDef(S,-1);
+      If I<>-1 then
+        PageSize:=I;
+      end;
+    end;
+  Inherited DoReadRecords(Stream);
+end;
+
+function TExtJSDataFormatter.ProduceContent: String;
+
+Var
+  S : TStringStream;
+
+begin
+  S:=TStringStream.Create('');
+  try
+    ContentToStream(S);
+    Result:=S.DataString;
+  finally
+    FreeAndNil(S);
+  end;
+end;
+
+
+end.
+

+ 1887 - 0
packages/fcl-web/src/webdata/fpwebdata.pp

@@ -0,0 +1,1887 @@
+unit fpwebdata;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, httpdefs, fphttp, db, websession;
+
+
+type
+  { TWebdataInputAdaptor }
+
+  // Translate web request to input for the dataprovider.
+  // Descendents must adapt the methods so they fit the particular JS/HTML engine used.
+
+  TWebDataAction = (wdaUnknown,wdaRead,wdaUpdate,wdaInsert,wdaDelete);
+  TCustomWebdataInputAdaptor = class(TComponent)
+  private
+    FAction: TWebDataAction;
+    FRequest: TRequest;
+    FBatchCount : Integer;
+    FRequestPathInfo : String;
+    function GetAction: TWebDataAction;
+    procedure SetRequest(const AValue: TRequest);
+  Protected
+    Function GetActionFromRequest : TWebDataAction; virtual;
+  Public
+    Function GetNextBatch : Boolean; virtual;
+    Function TryParamValue(Const AParamName : String; out AValue : String) : Boolean; virtual;
+    Function TryFieldValue(Const AFieldName : String; out AValue : String) : Boolean; virtual;
+    Function HaveParamValue(Const AParamName : String) : boolean;
+    Function HaveFieldValue(Const AFieldName : String) : boolean;
+    Function GetParamValue(Const AParamName : String) : String;
+    Function GetFieldValue(Const AFieldName : String) : String;
+    Property Request : TRequest Read FRequest Write SetRequest;
+    Property Action : TWebDataAction Read GetAction Write FAction;
+  end;
+  TCustomWebdataInputAdaptorClass = Class of TCustomWebdataInputAdaptor;
+
+  TWebdataInputAdaptor = Class(TCustomWebdataInputAdaptor)
+  Private
+    FInputFormat: String;
+    FProxy : TCustomWebdataInputAdaptor;
+    procedure SetInputFormat(const AValue: String);
+  Protected
+    Procedure ClearProxy;
+    Procedure CheckProxy;
+    Function CreateProxy : TCustomWebdataInputAdaptor; virtual;
+    Function GetActionFromRequest : TWebDataAction; override;
+  Public
+    Destructor Destroy; override;
+    Function GetNextBatch : Boolean; override;
+    Function TryParamValue(Const AParamName : String; out AValue : String) : Boolean; override;
+    Function TryFieldValue(Const AFieldName : String; out AValue : String) : Boolean; override;
+  Published
+    Property InputFormat : String Read FInputFormat Write SetInputFormat;
+  end;
+
+  // Manage the data for the content producer
+  // return a dataset for data, handles update/delete/insert in a simple TDataset manner.
+
+  { TFPCustomWebDataProvider }
+  TWebDataProviderOption = (wdpReadOnly,wdpDisableDelete,wdpDisableEdit,wdpDisableInsert);
+  TWebDataProviderOptions = set of TWebDataProviderOption;
+
+  TFPCustomWebDataProvider = Class(TComponent)
+  private
+    FAdaptor: TCustomWebdataInputAdaptor;
+    FIDFieldName: String;
+    FOptions: TWebDataProviderOptions;
+  Protected
+    // Check if adaptor and dataset are available.
+    procedure CheckAdaptor;
+    // Copy data from input to fields in dataset. Can be overridden
+    Procedure CopyFieldData; virtual;
+    Procedure DoUpdate; virtual;
+    Procedure DoDelete; virtual;
+    Procedure DoInsert; virtual;
+    // Locate current record. Assumes that
+    Procedure LocateCurrent; virtual;
+    Procedure DoApplyParams; virtual;
+    Function GetDataset : TDataset; virtual; abstract;
+  Public
+    // Perform an update on the dataset. Correct record is located first.
+    Procedure Update;
+    // Perform a delete on the dataset. Correct record is located first.
+    Procedure Delete;
+    // Perform an insert on the dataset.
+    Procedure Insert;
+    // Apply any parameters passed from request to the dataset. Used only in read operations
+    Procedure ApplyParams;
+    // get ID Field instance from dataset
+    function GetIDField: TField;
+    // Get value of ID field as string. After insert, this should contain the newly inserted ID.
+    Function IDFieldValue : String; virtual;
+    // The dataset
+    Property Dataset : TDataset Read GetDataset;
+    // Input adaptor
+    property Adaptor : TCustomWebdataInputAdaptor Read FAdaptor Write FAdaptor;
+    // Fieldname of ID field. If empty, field with pfInKey is searched.
+    Property IDFieldName : String Read FIDFieldName Write FIDFieldName;
+    // options
+    Property Options : TWebDataProviderOptions Read FOptions Write FOptions;
+  end;
+  TFPCustomWebDataProviderClass = Class of TFPCustomWebDataProvider;
+
+  { TFPWebDataProvider }
+  // Simple descendent that has a datasource property, can be dropped on a module.
+  TFPWebDataProvider = Class(TFPCustomWebDataProvider)
+  private
+    FDatasource: TDatasource;
+    procedure SetDataSource(const AValue: TDatasource);
+  Protected
+    Function GetDataset : TDataset; override;
+  Public
+    procedure Notification(AComponent: TComponent; Operation: TOperation);override;
+  Published
+    Property DataSource : TDatasource Read FDatasource Write SetDataSource;
+  end;
+
+  // Handle request for read/create/update/delete and return a result.
+
+  { TCustomHTTPDataContentProducer }
+
+  TCustomHTTPDataContentProducer = Class(THTTPContentProducer)
+  Private
+    FAllowPageSize: Boolean;
+    FDataProvider: TFPCustomWebDataProvider;
+    FMetadata: Boolean;
+    FPageSize: Integer;
+    FPageStart: Integer;
+    FSD: Boolean;
+    FSortField: String;
+    FAdaptor : TCustomWebdataInputAdaptor;
+    function GetDataset: TDataset;
+    procedure SetAdaptor(const AValue: TCustomWebDataInputAdaptor);
+    procedure SetDataProvider(const AValue: TFPCustomWebDataProvider);
+  Protected
+    Function GetDataContentType : String; virtual;
+    procedure DatasetToStream(Stream: TStream); virtual;abstract;
+    Function CreateAdaptor(ARequest : TRequest) : TCustomWebdataInputAdaptor; virtual;
+    Procedure DoGetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean); override;
+    Procedure DoHandleRequest(ARequest : TRequest; AResponse : TResponse; Var Handled : Boolean); override;
+    Procedure DoUpdateRecord(ResponseContent : TStream); virtual;
+    Procedure DoInsertRecord(ResponseContent : TStream); virtual;
+    Procedure DoDeleteRecord(ResponseContent : TStream); virtual;
+    Procedure DoReadRecords(ResponseContent : TStream); virtual;
+    Procedure DoExceptionToStream(E : Exception; ResponseContent : TStream); virtual; abstract;
+    procedure Notification(AComponent: TComponent; Operation: TOperation);override;
+    Property Dataset: TDataset Read GetDataSet;
+  Public
+    Constructor Create(AOwner : TComponent); override;
+    Property Adaptor : TCustomWebDataInputAdaptor Read FAdaptor Write SetAdaptor;
+    Property Provider : TFPCustomWebDataProvider read FDataProvider write SetDataProvider;
+    Property DataContentType : String Read GetDataContentType;
+  Published
+    Property PageStart : Integer Read FPageStart Write FPageStart default 0;
+    Property PageSize : Integer Read FPageSize Write FPageSize default 0;
+    Property MetaData : Boolean Read FMetadata Write FMetaData Default False;
+    Property SortField : String Read FSortField Write FSortField;
+    Property SortDescending : Boolean Read FSD Write FSD default False;
+    Property AllowPageSize : Boolean Read FAllowPageSize Write FAllowPageSize default True;
+  end;
+  TCustomHTTPDataContentProducerClass = Class of TCustomHTTPDataContentProducer;
+
+  { THTTPDataContentProducer }
+
+  THTTPDataContentProducer = Class(TCustomHTTPDataContentProducer)
+  private
+    FOnConfigure: TNotifyEvent;
+    FProxy : TCustomHTTPDataContentProducer;
+    FOutputFormat: String;
+    procedure SetOutputFormat(const AValue: String);
+  Protected
+    Procedure ClearProxy;
+    Procedure CheckProxy;
+    Function CreateProxy : TCustomHTTPDataContentProducer; virtual;
+    procedure ConfigureProxy(AProxy: TCustomHTTPDataContentProducer); virtual;
+  Public
+    Destructor destroy; override;
+  Published
+    Property Adaptor;
+    Property Provider;
+    Property OutputFormat : String Read FOutputFormat Write SetOutputFormat;
+    Property OnConfigureFormat : TNotifyEvent Read FOnConfigure Write FOnConfigure;
+  end;
+  TBeforeCreateWebDataProviderEvent = Procedure (Sender : TObject; Var AClass : TFPCustomWebDataProviderClass) of object;
+  TWebDataProviderEvent = Procedure (Sender : TObject; AProvider : TFPCustomWebDataProvider) of object;
+  //TWebDataCreateProviderEvent = Procedure (Sender : TObject; Const AProviderName : String; Out AnInstance : TFPCustomWebDataProvider) of object;
+  TDataModuleClass = Class of TDataModule;
+
+  { TWebInputAdaptorDef }
+
+  TWebInputAdaptorDef = Class(TCollectionItem)
+  private
+    FClass: TCustomWebdataInputAdaptorClass;
+    FName: String;
+    procedure SetName(const AValue: String);
+  protected
+    Function CreateInstance(AOwner : TComponent) :TCustomWebdataInputAdaptor; virtual;
+  Public
+    Property AdaptorClass : TCustomWebdataInputAdaptorClass Read FClass Write FClass;
+    Property Name : String Read FName Write SetName;
+  end;
+
+  { TWebInputAdaptorDefs }
+
+  TWebInputAdaptorDefs = Class(TCollection)
+  private
+    function GetD(Index : Integer): TWebInputAdaptorDef;
+    procedure SetD(Index : Integer; const AValue: TWebInputAdaptorDef);
+  Public
+    Function IndexOfAdaptor(Const AAdaptorName : String) : Integer;
+    Function AddAdaptor(Const AAdaptorName : String; AClass : TCustomWebdataInputAdaptorClass) : TWebInputAdaptorDef;
+    Property AdaptorDefs[Index : Integer] : TWebInputAdaptorDef Read GetD Write SetD; default;
+  end;
+
+  { THttpDataProducerDef }
+
+  THttpDataProducerDef = Class(TCollectionItem)
+  private
+    FClass: TCustomHTTPDataContentProducerClass;
+    FName: String;
+    procedure SetName(const AValue: String);
+  protected
+    Function CreateInstance(AOwner : TComponent) :TCustomHTTPDataContentProducer; virtual;
+  Public
+    Property ProducerClass : TCustomHTTPDataContentProducerClass Read FClass Write FClass;
+    Property Name : String Read FName Write SetName;
+  end;
+
+  { THttpDataProducerDefs }
+
+  THttpDataProducerDefs = Class(TCollection)
+  private
+    function GetD(Index : Integer): THttpDataProducerDef;
+    procedure SetD(Index : Integer; const AValue: THttpDataProducerDef);
+  Public
+    Function IndexOfProducer(Const AProducerName : String) : Integer;
+    Function AddProducer(Const AProducerName : String; AClass : TCustomHTTPDataContentProducerClass) : THttpDataProducerDef;
+    Property ProducerDefs[Index : Integer] : THttpDataProducerDef Read GetD Write SetD; default;
+  end;
+
+
+   { TWebDataProviderDef }
+
+
+  TWebDataProviderDef = Class(TCollectionItem)
+  private
+    FAfterCreate: TWebDataProviderEvent;
+    FBeforeCreate: TBeforeCreateWebDataProviderEvent;
+    FPClass: TFPCustomWebDataProviderClass;
+    FDataModuleClass : TDataModuleClass;
+    FProviderName: String;
+    procedure SetFPClass(const AValue: TFPCustomWebDataProviderClass);
+    procedure SetProviderName(const AValue: String);
+  protected
+    Function CreateInstance(AOwner : TComponent; Out AContainer : TComponent) : TFPCUstomWebDataProvider; virtual;
+    Property DataModuleClass : TDataModuleClass Read FDataModuleClass;
+  Public
+    Property ProviderName : String Read FProviderName Write SetProviderName;
+    Property ProviderClass : TFPCustomWebDataProviderClass Read FPClass Write SetFPClass;
+    Property BeforeCreate : TBeforeCreateWebDataProviderEvent Read FBeforeCreate Write FBeforeCreate;
+    Property AfterCreate : TWebDataProviderEvent Read FAfterCreate Write FAfterCreate;
+  end;
+
+  { TWebDataProviderDefs }
+
+  TWebDataProviderDefs = Class(TCollection)
+  private
+    function GetD(Index : Integer): TWebDataProviderDef;
+    procedure SetD(Index : Integer; const AValue: TWebDataProviderDef);
+  Public
+    Function IndexOfProvider(Const AProviderName : String) : Integer;
+    Function AddProvider(Const AProviderName : String) : TWebDataProviderDef; overload;
+    Function AddProvider(Const AProviderName : String; AClass :TFPCustomWebDataProviderClass) : TWebDataProviderDef; overload;
+    Property WebDataProviderDefs[Index : Integer] : TWebDataProviderDef Read GetD Write SetD; default;
+  end;
+
+  { TFPCustomWebDataProviderManager }
+
+  TFPCustomWebDataProviderManager = Class(TComponent)
+  Private
+    FRegistering: Boolean;
+  Protected
+    procedure Initialize; virtual;
+    // Provider support
+    Procedure RemoveProviderDef(Const Index : Integer); virtual; abstract;
+    function AddProviderDef(Const AProviderName : String) : TWebDataProviderDef; virtual; abstract;
+    function IndexOfProviderDef(Const AProviderName : String) : Integer; virtual; abstract;
+    function GetProviderDef(Index : Integer): TWebDataProviderDef; virtual; abstract;
+    function GetProviderDefCount: Integer; virtual; abstract;
+    // Inputadaptor support
+    function AddInputAdaptorDef(Const AAdaptorName : String; AClass : TCustomWebdataInputAdaptorClass) : TWebInputAdaptorDef; virtual; abstract;
+    function IndexOfInputAdaptorDef(Const AAdaptorName : String) : Integer; virtual; abstract;
+    Procedure RemoveInputAdaptorDef(Index : Integer); virtual; abstract;
+    function GetInputAdaptorDef(Index : Integer): TWebInputAdaptorDef; virtual; abstract;
+    function GetInputAdaptorDefCount: Integer; virtual; abstract;
+    // Outputproducer support
+    function AddHttpDataProducerDef(Const AProducerName : String; AClass : TCustomHTTPDataContentProducerClass) : THttpDataProducerDef; virtual; abstract;
+    function IndexOfHttpDataProducerDef(Const AProducerName : String) : Integer; virtual; abstract;
+    Procedure RemoveHttpDataProducerDef(Index : Integer); virtual; abstract;
+    function GetHttpDataProducerDef(Index : Integer): THttpDataProducerDef; virtual; abstract;
+    function GetHttpDataProducerDefCount: Integer; virtual; abstract;
+  Public
+    // Input Provider support
+    Procedure Unregisterprovider(Const AProviderName : String);
+    Procedure RegisterDatamodule(Const AClass : TDatamoduleClass);
+    Function RegisterProvider(Const AProviderName : String; AClass : TFPCustomWebDataProviderClass) : TWebDataProviderDef; overload;
+    Function FindProviderDefByName(Const AProviderName : String) : TWebDataProviderDef;
+    Function GetProviderDefByName(Const AProviderName : String) : TWebDataProviderDef;
+    Function GetProvider(Const ADef : TWebDataProviderDef; AOwner : TComponent; Out AContainer : TComponent): TFPCustomWebDataProvider;
+    Function GetProvider(Const AProviderName : String; AOwner : TComponent; Out AContainer : TComponent): TFPCustomWebDataProvider;
+    // Input Adaptor support
+    Function RegisterInputAdaptor(Const AAdaptorName : String; AClass : TCustomWebdataInputAdaptorClass) : TWebInputAdaptorDef;
+    Procedure UnRegisterInputAdaptor(Const AAdaptorName : String);
+    Function FindInputAdaptorDefByName(Const AAdaptorName : String) : TWebInputAdaptorDef;
+    Function GetInputAdaptorDefByName(Const AAdaptorName : String) : TWebInputAdaptorDef;
+    Function GetInputAdaptor(Const ADef : TWebInputAdaptorDef; AOwner : TComponent = Nil): TCustomWebdataInputAdaptor; overload;
+    Function GetInputAdaptor(Const AAdaptorName : String; AOwner : TComponent = Nil): TCustomWebdataInputAdaptor; overload;
+    // Outputproducer support
+    function RegisterDataProducer(Const AProducerName : String; AClass : TCustomHTTPDataContentProducerClass) : THttpDataProducerDef;
+    Procedure UnRegisterDataProducer(Const AProducerName : String);
+    function FindDataProducerDefByName(Const AProducerName : String) : THttpDataProducerDef;
+    function GetDataProducerDefByName(Const AProducerName : String) : THttpDataProducerDef;
+    function GetDataProducer(ADef : THttpDataProducerDef; AOwner : TComponent) : TCustomHTTPDataContentProducer;
+    function GetDataProducer(Const AProducerName: String; AOwner : TComponent) : TCustomHTTPDataContentProducer;
+    // properties
+    Property Registering : Boolean Read FRegistering;
+    Property ProviderCount : Integer Read GetProviderDefCount;
+    Property ProviderDefs[Index : Integer] : TWebDataProviderDef Read GetProviderDef;
+    Property InputAdaptorDefs[Index : Integer] : TWebInputAdaptorDef Read GetInputAdaptorDef;
+    Property InputAdaptorDefCount : Integer Read GetInputAdaptorDefCount;
+    Property DataProducerDefs[Index : Integer] : THttpDataProducerDef Read GetHttpDataProducerDef;
+    Property DataProducerDefCount : Integer Read GetHttpDataProducerDefCount;
+  end;
+  TFPCustomWebDataProviderManagerClass = Class of TFPCustomWebDataProviderManager;
+
+  { TFPWebDataProviderManager }
+
+  TFPWebDataProviderManager = Class(TFPCustomWebDataProviderManager)
+  Private
+    FProviderDefs : TWebDataProviderDefs;
+    FAdaptorDefs : TWebInputAdaptorDefs;
+    FProducerDefs : THttpDataProducerDefs;
+  Protected
+    Procedure RemoveProviderDef(Const Index : Integer); override;
+    function AddProviderDef(Const AProviderName : String) : TWebDataProviderDef; override;
+    function IndexOfProviderDef(Const AProviderName : String) : Integer; override;
+    function GetProviderDef(Index : Integer): TWebDataProviderDef; override;
+    function GetProviderDefCount: Integer; override;
+    // Inputadaptor support
+    function AddInputAdaptorDef(Const AAdaptorName : String; AClass : TCustomWebdataInputAdaptorClass) : TWebInputAdaptorDef; Override;
+    function IndexOfInputAdaptorDef(Const AAdaptorName : String) : Integer; Override;
+    procedure RemoveInputAdaptorDef(Index : Integer); Override;
+    function GetInputAdaptorDef(Index : Integer): TWebInputAdaptorDef; Override;
+    function GetInputAdaptorDefCount: Integer; Override;
+    // Outputproducer support
+    function AddHttpDataProducerDef(Const AProducerName : String; AClass : TCustomHTTPDataContentProducerClass) : THttpDataProducerDef; Override;
+    function IndexOfHttpDataProducerDef(Const AProducerName : String) : Integer; Override;
+    Procedure RemoveHttpDataProducerDef(Index : Integer); Override;
+    function GetHttpDataProducerDef(Index : Integer): THttpDataProducerDef; Override;
+    function GetHttpDataProducerDefCount: Integer; Override;
+  Public
+    Constructor Create(AOwner : TComponent); override;
+    Destructor Destroy; override;
+  end;
+
+  THandleWebDataEvent = Procedure (Sender : TObject;AProvider : TFPCustomWebDataProvider; Var Handled : Boolean) of object;
+  TWebDataEvent = Procedure (Sender : TObject; AProvider : TFPCustomWebDataProvider) of object;
+  TContentProducerEvent = Procedure (Sender : TObject; Var AContentProducer: TCustomHTTPDataContentProducer) of object;
+  TInputAdaptorEvent = Procedure (Sender : TObject; Var AInputAdaptor : TCustomWebdataInputAdaptor) of object;
+  TContentEvent = Procedure (Sender : TObject; Content : TStream) of Object;
+  TGetWebDataProviderEvent = Procedure (Sender : TObject; Const AProviderName : String; Var AnInstance : TFPCustomWebDataProvider) of object;
+
+  { TFPCustomWebDataModule }
+
+  { TFPCustomWebProviderDataModule }
+
+  TFPCustomWebProviderDataModule = Class(TSessionHTTPModule)
+  Private
+    FAfterDelete: TWebDataEvent;
+    FAfterInsert: TWebDataEvent;
+    FAfterRead: TWebDataEvent;
+    FAfterUpdate: TWebDataEvent;
+    FBeforeDelete: THandleWebDataEvent;
+    FBeforeInsert: THandleWebDataEvent;
+    FBeforeRead: THandleWebDataEvent;
+    FBeforeUpdate: THandleWebDataEvent;
+    FContentProducer: TCustomHTTPDataContentProducer;
+    FInputAdaptor: TCustomWebdataInputAdaptor;
+    FOnContent: TContentEvent;
+    FOnGetContentProducer: TContentProducerEvent;
+    FOnGetInputAdaptor: TInputAdaptorEvent;
+    FOnGetProvider: TGetWebDataProviderEvent;
+    FRequest: TRequest;
+    FResponse: TResponse;
+    FUseProviderManager: Boolean;
+    function GetAdaptor: TCustomWebDataInputAdaptor;
+    function GetContentProducer: TCustomHTTPDataContentProducer;
+    Procedure ReadWebData(AProvider : TFPCustomWebDataProvider);
+    Procedure InsertWebData(AProvider : TFPCustomWebDataProvider);
+    procedure SetContentProducer(const AValue: TCustomHTTPDataContentProducer);
+    procedure SetInputAdaptor(const AValue: TCustomWebdataInputAdaptor);
+    Procedure UpdateWebData(AProvider : TFPCustomWebDataProvider);
+    Procedure DeleteWebData(AProvider : TFPCustomWebDataProvider);
+  Protected
+    function GetProvider(const AProviderName: String; Out AContainer : TComponent): TFPCustomWebDataProvider; virtual;
+    procedure ProduceContent(AProvider : TFPCustomWebDataProvider); virtual;
+    Procedure DoReadWebData(AProvider : TFPCustomWebDataProvider); virtual;
+    Procedure DoInsertWebData(AProvider : TFPCustomWebDataProvider); virtual;
+    Procedure DoUpdateWebData(AProvider : TFPCustomWebDataProvider); virtual;
+    Procedure DoDeleteWebData(AProvider : TFPCustomWebDataProvider); virtual;
+    // Input adaptor to use when processing request. Can be nil, and provided in OnGetInputAdaptor
+    Property InputAdaptor : TCustomWebdataInputAdaptor Read FInputAdaptor Write SetInputAdaptor;
+    // Content producer to produce response content
+    Property ContentProducer : TCustomHTTPDataContentProducer Read FContentProducer Write SetContentProducer;
+    // Triggered before a read request is started
+    Property BeforeRead   : THandleWebDataEvent Read FBeforeRead Write FBeforeRead;
+    // Triggered after a read request completed
+    Property AfterRead    : TWebDataEvent Read FAfterRead Write FAfterRead;
+    // Triggered before an insert request is started
+    Property BeforeInsert : THandleWebDataEvent Read FBeforeInsert Write FBeforeInsert;
+    // Triggered after an insert request completed
+    Property AfterInsert  : TWebDataEvent Read FAfterInsert Write FAfterInsert;
+    // Triggered before an update request is started
+    Property BeforeUpdate : THandleWebDataEvent Read FBeforeUpdate Write FBeforeUpdate;
+    // Triggered after an update request completed
+    Property AfterUpdate  : TWebDataEvent Read FAfterUpdate Write FAfterUpdate;
+    // Triggered before a delete request is started
+    Property BeforeDelete : THandleWebDataEvent Read FBeforeDelete Write FBeforeDelete;
+    // Triggered after an insert request completed
+    Property AfterDelete  : TWebDataEvent Read FAfterDelete Write FAfterDelete;
+    // Triggered when the input adaptor needs to be determined.
+    Property OnGetInputAdaptor : TInputAdaptorEvent Read FOnGetInputAdaptor Write FOnGetInputAdaptor;
+    // Triggered when the WebDataProvider needs to be determined.
+    Property OnGetProvider : TGetWebDataProviderEvent Read FOnGetProvider Write FOnGetprovider;
+    // Triggered when the contentproducer needs to be determined
+    Property OnGetContentProducer : TContentProducerEvent Read FOnGetContentProducer Write  FOnGetContentProducer;
+    // Triggered when the content has been created.
+    Property OnContent : TContentEvent Read FOnContent Write FOnContent;
+    // Set to False if the ProviderManager should not be searched for a provider
+    Property UseProviderManager : Boolean Read FUseProviderManager Write FUseProviderManager default True;
+  Public
+    Constructor CreateNew(AOwner : TComponent; CreateMode : Integer); override;
+    Procedure HandleRequest(ARequest : TRequest; AResponse : TResponse); override;
+    // Access to request
+    Property Request: TRequest Read FRequest;
+    // Access to response
+    Property Response: TResponse Read FResponse;
+  end;
+
+  TFPWebProviderDataModule = Class(TFPCustomWebProviderDataModule)
+  Published
+    Property InputAdaptor;
+    Property ContentProducer;
+    Property UseProviderManager;
+    Property OnGetContentProducer;
+    Property BeforeRead;
+    Property AfterRead;
+    Property BeforeInsert;
+    Property AfterInsert;
+    Property BeforeUpdate;
+    Property AfterUpdate;
+    Property BeforeDelete;
+    Property AfterDelete;
+    Property OnGetInputAdaptor;
+    Property OnGetProvider;
+    Property OnContent;
+  end;
+
+Var
+  WebDataProviderManagerClass : TFPCustomWebDataProviderManagerClass = TFPWebDataProviderManager;
+
+Function WebDataProviderManager : TFPCustomWebDataProviderManager;
+
+implementation
+
+{ $define wmdebug}
+
+{$ifdef wmdebug}
+uses dbugintf;
+{$endif}
+
+Resourcestring
+  SErrNoIDField = 'No key field found';
+  SErrNoAdaptor = 'No adaptor assigned';
+  SErrNoDataset = 'No dataset assigned';
+  SErrNoIDValue = 'No key value specified';
+  SErrCouldNotLocateRecord = 'Could not locate record with value "%s" for key field "%s"';
+  SErrNoDatasource = 'No datasource property available';
+  SErrNoAction     = 'Cannot determine action from request';
+  SErrDuplicateWebDataProvider = 'Duplicate webdata provider';
+  SErrUnknownWebDataProvider = 'Unknown webdata provider: "%s"';
+  SErrContentProviderRequest = 'Content provider "%s" does not handle request.';
+  SErrUnknownProviderAction = 'Cannot determine action for provider "%s".';
+  SErrDuplicateAdaptor = 'Duplicate input adaptor name: "%s"';
+  SErrDuplicateHTTPDataProducer = 'Duplicate web data output content producer name: "%s"';
+  SErrUnknownInputAdaptor = 'Unknown web data input adaptor name: "%s"';
+  SErrUnknownHTTPDataProducer = 'Unknown web data output content producer name: "%s"';
+
+{ TCustomWebdataInputAdaptor }
+
+{ TFPCustomWebDataProvider }
+
+
+procedure TCustomWebdataInputAdaptor.SetRequest(const AValue: TRequest);
+begin
+  FRequest:=AValue;
+  FBatchCount:=0;
+  Faction:=wdaUnknown;
+end;
+
+function TCustomWebdataInputAdaptor.GetActionFromRequest: TWebDataAction;
+
+Var
+  N : String;
+
+begin
+  Result:=wdaUnknown;
+  If (Request<>Nil) then
+    begin
+    if (FRequestPathInfo='') then
+      FRequestPathInfo:=Request.GetNextPathInfo;
+    N:=lowercase(FRequestPathInfo);
+    If (N='read') then
+      Result:=wdaRead
+    else If (N='insert') then
+      Result:=wdaInsert
+    else If (N='delete') then
+      Result:=wdaDelete
+    else If (N='update') then
+      Result:=wdaUpdate;
+    end;
+end;
+
+function TCustomWebdataInputAdaptor.GetAction: TWebDataAction;
+
+begin
+  If (Faction=wdaUnknown) then
+    FAction:=GetActionFromRequest;
+  Result:=FAction;
+  If (Result=wdaUnknown) then
+    Raise EFPHTTPError.Create(SErrNoAction)
+end;
+
+function TCustomWebdataInputAdaptor.GetNextBatch: Boolean;
+begin
+  Result:=(FBatchCount=0);
+  Inc(FBatchCount);
+end;
+
+function TCustomWebdataInputAdaptor.TryParamValue(const AParamName: String;
+  out AValue: String): Boolean;
+
+Var
+  L : TStrings;
+  I : Integer;
+  N : String;
+begin
+  Result:=False;
+  If (Request.Method='GET') then
+    L:=Request.QueryFields
+  else // (Request.Method='POST') then
+    L:=FRequest.ContentFields;
+  I:=L.IndexOfName(AParamName);
+  Result:=(I<>-1);
+  If Result then
+    L.GetNameValue(I,N,AValue);
+end;
+
+function TCustomWebdataInputAdaptor.TryFieldValue(const AFieldName: String;
+  out AValue: String): Boolean;
+begin
+  Result:=TryParamValue(AFieldName,AValue);
+end;
+
+
+function TCustomWebdataInputAdaptor.HaveParamValue(const AParamName: String
+  ): boolean;
+
+Var
+  S: String;
+
+begin
+  Result:=TryParamValue(AParamName,S);
+end;
+
+function TCustomWebdataInputAdaptor.HaveFieldValue(const AFieldName: String
+  ): Boolean;
+Var
+  S: String;
+
+begin
+  Result:=TryFieldValue(AFieldName,S);
+end;
+
+function TCustomWebdataInputAdaptor.GetParamValue(const AParamName: String): String;
+begin
+  If not TryParamValue(AParamName,Result) then
+    Result:='';
+end;
+
+function TCustomWebdataInputAdaptor.GetFieldValue(const AFieldName: String): String;
+begin
+  If not TryFieldValue(AFieldName,Result) then
+    Result:='';
+end;
+{ TFPCustomWebDataProvider }
+
+procedure TFPCustomWebDataProvider.CopyFieldData;
+
+Var
+  I : Integer;
+  F : TField;
+  S : String;
+  DS : TDataset;
+
+begin
+  DS:=Dataset;
+  For I:=0 to DS.Fields.Count-1 do
+    begin
+    F:=DS.Fields[i];
+    If (F.DataType<>ftAutoInc) or (DS.State=dsInsert) then
+      If ADaptor.TryFieldValue(F.FieldName,S) then
+        begin
+        If (S<>'') then
+          F.AsString:=S
+        else if DS.State=dsEdit then
+          F.Clear;
+        end;
+    end;
+end;
+
+procedure TFPCustomWebDataProvider.DoUpdate;
+
+Var
+  DS : TDataset;
+
+begin
+  {$ifdef wmdebug}SendDebug('TFPCustomWebDataProvider.DoUpdate: Updating record');{$endif}
+  DS:=Dataset;
+  LocateCurrent;
+  DS.Edit;
+  CopyFieldData;
+  DS.Post;
+  {$ifdef wmdebug}SendDebug('TFPCustomWebDataProvider.DoUpdate: Done Updating record');{$endif}
+end;
+
+procedure TFPCustomWebDataProvider.DoDelete;
+
+Var
+  DS : TDataset;
+begin
+  {$ifdef wmdebug}SendDebug('TFPCustomWebDataProvider.DoDelete: Deleting record');{$endif}
+  LocateCurrent;
+  DS:=Dataset;
+  DS.Delete;
+end;
+
+procedure TFPCustomWebDataProvider.DoInsert;
+Var
+  DS : TDataset;
+begin
+  {$ifdef wmdebug}SendDebug('TFPCustomWebDataProvider.DoInsert: Inserting record');{$endif}
+  DS:=Dataset;
+  DS.Append;
+  CopyFieldData;
+  DS.Post;
+end;
+
+Function TFPCustomWebDataProvider.GetIDField : TField;
+
+Var
+  FN : String;
+  I : Integer;
+
+begin
+  Result:=Nil;
+  FN:=IDFieldName;
+  If (FN='') then
+    begin
+    I:=0;
+    While (Result=Nil) and (I<Dataset.Fields.Count) do
+      begin
+      If pfInKey in Dataset.Fields[i].ProviderFLags then
+        Result:=Dataset.Fields[i];
+      inc(I);
+      end;
+    end
+  else
+    Result:=Dataset.FieldByname(FN);
+  if (Result=Nil) then
+    Raise EFPHTTPError.Create(SErrNoIDField);
+end;
+
+procedure TFPCustomWebDataProvider.LocateCurrent;
+
+Var
+  V : String;
+  F : TField;
+
+begin
+  CheckAdaptor;
+  F:=GetIDField;
+  V:=Adaptor.GetFieldValue(F.FieldName);
+  If (V='') then
+    Raise EFPHTTPError.Create(SErrNoIDValue);
+  if Not Dataset.Locate(F.FieldName,V,[]) then
+    begin
+    // Search the hard way
+    Dataset.First;
+    While (not Dataset.EOF) and (F.AsString<>V)  do
+      Dataset.Next;
+    If Dataset.EOF and (F.AsString<>V) then
+      Raise EFPHTTPError.CreateFmt(SErrCouldNotLocateRecord,[V,F.FieldName]);
+    end;
+end;
+
+procedure TFPCustomWebDataProvider.DoApplyParams;
+begin
+  // Do nothing
+end;
+
+
+procedure TFPCustomWebDataProvider.CheckAdaptor;
+
+begin
+  if Not Assigned(Adaptor) then
+    Raise EFPHTTPError.Create(SErrNoAdaptor);
+  if Not Assigned(Dataset) then
+    Raise EFPHTTPError.Create(SerrNoDataset);
+end;
+
+procedure TFPCustomWebDataProvider.Update;
+begin
+  {$ifdef wmdebug}SendDebug('TFPCustomWebDataProvider.Update enter');{$endif}
+  CheckAdaptor;
+  DoUpdate;
+  {$ifdef wmdebug}SendDebug('TFPCustomWebDataProvider.Update leave');{$endif}
+end;
+
+procedure TFPCustomWebDataProvider.Delete;
+begin
+  CheckAdaptor;
+  DoDelete;
+end;
+
+procedure TFPCustomWebDataProvider.Insert;
+begin
+  CheckAdaptor;
+  DoInsert;
+end;
+
+procedure TFPCustomWebDataProvider.ApplyParams;
+begin
+  CheckAdaptor;
+  DoApplyParams;
+end;
+
+function TFPCustomWebDataProvider.IDFieldValue: String;
+begin
+  Result:=GetIDField.DisplayText;
+end;
+
+
+{ TFPWebDataProvider }
+
+procedure TFPWebDataProvider.SetDataSource(const AValue: TDatasource);
+begin
+  if FDataSource=AValue then exit;
+  If Assigned(FDatasource) then
+    FDataSource.RemoveFreeNotification(Self);
+  FDataSource:=AValue;
+  If Assigned(FDatasource) then
+    FDataSource.FreeNotification(Self);
+end;
+
+function TFPWebDataProvider.GetDataset: TDataset;
+begin
+  If Assigned(DataSource) then
+    Result:=Datasource.Dataset
+  else
+    Raise EFPHTTPError.Create(SErrNoDatasource)
+end;
+
+procedure TFPWebDataProvider.Notification(AComponent: TComponent;
+  Operation: TOperation);
+begin
+  If (Operation=opRemove) and (AComponent=FDatasource) then
+    FDatasource:=Nil;
+  inherited Notification(AComponent, Operation);
+end;
+
+{ TCustomHTTPDataContentProducer }
+
+function TCustomHTTPDataContentProducer.GetDataset: TDataset;
+begin
+  If Assigned(FDataProvider) then
+    Result:=FDataProvider.Dataset;
+end;
+
+procedure TCustomHTTPDataContentProducer.SetAdaptor(
+  const AValue: TCustomWebDataInputAdaptor);
+begin
+  If FAdaptor=AValue then
+     exit;
+  If Assigned(FAdaptor) then
+    FAdaptor.RemoveFreeNotification(Self);
+  FAdaptor:=AValue;
+  If Assigned(FAdaptor) then
+    FAdaptor.FreeNotification(Self);
+end;
+
+procedure TCustomHTTPDataContentProducer.Notification(AComponent: TComponent;
+  Operation: TOperation);
+begin
+  If (Operation=opRemove) then
+    if (AComponent=FDataProvider) then
+       FDataProvider:=Nil
+    else if (AComponent=FAdaptor) then
+       FAdaptor:=Nil;
+  inherited Notification(AComponent, Operation);
+end;
+
+procedure TCustomHTTPDataContentProducer.SetDataProvider(
+  const AValue: TFPCustomWebDataProvider);
+begin
+  if FDataProvider=AValue then exit;
+  If Assigned(FDataProvider) then
+    FDataProvider.RemoveFreeNotification(Self);
+  FDataProvider:=AValue;
+  If Assigned(FDataProvider) then
+    FDataProvider.FreeNotification(Self);
+end;
+
+function TCustomHTTPDataContentProducer.GetDataContentType: String;
+begin
+  Result:='';
+end;
+
+function TCustomHTTPDataContentProducer.CreateAdaptor(ARequest : TRequest): TCustomWebdataInputAdaptor;
+begin
+  Result:=TCustomWebdataInputAdaptor.Create(Self);
+  Result.Request:=ARequest
+end;
+
+
+procedure TCustomHTTPDataContentProducer.DoGetContent(ARequest : TRequest; Content : TStream; Var Handled : Boolean);
+
+Var
+  B : Boolean;
+  A : TCustomWebdataInputAdaptor;
+
+begin
+  B:=(Adaptor=Nil);
+  if B then
+    begin
+    A:=CreateAdaptor(ARequest);
+    Adaptor:=A;
+    end;
+  try
+    try
+      While Adaptor.GetNextBatch do
+        begin
+        {$ifdef wmdebug}SendDebug('Starting batch Loop');{$endif}
+        Case Adaptor.Action of
+          wdaInsert : DoInsertRecord(Content);
+          wdaUpdate : begin
+                      {$ifdef wmdebug}SendDebug('Aha1');{$endif}
+                      DoUpdateRecord(Content);
+                      {$ifdef wmdebug}SendDebug('Aha2');{$endif}
+                      end;
+          wdaDelete : DoDeleteRecord(Content);
+          wdaRead   : DoReadRecords(Content);
+        else
+          inherited DoGetContent(ARequest, Content,Handled);
+        end;
+        if (Adaptor.Action in [wdaInsert,wdaUpdate,wdaDelete,wdaRead]) then
+          Handled:=true;
+        {$ifdef wmdebug}SendDebug('Ended batch Loop');{$endif}
+        end;
+    except
+    On E : Exception do
+      begin
+      DoExceptionToStream(E,Content);
+      Handled:=True;
+      end;
+    end;
+  finally
+    If B then
+     FreeAndNil(A);
+  end;
+end;
+
+procedure TCustomHTTPDataContentProducer.DoHandleRequest(ARequest: TRequest;
+  AResponse: TResponse; var Handled: Boolean);
+
+Var
+  S : String;
+
+begin
+  inherited DoHandleRequest(ARequest, AResponse, Handled);
+  If Handled then
+    begin
+    S:=GetDataContentType;
+    If (S<>'') then
+      AResponse.ContentType:=S;
+    end;
+end;
+
+procedure TCustomHTTPDataContentProducer.DoUpdateRecord(ResponseContent: TStream);
+begin
+  {$ifdef wmdebug}SendDebug('DoUpdateRecord: Updating record');{$endif}
+  Provider.Update;
+  {$ifdef wmdebug}SendDebug('DoUpdateRecord: Updated record');{$endif}
+end;
+
+procedure TCustomHTTPDataContentProducer.DoInsertRecord(ResponseContent: TStream);
+begin
+  Provider.Insert;
+end;
+
+procedure TCustomHTTPDataContentProducer.DoDeleteRecord(ResponseContent: TStream);
+begin
+  Provider.Delete;
+end;
+
+procedure TCustomHTTPDataContentProducer.DoReadRecords(ResponseContent: TStream);
+
+Var
+  DS : TDataset;
+
+begin
+  DS:=Provider.Dataset;
+  If Not DS.Active then
+    begin
+    {$ifdef wmdebug}SendDebug('Doreadrecords: Applying parameters');{$endif}
+    Provider.ApplyParams;
+    {$ifdef wmdebug}SendDebug('Doreadrecords: Applied parameters');{$endif}
+    DS.Open;
+    {$ifdef wmdebug}SendDebug('Doreadrecords: opened dataset');{$endif}
+    end;
+  DatasetToStream(ResponseContent);
+end;
+
+constructor TCustomHTTPDataContentProducer.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  FAllowPagesize:=True;
+end;
+
+{ TWebDataProviderDef }
+
+procedure TWebDataProviderDef.SetFPClass(
+  const AValue: TFPCustomWebDataProviderClass);
+begin
+  if FPClass=AValue then exit;
+  FPClass:=AValue;
+end;
+
+procedure TWebDataProviderDef.SetProviderName(const AValue: String);
+begin
+  if FProviderName=AValue then exit;
+  FProviderName:=AValue;
+end;
+
+Function TWebDataProviderDef.CreateInstance(AOwner: TComponent; Out AContainer : TComponent) : TFPCUstomWebDataProvider;
+
+Var
+  AClass : TFPCustomWebDataProviderClass;
+  DM : TDataModule;
+  C : TComponent;
+
+begin
+  Result:=Nil;
+  {$ifdef wmdebug}SendDebug(Format('Creating instance for %s',[Self.ProviderName]));{$endif}
+  If Assigned(FDataModuleClass) then
+    begin
+    {$ifdef wmdebug}SendDebug(Format('Creating datamodule from class %d ',[Ord(Assigned(FDataModuleClass))]));{$endif}
+    DM:=FDataModuleClass.Create(AOwner);
+    {$ifdef wmdebug}SendDebug(Format('Created datamodule from class %s ',[DM.ClassName]));{$endif}
+    C:=DM.FindComponent(FProviderName);
+    If (C<>Nil) and (C is TFPCUstomWebDataProvider) then
+      Result:=TFPCUstomWebDataProvider(C)
+    else
+      begin
+      FreeAndNil(DM);
+      Raise EFPHTTPError.CreateFmt(SErrUnknownWebDataProvider,[FProviderName]);
+      end;
+    end
+  else
+    DM:=TDataModule.CreateNew(AOwner,0);
+  AContainer:=DM;
+  If (Result=Nil) then
+    begin
+    {$ifdef wmdebug}SendDebug(Format('Creating from class pointer %d ',[Ord(Assigned(FPClass))]));{$endif}
+    AClass:=FPCLass;
+    If Assigned(FBeforeCreate) then
+      FBeforeCreate(Self,AClass);
+    Result:=AClass.Create(AContainer);
+    end;
+  If Assigned(FAfterCreate) then
+    FAfterCreate(Self,Result);
+end;
+
+{ TWebDataProviderDefs }
+
+function TWebDataProviderDefs.GetD(Index : Integer): TWebDataProviderDef;
+begin
+  Result:=TWebDataProviderDef(Items[Index])
+end;
+
+procedure TWebDataProviderDefs.SetD(Index : Integer;
+  const AValue: TWebDataProviderDef);
+begin
+  Items[Index]:=AValue;
+end;
+
+function TWebDataProviderDefs.IndexOfProvider(const AProviderName: String
+  ): Integer;
+begin
+  Result:=Count-1;
+  While (Result>=0) and (CompareText(GetD(Result).ProviderName,AProviderName)<>0) do
+    Dec(Result);
+end;
+
+function TWebDataProviderDefs.AddProvider(const AProviderName: String
+  ): TWebDataProviderDef;
+begin
+  If IndexOfProvider(AProviderName)=-1 then
+    begin
+    Result:=Add as TWebDataProviderDef;
+    Result.ProviderName:=AProviderName;
+    end
+  else
+    Raise EFPHTTPError.CreateFmt(SErrDuplicateWebDataProvider,[AProviderName]);
+end;
+
+function TWebDataProviderDefs.AddProvider(const AProviderName: String;
+  AClass: TFPCustomWebDataProviderClass): TWebDataProviderDef;
+begin
+  Result:=AddProvider(AProviderName);
+  Result.ProviderClass:=AClass;
+end;
+
+
+Var
+  AWebDataProviderManager : TFPCustomWebDataProviderManager;
+
+Function WebDataProviderManager : TFPCustomWebDataProviderManager;
+
+begin
+  If (AWebDataProviderManager=Nil) then
+    begin
+    If WebDataProviderManagerClass=Nil then
+       WebDataProviderManagerClass:=TFPWebDataProviderManager;
+    AWebDataProviderManager:=WebDataProviderManagerClass.Create(Nil);
+    AWebDataProviderManager.Initialize;
+    end;
+  Result:=AWebDataProviderManager;
+end;
+
+{ TFPCustomWebDataProviderManager }
+
+procedure TFPCustomWebDataProviderManager.Initialize;
+begin
+  // Do nothing
+end;
+
+procedure TFPCustomWebDataProviderManager.Unregisterprovider(
+  const AProviderName: String);
+
+Var
+  I : Integer;
+
+begin
+  I:=IndexOfProviderDef(AProviderName);
+  If (I<>-1) then
+    RemoveProviderDef(I)
+  else
+    Raise EFPHTTPError.CreateFmt(SErrUnknownWebDataProvider,[AProviderName]);
+end;
+
+procedure TFPCustomWebDataProviderManager.RegisterDatamodule(
+  const AClass: TDatamoduleClass);
+
+Var
+  DM : TDatamodule;
+  I,J : Integer;
+  C : TComponent;
+  D : TWebDataProviderDef;
+
+begin
+  FRegistering:=True;
+  try
+    DM:=AClass.Create(Self);
+    try
+      For I:=0 to DM.ComponentCount-1 do
+        begin
+        C:=DM.Components[i];
+        if C is TFPCustomWebDataProvider then
+          begin
+          J:=IndexOfProviderDef(C.Name);
+          If (J<>-1) then
+            Raise EFPHTTPError.CreateFmt(SErrDuplicateWebDataProvider,[C.Name]);
+          D:=AddProviderDef(C.Name);
+          {$ifdef wmdebug}SendDebug('Registering provider '+C.Name);{$endif}
+          D.FDataModuleClass:=TDataModuleClass(DM.ClassType);
+          end;
+        end;
+    finally
+      DM.Free;
+    end;
+  finally
+    FRegistering:=False;
+  end;
+end;
+
+function TFPCustomWebDataProviderManager.RegisterProvider(
+  const AProviderName: String; AClass: TFPCustomWebDataProviderClass
+  ): TWebDataProviderDef;
+
+Var
+  I : Integer;
+
+begin
+  FRegistering:=True;
+  try
+    I:=IndexOfProviderDef(AProviderName);
+    If (I<>-1) then
+      Raise EFPHTTPError.CreateFmt(SErrDuplicateWebDataProvider,[AProviderName]);
+    Result:=AddProviderDef(AProviderName);
+    Result.ProviderClass:=AClass;
+  finally
+    FRegistering:=False;
+  end;
+end;
+
+function TFPCustomWebDataProviderManager.FindProviderDefByName(
+  const AProviderName: String): TWebDataProviderDef;
+
+Var
+  I : integer;
+
+begin
+  I:=IndexOfProviderDef(AProviderName);
+  If (I=-1) then
+    Result:=Nil
+  else
+    Result:=GetProviderDef(I);
+end;
+
+function TFPCustomWebDataProviderManager.GetProviderDefByName(
+  const AProviderName: String): TWebDataProviderDef;
+begin
+  Result:=FindProviderDefByName(AProviderName);
+  If (Result=Nil) then
+    Raise EFPHTTPError.CreateFmt(SErrUnknownWebDataProvider,[AProviderName]);
+end;
+
+function TFPCustomWebDataProviderManager.GetProvider(
+  const AProviderName: String; AOwner: TComponent; Out AContainer : TComponent): TFPCustomWebDataProvider;
+
+Var
+  D : TWebDataProviderDef;
+
+begin
+  D:=GetProviderDefByname(AProviderName);
+  Result:=GetProvider(D,AOwner,AContainer);
+end;
+
+function TFPCustomWebDataProviderManager.RegisterInputAdaptor(
+  const AAdaptorName: String; AClass: TCustomWebdataInputAdaptorClass
+  ): TWebInputAdaptorDef;
+begin
+  If IndexOfInputAdaptorDef(AAdaptorName)<>-1 then
+    Raise EFPHTTPError.CreateFmt(SErrDuplicateAdaptor,[AAdaptorName]);
+  Result:=AddInputAdaptorDef(AAdaptorName,AClass);
+end;
+
+procedure TFPCustomWebDataProviderManager.UnRegisterInputAdaptor(
+  const AAdaptorName: String);
+
+Var
+  I : Integer;
+
+begin
+  I:=IndexOfInputAdaptorDef(AAdaptorName);
+  If (I<>-1) then
+     RemoveInputAdaptorDef(I);
+
+end;
+
+function TFPCustomWebDataProviderManager.FindInputAdaptorDefByName(
+  const AAdaptorName: String): TWebInputAdaptorDef;
+
+Var
+  I: integer;
+
+begin
+  I:=IndexOfInputAdaptorDef(AAdaptorName);
+  If I<>-1 then
+    Result:=GetInputAdaptorDef(I)
+  else
+    Result:=Nil;
+end;
+
+function TFPCustomWebDataProviderManager.GetInputAdaptorDefByName(
+  const AAdaptorName: String): TWebInputAdaptorDef;
+begin
+  Result:=FindInputAdaptorDefByName(AAdaptorName);
+  If (Result=Nil) then
+    Raise EFPHTTPError.CreateFmt(SErrUnknownInputAdaptor,[AAdaptorName]);
+end;
+
+function TFPCustomWebDataProviderManager.GetInputAdaptor(
+  const ADef: TWebInputAdaptorDef; AOwner: TComponent
+  ): TCustomWebdataInputAdaptor;
+
+Var
+  O: TComponent;
+
+begin
+  O:=AOwner;
+  If (O=Nil) then
+    O:=Self;
+  Result:=ADef.CreateInstance(AOwner);
+end;
+
+function TFPCustomWebDataProviderManager.GetInputAdaptor(
+  const AAdaptorName: String; AOwner: TComponent): TCustomWebdataInputAdaptor;
+begin
+  Result:=GetInputAdaptor(GetInputAdaptorDefByName(AAdaptorName),Aowner);
+end;
+
+function TFPCustomWebDataProviderManager.RegisterDataProducer(
+  const AProducerName: String; AClass: TCustomHTTPDataContentProducerClass
+  ): THttpDataProducerDef;
+begin
+  If IndexOfHttpDataProducerDef(AProducerName)<>-1 then
+    Raise EFPHTTPError.CreateFmt(SErrDuplicateHTTPDataProducer,[AProducerName]);
+  Result:=AddHttpDataProducerDef(AProducerName,AClass);
+end;
+
+procedure TFPCustomWebDataProviderManager.UnRegisterDataProducer(
+  const AProducerName: String);
+
+Var
+  I : Integer;
+
+begin
+  I:=IndexOfHttpDataProducerDef(AProducerName);
+  If (I<>-1) then
+    RemoveHttpDataProducerDef(I);
+end;
+
+function TFPCustomWebDataProviderManager.FindDataProducerDefByName(
+  const AProducerName: String): THttpDataProducerDef;
+Var
+  I : Integer;
+
+begin
+  I:=IndexOfHttpDataProducerDef(AProducerName);
+  If (I<>-1) then
+    Result:=GetHttpDataProducerDef(I)
+  else
+    Result:=Nil;
+
+end;
+
+function TFPCustomWebDataProviderManager.GetDataProducerDefByName(
+  const AProducerName: String): THttpDataProducerDef;
+begin
+  Result:=FindDataProducerDefByName(AProducerName);
+  If (Result=Nil) then
+    Raise EFPHTTPError.CreateFmt(SErrUnknownHTTPDataProducer,[AProducerName]);
+end;
+
+function TFPCustomWebDataProviderManager.GetDataProducer(
+  ADef: THttpDataProducerDef; AOwner: TComponent
+  ): TCustomHTTPDataContentProducer;
+
+Var
+  O : TComponent;
+
+begin
+  O:=AOwner;
+  If (O=Nil) then
+    O:=Self;
+  Result:=ADef.CreateInstance(Aowner);
+end;
+
+function TFPCustomWebDataProviderManager.GetDataProducer(
+  const AProducerName: String; AOwner : TComponent): TCustomHTTPDataContentProducer;
+begin
+  Result:=GetDataProducer(GetDataProducerDefByName(AProducerName),Aowner);
+end;
+
+function TFPCustomWebDataProviderManager.GetProvider(
+  const ADef: TWebDataProviderDef; AOwner: TComponent; Out AContainer : TComponent): TFPCustomWebDataProvider;
+
+Var
+  O : TComponent;
+begin
+  If AOwner<>Nil then
+    O:=Self
+  else
+    O:=AOwner;
+  Result:=ADef.CreateInstance(O,AContainer);
+end;
+
+{ TFPWebDataProviderManager }
+
+constructor TFPWebDataProviderManager.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  FProviderDefs:=TWebDataProviderDefs.Create(TWebDataProviderDef);
+  FAdaptorDefs:=TWebInputAdaptorDefs.Create(TWebInputAdaptorDef);
+  FProducerDefs:=THttpDataProducerDefs.Create(THttpDataProducerDef);
+end;
+
+destructor TFPWebDataProviderManager.Destroy;
+begin
+  FreeAndNil(FProviderDefs);
+  FreeAndNil(FAdaptorDefs);
+  FreeAndNil(FProducerDefs);
+  inherited Destroy;
+end;
+
+procedure TFPWebDataProviderManager.RemoveProviderDef(const Index: Integer);
+
+begin
+  FProviderDefs.Delete(Index);
+end;
+
+function TFPWebDataProviderManager.AddProviderDef(const AProviderName: String
+  ): TWebDataProviderDef;
+begin
+  Result:=FProviderDefs.AddProvider(AProviderName);
+end;
+
+function TFPWebDataProviderManager.IndexOfProviderDef(const AProviderName: String
+  ): Integer;
+begin
+  {$ifdef wmdebug}Senddebug('Entering indexofproviderdef : '+AProviderName);{$endif}
+  {$ifdef wmdebug}Senddebug(Format('Providerdefs assigned: %d ',[Ord(Assigned(FProviderDefs))]));{$endif}
+  Result:=FProviderDefs.IndexOfProvider(AProviderName);
+  {$ifdef wmdebug}Senddebug('Exitining indexofproviderdef: '+IntToStr(result));{$endif}
+end;
+
+function TFPWebDataProviderManager.GetProviderDef(Index: Integer
+  ): TWebDataProviderDef;
+begin
+  Result:=FProviderDefs[Index];
+end;
+
+function TFPWebDataProviderManager.GetProviderDefCount: Integer;
+begin
+  Result:=FProviderDefs.Count;
+end;
+
+function TFPWebDataProviderManager.AddInputAdaptorDef(
+  const AAdaptorName: String; AClass: TCustomWebdataInputAdaptorClass
+  ): TWebInputAdaptorDef;
+begin
+  Result:=FAdaptorDefs.AddAdaptor(AAdaptorName,AClass);
+end;
+
+function TFPWebDataProviderManager.IndexOfInputAdaptorDef(
+  const AAdaptorName: String): Integer;
+begin
+  Result:=FAdaptorDefs.IndexOfAdaptor(AAdaptorName);
+end;
+
+Procedure TFPWebDataProviderManager.RemoveInputAdaptorDef(Index : integer);
+
+begin
+  If (Index<>-1) then
+    FAdaptorDefs.Delete(Index);
+end;
+
+function TFPWebDataProviderManager.GetInputAdaptorDef(Index: Integer
+  ): TWebInputAdaptorDef;
+begin
+  Result:=FAdaptorDefs[Index];
+end;
+
+function TFPWebDataProviderManager.GetInputAdaptorDefCount: Integer;
+begin
+  Result:=FAdaptorDefs.Count;
+end;
+
+function TFPWebDataProviderManager.AddHttpDataProducerDef(
+  const AProducerName: String; AClass: TCustomHTTPDataContentProducerClass
+  ): THttpDataProducerDef;
+begin
+  Result:=FProducerDefs.AddProducer(AProducerName,AClass);
+end;
+
+function TFPWebDataProviderManager.IndexOfHttpDataProducerDef(
+  const AProducerName: String): Integer;
+begin
+  Result:=FProducerDefs.IndexOfProducer(AProducerName);
+end;
+
+procedure TFPWebDataProviderManager.RemoveHttpDataProducerDef(Index: Integer);
+begin
+  FProducerDefs.Delete(Index);
+end;
+
+function TFPWebDataProviderManager.GetHttpDataProducerDef(Index: Integer
+  ): THttpDataProducerDef;
+begin
+  Result:=FProducerDefs[Index];
+end;
+
+function TFPWebDataProviderManager.GetHttpDataProducerDefCount: Integer;
+begin
+  Result:=FProducerDefs.Count;
+end;
+
+{ TFPCustomWebProviderDataModule }
+
+procedure TFPCustomWebProviderDataModule.ReadWebData(AProvider: TFPCustomWebDataProvider
+  );
+
+Var
+  B : Boolean;
+
+begin
+  B:=False;
+  If Assigned(FBeforeRead) then
+    FBeforeRead(Self,AProvider,B);
+  if Not B then
+      DoReadWebData(AProvider);
+  If Assigned(FAfterRead) then
+    FAfterRead(Self,AProvider);
+end;
+
+procedure TFPCustomWebProviderDataModule.InsertWebData(
+  AProvider: TFPCustomWebDataProvider);
+
+Var
+  B : Boolean;
+
+begin
+  B:=False;
+  If Assigned(FBeforeInsert) then
+    FBeforeInsert(Self,AProvider,B);
+  if Not B then
+      DoInsertWebData(AProvider);
+  If Assigned(FAfterInsert) then
+    FAfterInsert(Self,AProvider);
+end;
+
+procedure TFPCustomWebProviderDataModule.SetContentProducer(
+  const AValue: TCustomHTTPDataContentProducer);
+begin
+  if FContentProducer=AValue then exit;
+  FContentProducer:=AValue;
+end;
+
+procedure TFPCustomWebProviderDataModule.SetInputAdaptor(
+  const AValue: TCustomWebdataInputAdaptor);
+begin
+  if FInputAdaptor=AValue then exit;
+  FInputAdaptor:=AValue;
+end;
+
+procedure TFPCustomWebProviderDataModule.UpdateWebData(
+  AProvider: TFPCustomWebDataProvider);
+
+Var
+  B : Boolean;
+
+begin
+  B:=False;
+  If Assigned(FBeforeUpdate) then
+    FBeforeUpdate(Self,AProvider,B);
+  if Not B then
+      DoUpdateWebData(AProvider);
+  If Assigned(FAfterUpdate) then
+    FAfterUpdate(Self,AProvider);
+end;
+
+procedure TFPCustomWebProviderDataModule.DeleteWebData(
+  AProvider: TFPCustomWebDataProvider);
+Var
+  B : Boolean;
+
+begin
+  B:=False;
+  If Assigned(FBeforeDelete) then
+    FBeforeDelete(Self,AProvider,B);
+  if Not B then
+      DoDeleteWebData(AProvider);
+  If Assigned(FAfterDelete) then
+    FAfterDelete(Self,AProvider);
+end;
+
+Function TFPCustomWebProviderDataModule.GetAdaptor : TCustomWebdataInputAdaptor;
+
+begin
+  Result:=Self.InputAdaptor;
+  If Assigned(FOnGetInputAdaptor) then
+    FOnGetInputAdaptor(Self,Result);
+end;
+
+function TFPCustomWebProviderDataModule.GetContentProducer: TCustomHTTPDataContentProducer;
+begin
+  Result:=FContentProducer;
+  If Assigned(FOnGetContentProducer) then
+    FOnGetContentProducer(Self,Result);
+end;
+
+procedure TFPCustomWebProviderDataModule.ProduceContent(
+  AProvider: TFPCustomWebDataProvider);
+
+Var
+  A : TCustomWebdataInputAdaptor;
+  C : TCustomHTTPDataContentProducer;
+  Handled : boolean;
+  M : TmemoryStream;
+begin
+  A:=GetAdaptor;
+  A.Request:=Self.Request;
+  AProvider.Adaptor:=A;
+  C:=GetContentProducer;
+  C.Adaptor:=A;
+  C.Provider:=AProvider;
+  M:=TMemoryStream.Create;
+  try
+    Handled:=True;
+    C.GetContent(Request,M,Handled);
+    If Handled then
+      begin
+      M.Position:=0;
+      If Assigned(FOnContent) then
+        FOnContent(Self,M);
+      Response.ContentType:=C.DataContentType;
+      Response.ContentStream:=M;
+      Response.SendResponse;
+      Response.ContentStream:=Nil;
+      end
+    else
+      Raise EFPHTTPError.CreateFmt(SErrContentProviderRequest,[C.Name]);
+  finally
+    M.Free;
+  end;
+end;
+
+procedure TFPCustomWebProviderDataModule.DoReadWebData(
+  AProvider: TFPCustomWebDataProvider);
+
+begin
+  ProduceContent(AProvider);
+end;
+
+procedure TFPCustomWebProviderDataModule.DoInsertWebData(
+  AProvider: TFPCustomWebDataProvider);
+begin
+  ProduceContent(AProvider);
+end;
+
+procedure TFPCustomWebProviderDataModule.DoUpdateWebData(
+  AProvider: TFPCustomWebDataProvider);
+begin
+  ProduceContent(AProvider);
+end;
+
+procedure TFPCustomWebProviderDataModule.DoDeleteWebData(
+  AProvider: TFPCustomWebDataProvider);
+begin
+  ProduceContent(AProvider);
+end;
+
+Constructor TFPCustomWebProviderDataModule.CreateNew(AOwner : TComponent; CreateMode : Integer);
+begin
+  inherited;
+  FUseProviderManager:=True;
+end;
+
+Function TFPCustomWebProviderDataModule.GetProvider(Const AProviderName : String; Out AContainer : TComponent) : TFPCustomWebDataProvider;
+
+Var
+  C : TComponent;
+  ADef : TWebDataProviderDef;
+  P : TFPCustomWebDataProvider;
+
+begin
+  Result:=Nil;
+  AContainer:=Nil;
+  If Assigned(FOnGetProvider) then
+    begin
+    FOngetProvider(Self,AProviderName,Result);
+    If Assigned(Result) then
+      begin
+      AContainer:=Nil;
+      Exit;
+      end;
+    end;
+  C:=FindComponent(AProviderName);
+  {$ifdef wmdebug}SendDebug(Format('Searching provider "%s" 1 : %d ',[AProvidername,Ord(Assigned(C))]));{$endif}
+  If (C<>Nil) and (C is TFPCustomWebDataProvider) then
+    P:=TFPCustomWebDataProvider(C)
+  else if UseProviderManager then
+    begin
+    {$ifdef wmdebug}SendDebug(Format('Searching providerdef "%s" 1 : %d ',[AProvidername,Ord(Assigned(C))]));{$endif}
+    ADef:=WebDataProviderManager.FindProviderDefByName(AProviderName);
+    If (ADef<>Nil) then
+      begin
+      {$ifdef wmdebug}SendDebug(Format('Found providerdef "%s" 1 : %d ',[AProvidername,Ord(Assigned(C))]));{$endif}
+      P:=WebDataProviderManager.GetProvider(ADef,Self,AContainer);
+      end;
+    end;
+  {$ifdef wmdebug}SendDebug(Format('Searching provider "%s" 2 : %d ',[AProvidername,Ord(Assigned(C))]));{$endif}
+  Result:=P;
+  If (Result=Nil) then
+    Raise EFPHTTPError.CreateFmt(SErrUnknownWebDataProvider,[AProviderName]);
+end;
+
+procedure TFPCustomWebProviderDataModule.HandleRequest(ARequest: TRequest;
+  AResponse: TResponse);
+
+Var
+  ProviderName : String;
+  AProvider : TFPCustomWebDataProvider;
+  A : TCustomWebdataInputAdaptor;
+  Wa : TWebDataAction;
+  AContainer : TComponent;
+
+begin
+  FRequest:=ARequest;
+  FResponse:=AResponse;
+  try
+    ProviderName:=Request.GetNextPathInfo;
+    {$ifdef wmdebug}SendDebug('Handlerequest, providername : '+Providername);{$endif}
+    AProvider:=GetProvider(ProviderName,AContainer);
+    try
+      A:=GetAdaptor;
+      A.Request:=ARequest;
+      Wa:=A.GetAction;
+      Case WA of
+        wdaUnknown : Raise EFPHTTPError.CreateFmt(SErrUnknownProviderAction,[ProviderName]);
+        wdaRead    : ReadWebData(AProvider);
+        wdaUpdate  : UpdateWebData(AProvider);
+        wdaInsert  : InsertWebdata(AProvider);
+        wdaDelete  : DeleteWebData(AProvider);
+      end;
+    finally
+      If (AContainer=Nil) then
+        begin
+        If (AProvider.Owner<>Self) then
+          AProvider.Free;
+        end
+      else
+        AContainer.Free;
+    end;
+  finally
+    FRequest:=Nil;
+    FResponse:=Nil;
+  end;
+end;
+
+{ TWebInputAdaptorDef }
+
+procedure TWebInputAdaptorDef.SetName(const AValue: String);
+begin
+  if FName=AValue then exit;
+  FName:=AValue;
+end;
+
+function TWebInputAdaptorDef.CreateInstance(AOwner: TComponent
+  ): TCustomWebdataInputAdaptor;
+begin
+  Result:=FClass.Create(AOwner);
+end;
+
+{ TWebInputAdaptorDefs }
+
+function TWebInputAdaptorDefs.GetD(Index : Integer): TWebInputAdaptorDef;
+begin
+  Result:=TWebInputAdaptorDef(Items[Index]);
+end;
+
+procedure TWebInputAdaptorDefs.SetD(Index : Integer;
+  const AValue: TWebInputAdaptorDef);
+begin
+  Items[Index]:=AValue;
+end;
+
+function TWebInputAdaptorDefs.IndexOfAdaptor(const AAdaptorName: String
+  ): Integer;
+begin
+  Result:=Count-1;
+  While (Result>=0) and (CompareText(GetD(Result).Name,AAdaptorName)<>0) do
+    Dec(Result);
+end;
+
+function TWebInputAdaptorDefs.AddAdaptor(const AAdaptorName: String;
+  AClass: TCustomWebdataInputAdaptorClass): TWebInputAdaptorDef;
+
+Var
+  I : Integer;
+
+begin
+  I:=IndexOfAdaptor(AAdaptorName);
+  If (I=-1) then
+    begin
+    Result:=Add as TWebInputAdaptorDef;
+    Result.FName:=AAdaptorName;
+    Result.FClass:=AClass;
+    end
+  else
+    Raise EFPHTTPError.CreateFmt(SErrDuplicateAdaptor,[AAdaptorName]);
+end;
+
+{ THttpDataProducerDef }
+
+procedure THttpDataProducerDef.SetName(const AValue: String);
+
+begin
+  If AValue=FName then exit;
+  If (AValue<>'') and Assigned(Collection) and (Collection is THttpDataProducerDefs) then
+    if THttpDataProducerDefs(Collection).IndexOfProducer(AValue)<>-1 then
+      Raise EFPHTTPError.CreateFmt(SErrDuplicateHTTPDataProducer,[AValue]);
+  FName:=Avalue;
+end;
+
+function THttpDataProducerDef.CreateInstance(AOwner: TComponent
+  ): TCustomHTTPDataContentProducer;
+begin
+  Result:=FClass.Create(AOwner);
+end;
+
+{ THttpDataProducerDefs }
+
+function THttpDataProducerDefs.GetD(Index: Integer): THttpDataProducerDef;
+begin
+  Result:=THttpDataProducerDef(Items[Index]);
+end;
+
+procedure THttpDataProducerDefs.SetD(Index: Integer;
+  const AValue: THttpDataProducerDef);
+begin
+  Items[Index]:=AValue;
+end;
+
+function THttpDataProducerDefs.IndexOfProducer(const AProducerName: String
+  ): Integer;
+begin
+  Result:=Count-1;
+  While (Result>=0) and (CompareText(GetD(Result).Name,AProducerName)<>0) do
+    Dec(Result);
+end;
+
+function THttpDataProducerDefs.AddProducer(const AProducerName: String;
+  AClass: TCustomHTTPDataContentProducerClass): THttpDataProducerDef;
+
+Var
+  I : Integer;
+
+begin
+  I:=IndexOfProducer(AProducerName);
+  If (I=-1) then
+    begin
+    Result:=Add as THttpDataProducerDef;
+    Result.FName:=AProducerName;
+    Result.FClass:=AClass;
+    end
+  else
+    Raise EFPHTTPError.CreateFmt(SErrDuplicateHTTPDataProducer,[AProducerName]);
+end;
+
+{ TWebdataInputAdaptor }
+
+procedure TWebdataInputAdaptor.SetInputFormat(const AValue: String);
+begin
+  if FInputFormat=AValue then exit;
+  If Assigned(FProxy) then
+    ClearProxy;
+  FInputFormat:=AValue;
+end;
+
+procedure TWebdataInputAdaptor.ClearProxy;
+begin
+  FreeAndNil(FProxy);
+end;
+
+procedure TWebdataInputAdaptor.CheckProxy;
+begin
+  If (FProxy=Nil) then
+    FProxy:=CreateProxy;
+end;
+
+function TWebdataInputAdaptor.CreateProxy: TCustomWebdataInputAdaptor;
+begin
+  Result:=WebDataProviderManager.GetInputAdaptor(FInputFormat);
+end;
+
+function TWebdataInputAdaptor.GetActionFromRequest: TWebDataAction;
+begin
+  CheckProxy;
+  Result:=FProxy.GetActionFromRequest;
+end;
+
+destructor TWebdataInputAdaptor.Destroy;
+begin
+  ClearProxy;
+  Inherited;
+end;
+
+function TWebdataInputAdaptor.GetNextBatch: Boolean;
+begin
+  CheckProxy;
+  Result:=FProxy.GetNextBatch;
+end;
+
+function TWebdataInputAdaptor.TryParamValue(const AParamName: String; out
+  AValue: String): Boolean;
+begin
+  CheckProxy;
+  Result:=FProxy.TryParamValue(AParamName, AValue);
+end;
+
+function TWebdataInputAdaptor.TryFieldValue(const AFieldName: String; out
+  AValue: String): Boolean;
+begin
+  CheckProxy;
+  Result:=FProxy.TryFieldValue(AFieldName, AValue);
+end;
+
+{ THTTPDataContentProducer }
+
+procedure THTTPDataContentProducer.SetOutputFormat(const AValue: String);
+begin
+  if FOutputFormat=AValue then exit;
+  If Assigned(FProxy) then
+    ClearProxy;
+  FOutputFormat:=AValue;
+end;
+
+procedure THTTPDataContentProducer.ClearProxy;
+begin
+  FreeAndNil(FProxy);
+end;
+
+procedure THTTPDataContentProducer.CheckProxy;
+begin
+  If not Assigned(FProxy) then
+    begin
+    FProxy:=CreateProxy;
+    end;
+end;
+
+function THTTPDataContentProducer.CreateProxy: TCustomHTTPDataContentProducer;
+begin
+  Result:=WebDataProviderManager.GetDataProducer(FOutputFormat,Self);
+  ConfigureProxy(Result);
+end;
+
+Procedure THTTPDataContentProducer.ConfigureProxy(AProxy : TCustomHTTPDataContentProducer);
+begin
+  AProxy.PageSize:=Self.PageSize;
+  AProxy.PageStart:=Self.PageStart;
+  AProxy.MetaData:=Self.MetaData;
+  AProxy.SortField:=Self.SortField;
+  AProxy.SortDescending:=Self.SortDescending;
+  AProxy.AllowPageSize:=Self.AllowPageSize;
+  If Assigned(FOnConfigure) then
+     FOnConfigure(AProxy);
+end;
+
+destructor THTTPDataContentProducer.destroy;
+begin
+  ClearProxy;
+  inherited destroy;
+end;
+
+initialization
+
+finalization
+  FreeAndNil(AWebDataProviderManager);
+end.
+

+ 405 - 0
packages/fcl-web/src/webdata/sqldbwebdata.pp

@@ -0,0 +1,405 @@
+unit sqldbwebdata;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fphttp, fpwebdata, DB, SQLDB;
+
+
+Type
+  { TCustomSQLDBWebDataProvider }
+  TNewIDEvent = Procedure(Sender : TObject; Out AID : String) of object;
+  TGetParamTypeEvent = Procedure (Sender : TObject; Const ParamName,AValue : String; Var AType : TFieldtype) of object;
+
+  TCustomSQLDBWebDataProvider = Class(TFPCustomWebDataProvider)
+  private
+    FIDFieldName: String;
+    FOnGetNewID: TNewIDEvent;
+    FSQLS : Array[0..3] of TStringList;
+    FConnection: TSQLConnection;
+    FQuery : TSQLQuery;
+    FLastNewID : String;
+    FOnGetParamType : TGetParamTypeEvent;
+    procedure CheckDataset;
+    function GetS(AIndex: integer): TStrings;
+    procedure SetConnection(const AValue: TSQLConnection);
+    procedure SetS(AIndex: integer; const AValue: TStrings);
+  Protected
+    function CreateQuery(AOwner: TComponent; ATransaction: TSQLTransaction; ASQL: Tstrings): TSQLQuery;
+    function GetParamType(P: TParam; const AValue: String): TFieldType; virtual;
+    procedure SetTypedParam(P: TParam; Const AValue: String); virtual;
+    procedure ExecuteSQL(ASQL: TStrings; Msg: String=''; DoNewID : Boolean = False); virtual;
+    procedure ApplySQLParams(AQuery: TSQLQuery; DoNewID : Boolean = False); virtual;
+    Procedure SQLChanged(Sender : TObject); virtual;
+    Procedure DoUpdate; override;
+    Procedure DoDelete; override;
+    Procedure DoInsert; override;
+    Procedure DoApplyParams; override;
+    Function GetDataset : TDataset; override;
+    Function GetNewID : String;
+    Function IDFieldValue : String; override;
+    procedure Notification(AComponent: TComponent;  Operation: TOperation); override;
+    Property SelectSQL : TStrings Index 0 Read GetS Write SetS;
+    Property UpdateSQL : TStrings Index 1 Read GetS Write SetS;
+    Property DeleteSQL : TStrings Index 2 Read GetS Write SetS;
+    Property InsertSQL : TStrings Index 3 Read GetS Write SetS;
+    Property Connection : TSQLConnection Read FConnection Write SetConnection;
+    Property OnGetNewID : TNewIDEvent Read FOnGetNewID Write FOnGetNewID;
+    property OnGetParameterType : TGetParamTypeEvent Read FOnGetParamType Write FOnGetParamType;
+  Public
+    Constructor Create(AOwner : TComponent); override;
+    Destructor Destroy; override;
+  end;
+
+  TSQLDBWebDataProvider = Class(TCustomSQLDBWebDataProvider)
+  Published
+    Property SelectSQL;
+    Property UpdateSQL;
+    Property DeleteSQL;
+    Property InsertSQL;
+    Property Connection;
+    Property IDFieldName;
+    Property OnGetNewID;
+    property OnGetParameterType;
+  end;
+
+implementation
+
+{ $define wmdebug}
+
+{$ifdef wmdebug}
+uses dbugintf;
+{$endif}
+
+resourcestring
+  SErrNoSelectSQL = '%s: No select SQL statement provided.';
+  SErrNoUpdateSQL = '%s: No update SQL statement provided.';
+  SErrNoInsertSQL = '%s: No insert SQL statement provided.';
+  SErrNoDeleteSQL = '%s: No delete SQL statement provided.';
+  SErrUpdating = '%s: An error occurred during the update operation: %s';
+  SErrDeleting = '%s: An error occurred during the delete operation: %s';
+  SErrInserting = '%s: An error occurred during the insert operation: %s';
+  SErrNoNewIDEvent = '%s : Cannot generate ID: No OnGetNewID event assigned.';
+
+{ TCustomSQLDBWebDataProvider }
+
+function TCustomSQLDBWebDataProvider.GetS(AIndex: integer): TStrings;
+begin
+  Result:=FSQLS[AIndex];
+end;
+
+procedure TCustomSQLDBWebDataProvider.SetConnection(const AValue: TSQLConnection
+  );
+begin
+  if (FConnection=AValue) then exit;
+  If Assigned(FConnection) then
+    FConnection.RemoveFreeNotification(Self);
+  FConnection:=AValue;
+  If Assigned(FConnection) then
+    FConnection.FreeNotification(Self);
+end;
+
+procedure TCustomSQLDBWebDataProvider.SetS(AIndex: integer;
+  const AValue: TStrings);
+begin
+  FSQLS[AIndex].Assign(AValue);
+end;
+
+procedure TCustomSQLDBWebDataProvider.SQLChanged(Sender: TObject);
+begin
+  If (Sender=SelectSQL) and Assigned(FQuery) then
+    begin
+    FQuery.Close;
+    FQuery.SQL.Assign(SelectSQL);
+    end;
+end;
+
+procedure TCustomSQLDBWebDataProvider.ExecuteSQL(ASQL : TStrings; Msg : String = ''; DoNewID : Boolean = False);
+
+Var
+  Q : TSQLQuery;
+begin
+  {$ifdef wmdebug}SendDebug('Entering TCustomSQLDBWebDataProvider.ExecuteSQL');{$endif}
+  Q:=CreateQuery(Nil,Nil,ASQL);
+  try
+    Q.Transaction.Active:=True;
+    try
+      ApplySQLParams(Q,DoNewID);
+      Q.ExecSQL;
+      (Q.Transaction as TSQLTransaction).Commit;
+    except
+      On E : Exception do
+        begin
+        (Q.Transaction as TSQLTransaction).Rollback;
+        If (Msg<>'') then
+          E.Message:=Format(Msg,[Self.Name,E.Message]);
+        Raise;
+        end;
+    end
+  finally
+    Q.Free;
+  end;
+  {$ifdef wmdebug}SendDebug('Exiting TCustomSQLDBWebDataProvider.ExecuteSQL');{$endif}
+end;
+
+procedure TCustomSQLDBWebDataProvider.DoUpdate;
+
+begin
+{$ifdef wmdebug}SendDebug('Entering TCustomSQLDBWebDataProvider.DoUpdate');{$endif}
+  If (Trim(UpdateSQL.Text)='') then
+    Raise EFPHTTPError.CreateFmt(SErrNoUpdateSQL,[Self.Name]);
+  FLastNewID:='';
+  ExecuteSQL(UpdateSQL,SErrUpdating);
+{$ifdef wmdebug}SendDebug('Exiting TCustomSQLDBWebDataProvider.DoUpdate');{$endif}
+end;
+
+procedure TCustomSQLDBWebDataProvider.DoDelete;
+begin
+{$ifdef wmdebug}SendDebug('Entering TCustomSQLDBWebDataProvider.DoDelete');{$endif}
+  If (Trim(DeleteSQL.Text)='') then
+    Raise EFPHTTPError.CreateFmt(SErrNoDeleteSQL,[Self.Name]);
+  FLastNewID:='';
+  ExecuteSQL(DeleteSQL,SErrDeleting);
+{$ifdef wmdebug}SendDebug('Exiting TCustomSQLDBWebDataProvider.DoDelete');{$endif}
+end;
+
+procedure TCustomSQLDBWebDataProvider.DoInsert;
+begin
+{$ifdef wmdebug}SendDebug('Entering TCustomSQLDBWebDataProvider.DoInsert');{$endif}
+  If (Trim(InsertSQL.Text)='') then
+    Raise EFPHTTPError.CreateFmt(SErrNoInsertSQL,[Self.Name]);
+  FLastNewID:='';
+  ExecuteSQL(InsertSQL,SErrInserting,(IDFieldName<>''));
+{$ifdef wmdebug}SendDebug('Exiting TCustomSQLDBWebDataProvider.DoInsert');{$endif}
+end;
+
+procedure TCustomSQLDBWebDataProvider.Notification(AComponent: TComponent;
+  Operation: TOperation);
+
+begin
+  If (Operation=opRemove) then
+    begin
+    If (AComponent=FQuery) then
+      FQuery:=Nil
+    else if (AComponent=FConnection) then
+      FConnection:=Nil;
+    end;
+end;
+
+Function TCustomSQLDBWebDataProvider.CreateQuery(AOwner : TComponent; ATransaction : TSQLTransaction; ASQL : Tstrings) : TSQLQuery;
+
+begin
+  Result:=TSQLQuery.Create(AOwner);
+  If (AOwner<>Self) then
+    Result.FreeNotification(Self);
+  Result.DataBase:=Connection;
+  If ATransaction=Nil then
+    begin
+    ATransaction:=TSQLTransaction.Create(Result);
+    ATransaction.DataBase:=Connection;
+    end;
+  Result.Transaction:=ATransaction;
+  Result.SQL.Assign(ASQL);
+end;
+
+procedure TCustomSQLDBWebDataProvider.CheckDataset;
+
+begin
+{$ifdef wmdebug}SendDebug('Entering CheckDataset');{$endif}
+  If (Trim(SelectSQL.Text)='') then
+    Raise EFPHTTPError.CreateFmt(SErrNoSelectSQL,[Self.Name]);
+  If (FQuery=Nil) then
+    FQuery:=CreateQuery(Nil,Nil,SelectSQL)
+  else if not FQuery.Active then
+    FQuery.SQL.Assign(SelectSQL);
+{$ifdef wmdebug}SendDebug('Exiting CheckDataset');{$endif}
+end;
+
+Function TCustomSQLDBWebDataProvider.GetParamType(P : TParam; Const AValue : String) : TFieldType;
+
+begin
+  Result:=ftunknown;
+  If Assigned(FOnGetParamType) then
+    FOnGetParamType(Self,P.Name,AValue,Result);
+end;
+
+procedure TCustomSQLDBWebDataProvider.SetTypedParam(P : TParam; Const AValue : String);
+
+Var
+  I : Integer;
+  Q : Int64;
+  D : TDateTime;
+  ft : TFieldType;
+  F : Double;
+  B : Boolean;
+  C : Currency;
+
+begin
+  ft:=GetParamtype(P,AValue);
+  If ft<>ftUnknown then
+    begin
+    try
+      case ft of
+        ftInteger,
+        ftword,
+        ftsmallint  : I:=StrToInt(AValue);
+        ftDate      : D:=StrToDate(AValue);
+        ftDateTime,
+        ftTimestamp : D:=StrToDateTime(AValue);
+        ftBoolean   : B:=StrToBool(AValue);
+        ftTime      : D:=StrToTime(AValue);
+        ftLargeint  : Q:=StrToInt64(AValue);
+        ftCurrency  : C:=StrToCurr(Avalue);
+      else
+        ft:=ftString
+      end
+    except
+      ft:=ftUnknown
+    end;
+    end;
+  If (ft=ftUnknown) and (Length(AValue)<30) then
+    begin
+    if TryStrToInt(Avalue,I) then
+      ft:=ftInteger
+    else if TryStrToInt64(Avalue,Q) then
+      ft:=ftInteger
+    else if (Pos(DateSeparator,AValue)<>0) then
+        begin
+        if (Pos(TimeSeparator,AValue)<>0) and TryStrToDateTime(Avalue,D) then
+          ft:=ftDateTime
+        else if TryStrToDate(Avalue,D) then
+          ft:=ftDate
+        end
+    else If (Pos(TimeSeparator,AValue)<>0) and TryStrToTime(Avalue,D) then
+      ft:=ftTime
+    else if (Pos(DecimalSeparator,AValue)<>0) then
+      begin
+      if trystrtofloat(AValue,F) then
+        ft:=ftFloat
+      else if TryStrToCurr(Avalue,C) then
+        ft:=ftCurrency
+      end
+    else if TryStrToBool(Avalue,B) then
+      ft:=ftBoolean
+    end;
+  Case ft of
+    ftInteger,
+    ftword,
+    ftsmallint  : P.AsInteger:=I;
+    ftBoolean   : P.AsBoolean:=B;
+    ftLargeInt  : P.AsLargeInt:=Q;
+    ftDate      : P.AsDate:=D;
+    ftDateTime,
+    ftTimestamp : P.AsDateTime:=D;
+    ftTime      : P.AsTime:=D;
+    ftFloat,
+    ftBCD,
+    ftFMTBCD    : P.AsFloat:=F;
+    ftCurrency  : P.AsCurrency:=F;
+  else
+    P.AsString:=AValue;
+  end;
+end;
+
+procedure TCustomSQLDBWebDataProvider.ApplySQLParams(AQuery : TSQLQuery; DoNewID : Boolean = False);
+
+var
+  I: Integer;
+  P : TParam;
+  S : String;
+
+begin
+{$ifdef wmdebug}SendDebug('Entering ApplySQLPArams');{$endif}
+  For I:=0 to AQuery.Params.Count-1 do
+    begin
+    P:=AQuery.Params[i];
+    If (P.Name=IDFieldName) and DoNewID then
+      SetTypedParam(P,GetNewID)
+    else If Adaptor.TryFieldValue(P.Name,S) then
+      SetTypedParam(P,S)
+    else If Adaptor.TryParamValue(P.Name,S) then
+      SetTypedParam(P,S)
+    else
+      P.Clear;
+    end;
+{$ifdef wmdebug}SendDebug('Exiting ApplySQLPArams');{$endif}
+end;
+
+procedure TCustomSQLDBWebDataProvider.DoApplyParams;
+
+begin
+  CheckDataset;
+  ApplySQLParams(FQuery);
+end;
+
+function TCustomSQLDBWebDataProvider.GetDataset: TDataset;
+begin
+{$ifdef wmdebug}SendDebug('Get dataset: checking dataset');{$endif}
+  CheckDataset;
+  FLastNewID:='';
+  Result:=FQuery;
+{$ifdef wmdebug}SendDebug('Get dataset: activating transaction');{$endif}
+  If Not FQuery.Transaction.Active then
+    FQuery.Transaction.Active:=True;
+{$ifdef wmdebug}SendDebug('Get dataset: done');{$endif}
+end;
+
+function TCustomSQLDBWebDataProvider.GetNewID: String;
+
+begin
+  If Not Assigned(FOnGetNewID) then
+    Raise EFPHTTPError.CreateFmt(SErrNoNewIDEvent,[Self.Name]);
+  FOnGetNewID(Self,Result);
+  FLastNewID:=Result;
+end;
+
+function TCustomSQLDBWebDataProvider.IDFieldValue: String;
+
+begin
+{$ifdef wmdebug}SendDebug('Entering IDFieldValue');{$endif}
+  If (FLastNewID<>'') then
+    Result:=FLastNewID
+  else If (IDFieldName<>'') then
+    begin
+    If not Adaptor.TryParamValue(IDFieldName,Result) then
+      If not Adaptor.TryFieldValue(IDFieldName,Result) then
+        Result:=inherited IDFieldValue;
+    end
+  else
+    Result:=inherited IDFieldValue;
+{$ifdef wmdebug}SendDebug('Exiting IDFieldValue : '+Result);{$endif}
+end;
+
+constructor TCustomSQLDBWebDataProvider.Create(AOwner: TComponent);
+
+Var
+  I : Integer;
+  L : TStringList;
+
+begin
+  inherited Create(AOwner);
+  For I:=0 to 3 do
+    begin
+    L:=TStringList.Create;
+    L.OnChange:=@SQLChanged;
+    FSQLS[i]:=L;
+    end;
+end;
+
+destructor TCustomSQLDBWebDataProvider.Destroy;
+
+Var
+  I: Integer;
+
+begin
+  For I:=0 to 3 do
+   FreeAndNil(FSQLS[i]);
+  Connection:=Nil;
+  FreeAndNil(FQuery);
+  inherited Destroy;
+end;
+
+end.
+

+ 114 - 0
packages/fcl-web/src/webdata/webdata.txt

@@ -0,0 +1,114 @@
+FPC WebData architecture
+========================
+
+The aim of this set of components is to be able to easily send data 
+to a webapplication, and to handle updates of this data, all in a
+webserver module.
+
+The following components are used
+
+- TFPWebDataProvider
+  The central component, forming a bridge between TDataset and web content.
+
+- TCustomWebdataInputAdaptor
+    A class that transforms the input of a web request to something that
+    TFPWebDataProvider understands. Example implementations are provided 
+    for ExtJS, XML and JSON.
+
+- TWebdataInputAdaptor
+   A descendent of TCustomWebdataInputAdaptor that allows to select the
+   input format from a list of known formats.
+
+- TCustomHTTPDataContentProducer
+    This class produces the response for the webapplication. It is an
+    abstract class: descendents need to be made for the various expected
+    outputs. Example implementations are provided for ExtJS, XML and JSON.
+
+- THTTPDataContentProducer
+   A descendent of TCustomHTTPDataContentProducer that allows to select the
+   output format from a list of known formats.
+
+- TFPWebProviderDataModule
+   A THTTPSessionDatamodule descendent that can be used to handle data
+   requests from a webclient. It functions as a container for
+   TFPWebDataProvider components, InputAdaptors and Content producers.
+
+   A module is registered in the Lazarus IDE package under File/New.
+
+Typically, one will do the following
+ - Create a TFPWebProviderDataModule from the IDE.
+ - Drop some dataset components on it, and set them up for use with some
+   datasources
+ - For each dataset, drop a TFPWebDataProvider component on the module, 
+   and connect it to the datasource. The name of this component is exposed
+   to the client.
+ - Drop a suitable input adaptor.
+ 
+The data can then typically be read through the URL:
+baseurl/modulename/providername/read
+Or updated through the URLs
+baseurl/modulename/providername/update
+baseurl/modulename/providername/create
+baseurl/modulename/providername/delete
+where baseurl is the base URL for the web-application.
+
+Large applications: factory support
+For large-scale applications with lots of different datasets, there is
+support for registering dataproviders in a central factory system:
+
+The WebDataProviderManager function returns an instance of
+TFPWebDataProviderManager.
+
+It must be used to register WebDataProvider names and classes:
+
+Function RegisterProvider(Const AProviderName : String; AClass : TFPCustomWebDataProviderClass) : TWebDataProviderDef; overload;
+
+The first form registers a class: an instance of this class will
+be created by the factory whenever a provider of name AProviderName is
+requested.
+
+The TFPWebProviderDataModule class is aware of the WebDataProviderManager
+factory class, and will look there for a TFPCustomWebDataProvider instance
+if none is found in the webmodule instance itself and the
+'UseProviderManager' property is 'True'.
+
+The WebDataProviderManager factory can also Register a complete datamodule:
+
+Procedure RegisterDatamodule(Const AClass : TDatamoduleClass);
+
+This will register all WebDataProvider instances on the datamodule:
+An instance will be created, all  TFPCustomWebDataProvider instances
+will be registered with their component names. 
+When a provider belonging to such a datamodule is requested, then
+the module will be created, and the requested TFPCustomWebDataProvider 
+instance is returned. 
+
+A provider instance can be requested with the following factory methods:
+
+Function GetProvider(Const ADef : TWebDataProviderDef; AOwner : TComponent;out AContainer : TComponent): TFPCustomWebDataProvider; 
+Function GetProvider(Const AProviderName : String; AOwner : TComponent; Out AContainer : TComponent): TFPCustomWebDataProvider;
+
+The result is the provider instance. All instances are created using a
+container module: either this is the module class used in RegisterDatamodule
+or a vanilla TDatamodule class. This instance is returned in AContainer.
+
+The container must be freed by the caller.
+
+In practise, this means that one creates a datamodule, drops some
+TFPWebDataProvider instances on it, and adds the following call
+to the initialization section of the unit:
+
+WebDataProviderManager.RegisterDatamodule(TMyDataModule);
+
+The TFPWebProviderDataModule that handles web requests will then be able
+to handle requests for the TFPWebDataProvider instances on the datamodule.
+
+Note that the RegisterDataModule routine will create an instance of the
+datamodule to get a list of provider components (it uses the component.name
+property). The WebDataProviderManager's 'registering' property will be set 
+to true: this way one can avoid connecting to a database during registration.
+
+The WebDataProviderManager also handles the registration of inputadataptors
+and output contents producers.
+
+