From 4392bf4c5d188a9a03225a0ffa7f37466b73365d Mon Sep 17 00:00:00 2001 From: Norayr Chilingarian Date: Thu, 27 Mar 2014 16:44:51 +0400 Subject: [PATCH] linux clang platform added Former-commit-id: d2680335c65bc9ede4aedcb740186cbbb8ddd79c --- 05vishap.conf | 2 +- makefile.linux.clang.x86_64 | 303 ++++++ ocat | Bin 151012 -> 204112 bytes showdef.REMOVED.git-id | 2 +- src/lib/ooc/linux/clang/armv6j/oocC.Mod | 72 ++ .../ooc/linux/clang/armv6j_hardfp/oocC.Mod | 72 ++ src/lib/ooc/linux/clang/powerpc/oocC.Mod | 72 ++ src/lib/ooc/linux/clang/x86/oocC.Mod | 72 ++ src/lib/ooc/linux/clang/x86_64/oocC.Mod | 71 ++ src/lib/ooc2/linux/clang/oocwrapperlibc.Mod | 34 + src/lib/system/linux/clang/Console.Mod | 86 ++ src/lib/system/linux/clang/Files.Mod | 658 ++++++++++++++ src/lib/system/linux/clang/Files0.Mod | 630 +++++++++++++ src/lib/system/linux/clang/Kernel.Mod | 167 ++++ src/lib/system/linux/clang/Kernel0.Mod | 179 ++++ src/lib/system/linux/clang/SYSTEM.Mod | 520 +++++++++++ src/lib/system/linux/clang/Texts.Mod | 859 ++++++++++++++++++ src/lib/system/linux/clang/Texts0.Mod | 859 ++++++++++++++++++ src/lib/system/linux/clang/armv6j/Args.Mod | 64 ++ src/lib/system/linux/clang/armv6j/SYSTEM.c0 | 205 +++++ src/lib/system/linux/clang/armv6j/SYSTEM.h | 215 +++++ src/lib/system/linux/clang/armv6j/Unix.Mod | 419 +++++++++ .../system/linux/clang/armv6j_hardfp/Args.Mod | 64 ++ .../linux/clang/armv6j_hardfp/SYSTEM.c0 | 205 +++++ .../system/linux/clang/armv6j_hardfp/SYSTEM.h | 215 +++++ .../system/linux/clang/armv6j_hardfp/Unix.Mod | 419 +++++++++ .../system/linux/clang/armv7a_hardfp/Args.Mod | 64 ++ .../linux/clang/armv7a_hardfp/SYSTEM.c0 | 205 +++++ .../system/linux/clang/armv7a_hardfp/SYSTEM.h | 215 +++++ .../system/linux/clang/armv7a_hardfp/Unix.Mod | 419 +++++++++ src/lib/system/linux/clang/powerpc/Args.Mod | 64 ++ src/lib/system/linux/clang/powerpc/SYSTEM.c0 | 205 +++++ src/lib/system/linux/clang/powerpc/SYSTEM.h | 215 +++++ src/lib/system/linux/clang/powerpc/Unix.Mod | 419 +++++++++ src/lib/system/linux/clang/x86/Args.Mod | 64 ++ src/lib/system/linux/clang/x86/SYSTEM.c0 | 205 +++++ src/lib/system/linux/clang/x86/SYSTEM.h | 215 +++++ src/lib/system/linux/clang/x86/Unix.Mod | 419 +++++++++ src/lib/system/linux/clang/x86_64/Args.Mod | 65 ++ src/lib/system/linux/clang/x86_64/SYSTEM.c0 | 205 +++++ src/lib/system/linux/clang/x86_64/SYSTEM.h | 233 +++++ src/lib/system/linux/clang/x86_64/Unix.Mod | 501 ++++++++++ src/voc/linux/clang/armv6j/architecture.Mod | 4 + .../clang/armv6j_hardfp/architecture.Mod | 4 + .../clang/armv7a_hardfp/architecture.Mod | 4 + src/voc/linux/clang/extTools.Mod | 82 ++ src/voc/linux/clang/powerpc/architecture.Mod | 4 + src/voc/linux/clang/x86/architecture.Mod | 4 + src/voc/linux/clang/x86_64/architecture.Mod | 4 + src/voc/prf.Mod | 2 +- voc.REMOVED.git-id | 2 +- vocstatic.linux.clang.x86_64.REMOVED.git-id | 1 + 52 files changed, 10284 insertions(+), 4 deletions(-) create mode 100644 makefile.linux.clang.x86_64 create mode 100644 src/lib/ooc/linux/clang/armv6j/oocC.Mod create mode 100644 src/lib/ooc/linux/clang/armv6j_hardfp/oocC.Mod create mode 100644 src/lib/ooc/linux/clang/powerpc/oocC.Mod create mode 100644 src/lib/ooc/linux/clang/x86/oocC.Mod create mode 100644 src/lib/ooc/linux/clang/x86_64/oocC.Mod create mode 100644 src/lib/ooc2/linux/clang/oocwrapperlibc.Mod create mode 100644 src/lib/system/linux/clang/Console.Mod create mode 100644 src/lib/system/linux/clang/Files.Mod create mode 100644 src/lib/system/linux/clang/Files0.Mod create mode 100644 src/lib/system/linux/clang/Kernel.Mod create mode 100644 src/lib/system/linux/clang/Kernel0.Mod create mode 100644 src/lib/system/linux/clang/SYSTEM.Mod create mode 100644 src/lib/system/linux/clang/Texts.Mod create mode 100644 src/lib/system/linux/clang/Texts0.Mod create mode 100644 src/lib/system/linux/clang/armv6j/Args.Mod create mode 100644 src/lib/system/linux/clang/armv6j/SYSTEM.c0 create mode 100644 src/lib/system/linux/clang/armv6j/SYSTEM.h create mode 100644 src/lib/system/linux/clang/armv6j/Unix.Mod create mode 100644 src/lib/system/linux/clang/armv6j_hardfp/Args.Mod create mode 100644 src/lib/system/linux/clang/armv6j_hardfp/SYSTEM.c0 create mode 100644 src/lib/system/linux/clang/armv6j_hardfp/SYSTEM.h create mode 100644 src/lib/system/linux/clang/armv6j_hardfp/Unix.Mod create mode 100644 src/lib/system/linux/clang/armv7a_hardfp/Args.Mod create mode 100644 src/lib/system/linux/clang/armv7a_hardfp/SYSTEM.c0 create mode 100644 src/lib/system/linux/clang/armv7a_hardfp/SYSTEM.h create mode 100644 src/lib/system/linux/clang/armv7a_hardfp/Unix.Mod create mode 100644 src/lib/system/linux/clang/powerpc/Args.Mod create mode 100644 src/lib/system/linux/clang/powerpc/SYSTEM.c0 create mode 100644 src/lib/system/linux/clang/powerpc/SYSTEM.h create mode 100644 src/lib/system/linux/clang/powerpc/Unix.Mod create mode 100644 src/lib/system/linux/clang/x86/Args.Mod create mode 100644 src/lib/system/linux/clang/x86/SYSTEM.c0 create mode 100644 src/lib/system/linux/clang/x86/SYSTEM.h create mode 100644 src/lib/system/linux/clang/x86/Unix.Mod create mode 100644 src/lib/system/linux/clang/x86_64/Args.Mod create mode 100644 src/lib/system/linux/clang/x86_64/SYSTEM.c0 create mode 100644 src/lib/system/linux/clang/x86_64/SYSTEM.h create mode 100644 src/lib/system/linux/clang/x86_64/Unix.Mod create mode 100644 src/voc/linux/clang/armv6j/architecture.Mod create mode 100644 src/voc/linux/clang/armv6j_hardfp/architecture.Mod create mode 100644 src/voc/linux/clang/armv7a_hardfp/architecture.Mod create mode 100644 src/voc/linux/clang/extTools.Mod create mode 100644 src/voc/linux/clang/powerpc/architecture.Mod create mode 100644 src/voc/linux/clang/x86/architecture.Mod create mode 100644 src/voc/linux/clang/x86_64/architecture.Mod create mode 100644 vocstatic.linux.clang.x86_64.REMOVED.git-id diff --git a/05vishap.conf b/05vishap.conf index 7a43aef3..98072b24 100644 --- a/05vishap.conf +++ b/05vishap.conf @@ -1 +1 @@ -/Users/noch/local/voc-1.0/lib +/opt/voc-1.0/lib diff --git a/makefile.linux.clang.x86_64 b/makefile.linux.clang.x86_64 new file mode 100644 index 00000000..00ea58d9 --- /dev/null +++ b/makefile.linux.clang.x86_64 @@ -0,0 +1,303 @@ +#SHELL := /bin/bash +BUILDID=$(shell date +%Y/%m/%d) +TOS = linux +TARCH = x86_64 +#TARCH = x86 x86_64 armv6j armv6j_hardfp armv7a_hardfp powerpc +CCOMP = clang +RELEASE = 1.0 + + +INCLUDEPATH = -Isrc/lib/system/$(TOS)/$(CCOMP)/$(TARCH) + +SETPATH = CFLAGS=$(INCLUDEPATH) PATH=.:/bin:/usr/bin MODULES=.:src/lib:src/lib/v4:src/lib/v4/$(TARCH):src/lib/system/$(TOS)/$(CCOMP):src/lib/system/$(TOS)/$(CCOMP)/$(TARCH):src/lib/ulm:src/lib/ulm/$(TARCH):src/lib/ooc2:src/lib/ooc2/$(TOS)/$(CCOMP):src/lib/ooc:src/lib/ooc/$(TOS)/$(CCOMP)/$(TARCH):src/lib/pow:src/lib/misc:src/lib/s3:src/voc:src/voc/$(TOS)/$(CCOMP):src/voc/$(TOS)/$(CCOMP)/$(TARCH):src/tools/ocat:src/tools/browser:src/tools/vocparam:src/tools/vmake:src/tools/coco:src/test + +VOC = voc +VERSION = $(TOS).$(CCOMP).$(TARCH) +VOCSTATIC0 = $(SETPATH) ./vocstatic.$(TOS).$(CCOMP).$(TARCH) +VOCSTATIC = $(SETPATH) ./voc +VOCPARAM = $(shell ./vocparam > voc.par) +LIBNAME = VishapOberon +LIBRARY = lib$(LIBNAME) + +ifndef PRF +PRF = "/opt" +endif +PREFIX = $(PRF)/voc-$(RELEASE) +PREFIXLN = $(PRF)/voc + +CCOPT = -fPIC $(INCLUDEPATH) -g + +CC = clang $(CCOPT) -c +CL = clang $(CCOPT) +LD = clang -shared -lX11 -o $(LIBRARY).so +# s is necessary to create index inside a archive +ARCHIVE = ar rcs $(LIBRARY).a + +#%.c: %.Mod +#%.o: %.c +# $(CC) $(input) + +all: stage2 stage3 stage4 stage5 stage6 stage7 + +# when porting to new platform: +# * put corresponding .par file into current directory. it can be generated on the target platform by compiling vocparam (stage0) and running (stage1) +# * run make port0 - this will generate C source files for the target architecture +# * move the source tree to the target machine, and compile (or compile here via crosscompiler) (port1) +port0: stage2 stage3 stage4 + +# now compile C source files for voc, showdef and ocat on target machine (or by using crosscompiler) +port1: stage5 +# after you have "voc" compiled for target architecture. replace vocstatic with it and run make on target platform to get everything compiled + +# this builds binary which generates voc.par +stage0: src/tools/vocparam/vocparam.c + $(CL) -I src/lib -o vocparam src/tools/vocparam/vocparam.c + +# this creates voc.par for a host architecture. +# comment this out if you need to build a compiler for a different architecture. +stage1: + #rm voc.par + #$(shell "./vocparam > voc.par") + #./vocparam > voc.par + $(VOCPARAM) + +# this copies necessary voc.par to the current directory. +# skip this if you are building compiler for the host architecture. +stage2: + cp src/par/voc.par.$(CCOMP).$(TARCH) voc.par +# cp src/par/voc.par.gnu.x86_64 voc.par +# cp src/par/voc.par.gnu.x86 voc.par +# cp src/par/voc.par.gnu.armv6 voc.par +# cp src/par/voc.par.gnu.armv7 voc.par + cp src/voc/prf.Mod_default src/voc/prf.Mod + +# this prepares modules necessary to build the compiler itself +stage3: + + $(VOCSTATIC0) -siapxPS SYSTEM.Mod + $(VOCSTATIC0) -sPS Args.Mod Console.Mod Unix.Mod + sed -i.tmp "s#/opt#$(PRF)#g" src/voc/prf.Mod + $(VOCSTATIC0) -sPS prf.Mod + $(VOCSTATIC0) -sPS oocOakStrings.Mod architecture.Mod version.Mod Kernel0.Mod Modules.Mod + $(VOCSTATIC0) -sxPS Files0.Mod + $(VOCSTATIC0) -sPS Reals.Mod Texts0.Mod errors.Mod + +# build the compiler +stage4: + $(VOCSTATIC0) -sPS extTools.Mod + $(VOCSTATIC0) -sPS OPM.cmdln.Mod + $(VOCSTATIC0) -sxPS OPS.Mod + $(VOCSTATIC0) -sPS OPT.Mod OPC.Mod OPV.Mod OPB.Mod OPP.Mod + $(VOCSTATIC0) -smPS voc.Mod + $(VOCSTATIC0) -smPS BrowserCmd.Mod + $(VOCSTATIC0) -smPS OCatCmd.Mod + +#this is to build the compiler from C sources. +#this is a way to create a bootstrap binary. +stage5: + $(CC) SYSTEM.c Args.c Console.c Modules.c Unix.c \ + oocOakStrings.c architecture.c prf.c version.c Kernel0.c Files0.c Reals.c Texts0.c \ + extTools.c \ + OPM.c OPS.c OPT.c OPC.c OPV.c OPB.c OPP.c errors.c + + $(CL) -static voc.c -o voc \ + SYSTEM.o Args.o Console.o Modules.o Unix.o \ + oocOakStrings.o architecture.o prf.o version.o Kernel0.o Files0.o Reals.o Texts0.o \ + extTools.o \ + OPM.o OPS.o OPT.o OPC.o OPV.o OPB.o OPP.o errors.o + $(CL) BrowserCmd.c -o showdef \ + SYSTEM.o Args.o Console.o Modules.o Unix.o oocOakStrings.o architecture.o prf.o version.o Kernel0.o Files0.o Reals.o Texts0.o \ + OPM.o OPS.o OPT.o OPV.o OPC.o errors.o + + $(CL) OCatCmd.c -o ocat \ + SYSTEM.o Args.o Console.o Modules.o Unix.o oocOakStrings.o architecture.o prf.o version.o Kernel0.o Files0.o Reals.o Texts0.o + +# build all library files +stage6: + #v4 libs + $(VOCSTATIC) -sP Kernel.Mod + $(VOCSTATIC) -sP Files.Mod + $(VOCSTATIC) -sP Texts.Mod + $(VOCSTATIC) -sP Printer.Mod + $(VOCSTATIC) -sP Strings.Mod + $(VOCSTATIC) -sP Sets.Mod + $(VOCSTATIC) -sP Sets0.Mod + + #ooc libs + $(VOCSTATIC) -sP oocAscii.Mod + $(VOCSTATIC) -sP oocStrings.Mod + $(VOCSTATIC) -sP oocStrings2.Mod + $(VOCSTATIC) -sP oocCharClass.Mod + $(VOCSTATIC) -sP oocConvTypes.Mod + $(VOCSTATIC) -sP oocIntConv.Mod + $(VOCSTATIC) -sP oocIntStr.Mod + $(VOCSTATIC) -sP oocSysClock.Mod + $(VOCSTATIC) -sP oocTime.Mod +# $(VOCSTATIC) -s oocLongStrings.Mod +# $(CC) oocLongStrings.c +# $(VOCSTATIC) -s oocMsg.Mod +# $(CC) oocMsg.c + + + #ooc2 libs + $(VOCSTATIC) -sP ooc2Strings.Mod + $(VOCSTATIC) -sP ooc2Ascii.Mod + $(VOCSTATIC) -sP ooc2CharClass.Mod + $(VOCSTATIC) -sP ooc2ConvTypes.Mod + $(VOCSTATIC) -sP ooc2IntConv.Mod + $(VOCSTATIC) -sP ooc2IntStr.Mod + $(VOCSTATIC) -sP ooc2Real0.Mod + #ooc libs + $(VOCSTATIC) -sP oocLowReal.Mod oocLowLReal.Mod + $(VOCSTATIC) -sP oocRealMath.Mod oocOakMath.Mod + $(VOCSTATIC) -sP oocLRealMath.Mod + $(VOCSTATIC) -sP oocLongInts.Mod + $(VOCSTATIC) -sP oocComplexMath.Mod oocLComplexMath.Mod + $(VOCSTATIC) -sP oocLRealConv.Mod oocLRealStr.Mod + $(VOCSTATIC) -sP oocRealConv.Mod oocRealStr.Mod + $(VOCSTATIC) -sP oocMsg.Mod oocChannel.Mod + $(VOCSTATIC) -sP oocStrings2.Mod oocRts.Mod oocFilenames.Mod + $(VOCSTATIC) -sP oocTextRider.Mod oocBinaryRider.Mod oocJulianDay.Mod + $(VOCSTATIC) -sP oocFilenames.Mod + $(VOCSTATIC) -sP oocwrapperlibc.Mod + $(VOCSTATIC) -sP oocC.Mod + $(VOCSTATIC) -sP oocX11.Mod + $(VOCSTATIC) -sP oocXutil.Mod + $(VOCSTATIC) -sP oocXYplane.Mod + + #Ulm's Oberon system libs + $(VOCSTATIC) -sP ulmSys.Mod + $(VOCSTATIC) -sP ulmSYSTEM.Mod + $(VOCSTATIC) -sP ulmASCII.Mod + $(VOCSTATIC) -sP ulmSets.Mod + $(VOCSTATIC) -sP ulmObjects.Mod + $(VOCSTATIC) -sP ulmDisciplines.Mod + $(VOCSTATIC) -sP ulmPriorities.Mod + $(VOCSTATIC) -sP ulmServices.Mod + $(VOCSTATIC) -sP ulmEvents.Mod + $(VOCSTATIC) -sP ulmResources.Mod + $(VOCSTATIC) -sP ulmForwarders.Mod + $(VOCSTATIC) -sP ulmRelatedEvents.Mod + $(VOCSTATIC) -sP ulmIO.Mod + $(VOCSTATIC) -sP ulmProcess.Mod + $(VOCSTATIC) -sP ulmTypes.Mod + $(VOCSTATIC) -sP ulmStreams.Mod + $(VOCSTATIC) -sP ulmAssertions.Mod + $(VOCSTATIC) -sP ulmIndirectDisciplines.Mod + $(VOCSTATIC) -sP ulmStreamDisciplines.Mod + $(VOCSTATIC) -sP ulmIEEE.Mod + $(VOCSTATIC) -sP ulmMC68881.Mod + $(VOCSTATIC) -sP ulmReals.Mod + $(VOCSTATIC) -sP ulmPrint.Mod + $(VOCSTATIC) -sP ulmWrite.Mod + $(VOCSTATIC) -sP ulmTexts.Mod + $(VOCSTATIC) -sP ulmStrings.Mod + $(VOCSTATIC) -sP ulmConstStrings.Mod + $(VOCSTATIC) -sP ulmPlotters.Mod + $(VOCSTATIC) -sP ulmSysTypes.Mod + $(VOCSTATIC) -sP ulmSysConversions.Mod + $(VOCSTATIC) -sP ulmErrors.Mod + $(VOCSTATIC) -sP ulmSysErrors.Mod + $(VOCSTATIC) -sP ulmSysIO.Mod + $(VOCSTATIC) -sP ulmLoader.Mod + $(VOCSTATIC) -sP ulmNetIO.Mod + $(VOCSTATIC) -sP ulmPersistentObjects.Mod + $(VOCSTATIC) -sP ulmPersistentDisciplines.Mod + $(VOCSTATIC) -sP ulmOperations.Mod + $(VOCSTATIC) -sP ulmScales.Mod + $(VOCSTATIC) -sP ulmTimes.Mod + $(VOCSTATIC) -sP ulmClocks.Mod + $(VOCSTATIC) -sP ulmTimers.Mod + $(VOCSTATIC) -sP ulmConditions.Mod + $(VOCSTATIC) -sP ulmStreamConditions.Mod + $(VOCSTATIC) -sP ulmTimeConditions.Mod + $(VOCSTATIC) -sP ulmSysConversions.Mod + $(VOCSTATIC) -sP ulmSysStat.Mod + $(VOCSTATIC) -sP ulmCiphers.Mod + $(VOCSTATIC) -sP ulmCipherOps.Mod + $(VOCSTATIC) -sP ulmBlockCiphers.Mod + $(VOCSTATIC) -sP ulmAsymmetricCiphers.Mod + $(VOCSTATIC) -sP ulmConclusions.Mod + $(VOCSTATIC) -sP ulmRandomGenerators.Mod + $(VOCSTATIC) -sP ulmTCrypt.Mod + + #pow32 libs + $(VOCSTATIC) -sP powStrings.Mod + + #misc libs + $(VOCSTATIC) -sP MultiArrays.Mod + $(VOCSTATIC) -sP MultiArrayRiders.Mod + $(VOCSTATIC) -sP MersenneTwister.Mod + $(VOCSTATIC) -sP Listen.Mod + + #s3 libs + $(VOCSTATIC) -sP ethBTrees.Mod + $(VOCSTATIC) -sP ethMD5.Mod + $(VOCSTATIC) -sP ethSets.Mod + $(VOCSTATIC) -sP ethZlib.Mod + $(VOCSTATIC) -sP ethZlibBuffers.Mod + $(VOCSTATIC) -sP ethZlibInflate.Mod + $(VOCSTATIC) -sP ethZlibDeflate.Mod + $(VOCSTATIC) -sP ethZlibReaders.Mod + $(VOCSTATIC) -sP ethZlibWriters.Mod + $(VOCSTATIC) -sP ethZip.Mod + $(VOCSTATIC) -sP ethRandomNumbers.Mod + $(VOCSTATIC) -sP ethGZReaders.Mod + $(VOCSTATIC) -sP ethGZWriters.Mod + + +# build remaining tools +# $(VOCSTATIC0) -sPS compatIn.Mod +# $(VOCSTATIC0) -smPS vmake.Mod +# $(CC) compatIn.c +# $(CL) vmake.c -o vmake SYSTEM.o Args.o compatIn.o Texts.o Console.o Files.o Reals.o Modules.o Kernel.o Unix.o oocOakStrings.o oocIntStr.o oocConvTypes.o oocIntConv.o + + + +stage7: + #remove non library objects + rm -f Kernel0.o Files0.o Texts0.o architecture.o prf.o version.o extTools.o OPM.o OPS.o OPT.o OPC.o OPV.o OPB.o OPP.o errors.o + #objects := $(wildcard *.o) + #$(LD) objects + $(ARCHIVE) *.o + #$(ARCHIVE) objects + $(LD) *.o + echo "$(PREFIX)/lib" > 05vishap.conf + +clean: +# rm_objects := rm $(wildcard *.o) +# objects + rm *.h + rm *.c + rm *.sym + rm *.o + rm *.a + rm *.so + +install: + test -d $(PREFIX)/bin | mkdir -p $(PREFIX)/bin + cp voc $(PREFIX)/bin/ + cp showdef $(PREFIX)/bin/ + cp ocat $(PREFIX)/bin/ + #cp vmake $(PREFIX)/bin/ + cp -a src $(PREFIX)/ + + test -d $(PREFIX)/lib/voc | mkdir -p $(PREFIX)/lib/voc + test -d $(PREFIX)/lib/voc/ | mkdir -p $(PREFIX)/lib/voc + test -d $(PREFIX)/lib/voc/obj | mkdir -p $(PREFIX)/lib/voc/obj + test -d $(PREFIX)/lib/voc/sym | mkdir -p $(PREFIX)/lib/voc/sym + + cp $(LIBRARY).so $(PREFIX)/lib + cp $(LIBRARY).a $(PREFIX)/lib + cp *.c $(PREFIX)/lib/voc/obj/ + cp *.h $(PREFIX)/lib/voc/obj/ + cp *.sym $(PREFIX)/lib/voc/sym/ + + cp 05vishap.conf /etc/ld.so.conf.d/ + ldconfig + ln -s $(PREFIX) $(PREFIXLN) + +# cp *.o $(PREFIX)/lib/voc/$(RELEASE)/obj/ +uninstall: + rm -rf $(PREFIX) + rm -rf $(PREFIXLN) diff --git a/ocat b/ocat index a4727826442f2ef7b4d37096433a67cff723316d..37edd0a7853987d12fab6088bc77ecd0bf9c27a8 100755 GIT binary patch literal 204112 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
9odX4d0u1kxkrB&84 zU(EAu5)x+E9aQOhqg__^biYd1J1br9taQC0Lhq$o{yvh^X>5_@-MgINJDqYmopL&* zO%@4nyjwc?Ra*WRB=$bTC&k^|Pwah8vG+N}-Y3dB$1GGX|Zf$0-V7lb^|2FrEw} zvA;5+Qrw&U#Qw@D_E%1^zcPMi2mgG==g%auFBm;i+yuEFsJhY%PO&dI#lGP5`4^l% z{~P7=TK*)eV4f1?!NF>=Fx@FyXD^p{PAigO7TF-3%)HQ%RzjjWrtWyA8H-M zw`q3LRAF=;Y#qe0?jk*m&feBR{6X0}Q}{}H3+mwSV)&6ycIb0Iw5;)KYLXu*YrM=U zWeskBnI;|WM|gLeI}OdY6DQ8 zNjqogZd~e2?3~e2L+-D$uyaO74Fyrg0(8_+5EU#yM-2rrj0NbZAs2APh|JcTenmA4 z&{0E?GKK}{sG%T2EI>yM1yRESbktA~b(#H0{fc@PpreK&rI7{bsG%StEI>yM1rcQd zI%+70)hs|q4F%E80(8_+5bNaTAK!r-qUBHz$!tk}qveo3MKkds-VR)JGn(>jYMoIz zx8t_#MBLZ0(E)k}MMZPdK(qErPXIL9PvK=wP}`&2LM=Aq*ez#hITSXS_oG<0nM0Gi`3uyPm6by?vbi7o z`B`Shu-Tf~0Au0o)RH}Slv97-hk~br(D#7J)`f9faVW%7ACg!5xs=;* z&ft|Mo~&i*2dGTo5s>N^YhU?Ll*Pfbqi8P{7{)hOuXpoxY000F6>BB;YT8?pR7A@b zis(m4+;NnrM~Z3Q>lAmK5Vul@8!p5}gg8kxYT3dT`rk<08B`)F#oUn*$5&Zr5OlnS zM4dF%-Gu8LD$*gd{<2?@b3~o1-RGAg>v_L{aiNfA7E#Fyw#(cjKXT%}K$^kDtG(bA zRjPtYU0f}5FYQ{>s@>pn<6Bx zcJckoDJdb*wS+7+Md%U{rvmE))#&E050F&7W{#!W8ji|Zmh5-d)*!7TYHJX+trWF2 zh}t5ewgx4i&(*U8RWE9j6izixrrOp-Wi8KVYNOLzY>jL_A%BfSn>A7!&74UxZtOWI zkPfh%TC~ND3Ng3HjSd+%DjA-IBxC+|S^rB?7Mz@~s^^PRt6ls{rSnCps6Zvtq}DR6 zQP?>0F}MG0p|zy0bkp-6wm?X!Q(wyTlCE9?n=OU_?;lZEoz|3H{m5z5)i+>!SatPQ z09Sv<70IrC3u$x2JrfBX(=Oo2Bbvq4{@DIAydqmTne@IZ%B;vbJkXY@o|5IA8^+TB4ZC(sFdl(~n95d*{z7Q92mi521p z3j|TgJYA@ofB%2vQ1QzFT!8xJ072k{Jq9~%9|@pe4xq>B=b&OnzZ~EuPkfftHnUH} zt@$|aN8m>?ESv>)oCS8AK0D4rJI*3I<Tb|4a>$yzI+P&$xhJ5+OUS~8W?zC^@jDgl zj!bji2?PBGR^ttM7Yy`Ui-3V%2SIXJ2VQ>fdm9wJaf3aC^NP}g+&=;1FcMfz_S3j^ zKZlP!L{Bj3;$s(PDjRRF>>@a`?=Q&0J*5lp%a9^nIRi9}v}O7F`vZIXC?Dh#e52f?-Y}M4T@{@Q&>(F|6DPj#<@GiG%)}0oC$p6Nij3u7n{W$}5;Ls7dRB8PysRlg& z?I~C!Q|QIep1LSKx7SNN_AWYDlgFFAB2My(_$D)C;MYkAOEwA0CQXcmP-!qV%jzt+ zjB4`Zz$v^NNh8?utfDOBrk7-}6rN;pNYE`EY9K zKTzgL5;q*vX|)o!nZ$VpQtun$E_w@ja^aG!!VPh|Kot^I>4vxipe`e7s2ff3Pf%-# zI?j!zFd#ruviI?thPkQtkw<2iAg{X;A1M@M(@naJVRfEAU|qs}{xVpN_C2`IPetoc zpw9c&G@#F(LFJq9@h2*OrAe0%o8_T5k?_e2ZyfOyVek+HImE5VoiXV7a#Az=!1^;J z;n!6>M&nCOuo8ZMgt$1%@`<~M&JWk1Yv3L>pd)o0(kEmC3Lqo}8w8P4Qm_G?A(j+u zKnwZlLdpnML@_|4phB#Oj@0py>l62ORz&BBWx3Z_5gjC6By#q^StvnHkC~}5sO3-( z;e4E>v+}q!<2a~sClx;ofYwM&c&!F|abY4>@oja^ODXzuSM5i#?m8D{=RNmBIS41M9~QtRFkDe(b>d zu>pln8eGaVq z99Z``ut0~3d0t{AZZB9Fta}|;_d2ldbzt4=z`ECg zb*}^KUI*5_4y=0>R_?ERIoAIKs;hj!`XR8^Jtwge_ZV0itRFhCe(1pZp#$rO4y+$K zuzu*k`k@2shYqYCDy-bDA9AcdY=xE}fMFj1YvZpZR^lE7D}(g|2i6Z9SU+%J{lJ0s z0|(X*99TbaVEw>>^#g^KHl%^XF@71EF&qfrqNMkMd)+T3ZsPWWmBIbK1NZw5-0wSZ zzwf~Pz61CB4&3iMaKG=s{l3D@{o#FX<8y)PT5Kh;nTU@=Dxhrxr*I;Y#<1zGq6ZON z{fY8?pWgsX+pr4(55?8I-Ue4S!c5xR z$)@!|@nxu$UCuTg3L%H44LmHaY(~k0^n~_uwhUZ6tt#oVlTl4?qJnc6Nve>APR$gi z-;_nFEUf9vD0d5^urDNYJ=QOGi^?6mjXL)NM(a{+*#`NO#jAK(I@43!PO`e#7Fj;; z6ASW>sn#w=D4Q8;FGFg$>Vl1D&+iB%83Nera)Yg zjlm}ho==kNjZPZHpv|Ce{SI+7eERbmu$b4 zs`#z6K(vJa+KnP3LhNrP_(p;D6^XW9pjBjD&_(AD6EBIHbV56u;k?@ioREt|bDy3ikSEr%ex})vgI`tfM z2GRD4j0E|sDotH<71{QRtQU4uWSu~$$Qt3eiVOwcq_*|&ig?>|Ur;m*#eG51XnXDp ziryrBLDBdYeDQ~*Vwv73Ra^FVr;24##YW-YWm3g@p`s$|O5P@1W%}2mc}sR^oV_$2`dee zR$A94dW@pmrIi$YtW{V^(MMZFk5TlYR;~C8vQkKIm)7~>AC{H)DY}sU4>4Sn@RN=q zomSE02;3P%(uR=|?rtGzL+J0@w+x86~`yDb8A^ShetT za#M8L!Nk}rtXHSpO)K`1*k$@ADee~CDR!At>@p=*$XOxfL_{MfvQaCpAhCDo9a7v! zhEwbvPO*15#ondFYWnFU=TUByqf$m;mQ&WFPFasCSz7V=RQL(KLKaw-DMck8sb&VLTD_)0R>{l@lUVWQ>|%T%=eiWJ&`r52$5SCFy=wBjfgeB6l20(bT+ z__(v+rj1E~o(NE4(PB~9ma`>S1l<^LivlM{`$$7@uBFq22 zpPXl$a-Ol|@WJevjGRp*=UJmimLFZ}G|00~InP>hxbHk`DBt1n)vpXSY49OXk@aFa zea;ZmX`NP_pi18|w#&*M9O$g{EoY@~S(S3fdCL$Xpd31SoRumP1JsLD%SXm0DgCv6 zwS45PwN#FcfF?$hy~6I58AwIl4n}mKu;ahT<%tT12Q8%%Tl!y>p)EqXT4Wy{NP_ z>t0^z6s=e*N2Moab;!!z81Ag}Bxj{3IV(LWOAHK)gyJX3O68z3+QPsUuacP?#lTRV zMGqJB&daspLc(xoR*$TE>4{DZcRDfL>BMlS6T_VfLkSHmv0`T1uaIF}~?#ZGjM*R2BiieW|yR){86u_5{aw@RfslaZh0=tz0 zqUCy(0;1OUvL5A4g<11#s%2kRyOjRIDb8BnBVWi99qa$4oA06qE7=)%Lxs;Fcnc`%Zs0BmP ze5z%Ft3yh^;WTG06P&e7uxjDoL!97}J)wk)Rb-=Rwuvr!SVgZMDZZL&dEcd-A*A0g zuZWrWd93$cNv`$k68@FK_pMrZWcI#G1n`j{J&j=>DqXbVIEg*zsykPRy>^@ho)V~N|F|ufCWrrw*T#P#wfHWAJ<;7R;l44+g3YU*=yq6R zqFc2rS8AeLS>qVVo#ZB*dS^%kf|s}jOe{G0T%>4(>)iWl-OCWGa@hQPm6P4nf;?v6 zVXvYQuK$h1D;nWCS3}VV*VzzTI>L3@U168HX{I(hziADAPURK-&(+s#a@|_GH*)ZhEW-dP$IWWis@Y!9J>Q zs(U*;3F)(fZo)Us{idL&3!j|srYD~GF6=a|_(5uhq`UEZ!u+?$BS>m>nv{l?-jj4Y zyeG*GM}a&K)Lw8qyyr#UD%^Ycxw7Bz1Cd7Ovu#0sR9VqzmSTdr-A#|`DO4Nq%Q^vP z;br0)d7EA=|OHHOSu`py-}f97^CnfV$gVEzee6 zZJn_yxt|s;yWQ`J-lvs5NhUeb-6K7+L7GPO(-WPZd7|Z++;>h?CMn^rb|QB*>QLNK zM`cXHJ?|um7$(Ri6DS%Ts*vcDr6>KQZNQ%-oUbmin`E>!30#$%MA2|nZj#Zm0=OzS ziK5%vv;j)e=*f18RZ=3>np~oyvDV}gtE5CU0+*<0`pRDEb7Z;=u1#`i8!yKsWx5S= zh>MCLZi5`+B4Y8mL5@^%wRsO8Z1B}#(TNo)_h){&>d2u>Kuwz zo#PHEQFRVQi|@0R?x3bw$*QHyre#*s@cr$TYR9^SPXj9%og}2anKQ^hE18%AWwg7B z3G>RS`f6rP)qJpBEq5qkUcOqp2D`H4Ar5Nyg;ccL?9lZ z810JjQ<-C>WCX_%<~8gS_y7-Daad=)OtZxPL^8%lrC7xnrx;0@<5bBIVsB-12#4Z` z0WZr8vzH1HqMdGIqUF)jd=OJKTAB}Hw@K?@#^!^VqK~y|1C*rUs!Bfh+%6@erMW~! zqoujT+oeRzMO>ny@l6~24Y))Kvs7>XF2)#T^J`>|lO#i^-ofZJ61~TQqX%6LFlNFUYUzS%@#TvP`Y76i2aQG0-WWy&Ujum!gh9dA)fELcLTyt3C*P@T})Q%A?24r zFq^F50Wdux%_bvy#TO#7bwmd4JbX-{imx{5(#V!(jvGgT-$JyD!kPX)ev7aZw(a;fc2I2)o42H7w z>v-g4S$JKThxRbqDWw92e^#YbR^v1@i1#UF=ooP#`70uh3!zC=omnOBm0;4(OJlN(y|M*Nq*SQ z4_P@mR0!|<&a)(p$vG7aFJqJ`rxJOq;JUdaBqwJalJYVjG7$0!0?86}7G&}$kUqtl zGg`4+kq|Ctyz^;Nmd9+X$}jGJ=a6fmC$~!<=8LOalXuTG_>DHWOdF z&^#IAc%4?vv6bZ#@dfb=$UI@6e5FA_#y&o~VGH{kwn%7)7Y`DUfRz_EF1GTzL?e_a zlV$82bhhn)(bDXh9Hpv|-9rXCn`e;9<1}HJ6z&p@SS|}ma&Qj(u?U76B1@wIGSyaO zn5uazB{<|$tf84)88#uJErsyQ}02S1C}s_%g0yb%6hwexd@m^2O|odS<3Bk8%~ere39jotfiQ zKi8>#o>1|BhL}W>e_H)A136o0V=8TU4;3Si*KXDvfg{)IK{Pa3Jt#-?pnRt)1x{6b zswE4ByY=gv|H?MS8K&}StCwcn;D6aTa?r}y=>K8thE*J6xAbgh$Nx8G%IKWw?}hfZ z_@C+PY$La`jqJ|+uW;bkCTJl2A0hbvQ&>44pQJKVr_9%xv@nNTfTwH6LQyAkx2~GQmjB7#Br^C0rRG3T6N(+YQLDGM;AzBAMxb zptG$8Ioqnt?m6Gx9RHOW-&xQ9>yYwo=kWf!Zu4LF5!1Y%dcAP5T;*bU znNc8LgqZLN8X37SWEKa7mXXnvMOLdz=khyz!XhX*%`|al5-4%HUC`-v1C-k-Pp}1o z12ZZ-YmnwGRwtsZmc>@!c-Mr+#l#y71Tzj)s0 zxhSMf3s0Lq;nL9&Dn7k=^~x31xW|SD794uxun^s7MkVv==M?`U7E8ry^$~u3m|s86 zAL|N-W1IA$eltakVg7iR88<7F^=4&vva741-fYo_1>#|SsXuIn&8o0jZTf2y;Z&Ax zjPCGmjq4-*X40(f&SJ*8HgmK$r7!WDV^M0cKWzq#m$a>3v$H#$PU~a*X06!}){CI) z7&-%_2cJ2FJtYQ`w$HIs>0S27kp=&cQ}@_wP$`NhXpeY)R!BLI1~ z>KB!Glj*csq*wVDdCjrA^>h5@g&W z(g(Wq>cER$Gal2A_ZvA6dG#%NiTOy}9IM}p-`a?6OPVp$Z}uh4vE9Ah=}r1@f6@%Y z#JrBU*)kIbtv9Q>Wx`4R-SORIrDPgSu-Saryg6>3r~ir-zlK_kKWVV888Q1hlgVxR zk|MJsnM`)Y&<@?LyPXYjj8WE^-HBw}tVQFbli@IKaEBteR3`h92f~T9DYMe7N}JvK zV=NHsj+wRkuK|1$RVO~*NTwR%$uKYEPvIt&2yY`PeP;226ey&m%+4gP-T1{Qf6Ca? z`i0lrlq7tklgV__ycFh5-tC1?87~;~z2<6ttiL;!GUKZf;jXyjFQNW6ryPH9r*Hj- zW{Sg?Ze#w2FqEqz%wgl!>pQ&LQt|NG?v&{V)I(g*$Kt{ z2^fMJ);P?}dhc2=&{~yYa& znC`}fjVH+WFHNW5;^BCAcx@tV9Bwr$ypt2u1gT^^mPnDo%y24c`e8P(`;y`G=43jN z=uU?d=>z>!!jSQS_KyLGO+7A|2JjeKCt+6g(cKGR!XR;S zm1K%+37LLqpMqV&sRs0q4Qom7U$?>bgO<_kAD>1}skx<$0$tUyak z0y|2K?En^CtH9^C^wh>LU9w{7qGq88fp5Pugp2@R0`OzIyU_1aeGR}1^EN!={Zc>C zAJeD$^~wH3gL$0Se8EhGS@)qCErIx!S}&#%w)!v}D)T59As6J|q~Q0gSi zP`Wk+NWZ1jzn}KBOP9`zEo%Ob_N$JB$O4-2J3P5Dt8UUy_jl^G{zTYJw2U>YTJ#k~ z`luorg3t8NL^D;R4>;zp$9XfY(of>1N`$$=e#rcAa(!aJ7=-R@j*Vl4PU#m4vEwiU zv?TRNkv_U8iTWVB%HMF)8(ws7kTF=jCETe`qA>{bhuH!PPHsuIV8RHSedcLD*V{`fYn@-(Rv|b;bjtD?-Qx^`B(STZ?&V72FN;MF~2R z*@X-FK=0k+Via|tY6Jmdz_4nz-^};xmlWwuMVR{aOaJ$7&MwmHpd3X!S=Myc%U)K~a*t7)l2H1wrAZKVPWyyn9+8CTZE^q5~?sj_$J6N_h3btn5% z2RilZ{GuXMdJs_qd$i;MI#in>9i$Lb4;%rBDolpF+0 zE#~O&_(+<)33TU_W7O4MFu)$J%1Qsq7>J;2o0l(XUQ{ih^1j65XFi&4451Lrdp<^z ztJj*bZfe*K%>Ra0A0FsSeC7Q*rSCLKy!x<`1jQ1V5a|EK2z|q;wfdbHOYcA^uN$He&6=rHn(ivi z$^+pf#+>k0s6}zFJ~Z$pV(|lOQ;AMU{Zb!|k#t_YP%Fm|gwpwh}?)YHwd0b){k=z)YjR_Zqvk4vhEf&?6DjBx0Dwip(2Pe`gGq zya4fc0Qv&}aEy59=WU8s0!K&F*w3qKrNh!Q;?waA;}M4ZV*exrm7n z-BqSj`dvbNoEpB;9BK}&H;2Lu(0S9$n~cAc8ZX2WXx2nu*tpEx?=|0yr7>fq(qS4< z{Aol)F*BSD>*x8gB*7pR#teaYs5{Kbr1201(Fep>5{rq!gvfoE%Mcy>3SNv59)6CoGmh{!U7vbAmF&_RG0CUQzEnJ!;DJEc zOq*RBV368mxDz6W2H^YTPG;4%z>e^`#Q=Fyi{xAv2BTT4y5uf;VY~Fwa6P!KYklM2l#t&1Pi+BYl4% zW<#7-25@1lO2{3zrPJ|n!aN_7I&YWPG34(dqmQEnEVM$LUC{K>WyBrw=+(w0t9J@D2!npl#iz(u)KP6 zHx?N&wB+jAcwZW80n-oP>cCutIjYw5KkPNX>`I&Auc%Z4BiLj*DC*k~XMbFd0ZBD6AwZB=8r8rJMVga~NB5zz#n{KE;O$;7%wtc<#1#N2_keP)}fBcPGObc%zqkUdm|MjaZ^Kp4P+uw7vjC;er6x3Tgd% z+}_Rt7oJocA3DjXB6Q6uUNaJh<6tvmzZVPFgI-J_80m)lJJWE?6vjWyD$^|?aco<_YJK`# ze=@Na5^If{Te0rNGJI?*ok{>oAH>#Tyu#oi7MhzdE@L%qe24`y^@!M)X0kic*A0iJ zeqEI?e%MOOv9VCi^w*=aKC%3)f?IZKW%obFa!oMmscpuh?nM~o> zwu6{+Y3XmaV8;aAQe+~L+pMV}W~LKyqXJW(;nk04X1KPt7Gd|~bRXh}-o7q<3VeM9 z0(9W?>sR{Ih%2h#71R8j8^$uzZ0W;Nt*W*!yus|MovbfH?(`;DsH-;h5PgI9))o9CfglH-J2sur z*XuMd@_t4Q+h=yI%`%J^FhrMt#~kno z1r=Qw-qwcKhV{q!5Qg1Bu+lK`>*0ic4f!la`kP}1Fvwnx*1J3a2N{c`c}RlHN4f!i zXg7FhVwkfV9k4qV-rNONOS;>Pb-j*_Uo+jMA4ii~OSD9<6 zDQJfFcXwkm8_^xf=t5LuJk_=m76xuiT&H*wnAa&%$9B^j8a!7&uDEX%JPR{F^`!r+ zei%;rpkJ2)($dA%L-^VC9opRmBV#iB0WQ!I^LnN>qljGM%f3Vmp<6=!hjD5#1;mwz ztABz*w=lo)0Ha}d72JGE!1NoN+c3g~{C)A8*2VZ=iguyKk*lSX@nmf+Oz)@Ah6dm? zrtCNk6mk64AI2eyBoOl>CW~YJ1v0)3Ex^YBnuF1q(tSL#YQU~;9s)_TWo`T>9w=dS zfa+#T9Lt8Jh)HRL#}WYcha?QA;l6DMbm8E@0YAjBmF#=L81=MQzaY?OcyE+&_0#-a z1o(I;5l5tpDI})9#Qb5jyM8tHPge7x6FnHQL5n_$f@~~BV(?XcJtEU8j7DZS9j~XQ z(#`1WNp!dXd^?S`1^s`4A6wOs3Kk*>EG@CZ!IF%^#I=|@urYv@7S;`22xZAX*FF@( za0&!e(E@~)Ba2`pH2h5SKUh1{p8IBoRl6(d$QwXCR`I$`pJ3#Lt&ecI_& z^A{{>T6CiA5nEMc>Eh<9B}?Z{GSbv!_j;I{wl+E!wm)qAgmw zq@`lPl9k%*=<-!7tK|c|*%ZxP)VyM@oz|L{uGHous|fXGU%YgQBM;Fl=tG;kbdk1d z>HPUx^P=X(+T~iLY011r&8pl4FfU!vqR1MaxLg1@MR6&U9RSfP4Z-!i=H=Sl$SL@D zYUTl*2sLNVUa(}rO39sF)3nICkJ#>;R;*}VZlyFWZ<(t~;C_|5U$k`YLUj)#H7{Qt zi>_>*r&!b`^OrBSNU>q8$hzrM)$RP{&CQb+tgz~vv!LZdlD$G@Xj%la$tHUKg5@h# zPG5eF$`EO8imq62ZL^}`HQEw1lD2ftRq&1F3xSGzk}c20&MsB zs{5(7`wOPkDE0*xPP5%!q|I9zn*;Bb04GhUnJ_gYd%~3OqpQg@A}pV{XwnSDzw~<- zsoM!trcat+<*B(~vW0TWgv&3OYNbq_Fws^D)c8v+8K9^ zMqN1B(ie8PVDe;@Hqpujc}UVGEQu|yTe;lw*-7YTH8zt@X})@VB!)34<6hkT6g_Qj z(-L(*KGHmQAsSfGm%@YX_tRE3WqKYZj>jmmU>R(jCGQfn@ zE8zqjDfR89dCRrf95L`&!zhh_|EIKXfwHTrvfW7#qYW57Vqy=m=s<%Q%Bm24@@#LC zs*pfI%2a@e$gNvdx2i6w&!uivKA?6KT0R3A^}tVPR7!%1NNe~s@>HPsNkql6K^qVy zh@bdt%kGAk_KCc?)|%_wy-!uf>oMLLi$Bp`nO*0b_I5SY=?eGUR9|=ajCMAYF(`wx)k}X%Jng+}kaK?_f`+ zBlH%H0_F);4i64Oms!yIa}*5d?a=Z_83W{|a!+%1wbY5~-7Q5zu@s73p;!sU(NJj$ zJrzkis>4=wq`XPTDXZB^vwYl9IU!V*h02Mca#E7=$?O^K=Df`N!a=ocEV7ZlugAiTL=y82+xjP_NDPL)%59A~AGob#I zmRFR{LwK{N>}!FdEEhat)xcP-KMTn+Aq&_Ou`DQM@KkMBjo5SH;)-F+_a0bX-jZF* zM4bfMLX#cle43FLgrDAN1yb#I@27K1%$4j*g-IWfbcx zgJo^A33AD>RB#5Z83olyO4d>7LxUN`0wyACsf?6|Vqo1^t<;yW!f?v(H>(tZ=ZaRT%qtX>S0MK;H(GfpHW!7Z^r|!w~xI zMp?6!!&s#!^x;=6^)!W%9*pd=aFdm1m#u0`QsqJahq}>;2Q{q!Lp6+H-5S<^4UY|t z)ym*y=VqRl)`cCbxhz(*y*)C|S)0y3yidYx;VITu9_qurPYSMqB$x$Kki9AeTd)uq zE$1lLm8%1#?mUXM$4IF=&sC;?l;ujSOtHx>KPyxZRs=fEW32B$1Wqlue;6!nkyEjE z7)|^Xo=*-vRUyD=O=MX>Cpdd-U_fs2bE1Dd&(aNsV;kXkAH^i588Q^;+XQf z`-4aEoP}l8mIWBuhTF~z!`h&?vZW~(&VoJV-qP5>=z7d}m{02u(s@NuJOq7LWh(93 z5^9yuRSnhdu(1+0jzM>|jpvnW9awu|F(ChE0kJm5?qUJ!O`cN`>j!zforST8>*;_b zI&iGgOV3=Qwo04>tIjNM%>uZ_B#;FMDx;$VtU?*TR-s=o#Eve@((3kg?@5AdPH2 z?jjg8wb*D!2$ONWdWfy7U@Ih{av2j4uXa~4hBHx}M5{Dq6+>B$G3b)T7-}9j@npo| zl_A^~hRwqx8+B<$Oimic%@FQ=$|D*OAtgrkvuaq+_vyWsbEPa%uopWUwaq0gd~n80 zl?h-HI;FB?#%r;#=VkjC+L;H?np+|UGC-3|dNVI|IU8NC*ebW91Xjo{2CvT>!An$0 zAR*=ak#W*hS{5>ecxo)ihx*F0s^}ga#&%FfR_f7ZcNCV@c@%8Rg>wawmYb000j~Wc zj%SYzdI~LJEPw)0jv9_dP#}^)!*QOLVg{0mp+u1!vIpTZVLQS08z}Osfl4*e`^r*x zKgQe9x*E?aZ7d6Q+%{#K0<&blvt3=PLH!jrUAvD`D)r_Ig;md%(IK(|yhNX^3fVge z+_AQuVFpAgrCN8TLbBqzG20zwJc0o`hFEAyv%#J=ZnznRaosO{RALN*GAc2oJK`<2 ze2KA^Y?7_#H3Ms}l)H7Zv1%b@D|V-FA3Ot_kz5*7o^a)Gb!#45(}SC%O79Gu1xqp# z8D?aJD$k}M3MpM^$fqS@+H*Nm5z6+6L0&ALAkQ^MWI78YP`zw!uj~(afKscu?#MTE zm{ddMzSba^Bo5htvP$l2PdowKlB~mdmMTwY31##z7MDpXCGc?Qz_5#$6HY};S@zck z>yIv|WArC9eP$NvQ*M^9HHh6hY{)qqr^|N46Ct@vPAt=7kE}Tey1rvfqO4+KG^@fG zjO0r*%Nj>aowcGEls4F+O*oHgI_nIgd_uWdoRQeUJh3k0n5{G$=PpX} zYwe64u%)X)QfLeU*;7z$cG~zX2D{JXY%9#=1C=^c9qeVB&IXY7l1%r@mSNh*Xno?c zP%B@I^GPyq^`Q0!%B!$3Ah+=+EOo9O)qx7O5SYhVWm%vyAW@lmvC_%P1@VW7oiG7HM{8)o__-pqtO%Pj-EbHPUFE*8c_@qxhp`?!%nj#Y21FTfXN7w~Us~>LQ#l-LzSSb1seoSDMFcLn6D0?y5b)cmNe$_!Ie&dJ?H`%xUs%P4>8{TQ=D@fCiOk zkKcb@ParaD{u_ZQC6Wg5jSUAP$mbJ>!z(dtBGYro?1by`ZYax7KAs+4T-#B$VpH+itp&KCdc> zAILqEr&BTR10AVCM_ujNQ-mIAVdc8`Xyem$MzRM4D{(HTye4o0VzaVqLB5EJP7A`S zl(ujoesjb1Zw}!GX@(;PkvM3{&nyNvT!5y&|Fo67j&kw^_QY1e?cDY{mS6fRcDG{pyI#D@bR zpC_Sa!0_NF3B?rZ4@iItA7B4~x3d^p5 zJlHVKjwa6}F2iR#O4|`Va8ddlo@Mgv;9=C2(#wr!^eCbmsx&^?0~X~XP8Jl;KhJ1} zRSi+^8k{YmmMnCm(`FgepKI)JZN-mRMxoS9@$Ukow4P3io0~P*$z>rdfg)~3O3D3j zT&IcN0wm*k6ara;JqT&$hTokMf|@Es$dJ=dts|Dp%|M2bc?rLa*M+F8G^^hL5h2cx z<$P6hS@1t#IS{IQ4M;K$M*;ASMp^FYz5k)!2H0S z!>$;St;$ck0Ga3_@jrN`w!1A>LbG_)*ULaWGhyCRpK6vxrSPb578quVhHrT&`neTQ z0i19BABZG(8MUS&?^gm$lsP0Z;lVVl9qtY!<=`(?E#oG3F4__~+6sX^Ce=dkS$grF;=+T>3wPo)vQx@{xi(;0Yxl#{l{r=C3X|(>%ePk8|mzw*^=dtHN$a z@rZlN5I@O;X5Pn&SxH9vBKBfrMo5>)XVh5=EX_8Eu}>e-eV!4&;!Ky`gUc!`Vkk>L z@r*Z9E#eWCgub3*vEBx)FvfSB#As$#JL1Ed@oBAYLC<1@=}8TA67jXLcxNU=B`{lY z>CFf^MLqVzsghJF;z5Jdk)qY_FJaLqicjuhT%8fNj28p@^}BZQea>iG4l|kfyLH@l z-xwigRkKRrL@#qqeBUUWJV7j_k^@#*Vqo8s*;!X8Bw$|1VlPtmO0U?BCMc&MR+bsg zR1?HYgQqlQsG(lZP!?0yBPWuuX9aOmWh0FES*dT7iB)0NlMRz%mN*@p#Dp@r$#(56 z^`Lh;8E&vdu5BHZH}o27qa$|i_bXIld88T|hlWSXjmuZ8IbPnwYwQ~uYwRy!d%qDc z(IBy%u}an$f5IIHiijJ*^FB$yt14bSZq%2N8%ITFjo3=BAa1w^uMmdDa(_`@QY-f3 zjl?Vz8f90Yh79d=Q8yy>O`b|Oa>py!^4F-mjZYUgNE^G+Nw63MX}N1m-ZYfQM#4pd z)v>N2yb6?s@!ImR$CbLeRV#GhKd{p1H4cJ2LHbYW;$6SXj^$8z>-#1wHce6Apd25M4UIE1CXErk|FCIJ_A7@?VU&IQ^El7KA)(!L6zs zvZ*46q{l>>)t~F{Qee`im`#{EvVc&)Sx>>~EM$54wVXHM7pI?Q`e~-0kjUs*z-vE$ z7~wem_~L?6j4w9A%f<40ba*<4uE0f{{;-kd8g`0#e?*vD`ol&=3{nf_R& z|D;DSf$QJXeWDr@sZE}pO}6giKcEW z>DAPYmOihqeEPd{>31{z?*C@`Z{*TXGyOEv=kv>lCy`!MAhUv z&gH-TGgkiXpRw|{@1y>l&l9=ydv3Dydv3DyyAdBBp3cwzib$b!`FBlN`dt)!`;l?# zdjE6uC%6z^p1$)TOW*mBa791N)xVcpBk}h${DiW}0iHd*j1Tc)TrG{@zs1k7nC=J6 zf5HpO$UNKX*@B`W3kW%+ooY zOmp6L9Fz0spRn|2<`U$BD!Wm}sZpM144pjA@S|{&vBH~!&kHg=&zAqR?Dyg5#AZZ% zyi*1^Dry=dLx3te}AkWX5;hP;Om2w zetz(IKgC}cd_GU{*JFO3jsIU|^KVLjK=64r#SaWVU#9p$!RNsge?##3EyWiEpSM!{ z;NbI7iXReuo=NdTgU=r+epv8%A;sSqe7sNb!-J3GDgLJ5<8z8H3_k9r_@dzBX^Q6t zRYuMWxz3*9`Bk_@%u~~FF=xk*m~-D zd=`e)pD$^6xBlaiD)G)+4EOf4S@A_-XHL$nyyX88^0@-^v&nNU`7gNL_&-hh3F51F zrubdNC;utMA0gg(TZ+r_McRM(Vv7Hk`1Y@)_$$Qs){(I6N`-PPLI^eVE`DXH&%<;K*AM}rrepilO z9)!%s|7WD1%F+MZKIpxjOn<7NHU1IS`(E;SI>%=|8uo1Y9s*q2^Tf@@=P2?yn)np) zM&e6>OFcH+k?KvJpi95olgszL#CPZLjlgG?==3qneSD=Mb4>v3yOSnjz!!^ ze8DY---fUpUvm7mf`%JOe>d^YuN!`!#)j|+@$v5){u$ywBtCho;VtCzGw1(f!{3gu z953N4`q@kU>@_&N?lmTVxVxapRm9&!eCM-kCTP<67c-NzdYjPXnK=9&Z7zNBPcdKjyZnp&Ex`-K-52O}a}0lp z@+`>lk8*$%26QhE-A+h z4(rHg@7Gg4eZ(97m*L*7K1h7^y@q@JUPpXkj?Wi?OS#;Ur}v|~NPp!&r+mJx_@b~d zSKgnHkGs0PpYn^dTH)``m7Cd6=DgP0?bF{#`M(*s(7Uhl9n|wN#NBu5<7|h^$fx~l zsUFTGzUBTDmuF$pUpntGe428O60bgx(q9E!(ll`M3+bY1m)^HuAr>n#|*9{e*eWLKZ_g053SI`@{{rzT@^Sg^B;N214}1dFVX)H{y;ojYt;Wtnb?wztEGUq}4j=Sqs8_M8sZbT8~u9pXF1jb7rm{f-pD3&5kEF3&j|79oSrWu|HEB)*M$IGgzM#1|01i1_b;OSvYVC@JFQnu~{) zqR$1r1;yXZh(n2w-(dJEjSb-_;+^Li?)wbK1OJ;@`ipqsQvOdG{U-8RNj&_(@XgG3 z9dMCzLrxD}q%Zv1=zGZLV#OJVPM4E@^4&(?$$9YFebC=b`klFP;|}8EbC)ak_fXD9 zi8t*v{tqzkCxMInojLiR2fhINUHN^yUy{%CUmO3YIWE0Se6no(SCjv|1C0Mp)}zl~ zhXB`p@n+-W^>Vb+f4`(0yj`6}`u6jU|Fh)ZLVV}{H2g!vH#mNr@%Q#Tp!m#v+7aNQ zhsoSH^HK8I_GjZiGRHF5PJF!4aBn9&$Y)oM&)0~Lvp>2X9wR=<@?vqU$B%%Eej0|2 zzwcAMsJPL@|1UeACrxjb3eWfsG(Oul81f+HhgUN2pLzT(>6_ke^giD$1upstPZ@ug za|P)ePBHrTb9`$jUVXvv4>8{h9q0IP1VxbNMcN*2H2QaN-2MRZ@s8z6xm_N-;J6C7 z$g@4C=T9rW(Zv6Ekx$c-g2F!jJmCCy8-6qseP3A=r@z+d8`!^=5+9#3yq|npfQufca(Z|#>8Fk`z1>Ux71D>NOU8lt z81bgud~pSE87HT>uHdpIe2n}XxSn|r<(Y8)&!qhCB0m1@6n{whFmZJHk@I=h=zSdc zrP5w=O-E^gDlT`M#gB zt|s2lXm~I24&sv+7=94tEGkZ-=ydTu@Nx19e=$BcuswVlxYYZ6>Sq^u-A?-PhUJQ! z#`~lDh);05J(l#}B|bH3{5L_5a{Md#Kb>n=zX!fxmUYpeNI#LIKL86+k#lzrKN7g~ z_ucmuG`}PDA8*YQpL*W#PY^$uxO-E1fa7E<`S)}FqME}7(vRoXA^pTBIM4bMrcLBC z{&>l9B%{lKH&BN7be+)8#l8yn`91C?@*jV+pwL6)a|iM1dCL_)k_o;^y!uC@pGW$~ z6(>=2`U!B+=VWfa{+07zVtjm@`A_1V#~XehdCkE%s_o~ok|N%}76F%fY40=oACdkT zrLRB7r24~2N>8Hbw3>W6A2U9~j5}BPU>_#ePy0x}^C6?Zje6L!5B}GX-aQ(8l>9%r z5Be{Ye!R!{LoIsT16=el#eTGn_`{^{;kb7`@hA7e|5xO*fco_L{blm$JgJ}@mats= zVe*xH_vHG;Lg1qR>6+1>%6u1-{?;7*$)ukeFnal@a+P;@@-n#fCed zr+|yz_U7dLHR&5}GWtune)!+c=SjnTefZi#jZZb#kB%U|C5InRe05Hr1>)Os^liYU z9;?5zd>69-=R3~&URUyT0}@^2?T{x-v(Abt+WcwK=K6Rzx?QEZy z6K~*p0L@H~j{}!-jpy_~LA*1k&%2cm6Gx}V$bZ}4Em!nR++WG@6!B@U&rdTr$S0$k z?{`Xy`1t%1={vt%P`p6-!yBz$8m>0HljFwW#K)IfzJJtIA;@RC!hd_NT&IxU{SdxH z{;Nsf{$rEJatYzR#3yom`jihdi%wewpJn~|VWr17`9tG;CkuQn`S<7a{5jHZ+ivu) zqnvjVpJM+SW8RMvZ$HiSa2(si4}dq2CO-W_>0`vM|BHMkk1Hs^Y7DPA-1P50?R;EX zNPLR(<_DSY-x9BK-SReOwT$>gFgbt4aqhCjPt|C6p_PK%h$DRHKqklK?9mFT!X!3ua_&*b`b{hRc3i=@NLaX6F zC;j(9Nne*5p5i za=wfB)UQm=)ns-S@d=KTK5m~+eEMfb{~^|61-Rr}&9&!Ch);aCWSmKV1@SF8`t45t zy_Eh|;Q8=xt%HzK$pT)nY;& zRO1i+O>N$O{2G);1@Ty?Qr@zOy7>*h5Urmp7 zKKlTW>C|{xrmW%&7ZRuqXOnjxA(qW!_Y*K{mN`O@>&QofyR;DV5vUNgBH=l+76J3h z3|K-Y59`-s9uVtv{PYh={3AfxQSx9~qmJ4+(w#@RDDu5GnCfTWi5Ub%QhNys#dZY@ z7{zz%W|g`}J_A-Tv4x<>Oe4^VeFdfI$lF#hG_{mqSZv-w5%~hWZU!NPBGU_s#pN#I zYtWin>Q=!ML&DHW63%KUHu4LiIGEAotp1{2`Jp2c@G7I_*Z+udI{=YIR)-Rct+{XQ zoyJS%VW}4MBa9>V?I&{JN1*A~&;)1NbWANV#`YTjU-lu*5Iz~lCL9SR)&w#vwhk#{ zh>JU$ZOPak02xU4Z;#AP=F~(g*Aj!h__{W-6-(=`Vl+ZJt)7dtglGXzZy(EoCi^y< z*45<8XBb;Mc~QJUp3v;XI3p#+q94B9T?Reb`PY`YJwUXg0%0m6-6#zLQQ9*hkzsEcqCo z%%m37s-kv#2NRQFiIp&+h=x!mNK7mc%cdF+%j}Ns&!CvQOukb`ZEHBQai$?@X?5F+ zd9!CWa^S<{k$Bb$Sk(SnL|l@v@m(y z1|lP4UrY4DKCR4vIsA{A;qJJN@a@4||h*mRVF!N3i5B0jMgnN38J zz?Uy3b5m9ZTG975rXE$g`(dd$)u|U~1eu9ay@o|M<~Adxr!?w7%+tDse#X%emz1?u zgnl7mR$0hGW~)p}8qa6JYy@F7`Efm*q|F_jzb zNrn$NzA9}^W0<$h(ynW|1!D{?qNa5#wH>#|(Gl^+!xZ(&J*rY|0C8^?p9eZ5WUF2+ zYCPylGvMTysVs7Mkk-BQneNTGKI3)dt{&1-;09Bjc&HfCrggzCVswky`&3a@p=#W^ zSZrCpc3rXc?3QBD3oWvuWx5W<37j@2NF`n?q=BXUIMM06Sd_c7G@80Zu64%}?gE2x zS)Xzl6o5TfEswP(l157uDIOLjGX{SyVWTROw6@L=kku_UZ>oS<@V2b~S#InCYI=np z6)Av>p=zm?By?WqRj7VOiqU2R6bm71!^M8wox_$7bJr4@?RPI3*e+#(n?rdvleq^4;;CPV;eXi85l_Gje@e*XifO7W~4=_ zRx1W9ufhXB$|KV+bg)G_L>lc9p{Bikt2>ft=_Cs;_(c)tlWAHnCB1I>cxFxqsmIKS zvk0suFlRz6S~C7RzuDYaWm^Ekr&#Qrr6|lXyGO{WD4A91KS9@+X+IVxI}{ERHQY6D zSwrsi8w6qRDoaLNZC5e@P$Bt7Kv>q(nNsSmr34~{-Wj_d%d&%J8q~#^UHZ00RMvV= zR&{rnlP0oE)EFr&UTt9mF7YOzY_i>wD5rGh_Ld~$vW`~Cpdl*FW@cEBt<_S!N+Wh- z@KnF`PjMS3BU-k+;PQb)qUW>%*;`mRDVQ!rsQ`4`O{TiY7^Re{x3+aC*S^U@?_a%6 z#IL6hG^x)a3WS}zoIvjMiR`pkEhYH=aFH^%u5kyzb=JH_pd9rW#p?Joo;yQX^St-W$VdM#BMPV%}&7bnA zuhf~lN8Yd2X-Y3X9g#9SX$RUET|{whR?>+I9AHDk&bynf1BUOR4x}P13db zFfXOk3aPs@lyQRP!17BxpL%`sEO&0124^@Ts{6w#Z>i)4Tb41|7Le*7ZsUy!%EcaB zR(QWsM=D8Vn>FMP?iUIt7Zp=7{TTU9WE@K>FQ&RYPB^d5W;u2ix_#rWy?TshlW8+I zX$*mjxtuX}$+(Edrp=zE_3=-~3dG6E#@mm%Ahz+5*dYBTM;WzACf=yD79*!G8kV|D zWDxl@m8)FGIy1`8jNCVGI;wCzkb*2bd1YHKQI%TTiUxY$JkHZ(4N6*aR_F38Bq^X3 G`TqjNDmeE5 literal 151012 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
9S>7XeBiya1fId429!*d3Nu+#38Xb_v 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 diff --git a/showdef.REMOVED.git-id b/showdef.REMOVED.git-id index f32b26e8..8096e10f 100644 --- a/showdef.REMOVED.git-id +++ b/showdef.REMOVED.git-id @@ -1 +1 @@ -3ef157af2be64fd212c0769a459038c8a8df67cb \ No newline at end of file +453f2fd03c64825b88b3d5e3ad8fdb3a8532e273 \ No newline at end of file diff --git a/src/lib/ooc/linux/clang/armv6j/oocC.Mod b/src/lib/ooc/linux/clang/armv6j/oocC.Mod new file mode 100644 index 00000000..2e7751ff --- /dev/null +++ b/src/lib/ooc/linux/clang/armv6j/oocC.Mod @@ -0,0 +1,72 @@ +(* $Id: C.Mod,v 1.9 1999/10/03 11:46:01 ooc-devel Exp $ *) +MODULE oocC; +(* Basic data types for interfacing to C code. + Copyright (C) 1997-1998 Michael van Acken + + This module is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This module is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OOC. If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*) + +IMPORT + SYSTEM; + +(* +These types are intended to be equivalent to their C counterparts. +They may vary depending on your system, but as long as you stick to a 32 Bit +Unix they should be fairly safe. +*) + +TYPE + char* = CHAR; + signedchar* = SHORTINT; (* signed char *) + shortint* = INTEGER; (* short int *) + int* = LONGINT; + set* = SET; (* unsigned int, used as set *) + longint* = LONGINT; (* long int *) + (*longset* = SYSTEM.SET64; *) (* unsigned long, used as set *) + longset* = SET; + address* = LONGINT; + float* = REAL; + double* = LONGREAL; + + enum1* = int; + enum2* = int; + enum4* = int; + + (* if your C compiler uses short enumerations, you'll have to replace the + declarations above with + enum1* = SHORTINT; + enum2* = INTEGER; + enum4* = LONGINT; + *) + + FILE* = address; (* this is acually a replacement for `FILE*', i.e., for a pointer type *) + sizet* = longint; + uidt* = int; + gidt* = int; + + +TYPE (* some commonly used C array types *) + charPtr1d* = POINTER TO ARRAY OF char; + charPtr2d* = POINTER TO ARRAY OF charPtr1d; + intPtr1d* = POINTER TO ARRAY OF int; + +TYPE (* C string type, assignment compatible with character arrays and + string constants *) + string* = POINTER TO ARRAY OF char; + +TYPE + Proc* = PROCEDURE; + +END oocC. diff --git a/src/lib/ooc/linux/clang/armv6j_hardfp/oocC.Mod b/src/lib/ooc/linux/clang/armv6j_hardfp/oocC.Mod new file mode 100644 index 00000000..2e7751ff --- /dev/null +++ b/src/lib/ooc/linux/clang/armv6j_hardfp/oocC.Mod @@ -0,0 +1,72 @@ +(* $Id: C.Mod,v 1.9 1999/10/03 11:46:01 ooc-devel Exp $ *) +MODULE oocC; +(* Basic data types for interfacing to C code. + Copyright (C) 1997-1998 Michael van Acken + + This module is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This module is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OOC. If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*) + +IMPORT + SYSTEM; + +(* +These types are intended to be equivalent to their C counterparts. +They may vary depending on your system, but as long as you stick to a 32 Bit +Unix they should be fairly safe. +*) + +TYPE + char* = CHAR; + signedchar* = SHORTINT; (* signed char *) + shortint* = INTEGER; (* short int *) + int* = LONGINT; + set* = SET; (* unsigned int, used as set *) + longint* = LONGINT; (* long int *) + (*longset* = SYSTEM.SET64; *) (* unsigned long, used as set *) + longset* = SET; + address* = LONGINT; + float* = REAL; + double* = LONGREAL; + + enum1* = int; + enum2* = int; + enum4* = int; + + (* if your C compiler uses short enumerations, you'll have to replace the + declarations above with + enum1* = SHORTINT; + enum2* = INTEGER; + enum4* = LONGINT; + *) + + FILE* = address; (* this is acually a replacement for `FILE*', i.e., for a pointer type *) + sizet* = longint; + uidt* = int; + gidt* = int; + + +TYPE (* some commonly used C array types *) + charPtr1d* = POINTER TO ARRAY OF char; + charPtr2d* = POINTER TO ARRAY OF charPtr1d; + intPtr1d* = POINTER TO ARRAY OF int; + +TYPE (* C string type, assignment compatible with character arrays and + string constants *) + string* = POINTER TO ARRAY OF char; + +TYPE + Proc* = PROCEDURE; + +END oocC. diff --git a/src/lib/ooc/linux/clang/powerpc/oocC.Mod b/src/lib/ooc/linux/clang/powerpc/oocC.Mod new file mode 100644 index 00000000..2e7751ff --- /dev/null +++ b/src/lib/ooc/linux/clang/powerpc/oocC.Mod @@ -0,0 +1,72 @@ +(* $Id: C.Mod,v 1.9 1999/10/03 11:46:01 ooc-devel Exp $ *) +MODULE oocC; +(* Basic data types for interfacing to C code. + Copyright (C) 1997-1998 Michael van Acken + + This module is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This module is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OOC. If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*) + +IMPORT + SYSTEM; + +(* +These types are intended to be equivalent to their C counterparts. +They may vary depending on your system, but as long as you stick to a 32 Bit +Unix they should be fairly safe. +*) + +TYPE + char* = CHAR; + signedchar* = SHORTINT; (* signed char *) + shortint* = INTEGER; (* short int *) + int* = LONGINT; + set* = SET; (* unsigned int, used as set *) + longint* = LONGINT; (* long int *) + (*longset* = SYSTEM.SET64; *) (* unsigned long, used as set *) + longset* = SET; + address* = LONGINT; + float* = REAL; + double* = LONGREAL; + + enum1* = int; + enum2* = int; + enum4* = int; + + (* if your C compiler uses short enumerations, you'll have to replace the + declarations above with + enum1* = SHORTINT; + enum2* = INTEGER; + enum4* = LONGINT; + *) + + FILE* = address; (* this is acually a replacement for `FILE*', i.e., for a pointer type *) + sizet* = longint; + uidt* = int; + gidt* = int; + + +TYPE (* some commonly used C array types *) + charPtr1d* = POINTER TO ARRAY OF char; + charPtr2d* = POINTER TO ARRAY OF charPtr1d; + intPtr1d* = POINTER TO ARRAY OF int; + +TYPE (* C string type, assignment compatible with character arrays and + string constants *) + string* = POINTER TO ARRAY OF char; + +TYPE + Proc* = PROCEDURE; + +END oocC. diff --git a/src/lib/ooc/linux/clang/x86/oocC.Mod b/src/lib/ooc/linux/clang/x86/oocC.Mod new file mode 100644 index 00000000..2e7751ff --- /dev/null +++ b/src/lib/ooc/linux/clang/x86/oocC.Mod @@ -0,0 +1,72 @@ +(* $Id: C.Mod,v 1.9 1999/10/03 11:46:01 ooc-devel Exp $ *) +MODULE oocC; +(* Basic data types for interfacing to C code. + Copyright (C) 1997-1998 Michael van Acken + + This module is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This module is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OOC. If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*) + +IMPORT + SYSTEM; + +(* +These types are intended to be equivalent to their C counterparts. +They may vary depending on your system, but as long as you stick to a 32 Bit +Unix they should be fairly safe. +*) + +TYPE + char* = CHAR; + signedchar* = SHORTINT; (* signed char *) + shortint* = INTEGER; (* short int *) + int* = LONGINT; + set* = SET; (* unsigned int, used as set *) + longint* = LONGINT; (* long int *) + (*longset* = SYSTEM.SET64; *) (* unsigned long, used as set *) + longset* = SET; + address* = LONGINT; + float* = REAL; + double* = LONGREAL; + + enum1* = int; + enum2* = int; + enum4* = int; + + (* if your C compiler uses short enumerations, you'll have to replace the + declarations above with + enum1* = SHORTINT; + enum2* = INTEGER; + enum4* = LONGINT; + *) + + FILE* = address; (* this is acually a replacement for `FILE*', i.e., for a pointer type *) + sizet* = longint; + uidt* = int; + gidt* = int; + + +TYPE (* some commonly used C array types *) + charPtr1d* = POINTER TO ARRAY OF char; + charPtr2d* = POINTER TO ARRAY OF charPtr1d; + intPtr1d* = POINTER TO ARRAY OF int; + +TYPE (* C string type, assignment compatible with character arrays and + string constants *) + string* = POINTER TO ARRAY OF char; + +TYPE + Proc* = PROCEDURE; + +END oocC. diff --git a/src/lib/ooc/linux/clang/x86_64/oocC.Mod b/src/lib/ooc/linux/clang/x86_64/oocC.Mod new file mode 100644 index 00000000..14638e75 --- /dev/null +++ b/src/lib/ooc/linux/clang/x86_64/oocC.Mod @@ -0,0 +1,71 @@ +(* $Id: C.Mod,v 1.9 1999/10/03 11:46:01 ooc-devel Exp $ *) +MODULE oocC; +(* Basic data types for interfacing to C code. + Copyright (C) 1997-1998 Michael van Acken + + This module is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License + as published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This module is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OOC. If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*) + +IMPORT + SYSTEM; + +(* +These types are intended to be equivalent to their C counterparts. +They may vary depending on your system, but as long as you stick to a 32 Bit +Unix they should be fairly safe. +*) + +TYPE + char* = CHAR; + signedchar* = SHORTINT; (* signed char *) + shortint* = RECORD a,b : SYSTEM.BYTE END; (* 2 bytes on x64_64 *) (* short int *) + int* = INTEGER; + set* = INTEGER;(*SET;*) (* unsigned int, used as set *) + longint* = LONGINT; (* long int *) + longset* = SET; (*SYSTEM.SET64; *) (* unsigned long, used as set *) + address* = LONGINT; (*SYSTEM.ADDRESS;*) + float* = REAL; + double* = LONGREAL; + + enum1* = int; + enum2* = int; + enum4* = int; + + (* if your C compiler uses short enumerations, you'll have to replace the + declarations above with + enum1* = SHORTINT; + enum2* = INTEGER; + enum4* = LONGINT; + *) + + FILE* = address; (* this is acually a replacement for `FILE*', i.e., for a pointer type *) + sizet* = longint; + uidt* = int; + gidt* = int; + + +TYPE (* some commonly used C array types *) + charPtr1d* = POINTER TO ARRAY OF char; + charPtr2d* = POINTER TO ARRAY OF charPtr1d; + intPtr1d* = POINTER TO ARRAY OF int; + +TYPE (* C string type, assignment compatible with character arrays and + string constants *) + string* = POINTER (*[CSTRING]*) TO ARRAY OF char; + +TYPE + Proc* = PROCEDURE; + +END oocC. diff --git a/src/lib/ooc2/linux/clang/oocwrapperlibc.Mod b/src/lib/ooc2/linux/clang/oocwrapperlibc.Mod new file mode 100644 index 00000000..0d0cf9b6 --- /dev/null +++ b/src/lib/ooc2/linux/clang/oocwrapperlibc.Mod @@ -0,0 +1,34 @@ +MODULE oocwrapperlibc; +IMPORT SYSTEM; +PROCEDURE -includeStdio() + "#include "; + +PROCEDURE -sys(str: ARRAY OF CHAR): INTEGER + "system(str)"; + +PROCEDURE system*(cmd : ARRAY OF CHAR); +VAR r : INTEGER; +BEGIN +r := sys(cmd); +END system; +(* +PROCEDURE strtod* (string: C.address; + VAR tailptr: C.charPtr1d): C.double; +PROCEDURE strtof* (string: C.address; + VAR tailptr: C.charPtr1d): C.float; +PROCEDURE sscanf* (s: C.address; template: ARRAY OF CHAR; ...) : C.int; +*) + +PROCEDURE -sprntf(s, t0, t1, t2: ARRAY OF CHAR): INTEGER + "sprintf(s, t0, t1, t2)"; + +PROCEDURE sprintf* (VAR s: ARRAY OF CHAR; template0: ARRAY OF CHAR; template1: ARRAY OF CHAR; template2: ARRAY OF CHAR); +VAR r : INTEGER; +BEGIN + r := sprntf (s, template0, template1, template2); +END sprintf; + +BEGIN + + +END oocwrapperlibc. diff --git a/src/lib/system/linux/clang/Console.Mod b/src/lib/system/linux/clang/Console.Mod new file mode 100644 index 00000000..e523ef7b --- /dev/null +++ b/src/lib/system/linux/clang/Console.Mod @@ -0,0 +1,86 @@ +MODULE Console; (* J. Templ, 29-June-96 *) + + (* output to Unix standard output device based Write system call *) + + IMPORT SYSTEM; + + VAR line: ARRAY 128 OF CHAR; + pos: INTEGER; + + PROCEDURE -Write(adr, n: LONGINT) + "write(1/*stdout*/, adr, n)"; + + PROCEDURE -read(VAR ch: CHAR): LONGINT + "read(0/*stdin*/, ch, 1)"; + + PROCEDURE Flush*(); + BEGIN + Write(SYSTEM.ADR(line), pos); pos := 0; + END Flush; + + PROCEDURE Char*(ch: CHAR); + BEGIN + IF pos = LEN(line) THEN Flush() END ; + line[pos] := ch; INC(pos); + IF ch = 0AX THEN Flush() END + END Char; + + PROCEDURE String*(s: ARRAY OF CHAR); + VAR i: INTEGER; + BEGIN i := 0; + WHILE s[i] # 0X DO Char(s[i]); INC(i) END + END String; + + PROCEDURE Int*(i, n: LONGINT); + VAR s: ARRAY 32 OF CHAR; i1, k: LONGINT; + BEGIN + IF i = SYSTEM.LSH(LONG(LONG(1)), SIZE(LONGINT)*8 - 1) THEN + IF SIZE(LONGINT) = 8 THEN s := "8085774586302733229"; k := 19 + ELSE s := "8463847412"; k := 10 + END + ELSE + i1 := ABS(i); + s[0] := CHR(i1 MOD 10 + ORD("0")); i1 := i1 DIV 10; k := 1; + WHILE i1 > 0 DO s[k] := CHR(i1 MOD 10 + ORD("0")); i1 := i1 DIV 10; INC(k) END + END ; + IF i < 0 THEN s[k] := "-"; INC(k) END ; + WHILE n > k DO Char(" "); DEC(n) END ; + WHILE k > 0 DO DEC(k); Char(s[k]) END + END Int; + + PROCEDURE Ln*; + BEGIN Char(0AX); (* Unix end-of-line *) + END Ln; + + PROCEDURE Bool*(b: BOOLEAN); + BEGIN IF b THEN String("TRUE") ELSE String("FALSE") END + END Bool; + + PROCEDURE Hex*(i: LONGINT); + VAR k, n: LONGINT; + BEGIN + k := -28; + WHILE k <= 0 DO + n := ASH(i, k) MOD 16; + IF n <= 9 THEN Char(CHR(ORD("0") + n)) ELSE Char(CHR(ORD("A") - 10 + n)) END ; + INC(k, 4) + END + END Hex; + + PROCEDURE Read*(VAR ch: CHAR); + VAR n: LONGINT; + BEGIN Flush(); + n := read(ch); + IF n # 1 THEN ch := 0X END + END Read; + + PROCEDURE ReadLine*(VAR line: ARRAY OF CHAR); + VAR i: LONGINT; ch: CHAR; + BEGIN Flush(); + i := 0; Read(ch); + WHILE (i < LEN(line) - 1) & (ch # 0AX) & (ch # 0X) DO line[i] := ch; INC(i); Read(ch) END ; + line[i] := 0X + END ReadLine; + +BEGIN pos := 0; +END Console. diff --git a/src/lib/system/linux/clang/Files.Mod b/src/lib/system/linux/clang/Files.Mod new file mode 100644 index 00000000..60b81e43 --- /dev/null +++ b/src/lib/system/linux/clang/Files.Mod @@ -0,0 +1,658 @@ +MODULE Files; (* J. Templ 1.12. 89/12.4.95 Oberon files mapped onto Unix files *) +(* modified version of Files, which opens only the file provided and does not scan any path in any environment variable, also ReadLine procedure added; -- noch *) + IMPORT SYSTEM, Unix, Kernel, Args, Console; + + (* standard data type I/O + + little endian, + Sint:1, Int:2, Lint:4 + ORD({0}) = 1, + false = 0, true =1 + IEEE real format, + null terminated strings, + compact numbers according to M.Odersky *) + + + CONST + nofbufs = 4; + bufsize = 4096; + fileTabSize = 64; + noDesc = -1; + notDone = -1; + + (* file states *) + open = 0; create = 1; close = 2; + + + TYPE + FileName = ARRAY 101 OF CHAR; + File* = POINTER TO Handle; + Buffer = POINTER TO BufDesc; + + Handle = RECORD + workName, registerName: FileName; + tempFile: BOOLEAN; + dev, ino, mtime: LONGINT; + fd-, len, pos: LONGINT; + bufs: ARRAY nofbufs OF Buffer; + swapper, state: INTEGER + END ; + + BufDesc = RECORD + f: File; + chg: BOOLEAN; + org, size: LONGINT; + data: ARRAY bufsize OF SYSTEM.BYTE + END ; + + Rider* = RECORD + res*: LONGINT; + eof*: BOOLEAN; + buf: Buffer; + org, offset: LONGINT + END ; + + Time = POINTER TO TimeDesc; + TimeDesc = RECORD + sec*, min*, hour*, mday*, mon*, year*, wday*, isdst*, zone*, gmtoff*: LONGINT; +(* sec*, min*, hour*, mday*, mon*, year*, wday*, isdst*, zone*, gmtoff*: INTEGER;*) + END ; + + VAR + fileTab: ARRAY fileTabSize OF LONGINT (*=File*); + tempno: INTEGER; + +(* for localtime *) + PROCEDURE -includetime() + '#include "time.h"'; + + PROCEDURE -localtime(VAR clock: LONGINT): Time + "(Files_Time) localtime(clock)"; + + PROCEDURE -getcwd(VAR cwd: Unix.Name) + "getcwd(cwd, cwd__len)"; + + PROCEDURE -IdxTrap "__HALT(-1)"; + + PROCEDURE^ Finalize(o: SYSTEM.PTR); + + PROCEDURE Err(s: ARRAY OF CHAR; f: File; errno: LONGINT); + BEGIN + Console.Ln; Console.String("-- "); Console.String(s); Console.String(": "); + IF f # NIL THEN + IF f.registerName # "" THEN Console.String(f.registerName) ELSE Console.String(f.workName) END + END ; + IF errno # 0 THEN Console.String(" errno = "); Console.Int(errno, 1) END ; + Console.Ln; + HALT(99) + END Err; + + PROCEDURE MakeFileName(dir, name: ARRAY OF CHAR; VAR dest: ARRAY OF CHAR); + VAR i, j: INTEGER; + BEGIN i := 0; j := 0; + WHILE dir[i] # 0X DO dest[i] := dir[i]; INC(i) END ; + IF dest[i-1] # "/" THEN dest[i] := "/"; INC(i) END ; + WHILE name[j] # 0X DO dest[i] := name[j]; INC(i); INC(j) END ; + dest[i] := 0X + END MakeFileName; + + PROCEDURE GetTempName(finalName: ARRAY OF CHAR; VAR name: ARRAY OF CHAR); + VAR n, i, j: LONGINT; + BEGIN + INC(tempno); n := tempno; i := 0; + IF finalName[0] # "/" THEN (* relative pathname *) + WHILE Kernel.CWD[i] # 0X DO name[i] := Kernel.CWD[i]; INC(i) END; + IF Kernel.CWD[i-1] # "/" THEN name[i] := "/"; INC(i) END + END; + j := 0; + WHILE finalName[j] # 0X DO name[i] := finalName[j]; INC(i); INC(j) END; + DEC(i); + WHILE name[i] # "/" DO DEC(i) END; + name[i+1] := "."; name[i+2] := "t"; name[i+3] := "m"; name[i+4] := "p"; name[i+5] := "."; INC(i, 6); + WHILE n > 0 DO name[i] := CHR(n MOD 10 + ORD("0")); n := n DIV 10; INC(i) END; + name[i] := "."; INC(i); n := SHORT(Unix.Getpid()); + WHILE n > 0 DO name[i] := CHR(n MOD 10 + ORD("0")); n := n DIV 10; INC(i) END; + name[i] := 0X + END GetTempName; + + PROCEDURE Create(f: File); + VAR stat: Unix.Status; done: BOOLEAN; + errno: LONGINT; err: ARRAY 32 OF CHAR; + BEGIN + IF f.fd = noDesc THEN + IF f.state = create THEN GetTempName(f.registerName, f.workName); f.tempFile := TRUE + ELSIF f.state = close THEN + f.workName := f.registerName; f.registerName := ""; f.tempFile := FALSE + END ; + errno := Unix.Unlink(f.workName); (*unlink first to avoid stale NFS handles and to avoid reuse of inodes*) + f.fd := Unix.Open(f.workName, Unix.rdwr + Unix.creat + Unix.trunc, {2, 4,5, 7,8}); + done := f.fd >= 0; errno := Unix.errno(); + IF (~done & ((errno = Unix.ENFILE) OR (errno = Unix.EMFILE))) OR (done & (f.fd >= fileTabSize)) THEN + IF done & (f.fd >= fileTabSize) THEN errno := Unix.Close(f.fd) END ; + Kernel.GC(TRUE); + f.fd := Unix.Open(f.workName, Unix.rdwr + Unix.creat + Unix.trunc, {2, 4,5, 7,8}); + done := f.fd >= 0 + END ; + IF done THEN + IF f.fd >= fileTabSize THEN errno := Unix.Close(f.fd); Err("too many files open", f, 0) + ELSE fileTab[f.fd] := SYSTEM.VAL(LONGINT, f); INC(Kernel.nofiles); Kernel.RegisterObject(f, Finalize); + f.state := open; f.pos := 0; errno := Unix.Fstat(f.fd, stat); + f.dev := stat.dev; f.ino := stat.ino; f.mtime := stat.mtime + END + ELSE errno := Unix.errno(); + IF errno = Unix.ENOENT THEN err := "no such directory" + ELSIF (errno = Unix.ENFILE) OR (errno = Unix.EMFILE) THEN err := "too many files open" + ELSE err := "file not created" + END ; + Err(err, f, errno) + END + END + END Create; + + PROCEDURE Flush(buf: Buffer); + VAR res: LONGINT; f: File; stat: Unix.Status; + BEGIN + IF buf.chg THEN f := buf.f; Create(f); + IF buf.org # f.pos THEN res := Unix.Lseek(f.fd, buf.org, 0) END ; + res := Unix.Write(f.fd, SYSTEM.ADR(buf.data), buf.size); + IF res < 0 THEN Err("error in writing file", f, Unix.errno()) END ; + f.pos := buf.org + buf.size; + buf.chg := FALSE; + res := Unix.Fstat(f.fd, stat); + f.mtime := stat.mtime + END + END Flush; + + PROCEDURE Close* (f: File); + VAR i, res: LONGINT; + BEGIN + IF (f.state # create) OR (f.registerName # "") THEN + Create(f); i := 0; + WHILE (i < nofbufs) & (f.bufs[i] # NIL) DO Flush(f.bufs[i]); INC(i) END ; + res := Unix.Fsync(f.fd); + IF res < 0 THEN Err("error in writing file", f, Unix.errno()) END + END + END Close; + + PROCEDURE Length* (f: File): LONGINT; + BEGIN RETURN f.len + END Length; + + PROCEDURE New* (name: ARRAY OF CHAR): File; + VAR f: File; + BEGIN + NEW(f); f.workName := ""; COPY(name, f.registerName); + f.fd := noDesc; f.state := create; f.len := 0; f.pos := 0; f.swapper := -1; (*all f.buf[i] = NIL*) + RETURN f + END New; +(* + PROCEDURE ScanPath(VAR pos: INTEGER; VAR dir: ARRAY OF CHAR); (* supports ~, ~user and blanks inside path *) + VAR i: INTEGER; ch: CHAR; home: ARRAY 256 OF CHAR; + BEGIN + i := 0; ch := Kernel.OBERON[pos]; + WHILE (ch = " ") OR (ch = ":") DO INC(pos); ch := Kernel.OBERON[pos] END ; + IF ch = "~" THEN + INC(pos); ch := Kernel.OBERON[pos]; + home := ""; Args.GetEnv("HOME", home); + WHILE home[i] # 0X DO dir[i] := home[i]; INC(i) END ; + IF (ch # "/") & (ch # 0X) & (ch # ":") & (ch # " ") THEN + WHILE (i > 0) & (dir[i-1] # "/") DO DEC(i) END + END + END ; + WHILE (ch # 0X) & (ch # ":") DO dir[i] := ch; INC(i); INC(pos); ch := Kernel.OBERON[pos] END ; + WHILE (i > 0) & (dir[i-1] = " ") DO DEC(i) END ; + dir[i] := 0X + END ScanPath; +*) + PROCEDURE HasDir(VAR name: ARRAY OF CHAR): BOOLEAN; + VAR i: INTEGER; ch: CHAR; + BEGIN i := 0; ch := name[0]; + WHILE (ch # 0X) & (ch # "/") DO INC(i); ch := name[i] END ; + RETURN ch = "/" + END HasDir; + + PROCEDURE CacheEntry(dev, ino: LONGINT; mtime: LONGINT): File; + VAR f: File; i: INTEGER; stat: Unix.Status; res: LONGINT; + BEGIN i := 0; + WHILE i < fileTabSize DO + f := SYSTEM.VAL(File, fileTab[i]); + IF (f # NIL) & (ino = f.ino) & (dev = f.dev) THEN + IF mtime # f.mtime THEN i := 0; + WHILE i < nofbufs DO + IF f.bufs[i] # NIL THEN f.bufs[i].org := -1; f.bufs[i] := NIL END ; + INC(i) + END ; + f.swapper := -1; f.mtime := mtime; + res := Unix.Fstat(f.fd, stat); f.len := stat.size + END ; + RETURN f + END ; + INC(i) + END ; + RETURN NIL + END CacheEntry; + + PROCEDURE Old* (name: ARRAY OF CHAR): File; + VAR f: File; fd, res, errno: LONGINT; pos: INTEGER; done: BOOLEAN; + dir, path: ARRAY 256 OF CHAR; + stat: Unix.Status; + BEGIN + IF name # "" THEN + IF HasDir(name) THEN dir := ""; COPY(name, path) + ELSE + pos := 0; + COPY(name, path); (* -- noch *) + (*ScanPath(pos, dir);*) (*MakeFileName(dir, name, path);*) (*ScanPath(pos, dir)*) + END ; + LOOP + fd := Unix.Open(path, Unix.rdwr, {}); done := fd >= 0; errno := Unix.errno(); + IF (~done & ((errno = Unix.ENFILE) OR (errno = Unix.EMFILE))) OR (done & (fd >= fileTabSize)) THEN + IF done & (fd >= fileTabSize) THEN res := Unix.Close(fd) END ; + Kernel.GC(TRUE); + fd := Unix.Open(path, Unix.rdwr, {}); + done := fd >= 0; errno := Unix.errno(); + IF ~done & ((errno = Unix.ENFILE) OR (errno = Unix.EMFILE)) THEN Err("too many files open", f, errno) END + END ; + IF ~done & ((errno = Unix.EACCES) OR (errno = Unix.EROFS) OR (errno = Unix.EAGAIN)) THEN + (* errno EAGAIN observed on Solaris 2.4 *) + fd := Unix.Open(path, Unix.rdonly, {}); done := fd >= 0; errno := Unix.errno() + END ; +IF (~done) & (errno # Unix.ENOENT) THEN + Console.String("warning Files.Old "); Console.String(name); + Console.String(" errno = "); Console.Int(errno, 0); Console.Ln; +END ; + IF done THEN + res := Unix.Fstat(fd, stat); + f := CacheEntry(stat.dev, stat.ino, stat.mtime); + IF f # NIL THEN res := Unix.Close(fd); RETURN f + ELSIF fd >= fileTabSize THEN res := Unix.Close(fd); Err("too many files open", f, 0) + ELSE NEW(f); fileTab[fd] := SYSTEM.VAL(LONGINT, f); INC(Kernel.nofiles); Kernel.RegisterObject(f, Finalize); + f.fd := fd; f.state := open; f.len := stat.size; f.pos := 0; f.swapper := -1; (*all f.buf[i] = NIL*) + COPY(name, f.workName); f.registerName := ""; f.tempFile := FALSE; + f.dev := stat.dev; f.ino := stat.ino; f.mtime := stat.mtime; + RETURN f + END + ELSIF dir = "" THEN RETURN NIL + ELSE (*MakeFileName(dir, name, path);*) (*ScanPath(pos, dir)*) + RETURN NIL + END + END + ELSE RETURN NIL + END + END Old; + + PROCEDURE Purge* (f: File); + VAR i: INTEGER; stat: Unix.Status; res: LONGINT; + BEGIN i := 0; + WHILE i < nofbufs DO + IF f.bufs[i] # NIL THEN f.bufs[i].org := -1; f.bufs[i] := NIL END ; + INC(i) + END ; + IF f.fd # noDesc THEN res := Unix.Ftruncate(f.fd, 0); res := Unix.Lseek(f.fd, 0, 0) END ; + f.pos := 0; f.len := 0; f.swapper := -1; + res := Unix.Fstat(f.fd, stat); f.mtime := stat.mtime + END Purge; + + PROCEDURE GetDate* (f: File; VAR t, d: LONGINT); + VAR stat: Unix.Status; clock, res: LONGINT; time: Time; + BEGIN + Create(f); res := Unix.Fstat(f.fd, stat); + time := localtime(stat.mtime); + t := time.sec + ASH(time.min, 6) + ASH(time.hour, 12); + d := time.mday + ASH(time.mon+1, 5) + ASH(time.year MOD 100, 9) + END GetDate; + + PROCEDURE Pos* (VAR r: Rider): LONGINT; + BEGIN RETURN r.org + r.offset + END Pos; + + PROCEDURE Set* (VAR r: Rider; f: File; pos: LONGINT); + VAR org, offset, i, n, res: LONGINT; buf: Buffer; + BEGIN + IF f # NIL THEN + IF pos > f.len THEN pos := f.len ELSIF pos < 0 THEN pos := 0 END ; + offset := pos MOD bufsize; org := pos - offset; i := 0; + WHILE (i < nofbufs) & (f.bufs[i] # NIL) & (org # f.bufs[i].org) DO INC(i) END ; + IF i < nofbufs THEN + IF f.bufs[i] = NIL THEN NEW(buf); buf.chg := FALSE; buf.org := -1; buf.f := f; f.bufs[i] := buf + ELSE buf := f.bufs[i] + END + ELSE + f.swapper := (f.swapper + 1) MOD nofbufs; + buf := f.bufs[f.swapper]; + Flush(buf) + END ; + IF buf.org # org THEN + IF org = f.len THEN buf.size := 0 + ELSE Create(f); + IF f.pos # org THEN res := Unix.Lseek(f.fd, org, 0) END ; + n := Unix.ReadBlk(f.fd, buf.data); + IF n < 0 THEN Err("read from file not done", f, Unix.errno()) END ; + f.pos := org + n; + buf.size := n + END ; + buf.org := org; buf.chg := FALSE + END + ELSE buf := NIL; org := 0; offset := 0 + END ; + r.buf := buf; r.org := org; r.offset := offset; r.eof := FALSE; r.res := 0 + END Set; + + PROCEDURE Read* (VAR r: Rider; VAR x: SYSTEM.BYTE); + VAR offset: LONGINT; buf: Buffer; + BEGIN + buf := r.buf; offset := r.offset; + IF r.org # buf.org THEN Set(r, buf.f, r.org + offset); buf := r.buf; offset := r.offset END ; + IF (offset < buf.size) THEN + x := buf.data[offset]; r.offset := offset + 1 + ELSIF r.org + offset < buf.f.len THEN + Set(r, r.buf.f, r.org + offset); + x := r.buf.data[0]; r.offset := 1 + ELSE + x := 0X; r.eof := TRUE + END + END Read; + + PROCEDURE ReadBytes* (VAR r: Rider; VAR x: ARRAY OF SYSTEM.BYTE; n: LONGINT); + VAR xpos, min, restInBuf, offset: LONGINT; buf: Buffer; + BEGIN + IF n > LEN(x) THEN IdxTrap END ; + xpos := 0; buf := r.buf; offset := r.offset; + WHILE n > 0 DO + IF (r.org # buf.org) OR (offset >= bufsize) THEN + Set(r, buf.f, r.org + offset); + buf := r.buf; offset := r.offset + END ; + restInBuf := buf.size - offset; + IF restInBuf = 0 THEN r.res := n; r.eof := TRUE; RETURN + ELSIF n > restInBuf THEN min := restInBuf ELSE min := n END ; + SYSTEM.MOVE(SYSTEM.ADR(buf.data) + offset, SYSTEM.ADR(x) + xpos, min); + INC(offset, min); r.offset := offset; INC(xpos, min); DEC(n, min) + END ; + r.res := 0; r.eof := FALSE + END ReadBytes; + + PROCEDURE Base* (VAR r: Rider): File; + BEGIN RETURN r.buf.f + END Base; + + PROCEDURE Write* (VAR r: Rider; x: SYSTEM.BYTE); + VAR buf: Buffer; offset: LONGINT; + BEGIN + buf := r.buf; offset := r.offset; + IF (r.org # buf.org) OR (offset >= bufsize) THEN + Set(r, buf.f, r.org + offset); + buf := r.buf; offset := r.offset + END ; + buf.data[offset] := x; + buf.chg := TRUE; + IF offset = buf.size THEN + INC(buf.size); INC(buf.f.len) + END ; + r.offset := offset + 1; r.res := 0 + END Write; + + PROCEDURE WriteByte* (VAR r : Rider; x : SYSTEM.BYTE); (* added for compatibility with PO 2013, -- noch *) + BEGIN + Write(r, x); + END WriteByte; + + PROCEDURE WriteBytes* (VAR r: Rider; VAR x: ARRAY OF SYSTEM.BYTE; n: LONGINT); + VAR xpos, min, restInBuf, offset: LONGINT; buf: Buffer; + BEGIN + IF n > LEN(x) THEN IdxTrap END ; + xpos := 0; buf := r.buf; offset := r.offset; + WHILE n > 0 DO + IF (r.org # buf.org) OR (offset >= bufsize) THEN + Set(r, buf.f, r.org + offset); + buf := r.buf; offset := r.offset + END ; + restInBuf := bufsize - offset; + IF n > restInBuf THEN min := restInBuf ELSE min := n END ; + SYSTEM.MOVE(SYSTEM.ADR(x) + xpos, SYSTEM.ADR(buf.data) + offset, min); + INC(offset, min); r.offset := offset; + IF offset > buf.size THEN INC(buf.f.len, offset - buf.size); buf.size := offset END ; + INC(xpos, min); DEC(n, min); buf.chg := TRUE + END ; + r.res := 0 + END WriteBytes; + +(* another solution would be one that is similar to ReadBytes, WriteBytes. +No code duplication, more symmetric, only two ifs for +Read and Write in buffer, buf.size replaced by bufsize in Write ops, buf.size and len +must be made consistent with offset (if offset > buf.size) in a lazy way. + +PROCEDURE Write* (VAR r: Rider; x: SYSTEM.BYTE); + VAR buf: Buffer; offset: LONGINT; +BEGIN + buf := r.buf; offset := r.offset; + IF (offset >= bufsize) OR (r.org # buf.org) THEN + Set(r, buf.f, r.org + offset); buf := r.buf; offset := r.offset; + END ; + buf.data[offset] := x; r.offset := offset + 1; buf.chg := TRUE +END Write; + + +PROCEDURE WriteBytes ... + +PROCEDURE Read* (VAR r: Rider; VAR x: SYSTEM.BYTE); + VAR offset: LONGINT; buf: Buffer; +BEGIN + buf := r.buf; offset := r.offset; + IF (offset >= buf.size) OR (r.org # buf.org) THEN + IF r.org + offset >= buf.f.len THEN x := 0X; r.eof := TRUE; RETURN + ELSE Set(r, buf.f, r.org + offset); buf := r.buf; offset := r.offset + END + END ; + x := buf.data[offset]; r.offset := offset + 1 +END Read; + +but this would also affect Set, Length, and Flush. +Especially Length would become fairly complex. +*) + + PROCEDURE Delete* (name: ARRAY OF CHAR; VAR res: INTEGER); + BEGIN + res := SHORT(Unix.Unlink(name)); + res := SHORT(Unix.errno()) + END Delete; + + PROCEDURE Rename* (old, new: ARRAY OF CHAR; VAR res: INTEGER); + VAR fdold, fdnew, n, errno, r: LONGINT; + ostat, nstat: Unix.Status; + buf: ARRAY 4096 OF CHAR; + BEGIN + r := Unix.Stat(old, ostat); + IF r >= 0 THEN + r := Unix.Stat(new, nstat); + IF (r >= 0) & ((ostat.dev # nstat.dev) OR (ostat.ino # nstat.ino)) THEN + Delete(new, res); (* work around stale nfs handles *) + END ; + r := Unix.Rename(old, new); + IF r < 0 THEN res := SHORT(Unix.errno()); + IF res = Unix.EXDEV THEN (* cross device link, move the file *) + fdold := Unix.Open(old, Unix.rdonly, {}); + IF fdold < 0 THEN res := 2; RETURN END ; + fdnew := Unix.Open(new, Unix.rdwr + Unix.creat + Unix.trunc, {2, 4,5, 7,8}); + IF fdnew < 0 THEN r := Unix.Close(fdold); res := 3; RETURN END ; + n := Unix.Read(fdold, SYSTEM.ADR(buf), bufsize); + WHILE n > 0 DO + r := Unix.Write(fdnew, SYSTEM.ADR(buf), n); + IF r < 0 THEN errno := Unix.errno(); r := Unix.Close(fdold); r := Unix.Close(fdnew); + Err("cannot move file", NIL, errno) + END ; + n := Unix.Read(fdold, SYSTEM.ADR(buf), bufsize) + END ; + errno := Unix.errno(); + r := Unix.Close(fdold); r := Unix.Close(fdnew); + IF n = 0 THEN r := Unix.Unlink(old); res := 0 + ELSE Err("cannot move file", NIL, errno) + END ; + ELSE RETURN (* res is Unix.Rename return code *) + END + END ; + res := 0 + ELSE res := 2 (* old file not found *) + END + END Rename; + + PROCEDURE Register* (f: File); + VAR idx, errno: INTEGER; f1: File; file: ARRAY 104 OF CHAR; + BEGIN + IF (f.state = create) & (f.registerName # "") THEN f.state := close (* shortcut renaming *) END ; + Close(f); + IF f.registerName # "" THEN + Rename(f.workName, f.registerName, errno); + IF errno # 0 THEN COPY(f.registerName, file); HALT(99) END ; + f.workName := f.registerName; f.registerName := ""; f.tempFile := FALSE + END + END Register; + + PROCEDURE ChangeDirectory*(path: ARRAY OF CHAR; VAR res: INTEGER); + BEGIN + res := SHORT(Unix.Chdir(path)); + getcwd(Kernel.CWD) + END ChangeDirectory; + + PROCEDURE FlipBytes(VAR src, dest: ARRAY OF SYSTEM.BYTE); + VAR i, j: LONGINT; + BEGIN + IF ~Kernel.littleEndian THEN i := LEN(src); j := 0; + WHILE i > 0 DO DEC(i); dest[j] := src[i]; INC(j) END + ELSE SYSTEM.MOVE(SYSTEM.ADR(src), SYSTEM.ADR(dest), LEN(src)) + END + END FlipBytes; + + PROCEDURE ReadBool* (VAR R: Rider; VAR x: BOOLEAN); + BEGIN Read(R, SYSTEM.VAL(CHAR, x)) + END ReadBool; + + PROCEDURE ReadInt* (VAR R: Rider; VAR x: INTEGER); + VAR b: ARRAY 2 OF CHAR; + BEGIN ReadBytes(R, b, 2); + x := ORD(b[0]) + ORD(b[1])*256 + END ReadInt; + + PROCEDURE ReadLInt* (VAR R: Rider; VAR x: LONGINT); + VAR b: ARRAY 4 OF CHAR; + BEGIN ReadBytes(R, b, 4); + x := ORD(b[0]) + ORD(b[1])*100H + ORD(b[2])*10000H + ORD(b[3])*1000000H + END ReadLInt; + + PROCEDURE ReadSet* (VAR R: Rider; VAR x: SET); + VAR b: ARRAY 4 OF CHAR; + BEGIN ReadBytes(R, b, 4); + x := SYSTEM.VAL(SET, ORD(b[0]) + ORD(b[1])*100H + ORD(b[2])*10000H + ORD(b[3])*1000000H) + END ReadSet; + + PROCEDURE ReadReal* (VAR R: Rider; VAR x: REAL); + VAR b: ARRAY 4 OF CHAR; + BEGIN ReadBytes(R, b, 4); FlipBytes(b, x) + END ReadReal; + + PROCEDURE ReadLReal* (VAR R: Rider; VAR x: LONGREAL); + VAR b: ARRAY 8 OF CHAR; + BEGIN ReadBytes(R, b, 8); FlipBytes(b, x) + END ReadLReal; + + PROCEDURE ReadString* (VAR R: Rider; VAR x: ARRAY OF CHAR); + VAR i: INTEGER; ch: CHAR; + BEGIN i := 0; + REPEAT Read(R, ch); x[i] := ch; INC(i) UNTIL ch = 0X + END ReadString; + + (* need to read line; -- noch *) + PROCEDURE ReadLine* (VAR R: Rider; VAR x: ARRAY OF CHAR); + VAR i: INTEGER; ch: CHAR; b : BOOLEAN; + BEGIN i := 0; + b := FALSE; + REPEAT + Read(R, ch); + IF ((ch = 0X) OR (ch = 0AX) OR (ch = 0DX)) THEN + b := TRUE + ELSE + x[i] := ch; + INC(i); + END; + UNTIL b + END ReadLine; + + PROCEDURE ReadNum* (VAR R: Rider; VAR x: LONGINT); + VAR s: SHORTINT; ch: CHAR; n: LONGINT; + BEGIN s := 0; n := 0; Read(R, ch); + WHILE ORD(ch) >= 128 DO INC(n, ASH(ORD(ch) - 128, s) ); INC(s, 7); Read(R, ch) END; + INC(n, ASH(ORD(ch) MOD 64 - ORD(ch) DIV 64 * 64, s) ); + x := n + END ReadNum; + + PROCEDURE WriteBool* (VAR R: Rider; x: BOOLEAN); + BEGIN Write(R, SYSTEM.VAL(CHAR, x)) + END WriteBool; + + PROCEDURE WriteInt* (VAR R: Rider; x: INTEGER); + VAR b: ARRAY 2 OF CHAR; + BEGIN b[0] := CHR(x); b[1] := CHR(x DIV 256); + WriteBytes(R, b, 2); + END WriteInt; + + PROCEDURE WriteLInt* (VAR R: Rider; x: LONGINT); + VAR b: ARRAY 4 OF CHAR; + BEGIN + b[0] := CHR(x); b[1] := CHR(x DIV 100H); b[2] := CHR(x DIV 10000H); b[3] := CHR(x DIV 1000000H); + WriteBytes(R, b, 4); + END WriteLInt; + + PROCEDURE WriteSet* (VAR R: Rider; x: SET); + VAR b: ARRAY 4 OF CHAR; i: LONGINT; + BEGIN i := SYSTEM.VAL(LONGINT, x); + b[0] := CHR(i); b[1] := CHR(i DIV 100H); b[2] := CHR(i DIV 10000H); b[3] := CHR(i DIV 1000000H); + WriteBytes(R, b, 4); + END WriteSet; + + PROCEDURE WriteReal* (VAR R: Rider; x: REAL); + VAR b: ARRAY 4 OF CHAR; + BEGIN FlipBytes(x, b); WriteBytes(R, b, 4) + END WriteReal; + + PROCEDURE WriteLReal* (VAR R: Rider; x: LONGREAL); + VAR b: ARRAY 8 OF CHAR; + BEGIN FlipBytes(x, b); WriteBytes(R, b, 8) + END WriteLReal; + + PROCEDURE WriteString* (VAR R: Rider; x: ARRAY [1] OF CHAR); + VAR i: INTEGER; + BEGIN i := 0; + WHILE x[i] # 0X DO INC(i) END ; + WriteBytes(R, x, i+1) + END WriteString; + + PROCEDURE WriteNum* (VAR R: Rider; x: LONGINT); + BEGIN + WHILE (x < - 64) OR (x > 63) DO Write(R, CHR(x MOD 128 + 128)); x := x DIV 128 END; + Write(R, CHR(x MOD 128)) + END WriteNum; + + PROCEDURE GetName*(f: File; VAR name: ARRAY OF CHAR); + BEGIN + COPY (f.workName, name); + END GetName; + + PROCEDURE Finalize(o: SYSTEM.PTR); + VAR f: File; res: LONGINT; + BEGIN + f := SYSTEM.VAL(File, o); + IF f.fd >= 0 THEN + fileTab[f.fd] := 0; res := Unix.Close(f.fd); f.fd := -1; DEC(Kernel.nofiles); + IF f.tempFile THEN res := Unix.Unlink(f.workName) END + END + END Finalize; + + PROCEDURE Init; + VAR i: LONGINT; + BEGIN + i := 0; WHILE i < fileTabSize DO fileTab[i] := 0; INC(i) END ; + tempno := -1; Kernel.nofiles := 0 + END Init; + +BEGIN Init +END Files. diff --git a/src/lib/system/linux/clang/Files0.Mod b/src/lib/system/linux/clang/Files0.Mod new file mode 100644 index 00000000..f889db57 --- /dev/null +++ b/src/lib/system/linux/clang/Files0.Mod @@ -0,0 +1,630 @@ +MODULE Files0; (* J. Templ 1.12. 89/12.4.95 Oberon files mapped onto Unix files *) + +(* this module is not for use by developers and inteded to bootstrap voc *) +(* for general use import Files module *) + + IMPORT SYSTEM, Unix, Kernel := Kernel0, Args, Console; + + (* standard data type I/O + + little endian, + Sint:1, Int:2, Lint:4 + ORD({0}) = 1, + false = 0, true =1 + IEEE real format, + null terminated strings, + compact numbers according to M.Odersky *) + + + CONST + nofbufs = 4; + bufsize = 4096; + fileTabSize = 64; + noDesc = -1; + notDone = -1; + + (* file states *) + open = 0; create = 1; close = 2; + + + TYPE + FileName = ARRAY 101 OF CHAR; + File* = POINTER TO Handle; + Buffer = POINTER TO BufDesc; + + Handle = RECORD + workName, registerName: FileName; + tempFile: BOOLEAN; + dev, ino, mtime: LONGINT; + fd-, len, pos: LONGINT; + bufs: ARRAY nofbufs OF Buffer; + swapper, state: INTEGER + END ; + + BufDesc = RECORD + f: File; + chg: BOOLEAN; + org, size: LONGINT; + data: ARRAY bufsize OF SYSTEM.BYTE + END ; + + Rider* = RECORD + res*: LONGINT; + eof*: BOOLEAN; + buf: Buffer; + org, offset: LONGINT + END ; + + Time = POINTER TO TimeDesc; + TimeDesc = RECORD + sec*, min*, hour*, mday*, mon*, year*, wday*, isdst*, zone*, gmtoff*: LONGINT; +(* sec*, min*, hour*, mday*, mon*, year*, wday*, isdst*, zone*, gmtoff*: INTEGER;*) + END ; + + VAR + fileTab: ARRAY fileTabSize OF LONGINT (*=File*); + tempno: INTEGER; + +(* for localtime *) + PROCEDURE -includetime() + '#include "time.h"'; + + PROCEDURE -localtime(VAR clock: LONGINT): Time + "(Files0_Time) localtime(clock)"; + + PROCEDURE -getcwd(VAR cwd: Unix.Name) + "getcwd(cwd, cwd__len)"; + + PROCEDURE -IdxTrap "__HALT(-1)"; + + PROCEDURE^ Finalize(o: SYSTEM.PTR); + + PROCEDURE Err(s: ARRAY OF CHAR; f: File; errno: LONGINT); + BEGIN + Console.Ln; Console.String("-- "); Console.String(s); Console.String(": "); + IF f # NIL THEN + IF f.registerName # "" THEN Console.String(f.registerName) ELSE Console.String(f.workName) END + END ; + IF errno # 0 THEN Console.String(" errno = "); Console.Int(errno, 1) END ; + Console.Ln; + HALT(99) + END Err; + + PROCEDURE MakeFileName(dir, name: ARRAY OF CHAR; VAR dest: ARRAY OF CHAR); + VAR i, j: INTEGER; + BEGIN i := 0; j := 0; + WHILE dir[i] # 0X DO dest[i] := dir[i]; INC(i) END ; + IF dest[i-1] # "/" THEN dest[i] := "/"; INC(i) END ; + WHILE name[j] # 0X DO dest[i] := name[j]; INC(i); INC(j) END ; + dest[i] := 0X + END MakeFileName; + + PROCEDURE GetTempName(finalName: ARRAY OF CHAR; VAR name: ARRAY OF CHAR); + VAR n, i, j: LONGINT; + BEGIN + INC(tempno); n := tempno; i := 0; + IF finalName[0] # "/" THEN (* relative pathname *) + WHILE Kernel.CWD[i] # 0X DO name[i] := Kernel.CWD[i]; INC(i) END; + IF Kernel.CWD[i-1] # "/" THEN name[i] := "/"; INC(i) END + END; + j := 0; + WHILE finalName[j] # 0X DO name[i] := finalName[j]; INC(i); INC(j) END; + DEC(i); + WHILE name[i] # "/" DO DEC(i) END; + name[i+1] := "."; name[i+2] := "t"; name[i+3] := "m"; name[i+4] := "p"; name[i+5] := "."; INC(i, 6); + WHILE n > 0 DO name[i] := CHR(n MOD 10 + ORD("0")); n := n DIV 10; INC(i) END; + name[i] := "."; INC(i); n := SHORT(Unix.Getpid()); + WHILE n > 0 DO name[i] := CHR(n MOD 10 + ORD("0")); n := n DIV 10; INC(i) END; + name[i] := 0X + END GetTempName; + + PROCEDURE Create(f: File); + VAR stat: Unix.Status; done: BOOLEAN; + errno: LONGINT; err: ARRAY 32 OF CHAR; + BEGIN + IF f.fd = noDesc THEN + IF f.state = create THEN GetTempName(f.registerName, f.workName); f.tempFile := TRUE + ELSIF f.state = close THEN + f.workName := f.registerName; f.registerName := ""; f.tempFile := FALSE + END ; + errno := Unix.Unlink(f.workName); (*unlink first to avoid stale NFS handles and to avoid reuse of inodes*) + f.fd := Unix.Open(f.workName, Unix.rdwr + Unix.creat + Unix.trunc, {2, 4,5, 7,8}); + done := f.fd >= 0; errno := Unix.errno(); + IF (~done & ((errno = Unix.ENFILE) OR (errno = Unix.EMFILE))) OR (done & (f.fd >= fileTabSize)) THEN + IF done & (f.fd >= fileTabSize) THEN errno := Unix.Close(f.fd) END ; + Kernel.GC(TRUE); + f.fd := Unix.Open(f.workName, Unix.rdwr + Unix.creat + Unix.trunc, {2, 4,5, 7,8}); + done := f.fd >= 0 + END ; + IF done THEN + IF f.fd >= fileTabSize THEN errno := Unix.Close(f.fd); Err("too many files open", f, 0) + ELSE fileTab[f.fd] := SYSTEM.VAL(LONGINT, f); INC(Kernel.nofiles); Kernel.RegisterObject(f, Finalize); + f.state := open; f.pos := 0; errno := Unix.Fstat(f.fd, stat); + f.dev := stat.dev; f.ino := stat.ino; f.mtime := stat.mtime + END + ELSE errno := Unix.errno(); + IF errno = Unix.ENOENT THEN err := "no such directory" + ELSIF (errno = Unix.ENFILE) OR (errno = Unix.EMFILE) THEN err := "too many files open" + ELSE err := "file not created" + END ; + Err(err, f, errno) + END + END + END Create; + + PROCEDURE Flush(buf: Buffer); + VAR res: LONGINT; f: File; stat: Unix.Status; + BEGIN + IF buf.chg THEN f := buf.f; Create(f); + IF buf.org # f.pos THEN res := Unix.Lseek(f.fd, buf.org, 0) END ; + res := Unix.Write(f.fd, SYSTEM.ADR(buf.data), buf.size); + IF res < 0 THEN Err("error in writing file", f, Unix.errno()) END ; + f.pos := buf.org + buf.size; + buf.chg := FALSE; + res := Unix.Fstat(f.fd, stat); + f.mtime := stat.mtime + END + END Flush; + + PROCEDURE Close* (f: File); + VAR i, res: LONGINT; + BEGIN + IF (f.state # create) OR (f.registerName # "") THEN + Create(f); i := 0; + WHILE (i < nofbufs) & (f.bufs[i] # NIL) DO Flush(f.bufs[i]); INC(i) END ; + res := Unix.Fsync(f.fd); + IF res < 0 THEN Err("error in writing file", f, Unix.errno()) END + END + END Close; + + PROCEDURE Length* (f: File): LONGINT; + BEGIN RETURN f.len + END Length; + + PROCEDURE New* (name: ARRAY OF CHAR): File; + VAR f: File; + BEGIN + NEW(f); f.workName := ""; COPY(name, f.registerName); + f.fd := noDesc; f.state := create; f.len := 0; f.pos := 0; f.swapper := -1; (*all f.buf[i] = NIL*) + RETURN f + END New; + + PROCEDURE ScanPath(VAR pos: INTEGER; VAR dir: ARRAY OF CHAR); (* supports ~, ~user and blanks inside path *) + VAR i: INTEGER; ch: CHAR; home: ARRAY 256 OF CHAR; + BEGIN + i := 0; ch := Kernel.OBERON[pos]; + WHILE (ch = " ") OR (ch = ":") DO INC(pos); ch := Kernel.OBERON[pos] END ; + IF ch = "~" THEN + INC(pos); ch := Kernel.OBERON[pos]; + home := ""; Args.GetEnv("HOME", home); + WHILE home[i] # 0X DO dir[i] := home[i]; INC(i) END ; + IF (ch # "/") & (ch # 0X) & (ch # ":") & (ch # " ") THEN + WHILE (i > 0) & (dir[i-1] # "/") DO DEC(i) END + END + END ; + WHILE (ch # 0X) & (ch # ":") DO dir[i] := ch; INC(i); INC(pos); ch := Kernel.OBERON[pos] END ; + WHILE (i > 0) & (dir[i-1] = " ") DO DEC(i) END ; + dir[i] := 0X + END ScanPath; + + PROCEDURE HasDir(VAR name: ARRAY OF CHAR): BOOLEAN; + VAR i: INTEGER; ch: CHAR; + BEGIN i := 0; ch := name[0]; + WHILE (ch # 0X) & (ch # "/") DO INC(i); ch := name[i] END ; + RETURN ch = "/" + END HasDir; + + PROCEDURE CacheEntry(dev, ino: LONGINT; mtime: LONGINT): File; + VAR f: File; i: INTEGER; stat: Unix.Status; res: LONGINT; + BEGIN i := 0; + WHILE i < fileTabSize DO + f := SYSTEM.VAL(File, fileTab[i]); + IF (f # NIL) & (ino = f.ino) & (dev = f.dev) THEN + IF mtime # f.mtime THEN i := 0; + WHILE i < nofbufs DO + IF f.bufs[i] # NIL THEN f.bufs[i].org := -1; f.bufs[i] := NIL END ; + INC(i) + END ; + f.swapper := -1; f.mtime := mtime; + res := Unix.Fstat(f.fd, stat); f.len := stat.size + END ; + RETURN f + END ; + INC(i) + END ; + RETURN NIL + END CacheEntry; + + PROCEDURE Old* (name: ARRAY OF CHAR): File; + VAR f: File; fd, res, errno: LONGINT; pos: INTEGER; done: BOOLEAN; + dir, path: ARRAY 256 OF CHAR; + stat: Unix.Status; + BEGIN + IF name # "" THEN + IF HasDir(name) THEN dir := ""; COPY(name, path) + ELSE pos := 0; ScanPath(pos, dir); MakeFileName(dir, name, path); ScanPath(pos, dir) + END ; + LOOP + fd := Unix.Open(path, Unix.rdwr, {}); done := fd >= 0; errno := Unix.errno(); + IF (~done & ((errno = Unix.ENFILE) OR (errno = Unix.EMFILE))) OR (done & (fd >= fileTabSize)) THEN + IF done & (fd >= fileTabSize) THEN res := Unix.Close(fd) END ; + Kernel.GC(TRUE); + fd := Unix.Open(path, Unix.rdwr, {}); + done := fd >= 0; errno := Unix.errno(); + IF ~done & ((errno = Unix.ENFILE) OR (errno = Unix.EMFILE)) THEN Err("too many files open", f, errno) END + END ; + IF ~done & ((errno = Unix.EACCES) OR (errno = Unix.EROFS) OR (errno = Unix.EAGAIN)) THEN + (* errno EAGAIN observed on Solaris 2.4 *) + fd := Unix.Open(path, Unix.rdonly, {}); done := fd >= 0; errno := Unix.errno() + END ; +IF (~done) & (errno # Unix.ENOENT) THEN + Console.String("warning Files0.Old "); Console.String(name); + Console.String(" errno = "); Console.Int(errno, 0); Console.Ln; +END ; + IF done THEN + res := Unix.Fstat(fd, stat); + f := CacheEntry(stat.dev, stat.ino, stat.mtime); + IF f # NIL THEN res := Unix.Close(fd); RETURN f + ELSIF fd >= fileTabSize THEN res := Unix.Close(fd); Err("too many files open", f, 0) + ELSE NEW(f); fileTab[fd] := SYSTEM.VAL(LONGINT, f); INC(Kernel.nofiles); Kernel.RegisterObject(f, Finalize); + f.fd := fd; f.state := open; f.len := stat.size; f.pos := 0; f.swapper := -1; (*all f.buf[i] = NIL*) + COPY(name, f.workName); f.registerName := ""; f.tempFile := FALSE; + f.dev := stat.dev; f.ino := stat.ino; f.mtime := stat.mtime; + RETURN f + END + ELSIF dir = "" THEN RETURN NIL + ELSE MakeFileName(dir, name, path); ScanPath(pos, dir) + END + END + ELSE RETURN NIL + END + END Old; + + PROCEDURE Purge* (f: File); + VAR i: INTEGER; stat: Unix.Status; res: LONGINT; + BEGIN i := 0; + WHILE i < nofbufs DO + IF f.bufs[i] # NIL THEN f.bufs[i].org := -1; f.bufs[i] := NIL END ; + INC(i) + END ; + IF f.fd # noDesc THEN res := Unix.Ftruncate(f.fd, 0); res := Unix.Lseek(f.fd, 0, 0) END ; + f.pos := 0; f.len := 0; f.swapper := -1; + res := Unix.Fstat(f.fd, stat); f.mtime := stat.mtime + END Purge; + + PROCEDURE GetDate* (f: File; VAR t, d: LONGINT); + VAR stat: Unix.Status; clock, res: LONGINT; time: Time; + BEGIN + Create(f); res := Unix.Fstat(f.fd, stat); + time := localtime(stat.mtime); + t := time.sec + ASH(time.min, 6) + ASH(time.hour, 12); + d := time.mday + ASH(time.mon+1, 5) + ASH(time.year MOD 100, 9) + END GetDate; + + PROCEDURE Pos* (VAR r: Rider): LONGINT; + BEGIN RETURN r.org + r.offset + END Pos; + + PROCEDURE Set* (VAR r: Rider; f: File; pos: LONGINT); + VAR org, offset, i, n, res: LONGINT; buf: Buffer; + BEGIN + IF f # NIL THEN + IF pos > f.len THEN pos := f.len ELSIF pos < 0 THEN pos := 0 END ; + offset := pos MOD bufsize; org := pos - offset; i := 0; + WHILE (i < nofbufs) & (f.bufs[i] # NIL) & (org # f.bufs[i].org) DO INC(i) END ; + IF i < nofbufs THEN + IF f.bufs[i] = NIL THEN NEW(buf); buf.chg := FALSE; buf.org := -1; buf.f := f; f.bufs[i] := buf + ELSE buf := f.bufs[i] + END + ELSE + f.swapper := (f.swapper + 1) MOD nofbufs; + buf := f.bufs[f.swapper]; + Flush(buf) + END ; + IF buf.org # org THEN + IF org = f.len THEN buf.size := 0 + ELSE Create(f); + IF f.pos # org THEN res := Unix.Lseek(f.fd, org, 0) END ; + n := Unix.ReadBlk(f.fd, buf.data); + IF n < 0 THEN Err("read from file not done", f, Unix.errno()) END ; + f.pos := org + n; + buf.size := n + END ; + buf.org := org; buf.chg := FALSE + END + ELSE buf := NIL; org := 0; offset := 0 + END ; + r.buf := buf; r.org := org; r.offset := offset; r.eof := FALSE; r.res := 0 + END Set; + + PROCEDURE Read* (VAR r: Rider; VAR x: SYSTEM.BYTE); + VAR offset: LONGINT; buf: Buffer; + BEGIN + buf := r.buf; offset := r.offset; + IF r.org # buf.org THEN Set(r, buf.f, r.org + offset); buf := r.buf; offset := r.offset END ; + IF (offset < buf.size) THEN + x := buf.data[offset]; r.offset := offset + 1 + ELSIF r.org + offset < buf.f.len THEN + Set(r, r.buf.f, r.org + offset); + x := r.buf.data[0]; r.offset := 1 + ELSE + x := 0X; r.eof := TRUE + END + END Read; + + PROCEDURE ReadBytes* (VAR r: Rider; VAR x: ARRAY OF SYSTEM.BYTE; n: LONGINT); + VAR xpos, min, restInBuf, offset: LONGINT; buf: Buffer; + BEGIN + IF n > LEN(x) THEN IdxTrap END ; + xpos := 0; buf := r.buf; offset := r.offset; + WHILE n > 0 DO + IF (r.org # buf.org) OR (offset >= bufsize) THEN + Set(r, buf.f, r.org + offset); + buf := r.buf; offset := r.offset + END ; + restInBuf := buf.size - offset; + IF restInBuf = 0 THEN r.res := n; r.eof := TRUE; RETURN + ELSIF n > restInBuf THEN min := restInBuf ELSE min := n END ; + SYSTEM.MOVE(SYSTEM.ADR(buf.data) + offset, SYSTEM.ADR(x) + xpos, min); + INC(offset, min); r.offset := offset; INC(xpos, min); DEC(n, min) + END ; + r.res := 0; r.eof := FALSE + END ReadBytes; + + PROCEDURE Base* (VAR r: Rider): File; + BEGIN RETURN r.buf.f + END Base; + + PROCEDURE Write* (VAR r: Rider; x: SYSTEM.BYTE); + VAR buf: Buffer; offset: LONGINT; + BEGIN + buf := r.buf; offset := r.offset; + IF (r.org # buf.org) OR (offset >= bufsize) THEN + Set(r, buf.f, r.org + offset); + buf := r.buf; offset := r.offset + END ; + buf.data[offset] := x; + buf.chg := TRUE; + IF offset = buf.size THEN + INC(buf.size); INC(buf.f.len) + END ; + r.offset := offset + 1; r.res := 0 + END Write; + + PROCEDURE WriteBytes* (VAR r: Rider; VAR x: ARRAY OF SYSTEM.BYTE; n: LONGINT); + VAR xpos, min, restInBuf, offset: LONGINT; buf: Buffer; + BEGIN + IF n > LEN(x) THEN IdxTrap END ; + xpos := 0; buf := r.buf; offset := r.offset; + WHILE n > 0 DO + IF (r.org # buf.org) OR (offset >= bufsize) THEN + Set(r, buf.f, r.org + offset); + buf := r.buf; offset := r.offset + END ; + restInBuf := bufsize - offset; + IF n > restInBuf THEN min := restInBuf ELSE min := n END ; + SYSTEM.MOVE(SYSTEM.ADR(x) + xpos, SYSTEM.ADR(buf.data) + offset, min); + INC(offset, min); r.offset := offset; + IF offset > buf.size THEN INC(buf.f.len, offset - buf.size); buf.size := offset END ; + INC(xpos, min); DEC(n, min); buf.chg := TRUE + END ; + r.res := 0 + END WriteBytes; + +(* another solution would be one that is similar to ReadBytes, WriteBytes. +No code duplication, more symmetric, only two ifs for +Read and Write in buffer, buf.size replaced by bufsize in Write ops, buf.size and len +must be made consistent with offset (if offset > buf.size) in a lazy way. + +PROCEDURE Write* (VAR r: Rider; x: SYSTEM.BYTE); + VAR buf: Buffer; offset: LONGINT; +BEGIN + buf := r.buf; offset := r.offset; + IF (offset >= bufsize) OR (r.org # buf.org) THEN + Set(r, buf.f, r.org + offset); buf := r.buf; offset := r.offset; + END ; + buf.data[offset] := x; r.offset := offset + 1; buf.chg := TRUE +END Write; + +PROCEDURE WriteBytes ... + +PROCEDURE Read* (VAR r: Rider; VAR x: SYSTEM.BYTE); + VAR offset: LONGINT; buf: Buffer; +BEGIN + buf := r.buf; offset := r.offset; + IF (offset >= buf.size) OR (r.org # buf.org) THEN + IF r.org + offset >= buf.f.len THEN x := 0X; r.eof := TRUE; RETURN + ELSE Set(r, buf.f, r.org + offset); buf := r.buf; offset := r.offset + END + END ; + x := buf.data[offset]; r.offset := offset + 1 +END Read; + +but this would also affect Set, Length, and Flush. +Especially Length would become fairly complex. +*) + + PROCEDURE Delete* (name: ARRAY OF CHAR; VAR res: INTEGER); + BEGIN + res := SHORT(Unix.Unlink(name)); + res := SHORT(Unix.errno()) + END Delete; + + PROCEDURE Rename* (old, new: ARRAY OF CHAR; VAR res: INTEGER); + VAR fdold, fdnew, n, errno, r: LONGINT; + ostat, nstat: Unix.Status; + buf: ARRAY 4096 OF CHAR; + BEGIN + r := Unix.Stat(old, ostat); + IF r >= 0 THEN + r := Unix.Stat(new, nstat); + IF (r >= 0) & ((ostat.dev # nstat.dev) OR (ostat.ino # nstat.ino)) THEN + Delete(new, res); (* work around stale nfs handles *) + END ; + r := Unix.Rename(old, new); + IF r < 0 THEN res := SHORT(Unix.errno()); + IF res = Unix.EXDEV THEN (* cross device link, move the file *) + fdold := Unix.Open(old, Unix.rdonly, {}); + IF fdold < 0 THEN res := 2; RETURN END ; + fdnew := Unix.Open(new, Unix.rdwr + Unix.creat + Unix.trunc, {2, 4,5, 7,8}); + IF fdnew < 0 THEN r := Unix.Close(fdold); res := 3; RETURN END ; + n := Unix.Read(fdold, SYSTEM.ADR(buf), bufsize); + WHILE n > 0 DO + r := Unix.Write(fdnew, SYSTEM.ADR(buf), n); + IF r < 0 THEN errno := Unix.errno(); r := Unix.Close(fdold); r := Unix.Close(fdnew); + Err("cannot move file", NIL, errno) + END ; + n := Unix.Read(fdold, SYSTEM.ADR(buf), bufsize) + END ; + errno := Unix.errno(); + r := Unix.Close(fdold); r := Unix.Close(fdnew); + IF n = 0 THEN r := Unix.Unlink(old); res := 0 + ELSE Err("cannot move file", NIL, errno) + END ; + ELSE RETURN (* res is Unix.Rename return code *) + END + END ; + res := 0 + ELSE res := 2 (* old file not found *) + END + END Rename; + + PROCEDURE Register* (f: File); + VAR idx, errno: INTEGER; f1: File; file: ARRAY 104 OF CHAR; + BEGIN + IF (f.state = create) & (f.registerName # "") THEN f.state := close (* shortcut renaming *) END ; + Close(f); + IF f.registerName # "" THEN + Rename(f.workName, f.registerName, errno); + IF errno # 0 THEN COPY(f.registerName, file); HALT(99) END ; + f.workName := f.registerName; f.registerName := ""; f.tempFile := FALSE + END + END Register; + + PROCEDURE ChangeDirectory*(path: ARRAY OF CHAR; VAR res: INTEGER); + BEGIN + res := SHORT(Unix.Chdir(path)); + getcwd(Kernel.CWD) + END ChangeDirectory; + + PROCEDURE FlipBytes(VAR src, dest: ARRAY OF SYSTEM.BYTE); + VAR i, j: LONGINT; + BEGIN + IF ~Kernel.littleEndian THEN i := LEN(src); j := 0; + WHILE i > 0 DO DEC(i); dest[j] := src[i]; INC(j) END + ELSE SYSTEM.MOVE(SYSTEM.ADR(src), SYSTEM.ADR(dest), LEN(src)) + END + END FlipBytes; + + PROCEDURE ReadBool* (VAR R: Rider; VAR x: BOOLEAN); + BEGIN Read(R, SYSTEM.VAL(CHAR, x)) + END ReadBool; + + PROCEDURE ReadInt* (VAR R: Rider; VAR x: INTEGER); + VAR b: ARRAY 2 OF CHAR; + BEGIN ReadBytes(R, b, 2); + x := ORD(b[0]) + ORD(b[1])*256 + END ReadInt; + + PROCEDURE ReadLInt* (VAR R: Rider; VAR x: LONGINT); + VAR b: ARRAY 4 OF CHAR; + BEGIN ReadBytes(R, b, 4); + x := ORD(b[0]) + ORD(b[1])*100H + ORD(b[2])*10000H + ORD(b[3])*1000000H + END ReadLInt; + + PROCEDURE ReadSet* (VAR R: Rider; VAR x: SET); + VAR b: ARRAY 4 OF CHAR; + BEGIN ReadBytes(R, b, 4); + x := SYSTEM.VAL(SET, ORD(b[0]) + ORD(b[1])*100H + ORD(b[2])*10000H + ORD(b[3])*1000000H) + END ReadSet; + + PROCEDURE ReadReal* (VAR R: Rider; VAR x: REAL); + VAR b: ARRAY 4 OF CHAR; + BEGIN ReadBytes(R, b, 4); FlipBytes(b, x) + END ReadReal; + + PROCEDURE ReadLReal* (VAR R: Rider; VAR x: LONGREAL); + VAR b: ARRAY 8 OF CHAR; + BEGIN ReadBytes(R, b, 8); FlipBytes(b, x) + END ReadLReal; + + PROCEDURE ReadString* (VAR R: Rider; VAR x: ARRAY OF CHAR); + VAR i: INTEGER; ch: CHAR; + BEGIN i := 0; + REPEAT Read(R, ch); x[i] := ch; INC(i) UNTIL ch = 0X + END ReadString; + + PROCEDURE ReadNum* (VAR R: Rider; VAR x: LONGINT); + VAR s: SHORTINT; ch: CHAR; n: LONGINT; + BEGIN s := 0; n := 0; Read(R, ch); + WHILE ORD(ch) >= 128 DO INC(n, ASH(ORD(ch) - 128, s) ); INC(s, 7); Read(R, ch) END; + INC(n, ASH(ORD(ch) MOD 64 - ORD(ch) DIV 64 * 64, s) ); + x := n + END ReadNum; + + PROCEDURE WriteBool* (VAR R: Rider; x: BOOLEAN); + BEGIN Write(R, SYSTEM.VAL(CHAR, x)) + END WriteBool; + + PROCEDURE WriteInt* (VAR R: Rider; x: INTEGER); + VAR b: ARRAY 2 OF CHAR; + BEGIN b[0] := CHR(x); b[1] := CHR(x DIV 256); + WriteBytes(R, b, 2); + END WriteInt; + + PROCEDURE WriteLInt* (VAR R: Rider; x: LONGINT); + VAR b: ARRAY 4 OF CHAR; + BEGIN + b[0] := CHR(x); b[1] := CHR(x DIV 100H); b[2] := CHR(x DIV 10000H); b[3] := CHR(x DIV 1000000H); + WriteBytes(R, b, 4); + END WriteLInt; + + PROCEDURE WriteSet* (VAR R: Rider; x: SET); + VAR b: ARRAY 4 OF CHAR; i: LONGINT; + BEGIN i := SYSTEM.VAL(LONGINT, x); + b[0] := CHR(i); b[1] := CHR(i DIV 100H); b[2] := CHR(i DIV 10000H); b[3] := CHR(i DIV 1000000H); + WriteBytes(R, b, 4); + END WriteSet; + + PROCEDURE WriteReal* (VAR R: Rider; x: REAL); + VAR b: ARRAY 4 OF CHAR; + BEGIN FlipBytes(x, b); WriteBytes(R, b, 4) + END WriteReal; + + PROCEDURE WriteLReal* (VAR R: Rider; x: LONGREAL); + VAR b: ARRAY 8 OF CHAR; + BEGIN FlipBytes(x, b); WriteBytes(R, b, 8) + END WriteLReal; + + PROCEDURE WriteString* (VAR R: Rider; x: ARRAY [1] OF CHAR); + VAR i: INTEGER; + BEGIN i := 0; + WHILE x[i] # 0X DO INC(i) END ; + WriteBytes(R, x, i+1) + END WriteString; + + PROCEDURE WriteNum* (VAR R: Rider; x: LONGINT); + BEGIN + WHILE (x < - 64) OR (x > 63) DO Write(R, CHR(x MOD 128 + 128)); x := x DIV 128 END; + Write(R, CHR(x MOD 128)) + END WriteNum; + + PROCEDURE Finalize(o: SYSTEM.PTR); + VAR f: File; res: LONGINT; + BEGIN + f := SYSTEM.VAL(File, o); + IF f.fd >= 0 THEN + fileTab[f.fd] := 0; res := Unix.Close(f.fd); f.fd := -1; DEC(Kernel.nofiles); + IF f.tempFile THEN res := Unix.Unlink(f.workName) END + END + END Finalize; + + PROCEDURE Init; + VAR i: LONGINT; + BEGIN + i := 0; WHILE i < fileTabSize DO fileTab[i] := 0; INC(i) END ; + tempno := -1; Kernel.nofiles := 0 + END Init; + +BEGIN Init +END Files0. diff --git a/src/lib/system/linux/clang/Kernel.Mod b/src/lib/system/linux/clang/Kernel.Mod new file mode 100644 index 00000000..e84e5eae --- /dev/null +++ b/src/lib/system/linux/clang/Kernel.Mod @@ -0,0 +1,167 @@ +MODULE Kernel; +(* + J. Templ, 16.4.95 + communication with C-runtime and storage management +*) + + IMPORT SYSTEM, Unix, Args; + + TYPE + RealTime = POINTER TO TimeDesc; + TimeDesc = RECORD + sec, min, hour, mday, mon, year, wday, isdst, zone, gmtoff: LONGINT + END ; + + KeyCmd* = PROCEDURE; + + ObjFinalizer* = PROCEDURE(obj: SYSTEM.PTR); + + + VAR + (* trap handling *) + trapEnv*: Unix.JmpBuf; (* saved stack environment for trap handling *) + + (* oberon heap management *) + nofiles*: LONGINT; + + (* input event handling *) + readSet*, readySet*: Unix.FdSet; + + FKey*: ARRAY 16 OF KeyCmd; + + littleEndian*: BOOLEAN; + + TimeUnit*: LONGINT; (* 1 sec *) + + LIB*, CWD*: ARRAY 256 OF CHAR; + OBERON*: ARRAY 1024 OF CHAR; + + + timeStart: LONGINT; (* milliseconds *) + + PROCEDURE -includesetjmp() + '#include "setjmp.h"'; +(* for localtime *) + PROCEDURE -includetime() + '#include "time.h"'; + + PROCEDURE -Lock*() + "SYSTEM_lock++"; + + PROCEDURE -Unlock*() + "SYSTEM_lock--; if (SYSTEM_interrupted && SYSTEM_lock == 0) __HALT(-9)"; + + PROCEDURE -Exit*(n: LONGINT) + "exit(n)"; + + PROCEDURE -sigsetjmp*(VAR env: Unix.JmpBuf; savemask: LONGINT): LONGINT + "__sigsetjmp(env, savemask)"; + + PROCEDURE -siglongjmp*(VAR env:Unix. JmpBuf; val: LONGINT) + "siglongjmp(env, val)"; + + PROCEDURE -heapsize*(): LONGINT + "SYSTEM_heapsize"; + + PROCEDURE -allocated*(): LONGINT + "SYSTEM_allocated"; + + PROCEDURE -localtime(VAR clock: LONGINT): RealTime + "(Kernel_RealTime)localtime(clock)"; + + PROCEDURE -malloc*(size: LONGINT): LONGINT + "(LONGINT)malloc(size)"; + + PROCEDURE -free*(adr: LONGINT) + "(void)free(adr)"; + + PROCEDURE -getcwd(VAR cwd: Unix.Name) + "getcwd(cwd, cwd__len)"; + + + PROCEDURE GetClock* (VAR t, d: LONGINT); + VAR tv: Unix.Timeval; tz: Unix.Timezone; time: RealTime; + l : LONGINT; + BEGIN + l := Unix.Gettimeofday(tv, tz); + time := localtime(tv.sec); + t := time.sec + ASH(time.min, 6) + ASH(time.hour, 12); + d := time.mday + ASH(time.mon+1, 5) + ASH(time.year MOD 100, 9); + END GetClock; + + PROCEDURE SetClock* (t, d: LONGINT); + VAR err: ARRAY 25 OF CHAR; + BEGIN err := "not yet implemented"; HALT(99) + END SetClock; + + PROCEDURE Time*(): LONGINT; + VAR timeval: Unix.Timeval; timezone: Unix.Timezone; + l : LONGINT; + BEGIN + l := Unix.Gettimeofday(timeval, timezone); + RETURN (timeval.usec DIV 1000 + timeval.sec * 1000 - timeStart) MOD 7FFFFFFFH + END Time; + +(* + PROCEDURE UserTime*(): LONGINT; + VAR rusage: Unix.Rusage; + BEGIN + Unix.Getrusage(0, S.ADR(rusage)); + RETURN rusage.utime.sec*1000 + rusage.utime.usec DIV 1000 + (* + rusage.stime.sec*1000 + rusage.stime.usec DIV 1000*) + END UserTime; +*) + + PROCEDURE Select*(delay: LONGINT); + VAR rs, ws, xs: Unix.FdSet; n: LONGINT; tv: Unix.Timeval; + BEGIN + rs := readSet; + FOR n := 0 TO 7 DO ws[n] := {}; xs[n] := {}; readySet[n] := {} END; + IF delay < 0 THEN delay := 0 END ; + tv.sec := delay DIV 1000; tv.usec := delay MOD 1000 * 1000; + n := Unix.Select(256, rs, ws, xs, tv); + IF n >= 0 THEN readySet := rs END + END Select; + + PROCEDURE -GC*(markStack: BOOLEAN) + "SYSTEM_GC(markStack)"; + + PROCEDURE -RegisterObject*(obj: SYSTEM.PTR; finalize: ObjFinalizer) + "SYSTEM_REGFIN(obj, finalize)"; + + PROCEDURE -SetHalt*(p: PROCEDURE(n: LONGINT)) + "SYSTEM_Halt = p"; + + PROCEDURE InstallTermHandler*(p: PROCEDURE); + (* not yet supported; no Modules.Free *) + END InstallTermHandler; + + PROCEDURE LargestAvailable*(): LONGINT; + BEGIN + (* dummy proc for System 3 compatibility + no meaningful value except may be the remaining swap space can be returned + in the context of an extensible heap *) + RETURN MAX(LONGINT) + END LargestAvailable; + + PROCEDURE Halt(n: LONGINT); + VAR res: LONGINT; + BEGIN res := Unix.Kill(Unix.Getpid(), 4); + END Halt; + + PROCEDURE EndianTest; + VAR i: LONGINT; dmy: INTEGER; + BEGIN + dmy := 1; i := SYSTEM.ADR(dmy); + SYSTEM.GET(i, littleEndian); (* indirection via i avoids warning on SUN cc -O *) + END EndianTest; + +BEGIN + EndianTest(); + SetHalt(Halt); + CWD := ""; OBERON := "."; LIB := ""; + getcwd(CWD); + Args.GetEnv("OBERON", OBERON); + Args.GetEnv("OBERON_LIB", LIB); + TimeUnit := 1000; timeStart := 0; timeStart := Time() +END Kernel. diff --git a/src/lib/system/linux/clang/Kernel0.Mod b/src/lib/system/linux/clang/Kernel0.Mod new file mode 100644 index 00000000..99f7777d --- /dev/null +++ b/src/lib/system/linux/clang/Kernel0.Mod @@ -0,0 +1,179 @@ +MODULE Kernel0; +(* + J. Templ, 16.4.95 + communication with C-runtime and storage management +*) +(* version for bootstrapping voc *) + + IMPORT SYSTEM, Unix, Args, Strings := oocOakStrings, version; + + TYPE + RealTime = POINTER TO TimeDesc; + TimeDesc = RECORD + sec, min, hour, mday, mon, year, wday, isdst, zone, gmtoff: LONGINT +(* sec, min, hour, mday, mon, year, wday, isdst, zone, gmtoff: INTEGER*) + END ; + + KeyCmd* = PROCEDURE; + + ObjFinalizer* = PROCEDURE(obj: SYSTEM.PTR); + + + VAR + (* trap handling *) + trapEnv*: Unix.JmpBuf; (* saved stack environment for trap handling *) + + (* oberon heap management *) + nofiles*: LONGINT; + + (* input event handling *) + readSet*, readySet*: Unix.FdSet; + + FKey*: ARRAY 16 OF KeyCmd; + + littleEndian*: BOOLEAN; + + TimeUnit*: LONGINT; (* 1 sec *) + + LIB*, CWD*: ARRAY 256 OF CHAR; + OBERON*: ARRAY 1024 OF CHAR; + MODULES-: ARRAY 1024 OF CHAR; + + prefix*, fullprefix* : ARRAY 256 OF CHAR; + timeStart: LONGINT; (* milliseconds *) + + + PROCEDURE -includesetjmp() + '#include "setjmp.h"'; +(* for localtime *) + PROCEDURE -includetime() + '#include "time.h"'; + + PROCEDURE -Lock*() + "SYSTEM_lock++"; + + PROCEDURE -Unlock*() + "SYSTEM_lock--; if (SYSTEM_interrupted && SYSTEM_lock == 0) __HALT(-9)"; + + PROCEDURE -Exit*(n: LONGINT) + "exit(n)"; + + PROCEDURE -sigsetjmp*(VAR env: Unix.JmpBuf; savemask: LONGINT): LONGINT + "__sigsetjmp(env, savemask)"; + + PROCEDURE -siglongjmp*(VAR env:Unix.JmpBuf; val: LONGINT) + "siglongjmp(env, val)"; + + PROCEDURE -heapsize*(): LONGINT + "SYSTEM_heapsize"; + + PROCEDURE -allocated*(): LONGINT + "SYSTEM_allocated"; + + PROCEDURE -localtime(VAR clock: LONGINT): RealTime + "(Kernel0_RealTime)localtime(clock)"; + + PROCEDURE -malloc*(size: LONGINT): LONGINT + "(LONGINT)malloc(size)"; + + PROCEDURE -free*(adr: LONGINT) + "(void)free(adr)"; + + PROCEDURE -getcwd(VAR cwd: Unix.Name) + "getcwd(cwd, cwd__len)"; + + + PROCEDURE GetClock* (VAR t, d: LONGINT); + VAR tv: Unix.Timeval; tz: Unix.Timezone; time: RealTime; + l : LONGINT; + BEGIN + l := Unix.Gettimeofday(tv, tz); + time := localtime(tv.sec); + t := time.sec + ASH(time.min, 6) + ASH(time.hour, 12); + d := time.mday + ASH(time.mon+1, 5) + ASH(time.year MOD 100, 9); + END GetClock; + + PROCEDURE SetClock* (t, d: LONGINT); + VAR err: ARRAY 25 OF CHAR; + BEGIN err := "not yet implemented"; HALT(99) + END SetClock; + + PROCEDURE Time*(): LONGINT; + VAR timeval: Unix.Timeval; timezone: Unix.Timezone; + l : LONGINT; + BEGIN + l := Unix.Gettimeofday(timeval, timezone); + RETURN (timeval.usec DIV 1000 + timeval.sec * 1000 - timeStart) MOD 7FFFFFFFH + END Time; + +(* + PROCEDURE UserTime*(): LONGINT; + VAR rusage: Unix.Rusage; + BEGIN + Unix.Getrusage(0, S.ADR(rusage)); + RETURN rusage.utime.sec*1000 + rusage.utime.usec DIV 1000 + (* + rusage.stime.sec*1000 + rusage.stime.usec DIV 1000*) + END UserTime; +*) + + PROCEDURE Select*(delay: LONGINT); + VAR rs, ws, xs: Unix.FdSet; n: LONGINT; tv: Unix.Timeval; + BEGIN + rs := readSet; + FOR n := 0 TO 7 DO ws[n] := {}; xs[n] := {}; readySet[n] := {} END; + IF delay < 0 THEN delay := 0 END ; + tv.sec := delay DIV 1000; tv.usec := delay MOD 1000 * 1000; + n := Unix.Select(256, rs, ws, xs, tv); + IF n >= 0 THEN readySet := rs END + END Select; + + PROCEDURE -GC*(markStack: BOOLEAN) + "SYSTEM_GC(markStack)"; + + PROCEDURE -RegisterObject*(obj: SYSTEM.PTR; finalize: ObjFinalizer) + "SYSTEM_REGFIN(obj, finalize)"; + + PROCEDURE -SetHalt*(p: PROCEDURE(n: LONGINT)) + "SYSTEM_Halt = p"; + + PROCEDURE InstallTermHandler*(p: PROCEDURE); + (* not yet supported; no Modules.Free *) + END InstallTermHandler; + + PROCEDURE LargestAvailable*(): LONGINT; + BEGIN + (* dummy proc for System 3 compatibility + no meaningful value except may be the remaining swap space can be returned + in the context of an extensible heap *) + RETURN MAX(LONGINT) + END LargestAvailable; + + PROCEDURE Halt(n: LONGINT); + VAR res: LONGINT; + BEGIN res := Unix.Kill(Unix.Getpid(), 4); + END Halt; + + PROCEDURE EndianTest; + VAR i: LONGINT; dmy: INTEGER; + BEGIN + dmy := 1; i := SYSTEM.ADR(dmy); + SYSTEM.GET(i, littleEndian); (* indirection via i avoids warning on SUN cc -O *) + END EndianTest; + +BEGIN + EndianTest(); + SetHalt(Halt); + CWD := ""; OBERON := "."; LIB := ""; + MODULES := ""; (* additional modules path which can be specified on commandline and will be added to the OBERON variable; noch *) + getcwd(CWD); + Args.GetEnv ("MODULES", MODULES); + Args.GetEnv("OBERON", OBERON); + (* always have current directory in module search path, noch *) + Strings.Append(":.:", OBERON); + Strings.Append(MODULES, OBERON); + Strings.Append(":", OBERON); + Strings.Append(version.prefix, OBERON); + Strings.Append("/lib/voc/sym:", OBERON); + Args.GetEnv("OBERON_LIB", LIB); + TimeUnit := 1000; timeStart := 0; timeStart := Time() +END Kernel0. diff --git a/src/lib/system/linux/clang/SYSTEM.Mod b/src/lib/system/linux/clang/SYSTEM.Mod new file mode 100644 index 00000000..6fc08dcf --- /dev/null +++ b/src/lib/system/linux/clang/SYSTEM.Mod @@ -0,0 +1,520 @@ +(* +* voc (jet backend) runtime system, Version 1.1 +* +* Copyright (c) Software Templ, 1994, 1995, 1996 +* +* Module SYSTEM is subject to change any time without prior notification. +* Software Templ disclaims all warranties with regard to module SYSTEM, +* in particular shall Software Templ not be liable for any damage resulting +* from inappropriate use or modification of module SYSTEM. +*) + +MODULE SYSTEM; (* J. Templ, 31.5.95 *) + + IMPORT SYSTEM; (*must not import other modules*) + + CONST + ModNameLen = 20; + CmdNameLen = 24; + SZL = SIZE(LONGINT); + Unit = 4*SZL; (* smallest possible heap block *) + nofLists = 9; (* number of free_lists *) + heapSize0 = 8000*Unit; (* startup heap size *) + + (* all blocks look the same: + free blocks describe themselves: size = Unit + tag = &tag++ + ->blksize + sentinel = -SZL + next + *) + + (* heap chunks *) + nextChnkOff = 0; (* next heap chunk, sorted ascendingly! *) + endOff = SZL; (* end of heap chunk *) + blkOff = 3*SZL; (* first block in a chunk *) + + (* heap blocks *) + tagOff = 0; (* block starts with tag *) + sizeOff = SZL; (* block size in free block relative to block start *) + sntlOff = 2*SZL; (* pointer offset table sentinel in free block relative to block start *) + nextOff = 3*SZL; (* next pointer in free block relative to block start *) + NoPtrSntl = LONG(LONG(-SZL)); + + + TYPE + ModuleName = ARRAY ModNameLen OF CHAR; + CmdName = ARRAY CmdNameLen OF CHAR; + + Module = POINTER TO ModuleDesc; + Cmd = POINTER TO CmdDesc; + EnumProc = PROCEDURE(P: PROCEDURE(p: SYSTEM.PTR)); + ModuleDesc = RECORD + next: Module; + name: ModuleName; + refcnt: LONGINT; + cmds: Cmd; + types: LONGINT; + enumPtrs: EnumProc; + reserved1, reserved2: LONGINT + END ; + + Command = PROCEDURE; + + CmdDesc = RECORD + next: Cmd; + name: CmdName; + cmd: Command + END ; + + Finalizer = PROCEDURE(obj: SYSTEM.PTR); + + FinNode = POINTER TO FinDesc; + FinDesc = RECORD + next: FinNode; + obj: LONGINT; (* weak pointer *) + marked: BOOLEAN; + finalize: Finalizer; + END ; + + VAR + (* the list of loaded (=initialization started) modules *) + modules*: SYSTEM.PTR; + + freeList: ARRAY nofLists + 1 OF LONGINT; (* dummy, 16, 32, 48, 64, 80, 96, 112, 128, sentinel *) + bigBlocks, allocated*: LONGINT; + firstTry: BOOLEAN; + + (* extensible heap *) + heap, (* the sorted list of heap chunks *) + heapend, (* max possible pointer value (used for stack collection) *) + heapsize*: LONGINT; (* the sum of all heap chunk sizes *) + + (* finalization candidates *) + fin: FinNode; + + (* garbage collector locking *) + gclock*: SHORTINT; + + + PROCEDURE -malloc(size: LONGINT): LONGINT "(LONGINT)malloc(size)"; + PROCEDURE -Lock() "Lock"; + PROCEDURE -Unlock() "Unlock"; + PROCEDURE -Mainfrm(): LONGINT "SYSTEM_mainfrm"; +(* + PROCEDURE TAS*(VAR flag:BOOLEAN): BOOLEAN; (* added for compatibility with ulmSYSTEM module; noch *) + VAR oldflag : BOOLEAN; + BEGIN + oldflag := flag; + flag := TRUE; + RETURN oldflag; + END TAS; +*) + PROCEDURE REGMOD*(VAR name: ModuleName; enumPtrs: EnumProc): SYSTEM.PTR; + VAR m: Module; + BEGIN + IF name = "SYSTEM" THEN (* cannot use NEW *) + SYSTEM.NEW(m, SIZE(ModuleDesc)); m.cmds := NIL + ELSE NEW(m) + END ; + COPY(name, m.name); m.refcnt := 0; m.enumPtrs := enumPtrs; m.next := SYSTEM.VAL(Module, modules); + modules := m; + RETURN m + END REGMOD; + + PROCEDURE REGCMD*(m: Module; VAR name: CmdName; cmd: Command); + VAR c: Cmd; + BEGIN NEW(c); + COPY(name, c.name); c.cmd := cmd; c.next := m.cmds; m.cmds := c + END REGCMD; + + PROCEDURE REGTYP*(m: Module; typ: LONGINT); + BEGIN SYSTEM.PUT(typ, m.types); m.types := typ + END REGTYP; + + PROCEDURE INCREF*(m: Module); + BEGIN INC(m.refcnt) + END INCREF; + + PROCEDURE NewChunk(blksz: LONGINT): LONGINT; + VAR chnk: LONGINT; + BEGIN + chnk := malloc(blksz + blkOff); + IF chnk # 0 THEN + SYSTEM.PUT(chnk + endOff, chnk + (blkOff + blksz)); + SYSTEM.PUT(chnk + blkOff, chnk + (blkOff + sizeOff)); + SYSTEM.PUT(chnk + (blkOff + sizeOff), blksz); + SYSTEM.PUT(chnk + (blkOff + sntlOff), NoPtrSntl); + SYSTEM.PUT(chnk + (blkOff + nextOff), bigBlocks); + bigBlocks := chnk + blkOff; + INC(heapsize, blksz) + END ; + RETURN chnk + END NewChunk; + + PROCEDURE ExtendHeap(blksz: LONGINT); + VAR size, chnk, j, next: LONGINT; + BEGIN + IF blksz > 10000*Unit THEN size := blksz + ELSE size := 10000*Unit (* additional heuristics *) + END ; + chnk := NewChunk(size); + IF chnk # 0 THEN + (*sorted insertion*) + IF chnk < heap THEN + SYSTEM.PUT(chnk, heap); heap := chnk + ELSE + j := heap; SYSTEM.GET(j, next); + WHILE (next # 0) & (chnk > next) DO j := next; SYSTEM.GET(j, next) END ; + SYSTEM.PUT(chnk, next); SYSTEM.PUT(j, chnk) + END ; + IF next = 0 THEN SYSTEM.GET(chnk + endOff, heapend) END + END + END ExtendHeap; + + PROCEDURE ^GC*(markStack: BOOLEAN); + + PROCEDURE NEWREC*(tag: LONGINT): SYSTEM.PTR; + VAR i, i0, di, blksz, restsize, t, adr, end, next, prev: LONGINT; new: SYSTEM.PTR; + BEGIN + Lock(); + SYSTEM.GET(tag, blksz); + ASSERT(blksz MOD Unit = 0); + i0 := blksz DIV Unit; i := i0; + IF i < nofLists THEN adr := freeList[i]; + WHILE adr = 0 DO INC(i); adr := freeList[i] END + END ; + IF i < nofLists THEN (* unlink *) + SYSTEM.GET(adr + nextOff, next); + freeList[i] := next; + IF i # i0 THEN (* split *) + di := i - i0; restsize := di * Unit; end := adr + restsize; + SYSTEM.PUT(end + sizeOff, blksz); + SYSTEM.PUT(end + sntlOff, NoPtrSntl); + SYSTEM.PUT(end, end + sizeOff); + SYSTEM.PUT(adr + sizeOff, restsize); + SYSTEM.PUT(adr + nextOff, freeList[di]); + freeList[di] := adr; + INC(adr, restsize) + END + ELSE + adr := bigBlocks; prev := 0; + LOOP + IF adr = 0 THEN + IF firstTry THEN + GC(TRUE); INC(blksz, Unit); + IF (heapsize - allocated - blksz) * 4 < heapsize THEN + (* heap is still almost full; expand to avoid thrashing *) + ExtendHeap((allocated + blksz) DIV (3*Unit) * (4*Unit) - heapsize) + END ; + firstTry := FALSE; new := NEWREC(tag); firstTry := TRUE; + IF new = NIL THEN + (* depending on the fragmentation, the heap may not have been extended by + the anti-thrashing heuristics above *) + ExtendHeap((allocated + blksz) DIV (3*Unit) * (4*Unit) - heapsize); + new := NEWREC(tag); (* will find a free block if heap has been expanded properly *) + END ; + Unlock(); RETURN new + ELSE + Unlock(); RETURN NIL + END + END ; + SYSTEM.GET(adr+sizeOff, t); + IF t >= blksz THEN EXIT END ; + prev := adr; SYSTEM.GET(adr + nextOff, adr) + END ; + restsize := t - blksz; end := adr + restsize; + SYSTEM.PUT(end + sizeOff, blksz); + SYSTEM.PUT(end + sntlOff, NoPtrSntl); + SYSTEM.PUT(end, end + sizeOff); + IF restsize > nofLists * Unit THEN (*resize*) + SYSTEM.PUT(adr + sizeOff, restsize) + ELSE (*unlink*) + SYSTEM.GET(adr + nextOff, next); + IF prev = 0 THEN bigBlocks := next + ELSE SYSTEM.PUT(prev + nextOff, next); + END ; + IF restsize > 0 THEN (*move*) + di := restsize DIV Unit; + SYSTEM.PUT(adr + sizeOff, restsize); + SYSTEM.PUT(adr + nextOff, freeList[di]); + freeList[di] := adr + END + END ; + INC(adr, restsize) + END ; + i := adr + 4*SZL; end := adr + blksz; + WHILE i < end DO (*deliberately unrolled*) + SYSTEM.PUT(i, LONG(LONG(0))); + SYSTEM.PUT(i + SZL, LONG(LONG(0))); + SYSTEM.PUT(i + 2*SZL, LONG(LONG(0))); + SYSTEM.PUT(i + 3*SZL, LONG(LONG(0))); + INC(i, 4*SZL) + END ; + SYSTEM.PUT(adr + nextOff, LONG(LONG(0))); + SYSTEM.PUT(adr, tag); + SYSTEM.PUT(adr + sizeOff, LONG(LONG(0))); + SYSTEM.PUT(adr + sntlOff, LONG(LONG(0))); + INC(allocated, blksz); + Unlock(); + RETURN SYSTEM.VAL(SYSTEM.PTR, adr + SZL) + END NEWREC; + + PROCEDURE NEWBLK*(size: LONGINT): SYSTEM.PTR; + VAR blksz, tag: LONGINT; new: SYSTEM.PTR; + BEGIN + Lock(); + blksz := (size + (4*SZL + Unit - 1)) DIV Unit * Unit; (*size + tag + meta + blksz + sntnl + UnitAlignment*) + new := NEWREC(SYSTEM.ADR(blksz)); + tag := SYSTEM.VAL(LONGINT, new) + blksz - 3*SZL; + SYSTEM.PUT(tag - SZL, LONG(LONG(0))); (*reserved for meta info*) + SYSTEM.PUT(tag, blksz); + SYSTEM.PUT(tag + SZL, NoPtrSntl); + SYSTEM.PUT(SYSTEM.VAL(LONGINT, new) - SZL, tag); + Unlock(); + RETURN new + END NEWBLK; + + PROCEDURE Mark(q: LONGINT); + VAR p, tag, fld, n, offset, tagbits: LONGINT; + BEGIN + IF q # 0 THEN SYSTEM.GET(q - SZL, tagbits); + IF ~ODD(tagbits) THEN + SYSTEM.PUT(q - SZL, tagbits + 1); + p := 0; tag := tagbits + SZL; + LOOP + SYSTEM.GET(tag, offset); + IF offset < 0 THEN + SYSTEM.PUT(q - SZL, tag + offset + 1); + IF p = 0 THEN EXIT END ; + n := q; q := p; + SYSTEM.GET(q - SZL, tag); DEC(tag, 1); + SYSTEM.GET(tag, offset); fld := q + offset; + SYSTEM.GET(fld, p); SYSTEM.PUT(fld, n) + ELSE + fld := q + offset; + SYSTEM.GET(fld, n); + IF n # 0 THEN + SYSTEM.GET(n - SZL, tagbits); + IF ~ODD(tagbits) THEN + SYSTEM.PUT(n - SZL, tagbits + 1); + SYSTEM.PUT(q - SZL, tag + 1); + SYSTEM.PUT(fld, p); p := q; q := n; + tag := tagbits + END + END + END ; + INC(tag, SZL) + END + END + END + END Mark; + + PROCEDURE MarkP(p: SYSTEM.PTR); (* for compatibility with EnumPtrs in ANSI mode *) + BEGIN + Mark(SYSTEM.VAL(LONGINT, p)) + END MarkP; + + PROCEDURE Scan; + VAR chnk, adr, end, start, tag, i, size, freesize: LONGINT; + BEGIN bigBlocks := 0; i := 1; + WHILE i < nofLists DO freeList[i] := 0; INC(i) END ; + freesize := 0; allocated := 0; chnk := heap; + WHILE chnk # 0 DO + adr := chnk + blkOff; SYSTEM.GET(chnk + endOff, end); + WHILE adr < end DO + SYSTEM.GET(adr, tag); + IF ODD(tag) THEN (*marked*) + IF freesize > 0 THEN + start := adr - freesize; + SYSTEM.PUT(start, start+SZL); + SYSTEM.PUT(start+sizeOff, freesize); + SYSTEM.PUT(start+sntlOff, NoPtrSntl); + i := freesize DIV Unit; freesize := 0; + IF i < nofLists THEN SYSTEM.PUT(start + nextOff, freeList[i]); freeList[i] := start + ELSE SYSTEM.PUT(start + nextOff, bigBlocks); bigBlocks := start + END + END ; + DEC(tag, 1); + SYSTEM.PUT(adr, tag); + SYSTEM.GET(tag, size); + INC(allocated, size); + INC(adr, size) + ELSE (*unmarked*) + SYSTEM.GET(tag, size); + INC(freesize, size); + INC(adr, size) + END + END ; + IF freesize > 0 THEN (*collect last block*) + start := adr - freesize; + SYSTEM.PUT(start, start+SZL); + SYSTEM.PUT(start+sizeOff, freesize); + SYSTEM.PUT(start+sntlOff, NoPtrSntl); + i := freesize DIV Unit; freesize := 0; + IF i < nofLists THEN SYSTEM.PUT(start + nextOff, freeList[i]); freeList[i] := start + ELSE SYSTEM.PUT(start + nextOff, bigBlocks); bigBlocks := start + END + END ; + SYSTEM.GET(chnk, chnk) + END + END Scan; + + PROCEDURE Sift (l, r: LONGINT; VAR a: ARRAY OF LONGINT); + VAR i, j, x: LONGINT; + BEGIN j := l; x := a[j]; + LOOP i := j; j := 2*j + 1; + IF (j < r) & (a[j] < a[j+1]) THEN INC(j) END; + IF (j > r) OR (a[j] <= x) THEN EXIT END; + a[i] := a[j] + END; + a[i] := x + END Sift; + + PROCEDURE HeapSort (n: LONGINT; VAR a: ARRAY OF LONGINT); + VAR l, r, x: LONGINT; + BEGIN l := n DIV 2; r := n - 1; + WHILE l > 0 DO DEC(l); Sift(l, r, a) END; + WHILE r > 0 DO x := a[0]; a[0] := a[r]; a[r] := x; DEC(r); Sift(l, r, a) END + END HeapSort; + + PROCEDURE MarkCandidates(n: LONGINT; VAR cand: ARRAY OF LONGINT); + VAR chnk, adr, tag, next, lim, lim1, i, ptr, size: LONGINT; + BEGIN + chnk := heap; i := 0; lim := cand[n-1]; + WHILE (chnk # 0 ) & (chnk < lim) DO + adr := chnk + blkOff; + SYSTEM.GET(chnk + endOff, lim1); + IF lim < lim1 THEN lim1 := lim END ; + WHILE adr < lim1 DO + SYSTEM.GET(adr, tag); + IF ODD(tag) THEN (*already marked*) + SYSTEM.GET(tag-1, size); INC(adr, size) + ELSE + SYSTEM.GET(tag, size); + ptr := adr + SZL; + WHILE cand[i] < ptr DO INC(i) END ; + IF i = n THEN RETURN END ; + next := adr + size; + IF cand[i] < next THEN Mark(ptr) END ; + adr := next + END + END ; + SYSTEM.GET(chnk, chnk) + END + END MarkCandidates; + + PROCEDURE CheckFin; + VAR n: FinNode; tag: LONGINT; + BEGIN n := fin; + WHILE n # NIL DO + SYSTEM.GET(n.obj - SZL, tag); + IF ~ODD(tag) THEN n.marked := FALSE; Mark(n.obj) + ELSE n.marked := TRUE + END ; + n := n.next + END + END CheckFin; + + PROCEDURE Finalize; + VAR n, prev: FinNode; + BEGIN n := fin; prev := NIL; + WHILE n # NIL DO + IF ~n.marked THEN + IF n = fin THEN fin := fin.next ELSE prev.next := n.next END ; + n.finalize(SYSTEM.VAL(SYSTEM.PTR, n.obj)); + (* new nodes may have been pushed in n.finalize, therefore: *) + IF prev = NIL THEN n := fin ELSE n := n.next END + ELSE prev := n; n := n.next + END + END + END Finalize; + + PROCEDURE FINALL*; + VAR n: FinNode; + BEGIN + WHILE fin # NIL DO + n := fin; fin := fin.next; + n.finalize(SYSTEM.VAL(SYSTEM.PTR, n.obj)) + END + END FINALL; + + PROCEDURE MarkStack(n: LONGINT; VAR cand: ARRAY OF LONGINT); + VAR + frame: SYSTEM.PTR; + inc, nofcand: LONGINT; + sp, p, stack0, ptr: LONGINT; + align: RECORD ch: CHAR; p: SYSTEM.PTR END ; + BEGIN + IF n > 0 THEN MarkStack(n-1, cand); (* flush register windows by means of recursive calls *) + IF n > 100 THEN RETURN END (* prevent tail recursion optimization *) + END ; + IF n = 0 THEN + nofcand := 0; sp := SYSTEM.ADR(frame); + stack0 := Mainfrm(); + (* check for minimum alignment of pointers *) + inc := SYSTEM.ADR(align.p) - SYSTEM.ADR(align); + IF sp > stack0 THEN inc := -inc END ; + WHILE sp # stack0 DO + SYSTEM.GET(sp, p); + IF (p > heap) & (p < heapend) THEN + IF nofcand = LEN(cand) THEN HeapSort(nofcand, cand); MarkCandidates(nofcand, cand); nofcand := 0 END ; + cand[nofcand] := p; INC(nofcand) + END ; + INC(sp, inc) + END ; + IF nofcand > 0 THEN HeapSort(nofcand, cand); MarkCandidates(nofcand, cand) END + END + END MarkStack; + + PROCEDURE GC*(markStack: BOOLEAN); + VAR + m: Module; + i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23: LONGINT; + cand: ARRAY 10000 OF LONGINT; + BEGIN + IF (gclock = 0) OR (gclock = 1) & ~markStack THEN + Lock(); + m := SYSTEM.VAL(Module, modules); + WHILE m # NIL DO + IF m.enumPtrs # NIL THEN m.enumPtrs(MarkP) END ; + m := m^.next + END ; + IF markStack THEN + (* generate register pressure to force callee saved registers to memory; + may be simplified by inlining OS calls or processor specific instructions + *) + i0 := -100; i1 := -101; i2 := -102; i3 := -103; i4 := -104; i5 := -105; i6 := -106; i7 := -107; + i8 := 1; i9 := 2; i10 := 3; i11 := 4; i12 := 5; i13 := 6; i14 := 7; i15 := 8; + i16 := 9; i17 := 10; i18 := 11; i19 := 12; i20 := 13; i21 := 14; i22 := 15; i23 := 16; + LOOP INC(i0, 1); INC(i1, 2); INC(i2, 3); INC(i3, 4); INC(i4, 5); INC(i5, 6); INC(i6, 7); INC(i7, 8); + INC(i8, 9); INC(i9, 10); INC(i10, 11); INC(i11, 12); INC(i12, 13); INC(i13, 14); INC(i14, 15); INC(i15, 16); + INC(i16, 17); INC(i17, 18); INC(i18, 19); INC(i19, 20); INC(i20, 21); INC(i21, 22); INC(i22, 23); INC(i23, 24); + IF (i0 = -99) & (i15 = 24) THEN MarkStack(32, cand); EXIT END + END ; + IF i0 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + i10 + i11 + i12 + i13 + i14 + i15 + + i16 + i17 + i18 + i19 + i20 + i21 + i22 + i23 > 10000 THEN RETURN (* use all variables *) + END ; + END; + CheckFin; + Scan; + Finalize; + Unlock() + END + END GC; + + PROCEDURE REGFIN*(obj: SYSTEM.PTR; finalize: Finalizer); + VAR f: FinNode; + BEGIN NEW(f); + f.obj := SYSTEM.VAL(LONGINT, obj); f.finalize := finalize; f.marked := TRUE; f.next := fin; fin := f + END REGFIN; + + PROCEDURE InitHeap; (* initialized before body to enable NEW, SYSTEM.NEW *) + BEGIN + heap := NewChunk(heapSize0); + SYSTEM.GET(heap + endOff, heapend); + SYSTEM.PUT(heap, LONG(LONG(0))); + allocated := 0; firstTry := TRUE; freeList[nofLists] := 1; gclock := 0 + END InitHeap; + +END SYSTEM. diff --git a/src/lib/system/linux/clang/Texts.Mod b/src/lib/system/linux/clang/Texts.Mod new file mode 100644 index 00000000..320f426b --- /dev/null +++ b/src/lib/system/linux/clang/Texts.Mod @@ -0,0 +1,859 @@ +MODULE Texts; (** CAS/HM 23.9.93 -- interface based on Texts by JG/NW 6.12.91**) (* << RC, MB, JT *) + IMPORT + Files, Modules, Reals; + + (*--- insert field e: Elem into Texts.Scanner and change Texts.Scan to set it in case of class=6 *) + + + CONST + Displaywhite = 15; + ElemChar* = 1CX; + TAB = 9X; CR = 0DX; maxD = 9; + (**FileMsg.id**) + load* = 0; store* = 1; + (**Notifier op**) + replace* = 0; insert* = 1; delete* = 2; + (**Scanner.class**) + Inval* = 0; Name* = 1; String* = 2; Int* = 3; Real* = 4; LongReal* = 5; Char* = 6; + + textTag = 0F0X; DocBlockId = 0F7X; version = 01X; + + TYPE + FontsFont = POINTER TO FontDesc; + FontDesc = RECORD + name: ARRAY 32 OF CHAR; + END ; + + Run = POINTER TO RunDesc; + RunDesc = RECORD + prev, next: Run; + len: LONGINT; + fnt: FontsFont; + col, voff: SHORTINT; + ascii: BOOLEAN (* << *) + END; + + Piece = POINTER TO PieceDesc; + PieceDesc = RECORD (RunDesc) + file: Files.File; + org: LONGINT + END; + + Elem* = POINTER TO ElemDesc; + Buffer* = POINTER TO BufDesc; + Text* = POINTER TO TextDesc; + + ElemMsg* = RECORD END; + Handler* = PROCEDURE (e: Elem; VAR msg: ElemMsg); + + ElemDesc* = RECORD (RunDesc) + W*, H*: LONGINT; + handle*: Handler; + base: Text + END; + + FileMsg* = RECORD (ElemMsg) + id*: INTEGER; + pos*: LONGINT; + r*: Files.Rider + END; + + CopyMsg* = RECORD (ElemMsg) + e*: Elem + END; + + IdentifyMsg* = RECORD (ElemMsg) + mod*, proc*: ARRAY 32 OF CHAR + END; + + + BufDesc* = RECORD + len*: LONGINT; + head: Run + END; + + TextDesc* = RECORD + len*: LONGINT; + head, cache: Run; + corg: LONGINT + END; + + Reader* = RECORD + eot*: BOOLEAN; + fnt*: FontsFont; + col*, voff*: SHORTINT; + elem*: Elem; + rider: Files.Rider; + run: Run; + org, off: LONGINT + END; + + Scanner* = RECORD (Reader) + nextCh*: CHAR; + line*, class*: INTEGER; + i*: LONGINT; + x*: REAL; + y*: LONGREAL; + c*: CHAR; + len*: SHORTINT; + s*: ARRAY 64 OF CHAR (* << *) + END; + + Writer* = RECORD + buf*: Buffer; + fnt*: FontsFont; + col*, voff*: SHORTINT; + rider: Files.Rider; + file: Files.File + END; + + Alien = POINTER TO RECORD (ElemDesc) + file: Files.File; + org, span: LONGINT; + mod, proc: ARRAY 32 OF CHAR + END; + + VAR + new*: Elem; + del: Buffer; + FontsDefault: FontsFont; + + + PROCEDURE FontsThis(VAR name: ARRAY OF CHAR): FontsFont; + VAR F: FontsFont; + BEGIN + NEW(F); COPY(name, F.name); RETURN F + END FontsThis; + + (* run primitives *) + + PROCEDURE Find (T: Text; VAR pos: LONGINT; VAR u: Run; VAR org, off: LONGINT); + VAR v: Run; m: LONGINT; + BEGIN + IF pos >= T.len THEN pos := T.len; u := T.head; org := T.len; off := 0; T.cache := T.head; T.corg := 0 + ELSE v := T.cache.next; m := pos - T.corg; + IF pos >= T.corg THEN + WHILE m >= v.len DO DEC(m, v.len); v := v.next END + ELSE + WHILE m < 0 DO v := v.prev; INC(m, v.len) END; + END; + u := v; org := pos - m; off := m; T.cache := v.prev; T.corg := org + END + END Find; + + PROCEDURE Split (off: LONGINT; VAR u, un: Run); + VAR p, U: Piece; + BEGIN + IF off = 0 THEN un := u; u := un.prev + ELSIF off >= u.len THEN un := u.next + ELSE NEW(p); un := p; U := u(Piece); + p^ := U^; INC(p.org, off); DEC(p.len, off); DEC(U.len, p.len); + p.ascii := u.ascii; p.prev := U; p.next := U.next; p.next.prev := p; U.next := p (* << *) + END + END Split; + + PROCEDURE Merge (T: Text; u: Run; VAR v: Run); + VAR p, q: Piece; + BEGIN + IF (u IS Piece) & (v IS Piece) & (u.fnt.name = v.fnt.name) & (u.col = v.col) & (u.voff = v.voff) + & (u(Piece).ascii = v(Piece).ascii) THEN (* << *) + p := u(Piece); q := v(Piece); + IF (p.file = q.file) & (p.org + p.len = q.org) THEN + IF T.cache = u THEN INC(T.corg, q.len) + ELSIF T.cache = v THEN T.cache := T.head; T.corg := 0 + END; + INC(p.len, q.len); v := v.next + END + END + END Merge; + + PROCEDURE Splice (un, v, w: Run; base: Text); (* (u, un) -> (u, v, w, un) *) + VAR u: Run; + BEGIN + IF v # w.next THEN u := un.prev; + u.next := v; v.prev := u; un.prev := w; w.next := un; + REPEAT + IF v IS Elem THEN v(Elem).base := base END; + v := v.next + UNTIL v = un + END + END Splice; + + PROCEDURE ClonePiece (p: Piece): Piece; + VAR q: Piece; + BEGIN NEW(q); q^ := p^; RETURN q + END ClonePiece; + + PROCEDURE CloneElem (e: Elem): Elem; + VAR msg: CopyMsg; + BEGIN msg.e := NIL; e.handle(e, msg); RETURN msg.e + END CloneElem; + + + (** Elements **) + + PROCEDURE CopyElem* (SE, DE: Elem); + BEGIN DE.len := SE.len; DE.fnt := SE.fnt; DE.col := SE.col; DE.voff := SE.voff; + DE.W := SE.W; DE.H := SE.H; DE.handle := SE.handle + END CopyElem; + + PROCEDURE ElemBase* (E: Elem): Text; + BEGIN RETURN E.base + END ElemBase; + + PROCEDURE ElemPos* (E: Elem): LONGINT; + VAR u: Run; pos: LONGINT; + BEGIN u := E.base.head.next; pos := 0; + WHILE u # E DO pos := pos + u.len; u := u.next END; + RETURN pos + END ElemPos; + + + PROCEDURE HandleAlien (E: Elem; VAR msg: ElemMsg); + VAR e: Alien; r: Files.Rider; i: LONGINT; ch: CHAR; + BEGIN + WITH E: Alien DO + IF msg IS CopyMsg THEN + WITH msg: CopyMsg DO NEW(e); CopyElem(E, e); + e.file := E.file; e.org := E.org; e.span := E.span; e.mod := E.mod; e.proc := E.proc; + msg.e := e + END + ELSIF msg IS IdentifyMsg THEN + WITH msg: IdentifyMsg DO + COPY(E.mod, msg.mod); COPY(E.proc, msg.proc); msg.mod[31] := 1X (*alien*) + END + ELSIF msg IS FileMsg THEN + WITH msg: FileMsg DO + IF msg.id = store THEN Files.Set(r, E.file, E.org); i := E.span; + WHILE i > 0 DO Files.Read(r, ch); Files.Write(msg.r, ch); DEC(i) END + END + END + END + END + END HandleAlien; + + + (** Buffers **) + + PROCEDURE OpenBuf* (B: Buffer); + VAR u: Run; + BEGIN NEW(u); u.next := u; u.prev := u; B.head := u; B.len := 0 + END OpenBuf; + + PROCEDURE Copy* (SB, DB: Buffer); + VAR u, v, vn: Run; + BEGIN u := SB.head.next; v := DB.head.prev; + WHILE u # SB.head DO + IF u IS Piece THEN vn := ClonePiece(u(Piece)) ELSE vn := CloneElem(u(Elem)) END; + v.next := vn; vn.prev := v; v := vn; u := u.next + END; + v.next := DB.head; DB.head.prev := v; + INC(DB.len, SB.len) + END Copy; + + PROCEDURE Recall* (VAR B: Buffer); + BEGIN B := del; del := NIL + END Recall; + + + (** Texts **) + + PROCEDURE Save* (T: Text; beg, end: LONGINT; B: Buffer); + VAR u, v, w, wn: Run; uo, ud, vo, vd: LONGINT; + BEGIN Find(T, beg, u, uo, ud); Find(T, end, v, vo, vd); + w := B.head.prev; + WHILE u # v DO + IF u IS Piece THEN wn := ClonePiece(u(Piece)); DEC(wn.len, ud); INC(wn(Piece).org, ud) + ELSE wn := CloneElem(u(Elem)) + END; + w.next := wn; wn.prev := w; w := wn; u := u.next; ud := 0 + END; + IF vd > 0 THEN (*v IS Piece*) wn := ClonePiece(v(Piece)); wn.len := vd - ud; INC(wn(Piece).org, ud); + w.next := wn; wn.prev := w; w := wn + END; + w.next := B.head; B.head.prev := w; + INC(B.len, end - beg) + END Save; + + PROCEDURE Insert* (T: Text; pos: LONGINT; B: Buffer); + VAR u, un, v: Run; p, q: Piece; uo, ud, len: LONGINT; + BEGIN Find(T, pos, u, uo, ud); Split(ud, u, un); + len := B.len; v := B.head.next; + Merge(T, u, v); Splice(un, v, B.head.prev, T); + INC(T.len, len); B.head.next := B.head; B.head.prev := B.head; B.len := 0; + END Insert; + + PROCEDURE Append* (T: Text; B: Buffer); + VAR v: Run; pos, len: LONGINT; + BEGIN pos := T.len; len := B.len; v := B.head.next; + Merge(T, T.head.prev, v); Splice(T.head, v, B.head.prev, T); + INC(T.len, len); B.head.next := B.head; B.head.prev := B.head; B.len := 0; + END Append; + + PROCEDURE Delete* (T: Text; beg, end: LONGINT); + VAR c, u, un, v, vn: Run; co, uo, ud, vo, vd: LONGINT; + BEGIN + Find(T, beg, u, uo, ud); Split(ud, u, un); c := T.cache; co := T.corg; + Find(T, end, v, vo, vd); Split(vd, v, vn); T.cache := c; T.corg := co; + NEW(del); OpenBuf(del); del.len := end - beg; + Splice(del.head, un, v, NIL); + Merge(T, u, vn); u.next := vn; vn.prev := u; + DEC(T.len, end - beg); + END Delete; + + PROCEDURE ChangeLooks* (T: Text; beg, end: LONGINT; sel: SET; fnt: FontsFont; col, voff: SHORTINT); + VAR c, u, un, v, vn: Run; co, uo, ud, vo, vd: LONGINT; + BEGIN Find(T, beg, u, uo, ud); Split(ud, u, un); c := T.cache; co := T.corg; + Find(T, end, v, vo, vd); Split(vd, v, vn); T.cache := c; T.corg := co; + WHILE un # vn DO + IF (0 IN sel) & (fnt # NIL) THEN un.fnt := fnt END; + IF 1 IN sel THEN un.col := col END; + IF 2 IN sel THEN un.voff := voff END; + Merge(T, u, un); + IF u.next = un THEN u := un; un := un.next ELSE u.next := un; un.prev := u END + END; + Merge(T, u, un); u.next := un; un.prev := u; + END ChangeLooks; + + + (** Readers **) + + PROCEDURE OpenReader* (VAR R: Reader; T: Text; pos: LONGINT); + VAR u: Run; + BEGIN + IF pos >= T.len THEN pos := T.len END; + Find(T, pos, u, R.org, R.off); R.run := u; R.eot := FALSE; + IF u IS Piece THEN + Files.Set(R.rider, u(Piece).file, u(Piece).org + R.off) + END + END OpenReader; + + PROCEDURE Read* (VAR R: Reader; VAR ch: CHAR); + VAR u: Run; + BEGIN u := R.run; R.fnt := u.fnt; R.col := u.col; R.voff := u.voff; INC(R.off); + IF u IS Piece THEN Files.Read(R.rider, ch); R.elem := NIL; + IF (ch = 0AX) & u(Piece).ascii THEN ch := CR END (* << LF to CR *) + ELSIF u IS Elem THEN ch := ElemChar; R.elem := u(Elem) + ELSE ch := 0X; R.elem := NIL; R.eot := TRUE + END; + IF R.off = u.len THEN INC(R.org, u.len); u := u.next; + IF u IS Piece THEN + WITH u: Piece DO Files.Set(R.rider, u.file, u.org) END + END; + R.run := u; R.off := 0 + END + END Read; + + PROCEDURE ReadElem* (VAR R: Reader); + VAR u, un: Run; + BEGIN u := R.run; + WHILE u IS Piece DO INC(R.org, u.len); u := u.next END; + IF u IS Elem THEN un := u.next; R.run := un; INC(R.org); R.off := 0; + R.fnt := u.fnt; R.col := u.col; R.voff := u.voff; R.elem := u(Elem); + IF un IS Piece THEN + WITH un: Piece DO Files.Set(R.rider, un.file, un.org) END + END + ELSE R.eot := TRUE; R.elem := NIL + END + END ReadElem; + + PROCEDURE ReadPrevElem* (VAR R: Reader); + VAR u: Run; + BEGIN u := R.run.prev; + WHILE u IS Piece DO DEC(R.org, u.len); u := u.prev END; + IF u IS Elem THEN R.run := u; DEC(R.org); R.off := 0; + R.fnt := u.fnt; R.col := u.col; R.voff := u.voff; R.elem := u(Elem) + ELSE R.eot := TRUE; R.elem := NIL + END + END ReadPrevElem; + + PROCEDURE Pos* (VAR R: Reader): LONGINT; + BEGIN RETURN R.org + R.off + END Pos; + + + (** Scanners --------------- NW --------------- **) + + PROCEDURE OpenScanner* (VAR S: Scanner; T: Text; pos: LONGINT); + BEGIN OpenReader(S, T, pos); S.line := 0; S.nextCh := " " + END OpenScanner; + + (*IEEE floating point formats: + x = 2^(e-127) * 1.m bit 0: sign, bits 1- 8: e, bits 9-31: m + x = 2^(e-1023) * 1.m bit 0: sign, bits 1-11: e, bits 12-63: m *) + + PROCEDURE Scan* (VAR S: Scanner); + CONST maxD = 32; + VAR ch, term: CHAR; + neg, negE, hex: BOOLEAN; + i, j, h: SHORTINT; + e: INTEGER; k: LONGINT; + x, f: REAL; y, g: LONGREAL; + d: ARRAY maxD OF CHAR; + + PROCEDURE ReadScaleFactor; + BEGIN Read(S, ch); + IF ch = "-" THEN negE := TRUE; Read(S, ch) + ELSE negE := FALSE; + IF ch = "+" THEN Read(S, ch) END + END; + WHILE ("0" <= ch) & (ch <= "9") DO + e := e*10 + ORD(ch) - 30H; Read(S, ch) + END + END ReadScaleFactor; + + BEGIN ch := S.nextCh; i := 0; + LOOP + IF ch = CR THEN INC(S.line) + ELSIF (ch # " ") & (ch # TAB) THEN EXIT + END ; + Read(S, ch) + END; + IF ("A" <= CAP(ch)) & (CAP(ch) <= "Z") OR (ch = "/") OR (ch = ".") THEN (*name*) (* << *) + REPEAT S.s[i] := ch; INC(i); Read(S, ch) + UNTIL (CAP(ch) > "Z") & (ch # "_") (* << *) + OR ("A" > CAP(ch)) & (ch > "9") + OR ("0" > ch) & (ch # ".") & (ch # "/") (* << *) + OR (i = 63); (* << *) + S.s[i] := 0X; S.len := i; S.class := 1 + ELSIF ch = 22X THEN (*literal string*) + Read(S, ch); + WHILE (ch # 22X) & (ch >= " ") & (i # 63) DO (* << *) + S.s[i] := ch; INC(i); Read(S, ch) + END; + S.s[i] := 0X; S.len := i+1; Read(S, ch); S.class := 2 + ELSE + IF ch = "-" THEN neg := TRUE; Read(S, ch) ELSE neg := FALSE END ; + IF ("0" <= ch) & (ch <= "9") THEN (*number*) + hex := FALSE; j := 0; + LOOP d[i] := ch; INC(i); Read(S, ch); + IF ch < "0" THEN EXIT END; + IF "9" < ch THEN + IF ("A" <= ch) & (ch <= "F") THEN hex := TRUE; ch := CHR(ORD(ch)-7) + ELSIF ("a" <= ch) & (ch <= "f") THEN hex := TRUE; ch := CHR(ORD(ch)-27H) + ELSE EXIT + END + END + END; + IF ch = "H" THEN (*hex number*) + Read(S, ch); S.class := 3; + IF i-j > 8 THEN j := i-8 END ; + k := ORD(d[j]) - 30H; INC(j); + IF (i-j = 7) & (k >= 8) THEN DEC(k, 16) END ; + WHILE j < i DO k := k*10H + (ORD(d[j]) - 30H); INC(j) END ; + IF neg THEN S.i := -k ELSE S.i := k END + ELSIF ch = "." THEN (*read real*) + Read(S, ch); h := i; + WHILE ("0" <= ch) & (ch <= "9") DO d[i] := ch; INC(i); Read(S, ch) END ; + IF ch = "D" THEN + e := 0; y := 0; g := 1; + REPEAT y := y*10 + (ORD(d[j]) - 30H); INC(j) UNTIL j = h; + WHILE j < i DO g := g/10; y := (ORD(d[j]) - 30H)*g + y; INC(j) END ; + ReadScaleFactor; + IF negE THEN + IF e <= 308 THEN y := y / Reals.TenL(e) ELSE y := 0 END + ELSIF e > 0 THEN + IF e <= 308 THEN y := Reals.TenL(e) * y ELSE HALT(40) END + END ; + IF neg THEN y := -y END ; + S.class := 5; S.y := y + ELSE e := 0; x := 0; f := 1; + REPEAT x := x*10 + (ORD(d[j]) - 30H); INC(j) UNTIL j = h; + WHILE j < i DO f := f/10; x := (ORD(d[j])-30H)*f + x; INC(j) END; + IF ch = "E" THEN ReadScaleFactor END ; + IF negE THEN + IF e <= 38 THEN x := x / Reals.Ten(e) ELSE x := 0 END + ELSIF e > 0 THEN + IF e <= 38 THEN x := Reals.Ten(e) * x ELSE HALT(40) END + END ; + IF neg THEN x := -x END ; + S.class := 4; S.x := x + END ; + IF hex THEN S.class := 0 END + ELSE (*decimal integer*) + S.class := 3; k := 0; + REPEAT k := k*10 + (ORD(d[j]) - 30H); INC(j) UNTIL j = i; + IF neg THEN S.i := -k ELSE S.i := k END; + IF hex THEN S.class := 0 ELSE S.class := 3 END + END + ELSE S.class := 6; + IF neg THEN S.c := "-" ELSE S.c := ch; Read(S, ch) END + END + END; + S.nextCh := ch + END Scan; + + + (** Writers **) + + PROCEDURE OpenWriter* (VAR W: Writer); + BEGIN NEW(W.buf); OpenBuf(W.buf); + W.fnt := FontsDefault; W.col := Displaywhite; W.voff := 0; + W.file := Files.New(""); Files.Set(W.rider, W.file, 0) + END OpenWriter; + + PROCEDURE SetFont* (VAR W: Writer; fnt: FontsFont); + BEGIN W.fnt := fnt + END SetFont; + + PROCEDURE SetColor* (VAR W: Writer; col: SHORTINT); + BEGIN W.col := col + END SetColor; + + PROCEDURE SetOffset* (VAR W: Writer; voff: SHORTINT); + BEGIN W.voff := voff + END SetOffset; + + + PROCEDURE Write* (VAR W: Writer; ch: CHAR); + VAR u, un: Run; p: Piece; + BEGIN Files.Write(W.rider, ch); INC(W.buf.len); un := W.buf.head; u := un.prev; + IF (u IS Piece) & (u(Piece).file = W.file) & (u.fnt.name = W.fnt.name) & (u.col = W.col) & (u.voff = W.voff) + & ~u(Piece).ascii THEN (* << *) + INC(u.len) + ELSE NEW(p); u.next := p; p.prev := u; p.next := un; un.prev := p; + p.len := 1; p.fnt := W.fnt; p.col := W.col; p.voff := W.voff; + p.file := W.file; p.org := Files.Length(W.file) - 1; p.ascii := FALSE (* << *) + END + END Write; + + PROCEDURE WriteElem* (VAR W: Writer; e: Elem); + VAR u, un: Run; + BEGIN + IF e.base # NIL THEN HALT(99) END; + INC(W.buf.len); e.len := 1; e.fnt := W.fnt; e.col := W.col; e.voff := W.voff; + un := W.buf.head; u := un.prev; u.next := e; e.prev := u; e.next := un; un.prev := e + END WriteElem; + + PROCEDURE WriteLn* (VAR W: Writer); + BEGIN Write(W, CR) + END WriteLn; + + PROCEDURE WriteString* (VAR W: Writer; s: ARRAY OF CHAR); + VAR i: INTEGER; + BEGIN i := 0; + WHILE s[i] >= " " DO Write(W, s[i]); INC(i) END + END WriteString; + + PROCEDURE WriteInt* (VAR W: Writer; x, n: LONGINT); + VAR i: INTEGER; x0: LONGINT; + a: ARRAY 11 OF CHAR; + BEGIN i := 0; + IF x < 0 THEN + IF x = MIN(LONGINT) THEN WriteString(W, " -2147483648"); RETURN + ELSE DEC(n); x0 := -x + END + ELSE x0 := x + END; + REPEAT + a[i] := CHR(x0 MOD 10 + 30H); x0 := x0 DIV 10; INC(i) + UNTIL x0 = 0; + WHILE n > i DO Write(W, " "); DEC(n) END; + IF x < 0 THEN Write(W, "-") END; + REPEAT DEC(i); Write(W, a[i]) UNTIL i = 0 + END WriteInt; + + PROCEDURE WriteHex* (VAR W: Writer; x: LONGINT); + VAR i: INTEGER; y: LONGINT; + a: ARRAY 10 OF CHAR; + BEGIN i := 0; Write(W, " "); + REPEAT y := x MOD 10H; + IF y < 10 THEN a[i] := CHR(y + 30H) ELSE a[i] := CHR(y + 37H) END; + x := x DIV 10H; INC(i) + UNTIL i = 8; + REPEAT DEC(i); Write(W, a[i]) UNTIL i = 0 + END WriteHex; + + PROCEDURE WriteReal* (VAR W: Writer; x: REAL; n: INTEGER); + VAR e: INTEGER; x0: REAL; + d: ARRAY maxD OF CHAR; + BEGIN e := Reals.Expo(x); + IF e = 0 THEN + WriteString(W, " 0"); + REPEAT Write(W, " "); DEC(n) UNTIL n <= 3 + ELSIF e = 255 THEN + WriteString(W, " NaN"); + WHILE n > 4 DO Write(W, " "); DEC(n) END + ELSE + IF n <= 9 THEN n := 3 ELSE DEC(n, 6) END; + REPEAT Write(W, " "); DEC(n) UNTIL n <= 8; + (*there are 2 < n <= 8 digits to be written*) + IF x < 0.0 THEN Write(W, "-"); x := -x ELSE Write(W, " ") END; + e := (e - 127) * 77 DIV 256; + IF e >= 0 THEN x := x / Reals.Ten(e) ELSE x := Reals.Ten(-e) * x END; + IF x >= 10.0 THEN x := 0.1*x; INC(e) END; + x0 := Reals.Ten(n-1); x := x0*x + 0.5; + IF x >= 10.0*x0 THEN x := x*0.1; INC(e) END; + Reals.Convert(x, n, d); + DEC(n); Write(W, d[n]); Write(W, "."); + REPEAT DEC(n); Write(W, d[n]) UNTIL n = 0; + Write(W, "E"); + IF e < 0 THEN Write(W, "-"); e := -e ELSE Write(W, "+") END; + Write(W, CHR(e DIV 10 + 30H)); Write(W, CHR(e MOD 10 + 30H)) + END + END WriteReal; + + PROCEDURE WriteRealFix* (VAR W: Writer; x: REAL; n, k: INTEGER); + VAR e, i: INTEGER; sign: CHAR; x0: REAL; + d: ARRAY maxD OF CHAR; + + PROCEDURE seq(ch: CHAR; n: INTEGER); + BEGIN WHILE n > 0 DO Write(W, ch); DEC(n) END + END seq; + + PROCEDURE dig(n: INTEGER); + BEGIN + WHILE n > 0 DO + DEC(i); Write(W, d[i]); DEC(n) + END + END dig; + + BEGIN e := Reals.Expo(x); + IF k < 0 THEN k := 0 END; + IF e = 0 THEN seq(" ", n-k-2); Write(W, "0"); seq(" ", k+1) + ELSIF e = 255 THEN WriteString(W, " NaN"); seq(" ", n-4) + ELSE e := (e - 127) * 77 DIV 256; + IF x < 0 THEN sign := "-"; x := -x ELSE sign := " " END; + IF e >= 0 THEN (*x >= 1.0, 77/256 = log 2*) x := x/Reals.Ten(e) + ELSE (*x < 1.0*) x := Reals.Ten(-e) * x + END; + IF x >= 10.0 THEN x := 0.1*x; INC(e) END; + (* 1 <= x < 10 *) + IF k+e >= maxD-1 THEN k := maxD-1-e + ELSIF k+e < 0 THEN k := -e; x := 0.0 + END; + x0 := Reals.Ten(k+e); x := x0*x + 0.5; + IF x >= 10.0*x0 THEN INC(e) END; + (*e = no. of digits before decimal point*) + INC(e); i := k+e; Reals.Convert(x, i, d); + IF e > 0 THEN + seq(" ", n-e-k-2); Write(W, sign); dig(e); + Write(W, "."); dig(k) + ELSE seq(" ", n-k-3); + Write(W, sign); Write(W, "0"); Write(W, "."); + seq("0", -e); dig(k+e) + END + END + END WriteRealFix; + + PROCEDURE WriteRealHex* (VAR W: Writer; x: REAL); + VAR i: INTEGER; + d: ARRAY 8 OF CHAR; + BEGIN Reals.ConvertH(x, d); i := 0; + REPEAT Write(W, d[i]); INC(i) UNTIL i = 8 + END WriteRealHex; + + PROCEDURE WriteLongReal* (VAR W: Writer; x: LONGREAL; n: INTEGER); + CONST maxD = 16; + VAR e: INTEGER; x0: LONGREAL; + d: ARRAY maxD OF CHAR; + BEGIN e := Reals.ExpoL(x); + IF e = 0 THEN + WriteString(W, " 0"); + REPEAT Write(W, " "); DEC(n) UNTIL n <= 3 + ELSIF e = 2047 THEN + WriteString(W, " NaN"); + WHILE n > 4 DO Write(W, " "); DEC(n) END + ELSE + IF n <= 10 THEN n := 3 ELSE DEC(n, 7) END; + REPEAT Write(W, " "); DEC(n) UNTIL n <= maxD; + (*there are 2 <= n <= maxD digits to be written*) + IF x < 0 THEN Write(W, "-"); x := -x ELSE Write(W, " ") END; + e := SHORT(LONG(e - 1023) * 77 DIV 256); + IF e >= 0 THEN x := x / Reals.TenL(e) ELSE x := Reals.TenL(-e) * x END ; + IF x >= 10.0D0 THEN x := 0.1D0 * x; INC(e) END ; + x0 := Reals.TenL(n-1); x := x0*x + 0.5D0; + IF x >= 10.0D0*x0 THEN x := 0.1D0 * x; INC(e) END ; + Reals.ConvertL(x, n, d); + DEC(n); Write(W, d[n]); Write(W, "."); + REPEAT DEC(n); Write(W, d[n]) UNTIL n = 0; + Write(W, "D"); + IF e < 0 THEN Write(W, "-"); e := -e ELSE Write(W, "+") END; + Write(W, CHR(e DIV 100 + 30H)); e := e MOD 100; + Write(W, CHR(e DIV 10 + 30H)); + Write(W, CHR(e MOD 10 + 30H)) + END + END WriteLongReal; + + PROCEDURE WriteLongRealHex* (VAR W: Writer; x: LONGREAL); + VAR i: INTEGER; + d: ARRAY 16 OF CHAR; + BEGIN Reals.ConvertHL(x, d); i := 0; + REPEAT Write(W, d[i]); INC(i) UNTIL i = 16 + END WriteLongRealHex; + + PROCEDURE WriteDate* (VAR W: Writer; t, d: LONGINT); + + PROCEDURE WritePair(ch: CHAR; x: LONGINT); + BEGIN Write(W, ch); + Write(W, CHR(x DIV 10 + 30H)); Write(W, CHR(x MOD 10 + 30H)) + END WritePair; + + BEGIN + WritePair(" ", d MOD 32); WritePair(".", d DIV 32 MOD 16); WritePair(".", d DIV 512 MOD 128); + WritePair(" ", t DIV 4096 MOD 32); WritePair(":", t DIV 64 MOD 64); WritePair(":", t MOD 64) + END WriteDate; + + + (** Text Filing **) + + PROCEDURE Load0 (VAR r: Files.Rider; T: Text); + VAR u, un: Run; p: Piece; e: Elem; + org, pos, hlen, plen: LONGINT; ecnt, fno, fcnt, col, voff: SHORTINT; + f: Files.File; + msg: FileMsg; + mods, procs: ARRAY 64, 32 OF CHAR; + name: ARRAY 32 OF CHAR; + fnts: ARRAY 32 OF FontsFont; + + PROCEDURE LoadElem (VAR r: Files.Rider; pos, span: LONGINT; VAR e: Elem); + VAR M: Modules.Module; Cmd: Modules.Command; a: Alien; + org, ew, eh: LONGINT; eno: SHORTINT; + BEGIN new := NIL; + Files.ReadLInt(r, ew); Files.ReadLInt(r, eh); Files.Read(r, eno); + IF eno > ecnt THEN ecnt := eno; Files.ReadString(r, mods[eno]); Files.ReadString(r, procs[eno]) END; + org := Files.Pos(r); M := Modules.ThisMod(mods[eno]); + IF M # NIL THEN Cmd := Modules.ThisCommand(M, procs[eno]); + IF Cmd # NIL THEN Cmd END + END; + e := new; + IF e # NIL THEN e.W := ew; e.H := eh; e.base := T; + msg.pos := pos; e.handle(e, msg); + IF Files.Pos(r) # org + span THEN e := NIL END + END; + IF e = NIL THEN Files.Set(r, f, org + span); + NEW(a); a.W := ew; a.H := eh; a.handle := HandleAlien; a.base := T; + a.file := f; a.org := org; a.span := span; + COPY(mods[eno], a.mod); COPY(procs[eno], a.proc); + e := a + END + END LoadElem; + + BEGIN pos := Files.Pos(r); f := Files.Base(r); + NEW(u); u.len := MAX(LONGINT); (*u.fnt := FontsDefault;*)u.fnt := NIL; u.col := Displaywhite; + T.head := u; ecnt := 0; fcnt := 0; + msg.id := load; msg.r := r; + Files.ReadLInt(msg.r, hlen); (*!!!org := pos + hlen;*) org := pos -2 + hlen; pos := org; Files.Read(msg.r, fno); + WHILE fno # 0 DO + IF fno > fcnt THEN fcnt := fno; Files.ReadString(msg.r, name); fnts[fno] := FontsThis(name) END; + Files.Read(msg.r, col); Files.Read(msg.r, voff); Files.ReadLInt(msg.r, plen); + IF plen > 0 THEN NEW(p); p.file := f; p.org := pos; p.ascii := FALSE; un := p; un.len := plen + ELSE LoadElem(msg.r, pos - org, -plen, e); un := e; un.len := 1 + END; + un.fnt := fnts[fno]; un.col := col; un.voff := voff; + INC(pos, un.len); u.next := un; un.prev := u; u := un; Files.Read(msg.r, fno) + END; + u.next := T.head; T.head.prev := u; T.cache := T.head; T.corg := 0; + Files.ReadLInt(msg.r, T.len); Files.Set(r, f, Files.Pos(msg.r) + T.len) + END Load0; + + PROCEDURE Load* (VAR r: Files.Rider; T: Text); + CONST oldTag = -4095; + VAR tag: INTEGER; + BEGIN + (* for compatibility inner text tags are checked and skipped; remove this in a later version *) + Files.ReadInt(r, tag); IF tag # oldTag THEN Files.Set(r, Files.Base(r), Files.Pos(r)-2) END; + Load0(r, T) + END Load; + + PROCEDURE Open* (T: Text; name: ARRAY OF CHAR); + VAR f: Files.File; r: Files.Rider; u: Run; p: Piece; tag, version: CHAR; hlen: LONGINT; + BEGIN f := Files.Old(name); + IF f = NIL THEN f := Files.New("") END; + Files.Set(r, f, 0); Files.Read(r, tag); Files.Read(r, version); + IF (tag = textTag) OR (tag = 01X) & (version = textTag) THEN Load0(r, T) + ELSE (*ascii*) + NEW(u); u.len := MAX(LONGINT); u.fnt := NIL; u.col := Displaywhite; + NEW(p); + IF (tag = DocBlockId) & (version = 07X) THEN (* extract ascii text from System 3 text document *) + Files.Set(r, f, 28); Files.ReadLInt(r, hlen); + Files.Set(r, f, 22 + hlen); Files.ReadLInt(r, T.len); p.org := 26 + hlen + ELSE + T.len := Files.Length(f); p.org := 0 + END ; + IF T.len > 0 THEN p.len := T.len; p.fnt := FontsDefault; + p.col := Displaywhite; p.voff := 0; p.file := f; p.ascii := TRUE; + u.next := p; u.prev := p; p.next := u; p.prev := u + ELSE u.next := u; u.prev := u + END; + T.head := u; T.cache := T.head; T.corg := 0 + END + END Open; + + PROCEDURE Store* (VAR r: Files.Rider; T: Text); + VAR r1: Files.Rider; u, un: Run; e: Elem; org, pos, delta, hlen, rlen: LONGINT; ecnt, fno, fcnt: SHORTINT; ch: CHAR; (* << *) + msg: FileMsg; iden: IdentifyMsg; + mods, procs: ARRAY 64, 32 OF CHAR; + fnts: ARRAY 32 OF FontsFont; + block: ARRAY 1024 OF CHAR; + + PROCEDURE StoreElem (VAR r: Files.Rider; pos: LONGINT; e: Elem); + VAR r1: Files.Rider; org, span: LONGINT; eno: SHORTINT; + BEGIN COPY(iden.mod, mods[ecnt]); COPY(iden.proc, procs[ecnt]); eno := 1; + WHILE (mods[eno] # iden.mod) OR (procs[eno] # iden.proc) DO INC(eno) END; + Files.Set(r1, Files.Base(r), Files.Pos(r)); + Files.WriteLInt(r, 0); Files.WriteLInt(r, 0); Files.WriteLInt(r, 0); (*fixup slot*) + Files.Write(r, eno); + IF eno = ecnt THEN INC(ecnt); Files.WriteString(r, iden.mod); Files.WriteString(r, iden.proc) END; + msg.pos := pos; org := Files.Pos(r); e.handle(e, msg); span := Files.Pos(r) - org; + Files.WriteLInt(r1, -span); Files.WriteLInt(r1, e.W); Files.WriteLInt(r1, e.H) (*fixup*) + END StoreElem; + + BEGIN + org := Files.Pos(r); msg.id := store; msg.r := r; Files.WriteLInt(msg.r, 0); (*fixup slot*) + u := T.head.next; pos := 0; delta := 0; fcnt := 1; ecnt := 1; + WHILE u # T.head DO + IF u IS Elem THEN iden.mod[0] := 0X; u(Elem).handle(u(Elem), iden) ELSE iden.mod[0] := 1X END; + IF iden.mod[0] # 0X THEN + fnts[fcnt] := u.fnt; fno := 1; + WHILE fnts[fno].name # u.fnt.name DO INC(fno) END; + Files.Write(msg.r, fno); + IF fno = fcnt THEN INC(fcnt); Files.WriteString(msg.r, u.fnt.name) END; + Files.Write(msg.r, u.col); Files.Write(msg.r, u.voff) + END; + IF u IS Piece THEN rlen := u.len; un := u.next; + WHILE (un IS Piece) & (un.fnt = u.fnt) & (un.col = u.col) & (un.voff = u.voff) DO + INC(rlen, un.len); un := un.next + END; + Files.WriteLInt(msg.r, rlen); INC(pos, rlen); u := un + ELSIF iden.mod[0] # 0X THEN StoreElem(msg.r, pos, u(Elem)); INC(pos); u := u.next + ELSE INC(delta); u := u.next + END + END; + Files.Write(msg.r, 0); Files.WriteLInt(msg.r, T.len - delta); + (*!!!hlen := Files.Pos(msg.r) - org;*) hlen := Files.Pos(msg.r) - org + 2; + Files.Set(r1, Files.Base(msg.r), org); Files.WriteLInt(r1, hlen); (*fixup*) + u := T.head.next; + WHILE u # T.head DO + IF u IS Piece THEN + WITH u: Piece DO + IF u.ascii THEN Files.Set(r1, u.file, u.org); delta := u.len; (* << LF to CR *) + WHILE delta > 0 DO Files.Read(r1, ch); DEC(delta); + IF ch = 0AX THEN Files.Write(msg.r, CR) ELSE Files.Write(msg.r, ch) END + END + ELSE Files.Set(r1, u.file, u.org); delta := u.len; + WHILE delta > LEN(block) DO Files.ReadBytes(r1, block, LEN(block)); + Files.WriteBytes(msg.r, block, LEN(block)); DEC(delta, LEN(block)) + END; + Files.ReadBytes(r1, block, delta); Files.WriteBytes(msg.r, block, delta) + END + END + ELSE iden.mod[0] := 0X; u(Elem).handle(u(Elem), iden); + IF iden.mod[0] # 0X THEN Files.Write(msg.r, ElemChar) END + END; + u := u.next + END; + r := msg.r; + END Store; + + PROCEDURE Close* (T: Text; name: ARRAY OF CHAR); + VAR f: Files.File; r: Files.Rider; i, res: INTEGER; bak: ARRAY 64 OF CHAR; + BEGIN + f := Files.New(name); Files.Set(r, f, 0); Files.Write(r, textTag); Files.Write(r, version); Store(r, T); + i := 0; WHILE name[i] # 0X DO INC(i) END; + COPY(name, bak); bak[i] := "."; bak[i+1] := "B"; bak[i+2] := "a"; bak[i+3] := "k"; bak[i+4] := 0X; + Files.Rename(name, bak, res); Files.Register(f) + END Close; + +BEGIN del := NIL; NEW(FontsDefault); FontsDefault.name := "Syntax10.Scn.Fnt" +END Texts. diff --git a/src/lib/system/linux/clang/Texts0.Mod b/src/lib/system/linux/clang/Texts0.Mod new file mode 100644 index 00000000..7b95e031 --- /dev/null +++ b/src/lib/system/linux/clang/Texts0.Mod @@ -0,0 +1,859 @@ +MODULE Texts0; (** CAS/HM 23.9.93 -- interface based on Texts by JG/NW 6.12.91**) (* << RC, MB, JT *) + IMPORT + Files := Files0, Modules, Reals; + + (*--- insert field e: Elem into Texts.Scanner and change Texts.Scan to set it in case of class=6 *) + (* this module is for bootstrapping voc, use Texts instead *) + + CONST + Displaywhite = 15; + ElemChar* = 1CX; + TAB = 9X; CR = 0DX; maxD = 9; + (**FileMsg.id**) + load* = 0; store* = 1; + (**Notifier op**) + replace* = 0; insert* = 1; delete* = 2; + (**Scanner.class**) + Inval* = 0; Name* = 1; String* = 2; Int* = 3; Real* = 4; LongReal* = 5; Char* = 6; + + textTag = 0F0X; DocBlockId = 0F7X; version = 01X; + + TYPE + FontsFont = POINTER TO FontDesc; + FontDesc = RECORD + name: ARRAY 32 OF CHAR; + END ; + + Run = POINTER TO RunDesc; + RunDesc = RECORD + prev, next: Run; + len: LONGINT; + fnt: FontsFont; + col, voff: SHORTINT; + ascii: BOOLEAN (* << *) + END; + + Piece = POINTER TO PieceDesc; + PieceDesc = RECORD (RunDesc) + file: Files.File; + org: LONGINT + END; + + Elem* = POINTER TO ElemDesc; + Buffer* = POINTER TO BufDesc; + Text* = POINTER TO TextDesc; + + ElemMsg* = RECORD END; + Handler* = PROCEDURE (e: Elem; VAR msg: ElemMsg); + + ElemDesc* = RECORD (RunDesc) + W*, H*: LONGINT; + handle*: Handler; + base: Text + END; + + FileMsg* = RECORD (ElemMsg) + id*: INTEGER; + pos*: LONGINT; + r*: Files.Rider + END; + + CopyMsg* = RECORD (ElemMsg) + e*: Elem + END; + + IdentifyMsg* = RECORD (ElemMsg) + mod*, proc*: ARRAY 32 OF CHAR + END; + + + BufDesc* = RECORD + len*: LONGINT; + head: Run + END; + + TextDesc* = RECORD + len*: LONGINT; + head, cache: Run; + corg: LONGINT + END; + + Reader* = RECORD + eot*: BOOLEAN; + fnt*: FontsFont; + col*, voff*: SHORTINT; + elem*: Elem; + rider: Files.Rider; + run: Run; + org, off: LONGINT + END; + + Scanner* = RECORD (Reader) + nextCh*: CHAR; + line*, class*: INTEGER; + i*: LONGINT; + x*: REAL; + y*: LONGREAL; + c*: CHAR; + len*: SHORTINT; + s*: ARRAY 64 OF CHAR (* << *) + END; + + Writer* = RECORD + buf*: Buffer; + fnt*: FontsFont; + col*, voff*: SHORTINT; + rider: Files.Rider; + file: Files.File + END; + + Alien = POINTER TO RECORD (ElemDesc) + file: Files.File; + org, span: LONGINT; + mod, proc: ARRAY 32 OF CHAR + END; + + VAR + new*: Elem; + del: Buffer; + FontsDefault: FontsFont; + + + PROCEDURE FontsThis(VAR name: ARRAY OF CHAR): FontsFont; + VAR F: FontsFont; + BEGIN + NEW(F); COPY(name, F.name); RETURN F + END FontsThis; + + (* run primitives *) + + PROCEDURE Find (T: Text; VAR pos: LONGINT; VAR u: Run; VAR org, off: LONGINT); + VAR v: Run; m: LONGINT; + BEGIN + IF pos >= T.len THEN pos := T.len; u := T.head; org := T.len; off := 0; T.cache := T.head; T.corg := 0 + ELSE v := T.cache.next; m := pos - T.corg; + IF pos >= T.corg THEN + WHILE m >= v.len DO DEC(m, v.len); v := v.next END + ELSE + WHILE m < 0 DO v := v.prev; INC(m, v.len) END; + END; + u := v; org := pos - m; off := m; T.cache := v.prev; T.corg := org + END + END Find; + + PROCEDURE Split (off: LONGINT; VAR u, un: Run); + VAR p, U: Piece; + BEGIN + IF off = 0 THEN un := u; u := un.prev + ELSIF off >= u.len THEN un := u.next + ELSE NEW(p); un := p; U := u(Piece); + p^ := U^; INC(p.org, off); DEC(p.len, off); DEC(U.len, p.len); + p.ascii := u.ascii; p.prev := U; p.next := U.next; p.next.prev := p; U.next := p (* << *) + END + END Split; + + PROCEDURE Merge (T: Text; u: Run; VAR v: Run); + VAR p, q: Piece; + BEGIN + IF (u IS Piece) & (v IS Piece) & (u.fnt.name = v.fnt.name) & (u.col = v.col) & (u.voff = v.voff) + & (u(Piece).ascii = v(Piece).ascii) THEN (* << *) + p := u(Piece); q := v(Piece); + IF (p.file = q.file) & (p.org + p.len = q.org) THEN + IF T.cache = u THEN INC(T.corg, q.len) + ELSIF T.cache = v THEN T.cache := T.head; T.corg := 0 + END; + INC(p.len, q.len); v := v.next + END + END + END Merge; + + PROCEDURE Splice (un, v, w: Run; base: Text); (* (u, un) -> (u, v, w, un) *) + VAR u: Run; + BEGIN + IF v # w.next THEN u := un.prev; + u.next := v; v.prev := u; un.prev := w; w.next := un; + REPEAT + IF v IS Elem THEN v(Elem).base := base END; + v := v.next + UNTIL v = un + END + END Splice; + + PROCEDURE ClonePiece (p: Piece): Piece; + VAR q: Piece; + BEGIN NEW(q); q^ := p^; RETURN q + END ClonePiece; + + PROCEDURE CloneElem (e: Elem): Elem; + VAR msg: CopyMsg; + BEGIN msg.e := NIL; e.handle(e, msg); RETURN msg.e + END CloneElem; + + + (** Elements **) + + PROCEDURE CopyElem* (SE, DE: Elem); + BEGIN DE.len := SE.len; DE.fnt := SE.fnt; DE.col := SE.col; DE.voff := SE.voff; + DE.W := SE.W; DE.H := SE.H; DE.handle := SE.handle + END CopyElem; + + PROCEDURE ElemBase* (E: Elem): Text; + BEGIN RETURN E.base + END ElemBase; + + PROCEDURE ElemPos* (E: Elem): LONGINT; + VAR u: Run; pos: LONGINT; + BEGIN u := E.base.head.next; pos := 0; + WHILE u # E DO pos := pos + u.len; u := u.next END; + RETURN pos + END ElemPos; + + + PROCEDURE HandleAlien (E: Elem; VAR msg: ElemMsg); + VAR e: Alien; r: Files.Rider; i: LONGINT; ch: CHAR; + BEGIN + WITH E: Alien DO + IF msg IS CopyMsg THEN + WITH msg: CopyMsg DO NEW(e); CopyElem(E, e); + e.file := E.file; e.org := E.org; e.span := E.span; e.mod := E.mod; e.proc := E.proc; + msg.e := e + END + ELSIF msg IS IdentifyMsg THEN + WITH msg: IdentifyMsg DO + COPY(E.mod, msg.mod); COPY(E.proc, msg.proc); msg.mod[31] := 1X (*alien*) + END + ELSIF msg IS FileMsg THEN + WITH msg: FileMsg DO + IF msg.id = store THEN Files.Set(r, E.file, E.org); i := E.span; + WHILE i > 0 DO Files.Read(r, ch); Files.Write(msg.r, ch); DEC(i) END + END + END + END + END + END HandleAlien; + + + (** Buffers **) + + PROCEDURE OpenBuf* (B: Buffer); + VAR u: Run; + BEGIN NEW(u); u.next := u; u.prev := u; B.head := u; B.len := 0 + END OpenBuf; + + PROCEDURE Copy* (SB, DB: Buffer); + VAR u, v, vn: Run; + BEGIN u := SB.head.next; v := DB.head.prev; + WHILE u # SB.head DO + IF u IS Piece THEN vn := ClonePiece(u(Piece)) ELSE vn := CloneElem(u(Elem)) END; + v.next := vn; vn.prev := v; v := vn; u := u.next + END; + v.next := DB.head; DB.head.prev := v; + INC(DB.len, SB.len) + END Copy; + + PROCEDURE Recall* (VAR B: Buffer); + BEGIN B := del; del := NIL + END Recall; + + + (** Texts **) + + PROCEDURE Save* (T: Text; beg, end: LONGINT; B: Buffer); + VAR u, v, w, wn: Run; uo, ud, vo, vd: LONGINT; + BEGIN Find(T, beg, u, uo, ud); Find(T, end, v, vo, vd); + w := B.head.prev; + WHILE u # v DO + IF u IS Piece THEN wn := ClonePiece(u(Piece)); DEC(wn.len, ud); INC(wn(Piece).org, ud) + ELSE wn := CloneElem(u(Elem)) + END; + w.next := wn; wn.prev := w; w := wn; u := u.next; ud := 0 + END; + IF vd > 0 THEN (*v IS Piece*) wn := ClonePiece(v(Piece)); wn.len := vd - ud; INC(wn(Piece).org, ud); + w.next := wn; wn.prev := w; w := wn + END; + w.next := B.head; B.head.prev := w; + INC(B.len, end - beg) + END Save; + + PROCEDURE Insert* (T: Text; pos: LONGINT; B: Buffer); + VAR u, un, v: Run; p, q: Piece; uo, ud, len: LONGINT; + BEGIN Find(T, pos, u, uo, ud); Split(ud, u, un); + len := B.len; v := B.head.next; + Merge(T, u, v); Splice(un, v, B.head.prev, T); + INC(T.len, len); B.head.next := B.head; B.head.prev := B.head; B.len := 0; + END Insert; + + PROCEDURE Append* (T: Text; B: Buffer); + VAR v: Run; pos, len: LONGINT; + BEGIN pos := T.len; len := B.len; v := B.head.next; + Merge(T, T.head.prev, v); Splice(T.head, v, B.head.prev, T); + INC(T.len, len); B.head.next := B.head; B.head.prev := B.head; B.len := 0; + END Append; + + PROCEDURE Delete* (T: Text; beg, end: LONGINT); + VAR c, u, un, v, vn: Run; co, uo, ud, vo, vd: LONGINT; + BEGIN + Find(T, beg, u, uo, ud); Split(ud, u, un); c := T.cache; co := T.corg; + Find(T, end, v, vo, vd); Split(vd, v, vn); T.cache := c; T.corg := co; + NEW(del); OpenBuf(del); del.len := end - beg; + Splice(del.head, un, v, NIL); + Merge(T, u, vn); u.next := vn; vn.prev := u; + DEC(T.len, end - beg); + END Delete; + + PROCEDURE ChangeLooks* (T: Text; beg, end: LONGINT; sel: SET; fnt: FontsFont; col, voff: SHORTINT); + VAR c, u, un, v, vn: Run; co, uo, ud, vo, vd: LONGINT; + BEGIN Find(T, beg, u, uo, ud); Split(ud, u, un); c := T.cache; co := T.corg; + Find(T, end, v, vo, vd); Split(vd, v, vn); T.cache := c; T.corg := co; + WHILE un # vn DO + IF (0 IN sel) & (fnt # NIL) THEN un.fnt := fnt END; + IF 1 IN sel THEN un.col := col END; + IF 2 IN sel THEN un.voff := voff END; + Merge(T, u, un); + IF u.next = un THEN u := un; un := un.next ELSE u.next := un; un.prev := u END + END; + Merge(T, u, un); u.next := un; un.prev := u; + END ChangeLooks; + + + (** Readers **) + + PROCEDURE OpenReader* (VAR R: Reader; T: Text; pos: LONGINT); + VAR u: Run; + BEGIN + IF pos >= T.len THEN pos := T.len END; + Find(T, pos, u, R.org, R.off); R.run := u; R.eot := FALSE; + IF u IS Piece THEN + Files.Set(R.rider, u(Piece).file, u(Piece).org + R.off) + END + END OpenReader; + + PROCEDURE Read* (VAR R: Reader; VAR ch: CHAR); + VAR u: Run; + BEGIN u := R.run; R.fnt := u.fnt; R.col := u.col; R.voff := u.voff; INC(R.off); + IF u IS Piece THEN Files.Read(R.rider, ch); R.elem := NIL; + IF (ch = 0AX) & u(Piece).ascii THEN ch := CR END (* << LF to CR *) + ELSIF u IS Elem THEN ch := ElemChar; R.elem := u(Elem) + ELSE ch := 0X; R.elem := NIL; R.eot := TRUE + END; + IF R.off = u.len THEN INC(R.org, u.len); u := u.next; + IF u IS Piece THEN + WITH u: Piece DO Files.Set(R.rider, u.file, u.org) END + END; + R.run := u; R.off := 0 + END + END Read; + + PROCEDURE ReadElem* (VAR R: Reader); + VAR u, un: Run; + BEGIN u := R.run; + WHILE u IS Piece DO INC(R.org, u.len); u := u.next END; + IF u IS Elem THEN un := u.next; R.run := un; INC(R.org); R.off := 0; + R.fnt := u.fnt; R.col := u.col; R.voff := u.voff; R.elem := u(Elem); + IF un IS Piece THEN + WITH un: Piece DO Files.Set(R.rider, un.file, un.org) END + END + ELSE R.eot := TRUE; R.elem := NIL + END + END ReadElem; + + PROCEDURE ReadPrevElem* (VAR R: Reader); + VAR u: Run; + BEGIN u := R.run.prev; + WHILE u IS Piece DO DEC(R.org, u.len); u := u.prev END; + IF u IS Elem THEN R.run := u; DEC(R.org); R.off := 0; + R.fnt := u.fnt; R.col := u.col; R.voff := u.voff; R.elem := u(Elem) + ELSE R.eot := TRUE; R.elem := NIL + END + END ReadPrevElem; + + PROCEDURE Pos* (VAR R: Reader): LONGINT; + BEGIN RETURN R.org + R.off + END Pos; + + + (** Scanners --------------- NW --------------- **) + + PROCEDURE OpenScanner* (VAR S: Scanner; T: Text; pos: LONGINT); + BEGIN OpenReader(S, T, pos); S.line := 0; S.nextCh := " " + END OpenScanner; + + (*IEEE floating point formats: + x = 2^(e-127) * 1.m bit 0: sign, bits 1- 8: e, bits 9-31: m + x = 2^(e-1023) * 1.m bit 0: sign, bits 1-11: e, bits 12-63: m *) + + PROCEDURE Scan* (VAR S: Scanner); + CONST maxD = 32; + VAR ch, term: CHAR; + neg, negE, hex: BOOLEAN; + i, j, h: SHORTINT; + e: INTEGER; k: LONGINT; + x, f: REAL; y, g: LONGREAL; + d: ARRAY maxD OF CHAR; + + PROCEDURE ReadScaleFactor; + BEGIN Read(S, ch); + IF ch = "-" THEN negE := TRUE; Read(S, ch) + ELSE negE := FALSE; + IF ch = "+" THEN Read(S, ch) END + END; + WHILE ("0" <= ch) & (ch <= "9") DO + e := e*10 + ORD(ch) - 30H; Read(S, ch) + END + END ReadScaleFactor; + + BEGIN ch := S.nextCh; i := 0; + LOOP + IF ch = CR THEN INC(S.line) + ELSIF (ch # " ") & (ch # TAB) THEN EXIT + END ; + Read(S, ch) + END; + IF ("A" <= CAP(ch)) & (CAP(ch) <= "Z") OR (ch = "/") OR (ch = ".") THEN (*name*) (* << *) + REPEAT S.s[i] := ch; INC(i); Read(S, ch) + UNTIL (CAP(ch) > "Z") & (ch # "_") (* << *) + OR ("A" > CAP(ch)) & (ch > "9") + OR ("0" > ch) & (ch # ".") & (ch # "/") (* << *) + OR (i = 63); (* << *) + S.s[i] := 0X; S.len := i; S.class := 1 + ELSIF ch = 22X THEN (*literal string*) + Read(S, ch); + WHILE (ch # 22X) & (ch >= " ") & (i # 63) DO (* << *) + S.s[i] := ch; INC(i); Read(S, ch) + END; + S.s[i] := 0X; S.len := i+1; Read(S, ch); S.class := 2 + ELSE + IF ch = "-" THEN neg := TRUE; Read(S, ch) ELSE neg := FALSE END ; + IF ("0" <= ch) & (ch <= "9") THEN (*number*) + hex := FALSE; j := 0; + LOOP d[i] := ch; INC(i); Read(S, ch); + IF ch < "0" THEN EXIT END; + IF "9" < ch THEN + IF ("A" <= ch) & (ch <= "F") THEN hex := TRUE; ch := CHR(ORD(ch)-7) + ELSIF ("a" <= ch) & (ch <= "f") THEN hex := TRUE; ch := CHR(ORD(ch)-27H) + ELSE EXIT + END + END + END; + IF ch = "H" THEN (*hex number*) + Read(S, ch); S.class := 3; + IF i-j > 8 THEN j := i-8 END ; + k := ORD(d[j]) - 30H; INC(j); + IF (i-j = 7) & (k >= 8) THEN DEC(k, 16) END ; + WHILE j < i DO k := k*10H + (ORD(d[j]) - 30H); INC(j) END ; + IF neg THEN S.i := -k ELSE S.i := k END + ELSIF ch = "." THEN (*read real*) + Read(S, ch); h := i; + WHILE ("0" <= ch) & (ch <= "9") DO d[i] := ch; INC(i); Read(S, ch) END ; + IF ch = "D" THEN + e := 0; y := 0; g := 1; + REPEAT y := y*10 + (ORD(d[j]) - 30H); INC(j) UNTIL j = h; + WHILE j < i DO g := g/10; y := (ORD(d[j]) - 30H)*g + y; INC(j) END ; + ReadScaleFactor; + IF negE THEN + IF e <= 308 THEN y := y / Reals.TenL(e) ELSE y := 0 END + ELSIF e > 0 THEN + IF e <= 308 THEN y := Reals.TenL(e) * y ELSE HALT(40) END + END ; + IF neg THEN y := -y END ; + S.class := 5; S.y := y + ELSE e := 0; x := 0; f := 1; + REPEAT x := x*10 + (ORD(d[j]) - 30H); INC(j) UNTIL j = h; + WHILE j < i DO f := f/10; x := (ORD(d[j])-30H)*f + x; INC(j) END; + IF ch = "E" THEN ReadScaleFactor END ; + IF negE THEN + IF e <= 38 THEN x := x / Reals.Ten(e) ELSE x := 0 END + ELSIF e > 0 THEN + IF e <= 38 THEN x := Reals.Ten(e) * x ELSE HALT(40) END + END ; + IF neg THEN x := -x END ; + S.class := 4; S.x := x + END ; + IF hex THEN S.class := 0 END + ELSE (*decimal integer*) + S.class := 3; k := 0; + REPEAT k := k*10 + (ORD(d[j]) - 30H); INC(j) UNTIL j = i; + IF neg THEN S.i := -k ELSE S.i := k END; + IF hex THEN S.class := 0 ELSE S.class := 3 END + END + ELSE S.class := 6; + IF neg THEN S.c := "-" ELSE S.c := ch; Read(S, ch) END + END + END; + S.nextCh := ch + END Scan; + + + (** Writers **) + + PROCEDURE OpenWriter* (VAR W: Writer); + BEGIN NEW(W.buf); OpenBuf(W.buf); + W.fnt := FontsDefault; W.col := Displaywhite; W.voff := 0; + W.file := Files.New(""); Files.Set(W.rider, W.file, 0) + END OpenWriter; + + PROCEDURE SetFont* (VAR W: Writer; fnt: FontsFont); + BEGIN W.fnt := fnt + END SetFont; + + PROCEDURE SetColor* (VAR W: Writer; col: SHORTINT); + BEGIN W.col := col + END SetColor; + + PROCEDURE SetOffset* (VAR W: Writer; voff: SHORTINT); + BEGIN W.voff := voff + END SetOffset; + + + PROCEDURE Write* (VAR W: Writer; ch: CHAR); + VAR u, un: Run; p: Piece; + BEGIN Files.Write(W.rider, ch); INC(W.buf.len); un := W.buf.head; u := un.prev; + IF (u IS Piece) & (u(Piece).file = W.file) & (u.fnt.name = W.fnt.name) & (u.col = W.col) & (u.voff = W.voff) + & ~u(Piece).ascii THEN (* << *) + INC(u.len) + ELSE NEW(p); u.next := p; p.prev := u; p.next := un; un.prev := p; + p.len := 1; p.fnt := W.fnt; p.col := W.col; p.voff := W.voff; + p.file := W.file; p.org := Files.Length(W.file) - 1; p.ascii := FALSE (* << *) + END + END Write; + + PROCEDURE WriteElem* (VAR W: Writer; e: Elem); + VAR u, un: Run; + BEGIN + IF e.base # NIL THEN HALT(99) END; + INC(W.buf.len); e.len := 1; e.fnt := W.fnt; e.col := W.col; e.voff := W.voff; + un := W.buf.head; u := un.prev; u.next := e; e.prev := u; e.next := un; un.prev := e + END WriteElem; + + PROCEDURE WriteLn* (VAR W: Writer); + BEGIN Write(W, CR) + END WriteLn; + + PROCEDURE WriteString* (VAR W: Writer; s: ARRAY OF CHAR); + VAR i: INTEGER; + BEGIN i := 0; + WHILE s[i] >= " " DO Write(W, s[i]); INC(i) END + END WriteString; + + PROCEDURE WriteInt* (VAR W: Writer; x, n: LONGINT); + VAR i: INTEGER; x0: LONGINT; + a: ARRAY 11 OF CHAR; + BEGIN i := 0; + IF x < 0 THEN + IF x = MIN(LONGINT) THEN WriteString(W, " -2147483648"); RETURN + ELSE DEC(n); x0 := -x + END + ELSE x0 := x + END; + REPEAT + a[i] := CHR(x0 MOD 10 + 30H); x0 := x0 DIV 10; INC(i) + UNTIL x0 = 0; + WHILE n > i DO Write(W, " "); DEC(n) END; + IF x < 0 THEN Write(W, "-") END; + REPEAT DEC(i); Write(W, a[i]) UNTIL i = 0 + END WriteInt; + + PROCEDURE WriteHex* (VAR W: Writer; x: LONGINT); + VAR i: INTEGER; y: LONGINT; + a: ARRAY 10 OF CHAR; + BEGIN i := 0; Write(W, " "); + REPEAT y := x MOD 10H; + IF y < 10 THEN a[i] := CHR(y + 30H) ELSE a[i] := CHR(y + 37H) END; + x := x DIV 10H; INC(i) + UNTIL i = 8; + REPEAT DEC(i); Write(W, a[i]) UNTIL i = 0 + END WriteHex; + + PROCEDURE WriteReal* (VAR W: Writer; x: REAL; n: INTEGER); + VAR e: INTEGER; x0: REAL; + d: ARRAY maxD OF CHAR; + BEGIN e := Reals.Expo(x); + IF e = 0 THEN + WriteString(W, " 0"); + REPEAT Write(W, " "); DEC(n) UNTIL n <= 3 + ELSIF e = 255 THEN + WriteString(W, " NaN"); + WHILE n > 4 DO Write(W, " "); DEC(n) END + ELSE + IF n <= 9 THEN n := 3 ELSE DEC(n, 6) END; + REPEAT Write(W, " "); DEC(n) UNTIL n <= 8; + (*there are 2 < n <= 8 digits to be written*) + IF x < 0.0 THEN Write(W, "-"); x := -x ELSE Write(W, " ") END; + e := (e - 127) * 77 DIV 256; + IF e >= 0 THEN x := x / Reals.Ten(e) ELSE x := Reals.Ten(-e) * x END; + IF x >= 10.0 THEN x := 0.1*x; INC(e) END; + x0 := Reals.Ten(n-1); x := x0*x + 0.5; + IF x >= 10.0*x0 THEN x := x*0.1; INC(e) END; + Reals.Convert(x, n, d); + DEC(n); Write(W, d[n]); Write(W, "."); + REPEAT DEC(n); Write(W, d[n]) UNTIL n = 0; + Write(W, "E"); + IF e < 0 THEN Write(W, "-"); e := -e ELSE Write(W, "+") END; + Write(W, CHR(e DIV 10 + 30H)); Write(W, CHR(e MOD 10 + 30H)) + END + END WriteReal; + + PROCEDURE WriteRealFix* (VAR W: Writer; x: REAL; n, k: INTEGER); + VAR e, i: INTEGER; sign: CHAR; x0: REAL; + d: ARRAY maxD OF CHAR; + + PROCEDURE seq(ch: CHAR; n: INTEGER); + BEGIN WHILE n > 0 DO Write(W, ch); DEC(n) END + END seq; + + PROCEDURE dig(n: INTEGER); + BEGIN + WHILE n > 0 DO + DEC(i); Write(W, d[i]); DEC(n) + END + END dig; + + BEGIN e := Reals.Expo(x); + IF k < 0 THEN k := 0 END; + IF e = 0 THEN seq(" ", n-k-2); Write(W, "0"); seq(" ", k+1) + ELSIF e = 255 THEN WriteString(W, " NaN"); seq(" ", n-4) + ELSE e := (e - 127) * 77 DIV 256; + IF x < 0 THEN sign := "-"; x := -x ELSE sign := " " END; + IF e >= 0 THEN (*x >= 1.0, 77/256 = log 2*) x := x/Reals.Ten(e) + ELSE (*x < 1.0*) x := Reals.Ten(-e) * x + END; + IF x >= 10.0 THEN x := 0.1*x; INC(e) END; + (* 1 <= x < 10 *) + IF k+e >= maxD-1 THEN k := maxD-1-e + ELSIF k+e < 0 THEN k := -e; x := 0.0 + END; + x0 := Reals.Ten(k+e); x := x0*x + 0.5; + IF x >= 10.0*x0 THEN INC(e) END; + (*e = no. of digits before decimal point*) + INC(e); i := k+e; Reals.Convert(x, i, d); + IF e > 0 THEN + seq(" ", n-e-k-2); Write(W, sign); dig(e); + Write(W, "."); dig(k) + ELSE seq(" ", n-k-3); + Write(W, sign); Write(W, "0"); Write(W, "."); + seq("0", -e); dig(k+e) + END + END + END WriteRealFix; + + PROCEDURE WriteRealHex* (VAR W: Writer; x: REAL); + VAR i: INTEGER; + d: ARRAY 8 OF CHAR; + BEGIN Reals.ConvertH(x, d); i := 0; + REPEAT Write(W, d[i]); INC(i) UNTIL i = 8 + END WriteRealHex; + + PROCEDURE WriteLongReal* (VAR W: Writer; x: LONGREAL; n: INTEGER); + CONST maxD = 16; + VAR e: INTEGER; x0: LONGREAL; + d: ARRAY maxD OF CHAR; + BEGIN e := Reals.ExpoL(x); + IF e = 0 THEN + WriteString(W, " 0"); + REPEAT Write(W, " "); DEC(n) UNTIL n <= 3 + ELSIF e = 2047 THEN + WriteString(W, " NaN"); + WHILE n > 4 DO Write(W, " "); DEC(n) END + ELSE + IF n <= 10 THEN n := 3 ELSE DEC(n, 7) END; + REPEAT Write(W, " "); DEC(n) UNTIL n <= maxD; + (*there are 2 <= n <= maxD digits to be written*) + IF x < 0 THEN Write(W, "-"); x := -x ELSE Write(W, " ") END; + e := SHORT(LONG(e - 1023) * 77 DIV 256); + IF e >= 0 THEN x := x / Reals.TenL(e) ELSE x := Reals.TenL(-e) * x END ; + IF x >= 10.0D0 THEN x := 0.1D0 * x; INC(e) END ; + x0 := Reals.TenL(n-1); x := x0*x + 0.5D0; + IF x >= 10.0D0*x0 THEN x := 0.1D0 * x; INC(e) END ; + Reals.ConvertL(x, n, d); + DEC(n); Write(W, d[n]); Write(W, "."); + REPEAT DEC(n); Write(W, d[n]) UNTIL n = 0; + Write(W, "D"); + IF e < 0 THEN Write(W, "-"); e := -e ELSE Write(W, "+") END; + Write(W, CHR(e DIV 100 + 30H)); e := e MOD 100; + Write(W, CHR(e DIV 10 + 30H)); + Write(W, CHR(e MOD 10 + 30H)) + END + END WriteLongReal; + + PROCEDURE WriteLongRealHex* (VAR W: Writer; x: LONGREAL); + VAR i: INTEGER; + d: ARRAY 16 OF CHAR; + BEGIN Reals.ConvertHL(x, d); i := 0; + REPEAT Write(W, d[i]); INC(i) UNTIL i = 16 + END WriteLongRealHex; + + PROCEDURE WriteDate* (VAR W: Writer; t, d: LONGINT); + + PROCEDURE WritePair(ch: CHAR; x: LONGINT); + BEGIN Write(W, ch); + Write(W, CHR(x DIV 10 + 30H)); Write(W, CHR(x MOD 10 + 30H)) + END WritePair; + + BEGIN + WritePair(" ", d MOD 32); WritePair(".", d DIV 32 MOD 16); WritePair(".", d DIV 512 MOD 128); + WritePair(" ", t DIV 4096 MOD 32); WritePair(":", t DIV 64 MOD 64); WritePair(":", t MOD 64) + END WriteDate; + + + (** Text Filing **) + + PROCEDURE Load0 (VAR r: Files.Rider; T: Text); + VAR u, un: Run; p: Piece; e: Elem; + org, pos, hlen, plen: LONGINT; ecnt, fno, fcnt, col, voff: SHORTINT; + f: Files.File; + msg: FileMsg; + mods, procs: ARRAY 64, 32 OF CHAR; + name: ARRAY 32 OF CHAR; + fnts: ARRAY 32 OF FontsFont; + + PROCEDURE LoadElem (VAR r: Files.Rider; pos, span: LONGINT; VAR e: Elem); + VAR M: Modules.Module; Cmd: Modules.Command; a: Alien; + org, ew, eh: LONGINT; eno: SHORTINT; + BEGIN new := NIL; + Files.ReadLInt(r, ew); Files.ReadLInt(r, eh); Files.Read(r, eno); + IF eno > ecnt THEN ecnt := eno; Files.ReadString(r, mods[eno]); Files.ReadString(r, procs[eno]) END; + org := Files.Pos(r); M := Modules.ThisMod(mods[eno]); + IF M # NIL THEN Cmd := Modules.ThisCommand(M, procs[eno]); + IF Cmd # NIL THEN Cmd END + END; + e := new; + IF e # NIL THEN e.W := ew; e.H := eh; e.base := T; + msg.pos := pos; e.handle(e, msg); + IF Files.Pos(r) # org + span THEN e := NIL END + END; + IF e = NIL THEN Files.Set(r, f, org + span); + NEW(a); a.W := ew; a.H := eh; a.handle := HandleAlien; a.base := T; + a.file := f; a.org := org; a.span := span; + COPY(mods[eno], a.mod); COPY(procs[eno], a.proc); + e := a + END + END LoadElem; + + BEGIN pos := Files.Pos(r); f := Files.Base(r); + NEW(u); u.len := MAX(LONGINT); (*u.fnt := FontsDefault;*)u.fnt := NIL; u.col := Displaywhite; + T.head := u; ecnt := 0; fcnt := 0; + msg.id := load; msg.r := r; + Files.ReadLInt(msg.r, hlen); (*!!!org := pos + hlen;*) org := pos -2 + hlen; pos := org; Files.Read(msg.r, fno); + WHILE fno # 0 DO + IF fno > fcnt THEN fcnt := fno; Files.ReadString(msg.r, name); fnts[fno] := FontsThis(name) END; + Files.Read(msg.r, col); Files.Read(msg.r, voff); Files.ReadLInt(msg.r, plen); + IF plen > 0 THEN NEW(p); p.file := f; p.org := pos; p.ascii := FALSE; un := p; un.len := plen + ELSE LoadElem(msg.r, pos - org, -plen, e); un := e; un.len := 1 + END; + un.fnt := fnts[fno]; un.col := col; un.voff := voff; + INC(pos, un.len); u.next := un; un.prev := u; u := un; Files.Read(msg.r, fno) + END; + u.next := T.head; T.head.prev := u; T.cache := T.head; T.corg := 0; + Files.ReadLInt(msg.r, T.len); Files.Set(r, f, Files.Pos(msg.r) + T.len) + END Load0; + + PROCEDURE Load* (VAR r: Files.Rider; T: Text); + CONST oldTag = -4095; + VAR tag: INTEGER; + BEGIN + (* for compatibility inner text tags are checked and skipped; remove this in a later version *) + Files.ReadInt(r, tag); IF tag # oldTag THEN Files.Set(r, Files.Base(r), Files.Pos(r)-2) END; + Load0(r, T) + END Load; + + PROCEDURE Open* (T: Text; name: ARRAY OF CHAR); + VAR f: Files.File; r: Files.Rider; u: Run; p: Piece; tag, version: CHAR; hlen: LONGINT; + BEGIN f := Files.Old(name); + IF f = NIL THEN f := Files.New("") END; + Files.Set(r, f, 0); Files.Read(r, tag); Files.Read(r, version); + IF (tag = textTag) OR (tag = 01X) & (version = textTag) THEN Load0(r, T) + ELSE (*ascii*) + NEW(u); u.len := MAX(LONGINT); u.fnt := NIL; u.col := Displaywhite; + NEW(p); + IF (tag = DocBlockId) & (version = 07X) THEN (* extract ascii text from System 3 text document *) + Files.Set(r, f, 28); Files.ReadLInt(r, hlen); + Files.Set(r, f, 22 + hlen); Files.ReadLInt(r, T.len); p.org := 26 + hlen + ELSE + T.len := Files.Length(f); p.org := 0 + END ; + IF T.len > 0 THEN p.len := T.len; p.fnt := FontsDefault; + p.col := Displaywhite; p.voff := 0; p.file := f; p.ascii := TRUE; + u.next := p; u.prev := p; p.next := u; p.prev := u + ELSE u.next := u; u.prev := u + END; + T.head := u; T.cache := T.head; T.corg := 0 + END + END Open; + + PROCEDURE Store* (VAR r: Files.Rider; T: Text); + VAR r1: Files.Rider; u, un: Run; e: Elem; org, pos, delta, hlen, rlen: LONGINT; ecnt, fno, fcnt: SHORTINT; ch: CHAR; (* << *) + msg: FileMsg; iden: IdentifyMsg; + mods, procs: ARRAY 64, 32 OF CHAR; + fnts: ARRAY 32 OF FontsFont; + block: ARRAY 1024 OF CHAR; + + PROCEDURE StoreElem (VAR r: Files.Rider; pos: LONGINT; e: Elem); + VAR r1: Files.Rider; org, span: LONGINT; eno: SHORTINT; + BEGIN COPY(iden.mod, mods[ecnt]); COPY(iden.proc, procs[ecnt]); eno := 1; + WHILE (mods[eno] # iden.mod) OR (procs[eno] # iden.proc) DO INC(eno) END; + Files.Set(r1, Files.Base(r), Files.Pos(r)); + Files.WriteLInt(r, 0); Files.WriteLInt(r, 0); Files.WriteLInt(r, 0); (*fixup slot*) + Files.Write(r, eno); + IF eno = ecnt THEN INC(ecnt); Files.WriteString(r, iden.mod); Files.WriteString(r, iden.proc) END; + msg.pos := pos; org := Files.Pos(r); e.handle(e, msg); span := Files.Pos(r) - org; + Files.WriteLInt(r1, -span); Files.WriteLInt(r1, e.W); Files.WriteLInt(r1, e.H) (*fixup*) + END StoreElem; + + BEGIN + org := Files.Pos(r); msg.id := store; msg.r := r; Files.WriteLInt(msg.r, 0); (*fixup slot*) + u := T.head.next; pos := 0; delta := 0; fcnt := 1; ecnt := 1; + WHILE u # T.head DO + IF u IS Elem THEN iden.mod[0] := 0X; u(Elem).handle(u(Elem), iden) ELSE iden.mod[0] := 1X END; + IF iden.mod[0] # 0X THEN + fnts[fcnt] := u.fnt; fno := 1; + WHILE fnts[fno].name # u.fnt.name DO INC(fno) END; + Files.Write(msg.r, fno); + IF fno = fcnt THEN INC(fcnt); Files.WriteString(msg.r, u.fnt.name) END; + Files.Write(msg.r, u.col); Files.Write(msg.r, u.voff) + END; + IF u IS Piece THEN rlen := u.len; un := u.next; + WHILE (un IS Piece) & (un.fnt = u.fnt) & (un.col = u.col) & (un.voff = u.voff) DO + INC(rlen, un.len); un := un.next + END; + Files.WriteLInt(msg.r, rlen); INC(pos, rlen); u := un + ELSIF iden.mod[0] # 0X THEN StoreElem(msg.r, pos, u(Elem)); INC(pos); u := u.next + ELSE INC(delta); u := u.next + END + END; + Files.Write(msg.r, 0); Files.WriteLInt(msg.r, T.len - delta); + (*!!!hlen := Files.Pos(msg.r) - org;*) hlen := Files.Pos(msg.r) - org + 2; + Files.Set(r1, Files.Base(msg.r), org); Files.WriteLInt(r1, hlen); (*fixup*) + u := T.head.next; + WHILE u # T.head DO + IF u IS Piece THEN + WITH u: Piece DO + IF u.ascii THEN Files.Set(r1, u.file, u.org); delta := u.len; (* << LF to CR *) + WHILE delta > 0 DO Files.Read(r1, ch); DEC(delta); + IF ch = 0AX THEN Files.Write(msg.r, CR) ELSE Files.Write(msg.r, ch) END + END + ELSE Files.Set(r1, u.file, u.org); delta := u.len; + WHILE delta > LEN(block) DO Files.ReadBytes(r1, block, LEN(block)); + Files.WriteBytes(msg.r, block, LEN(block)); DEC(delta, LEN(block)) + END; + Files.ReadBytes(r1, block, delta); Files.WriteBytes(msg.r, block, delta) + END + END + ELSE iden.mod[0] := 0X; u(Elem).handle(u(Elem), iden); + IF iden.mod[0] # 0X THEN Files.Write(msg.r, ElemChar) END + END; + u := u.next + END; + r := msg.r; + END Store; + + PROCEDURE Close* (T: Text; name: ARRAY OF CHAR); + VAR f: Files.File; r: Files.Rider; i, res: INTEGER; bak: ARRAY 64 OF CHAR; + BEGIN + f := Files.New(name); Files.Set(r, f, 0); Files.Write(r, textTag); Files.Write(r, version); Store(r, T); + i := 0; WHILE name[i] # 0X DO INC(i) END; + COPY(name, bak); bak[i] := "."; bak[i+1] := "B"; bak[i+2] := "a"; bak[i+3] := "k"; bak[i+4] := 0X; + Files.Rename(name, bak, res); Files.Register(f) + END Close; + +BEGIN del := NIL; NEW(FontsDefault); FontsDefault.name := "Syntax10.Scn.Fnt" +END Texts0. diff --git a/src/lib/system/linux/clang/armv6j/Args.Mod b/src/lib/system/linux/clang/armv6j/Args.Mod new file mode 100644 index 00000000..e8cd2a3c --- /dev/null +++ b/src/lib/system/linux/clang/armv6j/Args.Mod @@ -0,0 +1,64 @@ +MODULE Args; (* jt, 8.12.94 *) + + (* command line argument handling for ofront *) + + + IMPORT SYSTEM; + + TYPE + ArgPtr = POINTER TO ARRAY 1024 OF CHAR; + ArgVec = POINTER TO ARRAY 1024 OF ArgPtr; + + VAR argc-, argv-: LONGINT; + + PROCEDURE -Argc(): INTEGER "SYSTEM_argc"; + PROCEDURE -Argv(): LONGINT "(long)SYSTEM_argv"; + PROCEDURE -getenv(var: ARRAY OF CHAR): ArgPtr + "(Args_ArgPtr)getenv(var)"; + + PROCEDURE Get*(n: INTEGER; VAR val: ARRAY OF CHAR); + VAR av: ArgVec; + BEGIN + IF n < argc THEN av := SYSTEM.VAL(ArgVec, argv); COPY(av[n]^, val) END + END Get; + + PROCEDURE GetInt*(n: INTEGER; VAR val: LONGINT); + VAR s: ARRAY 64 OF CHAR; k, d, i: LONGINT; + BEGIN + s := ""; Get(n, s); i := 0; + IF s[0] = "-" THEN i := 1 END ; + k := 0; d := ORD(s[i]) - ORD("0"); + WHILE (d >= 0 ) & (d <= 9) DO k := k*10 + d; INC(i); d := ORD(s[i]) - ORD("0") END ; + IF s[0] = "-" THEN d := -d; DEC(i) END ; + IF i > 0 THEN val := k END + END GetInt; + + PROCEDURE Pos*(s: ARRAY OF CHAR): INTEGER; + VAR i: INTEGER; arg: ARRAY 256 OF CHAR; + BEGIN + i := 0; Get(i, arg); + WHILE (i < argc) & (s # arg) DO INC(i); Get(i, arg) END ; + RETURN i + END Pos; + + PROCEDURE GetEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR); + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN COPY(p^, val) END + END GetEnv; + + PROCEDURE getEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR): BOOLEAN; + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN + COPY(p^, val); + RETURN TRUE + ELSE + RETURN FALSE + END + END getEnv; + +BEGIN argc := Argc(); argv := Argv() +END Args. diff --git a/src/lib/system/linux/clang/armv6j/SYSTEM.c0 b/src/lib/system/linux/clang/armv6j/SYSTEM.c0 new file mode 100644 index 00000000..580449aa --- /dev/null +++ b/src/lib/system/linux/clang/armv6j/SYSTEM.c0 @@ -0,0 +1,205 @@ +/* +* The body prefix file of the Ofront runtime system, Version 1.0 +* +* Copyright (c) Software Templ, 1994, 1995 +* +* Module SYSTEM is subject to change any time without prior notification. +* Software Templ disclaims all warranties with regard to module SYSTEM, +* in particular shall Software Templ not be liable for any damage resulting +* from inappropriate use or modification of module SYSTEM. +* +* Version 1.1 jt, 24.11.95 fixes for correct pointer arithmetic on Cray computers +* jt 31.1.2007 ANSI prototypes for malloc and exit in order to avoid cc warnings +* +*/ + +#include "SYSTEM.h" +#ifdef __STDC__ +#include "stdarg.h" +#else +#include "varargs.h" +#endif + +extern void *malloc(long size); +extern void exit(int status); + +void (*SYSTEM_Halt)(); +LONGINT SYSTEM_halt; /* x in HALT(x) */ +LONGINT SYSTEM_assert; /* x in ASSERT(cond, x) */ +LONGINT SYSTEM_argc; +LONGINT SYSTEM_argv; +LONGINT SYSTEM_lock; +BOOLEAN SYSTEM_interrupted; +static LONGINT SYSTEM_mainfrm; /* adr of main proc stack frame, used for stack collection */ + +#define Lock SYSTEM_lock++ +#define Unlock SYSTEM_lock--; if (SYSTEM_interrupted && (SYSTEM_lock == 0)) __HALT(-9) + + +static void SYSTEM_InitHeap(); +void *SYSTEM__init(); + +void SYSTEM_INIT(argc, argvadr) + int argc; long argvadr; +{ + SYSTEM_mainfrm = argvadr; + SYSTEM_argc = argc; + SYSTEM_argv = *(long*)argvadr; + SYSTEM_InitHeap(); + SYSTEM_halt = -128; + SYSTEM__init(); +} + +void SYSTEM_FINI() +{ + SYSTEM_FINALL(); +} + +long SYSTEM_XCHK(i, ub) long i, ub; {return __X(i, ub);} +long SYSTEM_RCHK(i, ub) long i, ub; {return __R(i, ub);} +long SYSTEM_ASH(i, n) long i, n; {return __ASH(i, n);} +long SYSTEM_ABS(i) long i; {return __ABS(i);} +double SYSTEM_ABSD(i) double i; {return __ABS(i);} + +void SYSTEM_INHERIT(t, t0) + long *t, *t0; +{ + t -= __TPROC0OFF; + t0 -= __TPROC0OFF; + while (*t0 != __EOM) {*t = *t0; t--; t0--;} +} + +void SYSTEM_ENUMP(adr, n, P) + long *adr; + long n; + void (*P)(); +{ + while (n > 0) {P(*adr); adr++; n--;} +} + +void SYSTEM_ENUMR(adr, typ, size, n, P) + char *adr; + long *typ, size, n; + void (*P)(); +{ + long *t, off; + typ++; + while (n > 0) { + t = typ; + off = *t; + while (off >= 0) {P(*(long*)(adr+off)); t++; off = *t;} + adr += size; n--; + } +} + +long SYSTEM_DIV(x, y) + unsigned long x, y; +{ if ((long) x >= 0) return (x / y); + else return -((y - 1 - x) / y); +} + +long SYSTEM_MOD(x, y) + unsigned long x, y; +{ unsigned long m; + if ((long) x >= 0) return (x % y); + else { m = (-x) % y; + if (m != 0) return (y - m); else return 0; + } +} + +long SYSTEM_ENTIER(x) + double x; +{ + long y; + if (x >= 0) + return (long)x; + else { + y = (long)x; + if (y <= x) return y; else return y - 1; + } +} + +void SYSTEM_HALT(n) + int n; +{ + SYSTEM_halt = n; + if (SYSTEM_Halt!=0) SYSTEM_Halt(n); + exit(n); +} + +#ifdef __STDC__ +SYSTEM_PTR SYSTEM_NEWARR(long *typ, long elemsz, int elemalgn, int nofdim, int nofdyn, ...) +#else +SYSTEM_PTR SYSTEM_NEWARR(typ, elemsz, elemalgn, nofdim, nofdyn, va_alist) + long *typ, elemsz; + int elemalgn, nofdim, nofdyn; + va_dcl +#endif +{ + long nofelems, size, dataoff, n, nptr, *x, *p, nofptrs, i, *ptab, off; + va_list ap; +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + nofelems = 1; + while (nofdim > 0) { + nofelems = nofelems * va_arg(ap, long); nofdim--; + if (nofelems <= 0) __HALT(-20); + } + va_end(ap); + dataoff = nofdyn * sizeof(long); + if (elemalgn > sizeof(long)) { + n = dataoff % elemalgn; + if (n != 0) dataoff += elemalgn - n; + } + size = dataoff + nofelems * elemsz; + Lock; + if (typ == NIL) { + /* element typ does not contain pointers */ + x = SYSTEM_NEWBLK(size); + } + else if (typ == POINTER__typ) { + /* element type is a pointer */ + x = SYSTEM_NEWBLK(size + nofelems * sizeof(long)); + p = (long*)x[-1]; + p[-nofelems] = *p; /* build new type desc in situ: 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nofelems - 1; n = 1; /* n =1 for skipping the size field */ + while (n <= nofelems) {*p = n*sizeof(long); p++; n++;} + *p = - (nofelems + 1) * sizeof(long); /* sentinel */ + x[-1] -= nofelems * sizeof(long); + } + else { + /* element type is a record that contains pointers */ + ptab = typ + 1; nofptrs = 0; + while (ptab[nofptrs] >= 0) {nofptrs++;} /* number of pointers per element */ + nptr = nofelems * nofptrs; /* total number of pointers */ + x = SYSTEM_NEWBLK(size + nptr * sizeof(long)); + p = (long*)x[- 1]; + p[-nptr] = *p; /* build new type desc in situ; 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nptr - 1; n = 0; off = dataoff; + while (n < nofelems) {i = 0; + while (i < nofptrs) {*p = off + ptab[i]; p++; i++;} + off += elemsz; n++; + } + *p = - (nptr + 1) * sizeof(long); /* sentinel */ + x[-1] -= nptr * sizeof(long); + } + if (nofdyn != 0) { + /* setup len vector for index checks */ +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + p = x; + while (nofdyn > 0) {*p = va_arg(ap, long); p++, nofdyn--;} + va_end(ap); + } + Unlock; + return x; +} + +/* ----------- end of SYSTEM.co ------------- */ + diff --git a/src/lib/system/linux/clang/armv6j/SYSTEM.h b/src/lib/system/linux/clang/armv6j/SYSTEM.h new file mode 100644 index 00000000..719a6d18 --- /dev/null +++ b/src/lib/system/linux/clang/armv6j/SYSTEM.h @@ -0,0 +1,215 @@ +#ifndef SYSTEM__h +#define SYSTEM__h + +/* + +the Ofront runtime system interface and macros library +copyright (c) Josef Templ, 1995, 1996 + +gcc for Linux version (same as SPARC/Solaris2) +uses double # as concatenation operator + +*/ + +#include + +//extern void *memcpy(void *dest, const void *src, long n); +extern void *memcpy(void *dest, const void *src, size_t n); +extern void *malloc(long size); +extern void exit(int status); + +#define export +#define import extern + +/* constants */ +#define __MAXEXT 16 +#define NIL 0L +#define POINTER__typ (long*)1L /* not NIL and not a valid type */ + +/* basic types */ +typedef char BOOLEAN; +typedef unsigned char CHAR; +typedef signed char SHORTINT; +typedef short int INTEGER; +typedef long LONGINT; +typedef float REAL; +typedef double LONGREAL; +typedef unsigned long SET; +typedef void *SYSTEM_PTR; +typedef unsigned char SYSTEM_BYTE; + +/* runtime system routines */ +extern long SYSTEM_DIV(); +extern long SYSTEM_MOD(); +extern long SYSTEM_ENTIER(); +extern long SYSTEM_ASH(); +extern long SYSTEM_ABS(); +extern long SYSTEM_XCHK(); +extern long SYSTEM_RCHK(); +extern double SYSTEM_ABSD(); +extern SYSTEM_PTR SYSTEM_NEWREC(); +extern SYSTEM_PTR SYSTEM_NEWBLK(); +#ifdef __STDC__ +extern SYSTEM_PTR SYSTEM_NEWARR(long*, long, int, int, int, ...); +#else +extern SYSTEM_PTR SYSTEM_NEWARR(); +#endif +extern SYSTEM_PTR SYSTEM_REGMOD(); +extern void SYSTEM_INCREF(); +extern void SYSTEM_REGCMD(); +extern void SYSTEM_REGTYP(); +extern void SYSTEM_REGFIN(); +extern void SYSTEM_FINALL(); +extern void SYSTEM_INIT(); +extern void SYSTEM_FINI(); +extern void SYSTEM_HALT(); +extern void SYSTEM_INHERIT(); +extern void SYSTEM_ENUMP(); +extern void SYSTEM_ENUMR(); + +/* module registry */ +#define __DEFMOD static void *m; if(m!=0)return m +#define __REGMOD(name, enum) if(m==0)m=SYSTEM_REGMOD((CHAR*)name,enum); else return m +#define __ENDMOD return m +#define __INIT(argc, argv) static void *m; SYSTEM_INIT(argc, (long)&argv); +#define __REGMAIN(name, enum) m=SYSTEM_REGMOD(name,enum) +#define __FINI SYSTEM_FINI(); return 0 +#define __IMPORT(name) SYSTEM_INCREF(name##__init()) +#define __REGCMD(name, cmd) SYSTEM_REGCMD(m, name, cmd) + +/* SYSTEM ops */ +#define __SYSNEW(p, len) p=SYSTEM_NEWBLK((long)(len)) +#define __VAL(t, x) (*(t*)&(x)) +#define __GET(a, x, t) x= *(t*)(a) +#define __PUT(a, x, t) *(t*)(a)=x +#define __LSHL(x, n, t) ((t)((unsigned)(x)<<(n))) +#define __LSHR(x, n, t) ((t)((unsigned)(x)>>(n))) +#define __LSH(x, n, t) ((n)>=0? __LSHL(x, n, t): __LSHR(x, -(n), t)) +#define __ROTL(x, n, t) ((t)((unsigned)(x)<<(n)|(unsigned)(x)>>(8*sizeof(t)-(n)))) +#define __ROTR(x, n, t) ((t)((unsigned)(x)>>(n)|(unsigned)(x)<<(8*sizeof(t)-(n)))) +#define __ROT(x, n, t) ((n)>=0? __ROTL(x, n, t): __ROTR(x, -(n), t)) +#define __BIT(x, n) (*(unsigned long*)(x)>>(n)&1) +#define __MOVE(s, d, n) memcpy((char*)(d),(char*)(s),n) + +/* std procs and operator mappings */ +#define __SHORT(x, y) ((int)((unsigned long)(x)+(y)<(y)+(y)?(x):(__HALT(-8),0))) +#define __SHORTF(x, y) ((int)(__RF((x)+(y),(y)+(y))-(y))) +#define __CHR(x) ((CHAR)__R(x, 256)) +#define __CHRF(x) ((CHAR)__RF(x, 256)) +#define __DIV(x, y) ((x)>=0?(x)/(y):-(((y)-1-(x))/(y))) +#define __DIVF(x, y) SYSTEM_DIV((long)(x),(long)(y)) +#define __MOD(x, y) ((x)>=0?(x)%(y):__MODF(x,y)) +#define __MODF(x, y) SYSTEM_MOD((long)(x),(long)(y)) +#define __NEW(p, t) p=SYSTEM_NEWREC((long)t##__typ) +#define __NEWARR SYSTEM_NEWARR +#define __HALT(x) SYSTEM_HALT(x) +#define __ASSERT(cond, x) if (!(cond)) {SYSTEM_assert = x; SYSTEM_HALT(-1);} +#define __ENTIER(x) SYSTEM_ENTIER(x) +#define __ABS(x) (((x)<0)?-(x):(x)) +#define __ABSF(x) SYSTEM_ABS((long)(x)) +#define __ABSFD(x) SYSTEM_ABSD((double)(x)) +#define __CAP(ch) ((CHAR)((ch)&0x5f)) +#define __ODD(x) ((x)&1) +#define __IN(x, s) (((s)>>(x))&1) +#define __SETOF(x) ((SET)1<<(x)) +#define __SETRNG(l, h) ((~(SET)0<<(l))&~(SET)0>>(8*sizeof(SET)-1-(h))) +#define __MASK(x, m) ((x)&~(m)) +#define __COPY(s, d, n) {char*_a=(void*)s,*_b=(void*)d;long _i=0,_t=n-1;while(_i<_t&&((_b[_i]=_a[_i])!=0)){_i++;};_b[_i]=0;} +static int __STRCMP(x, y) + CHAR *x, *y; +{long i = 0; CHAR ch1, ch2; + do {ch1 = x[i]; ch2 = y[i]; i++; + if (!ch1) return -(int)ch2; + } while (ch1==ch2); + return (int)ch1 - (int)ch2; +} +#define __ASH(x, n) ((n)>=0?__ASHL(x,n):__ASHR(x,-(n))) +#define __ASHL(x, n) ((long)(x)<<(n)) +#define __ASHR(x, n) ((long)(x)>>(n)) +#define __ASHF(x, n) SYSTEM_ASH((long)(x), (long)(n)) +#define __DUP(x, l, t) x=(void*)memcpy(alloca(l*sizeof(t)),x,l*sizeof(t)) +#define __DUPARR(v, t) v=(void*)memcpy(v##__copy,v,sizeof(t)) +#define __DEL(x) /* DUP with alloca frees storage automatically */ +#define __IS(tag, typ, level) (*(tag-(__BASEOFF-level))==(long)typ##__typ) +#define __TYPEOF(p) (*(((long**)(p))-1)) +#define __ISP(p, typ, level) __IS(__TYPEOF(p),typ,level) + +/* runtime checks */ +#define __X(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-2),0)) +#define __XF(i, ub) SYSTEM_XCHK((long)(i), (long)(ub)) +#define __RETCHK __retchk: __HALT(-3) +#define __CASECHK __HALT(-4) +#define __GUARDP(p, typ, level) ((typ*)(__ISP(p,typ,level)?p:(__HALT(-5),p))) +#define __GUARDR(r, typ, level) (*((typ*)(__IS(r##__typ,typ,level)?r:(__HALT(-5),r)))) +#define __GUARDA(p, typ, level) ((struct typ*)(__IS(__TYPEOF(p),typ,level)?p:(__HALT(-5),p))) +#define __GUARDEQR(p, dyntyp, typ) if(dyntyp!=typ##__typ) __HALT(-6);*(p) +#define __GUARDEQP(p, typ) if(__TYPEOF(p)!=typ##__typ)__HALT(-6);*(p) +#define __WITHCHK __HALT(-7) +#define __R(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-8),0)) +#define __RF(i, ub) SYSTEM_RCHK((long)(i),(long)(ub)) + +/* record type descriptors */ +#define __TDESC(t, m, n) \ + static struct t##__desc {\ + long tproc[m]; \ + long tag, next, level, module; \ + char name[24]; \ + long *base[__MAXEXT]; \ + char *rsrvd; \ + long blksz, ptr[n+1]; \ + } t##__desc + +#define __BASEOFF (__MAXEXT+1) +#define __TPROC0OFF (__BASEOFF+24/sizeof(long)+5) +#define __EOM 1 +#define __TDFLDS(name, size) {__EOM}, 1, 0, 0, 0, name, {0}, 0, size +#define __ENUMP(adr, n, P) SYSTEM_ENUMP(adr, (long)(n), P) +#define __ENUMR(adr, typ, size, n, P) SYSTEM_ENUMR(adr, typ, (long)(size), (long)(n), P) + +#define __INITYP(t, t0, level) \ + t##__typ= &t##__desc.blksz; \ + memcpy(t##__desc.base, t0##__typ - __BASEOFF, level*sizeof(long)); \ + t##__desc.base[level]=t##__typ; \ + t##__desc.module=(long)m; \ + if(t##__desc.blksz!=sizeof(struct t)) __HALT(-15); \ + t##__desc.blksz=(t##__desc.blksz+5*sizeof(long)-1)/(4*sizeof(long))*(4*sizeof(long)); \ + SYSTEM_REGTYP(m, (long)&t##__desc.next); \ + SYSTEM_INHERIT(t##__typ, t0##__typ) + +/* Oberon-2 type bound procedures support */ +#define __INITBP(t, proc, num) *(t##__typ-(__TPROC0OFF+num))=(long)proc +#define __SEND(typ, num, funtyp, parlist) ((funtyp)(*(typ-(__TPROC0OFF+num))))parlist + +/* runtime system variables */ +extern LONGINT SYSTEM_argc; +extern LONGINT SYSTEM_argv; +extern void (*SYSTEM_Halt)(); +extern LONGINT SYSTEM_halt; +extern LONGINT SYSTEM_assert; +extern SYSTEM_PTR SYSTEM_modules; +extern LONGINT SYSTEM_heapsize; +extern LONGINT SYSTEM_allocated; +extern LONGINT SYSTEM_lock; +extern SHORTINT SYSTEM_gclock; +extern BOOLEAN SYSTEM_interrupted; + +/* ANSI prototypes; not used so far +static int __STRCMP(CHAR *x, CHAR *y); +void SYSTEM_INIT(int argc, long argvadr); +void SYSTEM_FINI(void); +long SYSTEM_XCHK(long i, long ub); +long SYSTEM_RCHK(long i, long ub); +long SYSTEM_ASH(long i, long n); +long SYSTEM_ABS(long i); +double SYSTEM_ABSD(double i); +void SYSTEM_INHERIT(long *t, long *t0); +void SYSTEM_ENUMP(long *adr, long n, void (*P)(void*)); +void SYSTEM_ENUMR(char *adr, long *typ, long size, long n, void (*P)(void*)); +long SYSTEM_DIV(unsigned long x, unsigned long y); +long SYSTEM_MOD(unsigned long x, unsigned long y); +long SYSTEM_ENTIER(double x); +void SYSTEM_HALT(int n); +*/ + +#endif + diff --git a/src/lib/system/linux/clang/armv6j/Unix.Mod b/src/lib/system/linux/clang/armv6j/Unix.Mod new file mode 100644 index 00000000..9e46278e --- /dev/null +++ b/src/lib/system/linux/clang/armv6j/Unix.Mod @@ -0,0 +1,419 @@ +MODULE Unix; (* Josef Templ, 5.3.90 Linux system calls *) +(* system procedure added by noch *) +(* Module Unix provides a system call interface to Linux. + Naming conventions: + Procedure and Type-names always start with a capital letter. + error numbers as defined in Unix + other constants start with lower case letters *) + +IMPORT SYSTEM; + +CONST + +(* various important constants *) + + stdin* = 0; stdout* =1; stderr* = 2; + + LOCKEX* = 2; LOCKUN* = 8; (* /usr/include/file.h *) + AFINET* = 2; (* /usr/include/sys/socket.h *) + PFINET* = AFINET; (* /usr/include/linux/socket.h *) + SOCKSTREAM* = 1; (* /usr/include/linux/socket.h *) + FIONREAD* = 541BH; (* in /usr/include/asm/termios.h *) + SETFL* = 4; (* set file descriptor flags; in asm/fcntl.h *) + TCP* = 0; + +(* flag sets, cf. /usr/include/asm/fcntl.h *) + rdonly* = {}; wronly* = {0}; rdwr* = {1}; creat* = {6}; excl* = {7}; trunc* = {9}; append* = {10}; ndelay = {11}; + +(* error numbers *) + + EPERM* = 1; (* Not owner *) + ENOENT* = 2; (* No such file or directory *) + ESRCH* = 3; (* No such process *) + EINTR* = 4; (* Interrupted system call *) + EIO* = 5; (* I/O error *) + ENXIO* = 6; (* No such device or address *) + E2BIG* = 7; (* Arg list too long *) + ENOEXEC* = 8; (* Exec format error *) + EBADF* = 9; (* Bad file number *) + ECHILD* = 10; (* No children *) + EAGAIN* = 11; (* No more processes *) + ENOMEM* = 12; (* Not enough core *) + EACCES* = 13; (* Permission denied *) + EFAULT* = 14; (* Bad address *) + ENOTBLK* = 15; (* Block device required *) + EBUSY* = 16; (* Mount device busy *) + EEXIST* = 17; (* File exists *) + EXDEV* = 18; (* Cross-device link *) + ENODEV* = 19; (* No such device *) + ENOTDIR* = 20; (* Not a directory*) + EISDIR* = 21; (* Is a directory *) + EINVAL* = 22; (* Invalid argument *) + ENFILE* = 23; (* File table overflow *) + EMFILE* = 24; (* Too many open files *) + ENOTTY* = 25; (* Not a typewriter *) + ETXTBSY* = 26; (* Text file busy *) + EFBIG* = 27; (* File too large *) + ENOSPC* = 28; (* No space left on device *) + ESPIPE* = 29; (* Illegal seek *) + EROFS* = 30; (* Read-only file system *) + EMLINK* = 31; (* Too many links *) + EPIPE* = 32; (* Broken pipe *) + EDOM* = 33; (* Argument too large *) + ERANGE* = 34; (* Result too large *) + EDEADLK* = 35; (* Resource deadlock would occur *) + ENAMETOOLONG* = 36; (* File name too long *) + ENOLCK* = 37; (* No record locks available *) + ENOSYS* = 38; (* Function not implemented *) + ENOTEMPTY* = 39; (* Directory not empty *) + ELOOP* = 40; (* Too many symbolic links encountered *) + EWOULDBLOCK* = EAGAIN; (* Operation would block *) + ENOMSG* = 42; (* No message of desired type *) + EIDRM* = 43; (* Identifier removed *) + ECHRNG* = 44; (* Channel number out of range *) + EL2NSYNC* = 45; (* Level 2 not synchronized *) + EL3HLT* = 46; (* Level 3 halted *) + EL3RST* = 47; (* Level 3 reset *) + ELNRNG* = 48; (* Link number out of range *) + EUNATCH* = 49; (* Protocol driver not attached *) + ENOCSI* = 50; (* No CSI structure available *) + EL2HLT* = 51; (* Level 2 halted *) + EBADE* = 52; (* Invalid exchange *) + EBADR* = 53; (* Invalid request descriptor *) + EXFULL* = 54; (* Exchange full *) + ENOANO* = 55; (* No anode *) + EBADRQC* = 56; (* Invalid request code *) + EBADSLT* = 57; (* Invalid slot *) + EDEADLOCK* = 58; (* File locking deadlock error *) + EBFONT* = 59; (* Bad font file format *) + ENOSTR* = 60; (* Device not a stream *) + ENODATA* = 61; (* No data available *) + ETIME* = 62; (* Timer expired *) + ENOSR* = 63; (* Out of streams resources *) + ENONET* = 64; (* Machine is not on the network *) + ENOPKG* = 65; (* Package not installed *) + EREMOTE* = 66; (* Object is remote *) + ENOLINK* = 67; (* Link has been severed *) + EADV* = 68; (* Advertise error *) + ESRMNT* = 69; (* Srmount error *) + ECOMM* = 70; (* Communication error on send *) + EPROTO* = 71; (* Protocol error *) + EMULTIHOP* = 72; (* Multihop attempted *) + EDOTDOT* = 73; (* RFS specific error *) + EBADMSG* = 74; (* Not a data message *) + EOVERFLOW* = 75; (* Value too large for defined data type *) + ENOTUNIQ* = 76; (* Name not unique on network *) + EBADFD* = 77; (* File descriptor in bad state *) + EREMCHG* = 78; (* Remote address changed *) + ELIBACC* = 79; (* Can not access a needed shared library *) + ELIBBAD* = 80; (* Accessing a corrupted shared library *) + ELIBSCN* = 81; (* .lib section in a.out corrupted *) + ELIBMAX* = 82; (* Attempting to link in too many shared libraries *) + ELIBEXEC* = 83; (* Cannot exec a shared library directly *) + EILSEQ* = 84; (* Illegal byte sequence *) + ERESTART* = 85; (* Interrupted system call should be restarted *) + ESTRPIPE* = 86; (* Streams pipe error *) + EUSERS* = 87; (* Too many users *) + ENOTSOCK* = 88; (* Socket operation on non-socket *) + EDESTADDRREQ* = 89; (* Destination address required *) + EMSGSIZE* = 90; (* Message too long *) + EPROTOTYPE* = 91; (* Protocol wrong type for socket *) + ENOPROTOOPT* = 92; (* Protocol not available *) + EPROTONOSUPPORT* = 93; (* Protocol not supported *) + ESOCKTNOSUPPORT* = 94; (* Socket type not supported *) + EOPNOTSUPP* = 95; (* Operation not supported on transport endpoint *) + EPFNOSUPPORT* = 96; (* Protocol family not supported *) + EAFNOSUPPORT* = 97; (* Address family not supported by protocol *) + EADDRINUSE* = 98; (* Address already in use *) + EADDRNOTAVAIL* = 99; (* Cannot assign requested address *) + ENETDOWN* = 100; (* Network is down *) + ENETUNREACH* = 101; (* Network is unreachable *) + ENETRESET* = 102; (* Network dropped connection because of reset *) + ECONNABORTED* = 103; (* Software caused connection abort *) + ECONNRESET* = 104; (* Connection reset by peer *) + ENOBUFS* = 105; (* No buffer space available *) + EISCONN* = 106; (* Transport endpoint is already connected *) + ENOTCONN* = 107; (* Transport endpoint is not connected *) + ESHUTDOWN* = 108; (* Cannot send after transport endpoint shutdown *) + ETOOMANYREFS* = 109; (* Too many references: cannot splice *) + ETIMEDOUT* = 110; (* Connection timed out *) + ECONNREFUSED* = 111; (* Connection refused *) + EHOSTDOWN* = 112; (* Host is down *) + EHOSTUNREACH* = 113; (* No route to host *) + EALREADY* = 114; (* Operation already in progress *) + EINPROGRESS* = 115; (* Operation now in progress *) + ESTALE* = 116; (* Stale NFS file handle *) + EUCLEAN* = 117; (* Structure needs cleaning *) + ENOTNAM* = 118; (* Not a XENIX named type file *) + ENAVAIL* = 119; (* No XENIX semaphores available *) + EISNAM* = 120; (* Is a named type file *) + EREMOTEIO* = 121; (* Remote I/O error *) + EDQUOT* = 122; (* Quota exceeded *) + + +TYPE + JmpBuf* = RECORD + bx*, si*, di*, bp*, sp*, pc*: LONGINT; + maskWasSaved*, savedMask*: LONGINT; + END ; + + Status* = RECORD (* struct stat *) + dev*, devX*: LONGINT; (* 64 bit in Linux 2.2 *) + pad1: INTEGER; + ino*, mode*, nlink*, uid*, gid*: LONGINT; + rdev*, rdevX*: LONGINT; (* 64 bit in Linux 2.2 *) + pad2: INTEGER; + size*, blksize*, blocks*, atime*, unused1*, mtime*, unused2*, ctime*, + unused3*, unused4*, unused5*: LONGINT; + END ; + + Timeval* = RECORD + sec*, usec*: LONGINT + END ; + + Timezone* = RECORD + minuteswest*, dsttime*: LONGINT + END ; + + Itimerval* = RECORD + interval*, value*: Timeval + END ; + + FdSet* = ARRAY 8 OF SET; + + SigCtxPtr* = POINTER TO SigContext; + SigContext* = RECORD + END ; + + SignalHandler* = PROCEDURE (sig, code: LONGINT; scp: SigCtxPtr); + + Dirent* = RECORD + ino, off: LONGINT; + reclen: INTEGER; + name: ARRAY 256 OF CHAR; + END ; + + Rusage* = RECORD + utime*, stime*: Timeval; + maxrss*, ixrss*, idrss*, isrss*, + minflt*, majflt*, nswap*, inblock*, + oublock*, msgsnd*, msgrcv*, nsignals*, + nvcsw*, nivcsw*: LONGINT + END ; + + Iovec* = RECORD + base*, len*: LONGINT + END ; + + SocketPair* = ARRAY 2 OF LONGINT; + + Pollfd* = RECORD + fd*: LONGINT; + events*, revents*: INTEGER + END ; + + Sockaddr* = RECORD + family*: INTEGER; + port*: INTEGER; + internetAddr*: LONGINT; + pad*: ARRAY 8 OF CHAR; + END ; + + HostEntry* = POINTER [1] TO Hostent; + Hostent* = RECORD + name*, aliases*: LONGINT; + addrtype*, length*: LONGINT; + addrlist*: LONGINT; (*POINTER TO POINTER TO LONGINT, network byte order*) + END; + + Name* = ARRAY OF CHAR; + + PROCEDURE -includeStat() + "#include "; + + PROCEDURE -includeErrno() + "#include "; + + PROCEDURE -err(): LONGINT + "errno"; + + PROCEDURE errno*(): LONGINT; + BEGIN + RETURN err() + END errno; + + PROCEDURE -Exit*(n: LONGINT) + "exit(n)"; + + PROCEDURE -Fork*(): LONGINT + "fork()"; + + PROCEDURE -Wait*(VAR status: LONGINT): LONGINT + "wait(status)"; + + PROCEDURE -Select*(width: LONGINT; VAR readfds, writefds, exceptfds: FdSet; VAR timeout: Timeval): LONGINT + "select(width, readfds, writefds, exceptfds, timeout)"; + + PROCEDURE -Gettimeofday* (VAR tv: Timeval; VAR tz: Timezone) : LONGINT + "gettimeofday(tv, tz)"; + + PROCEDURE -Read* (fd, buf, nbyte: LONGINT): LONGINT + "read(fd, buf, nbyte)"; + + PROCEDURE -ReadBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "read(fd, buf, buf__len)"; + + PROCEDURE -Write* (fd, buf, nbyte: LONGINT): LONGINT + "write(fd, buf, nbyte)"; + + PROCEDURE -WriteBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "write(fd, buf, buf__len)"; + + PROCEDURE -Dup*(fd: LONGINT): LONGINT + "dup(fd)"; + + PROCEDURE -Dup2*(fd1, fd2: LONGINT): LONGINT + "dup(fd1, fd2)"; + + PROCEDURE -Pipe*(fds : LONGINT): LONGINT + "pipe(fds)"; + + PROCEDURE -Getpid*(): LONGINT + "getpid()"; + + PROCEDURE -Getuid*(): LONGINT + "getuid()"; + + PROCEDURE -Geteuid*(): LONGINT + "geteuid()"; + + PROCEDURE -Getgid*(): LONGINT + "getgid()"; + + PROCEDURE -Getegid*(): LONGINT + "getegid()"; + + PROCEDURE -Unlink*(name: Name): LONGINT + "unlink(name)"; + + PROCEDURE -Open*(name: Name; flag, mode: SET): LONGINT + "open(name, flag, mode)"; + + PROCEDURE -Close*(fd: LONGINT): LONGINT + "close(fd)"; + + PROCEDURE -stat(name: Name; VAR statbuf: Status): LONGINT + "stat((const char*)name, (struct stat*)statbuf)"; + + PROCEDURE Stat*(name: Name; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := stat(name, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); + RETURN res; + END Stat; + + PROCEDURE -fstat(fd: LONGINT; VAR statbuf: Status): LONGINT + "fstat(fd, (struct stat*)statbuf)"; + + PROCEDURE Fstat*(fd: LONGINT; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := fstat(fd, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); + RETURN res; + END Fstat; + + PROCEDURE -Fchmod*(fd, mode: LONGINT): LONGINT + "fchmod(fd, mode)"; + + PROCEDURE -Chmod*(path: Name; mode: LONGINT): LONGINT + "chmod(path, mode)"; + + PROCEDURE -Lseek*(fd, offset, origin: LONGINT): LONGINT + "lseek(fd, offset, origin)"; + + PROCEDURE -Fsync*(fd: LONGINT): LONGINT + "fsync(fd)"; + + PROCEDURE -Fcntl*(fd, cmd, arg: LONGINT ): LONGINT + "fcntl(fd, cmd, arg)"; + + PROCEDURE -Flock*(fd, operation: LONGINT): LONGINT + "flock(fd, operation)"; + + PROCEDURE -Ftruncate*(fd, length: LONGINT): LONGINT + "ftruncate(fd, length)"; + + PROCEDURE -Readblk*(fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE; len: LONGINT): LONGINT + "read(fd, buf, len)"; + + PROCEDURE -Rename*(old, new: Name): LONGINT + "rename(old, new)"; + + PROCEDURE -Chdir*(path: Name): LONGINT + "chdir(path)"; + + PROCEDURE -Ioctl*(fd, request, arg: LONGINT): LONGINT + "ioctl(fd, request, arg)"; + + PROCEDURE -Kill*(pid, sig: LONGINT): LONGINT + "kill(pid, sig)"; + + PROCEDURE -Sigsetmask*(mask: LONGINT): LONGINT + "sigsetmask(mask)"; + + + (* TCP/IP networking *) + + PROCEDURE -Gethostbyname*(name: Name): HostEntry + "(Unix_HostEntry)gethostbyname(name)"; + + PROCEDURE -Gethostname*(VAR name: Name): LONGINT + "gethostname(name, name__len)"; + + PROCEDURE -Socket*(af, type, protocol: LONGINT): LONGINT + "socket(af, type, protocol)"; + + PROCEDURE -Connect*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "connect(socket, &(name), namelen)"; + + PROCEDURE -Getsockname*(socket: LONGINT; VAR name: Sockaddr; VAR namelen: LONGINT): LONGINT + "getsockname(socket, name, namelen)"; + + PROCEDURE -Bind*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "bind(socket, &(name), namelen)"; + + PROCEDURE -Listen*(socket, backlog: LONGINT): LONGINT + "listen(socket, backlog)"; + + PROCEDURE -Accept*(socket: LONGINT; VAR addr: Sockaddr; VAR addrlen: LONGINT): LONGINT + "accept(socket, addr, addrlen)"; + + PROCEDURE -Recv*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "recv(socket, bufadr, buflen, flags)"; + + PROCEDURE -Send*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "send(socket, bufadr, buflen, flags)"; + + PROCEDURE -sys(str: ARRAY OF CHAR): INTEGER (* need this to call external tools like gcc or gas; noch *) + "system(str)"; + + PROCEDURE system*(cmd : ARRAY OF CHAR); + VAR r : INTEGER; + BEGIN + r := sys(cmd); + END system; + + PROCEDURE System*(cmd : ARRAY OF CHAR): INTEGER; + VAR r : INTEGER; + BEGIN + r := sys(cmd); + RETURN r + END System; + +END Unix. diff --git a/src/lib/system/linux/clang/armv6j_hardfp/Args.Mod b/src/lib/system/linux/clang/armv6j_hardfp/Args.Mod new file mode 100644 index 00000000..e8cd2a3c --- /dev/null +++ b/src/lib/system/linux/clang/armv6j_hardfp/Args.Mod @@ -0,0 +1,64 @@ +MODULE Args; (* jt, 8.12.94 *) + + (* command line argument handling for ofront *) + + + IMPORT SYSTEM; + + TYPE + ArgPtr = POINTER TO ARRAY 1024 OF CHAR; + ArgVec = POINTER TO ARRAY 1024 OF ArgPtr; + + VAR argc-, argv-: LONGINT; + + PROCEDURE -Argc(): INTEGER "SYSTEM_argc"; + PROCEDURE -Argv(): LONGINT "(long)SYSTEM_argv"; + PROCEDURE -getenv(var: ARRAY OF CHAR): ArgPtr + "(Args_ArgPtr)getenv(var)"; + + PROCEDURE Get*(n: INTEGER; VAR val: ARRAY OF CHAR); + VAR av: ArgVec; + BEGIN + IF n < argc THEN av := SYSTEM.VAL(ArgVec, argv); COPY(av[n]^, val) END + END Get; + + PROCEDURE GetInt*(n: INTEGER; VAR val: LONGINT); + VAR s: ARRAY 64 OF CHAR; k, d, i: LONGINT; + BEGIN + s := ""; Get(n, s); i := 0; + IF s[0] = "-" THEN i := 1 END ; + k := 0; d := ORD(s[i]) - ORD("0"); + WHILE (d >= 0 ) & (d <= 9) DO k := k*10 + d; INC(i); d := ORD(s[i]) - ORD("0") END ; + IF s[0] = "-" THEN d := -d; DEC(i) END ; + IF i > 0 THEN val := k END + END GetInt; + + PROCEDURE Pos*(s: ARRAY OF CHAR): INTEGER; + VAR i: INTEGER; arg: ARRAY 256 OF CHAR; + BEGIN + i := 0; Get(i, arg); + WHILE (i < argc) & (s # arg) DO INC(i); Get(i, arg) END ; + RETURN i + END Pos; + + PROCEDURE GetEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR); + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN COPY(p^, val) END + END GetEnv; + + PROCEDURE getEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR): BOOLEAN; + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN + COPY(p^, val); + RETURN TRUE + ELSE + RETURN FALSE + END + END getEnv; + +BEGIN argc := Argc(); argv := Argv() +END Args. diff --git a/src/lib/system/linux/clang/armv6j_hardfp/SYSTEM.c0 b/src/lib/system/linux/clang/armv6j_hardfp/SYSTEM.c0 new file mode 100644 index 00000000..580449aa --- /dev/null +++ b/src/lib/system/linux/clang/armv6j_hardfp/SYSTEM.c0 @@ -0,0 +1,205 @@ +/* +* The body prefix file of the Ofront runtime system, Version 1.0 +* +* Copyright (c) Software Templ, 1994, 1995 +* +* Module SYSTEM is subject to change any time without prior notification. +* Software Templ disclaims all warranties with regard to module SYSTEM, +* in particular shall Software Templ not be liable for any damage resulting +* from inappropriate use or modification of module SYSTEM. +* +* Version 1.1 jt, 24.11.95 fixes for correct pointer arithmetic on Cray computers +* jt 31.1.2007 ANSI prototypes for malloc and exit in order to avoid cc warnings +* +*/ + +#include "SYSTEM.h" +#ifdef __STDC__ +#include "stdarg.h" +#else +#include "varargs.h" +#endif + +extern void *malloc(long size); +extern void exit(int status); + +void (*SYSTEM_Halt)(); +LONGINT SYSTEM_halt; /* x in HALT(x) */ +LONGINT SYSTEM_assert; /* x in ASSERT(cond, x) */ +LONGINT SYSTEM_argc; +LONGINT SYSTEM_argv; +LONGINT SYSTEM_lock; +BOOLEAN SYSTEM_interrupted; +static LONGINT SYSTEM_mainfrm; /* adr of main proc stack frame, used for stack collection */ + +#define Lock SYSTEM_lock++ +#define Unlock SYSTEM_lock--; if (SYSTEM_interrupted && (SYSTEM_lock == 0)) __HALT(-9) + + +static void SYSTEM_InitHeap(); +void *SYSTEM__init(); + +void SYSTEM_INIT(argc, argvadr) + int argc; long argvadr; +{ + SYSTEM_mainfrm = argvadr; + SYSTEM_argc = argc; + SYSTEM_argv = *(long*)argvadr; + SYSTEM_InitHeap(); + SYSTEM_halt = -128; + SYSTEM__init(); +} + +void SYSTEM_FINI() +{ + SYSTEM_FINALL(); +} + +long SYSTEM_XCHK(i, ub) long i, ub; {return __X(i, ub);} +long SYSTEM_RCHK(i, ub) long i, ub; {return __R(i, ub);} +long SYSTEM_ASH(i, n) long i, n; {return __ASH(i, n);} +long SYSTEM_ABS(i) long i; {return __ABS(i);} +double SYSTEM_ABSD(i) double i; {return __ABS(i);} + +void SYSTEM_INHERIT(t, t0) + long *t, *t0; +{ + t -= __TPROC0OFF; + t0 -= __TPROC0OFF; + while (*t0 != __EOM) {*t = *t0; t--; t0--;} +} + +void SYSTEM_ENUMP(adr, n, P) + long *adr; + long n; + void (*P)(); +{ + while (n > 0) {P(*adr); adr++; n--;} +} + +void SYSTEM_ENUMR(adr, typ, size, n, P) + char *adr; + long *typ, size, n; + void (*P)(); +{ + long *t, off; + typ++; + while (n > 0) { + t = typ; + off = *t; + while (off >= 0) {P(*(long*)(adr+off)); t++; off = *t;} + adr += size; n--; + } +} + +long SYSTEM_DIV(x, y) + unsigned long x, y; +{ if ((long) x >= 0) return (x / y); + else return -((y - 1 - x) / y); +} + +long SYSTEM_MOD(x, y) + unsigned long x, y; +{ unsigned long m; + if ((long) x >= 0) return (x % y); + else { m = (-x) % y; + if (m != 0) return (y - m); else return 0; + } +} + +long SYSTEM_ENTIER(x) + double x; +{ + long y; + if (x >= 0) + return (long)x; + else { + y = (long)x; + if (y <= x) return y; else return y - 1; + } +} + +void SYSTEM_HALT(n) + int n; +{ + SYSTEM_halt = n; + if (SYSTEM_Halt!=0) SYSTEM_Halt(n); + exit(n); +} + +#ifdef __STDC__ +SYSTEM_PTR SYSTEM_NEWARR(long *typ, long elemsz, int elemalgn, int nofdim, int nofdyn, ...) +#else +SYSTEM_PTR SYSTEM_NEWARR(typ, elemsz, elemalgn, nofdim, nofdyn, va_alist) + long *typ, elemsz; + int elemalgn, nofdim, nofdyn; + va_dcl +#endif +{ + long nofelems, size, dataoff, n, nptr, *x, *p, nofptrs, i, *ptab, off; + va_list ap; +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + nofelems = 1; + while (nofdim > 0) { + nofelems = nofelems * va_arg(ap, long); nofdim--; + if (nofelems <= 0) __HALT(-20); + } + va_end(ap); + dataoff = nofdyn * sizeof(long); + if (elemalgn > sizeof(long)) { + n = dataoff % elemalgn; + if (n != 0) dataoff += elemalgn - n; + } + size = dataoff + nofelems * elemsz; + Lock; + if (typ == NIL) { + /* element typ does not contain pointers */ + x = SYSTEM_NEWBLK(size); + } + else if (typ == POINTER__typ) { + /* element type is a pointer */ + x = SYSTEM_NEWBLK(size + nofelems * sizeof(long)); + p = (long*)x[-1]; + p[-nofelems] = *p; /* build new type desc in situ: 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nofelems - 1; n = 1; /* n =1 for skipping the size field */ + while (n <= nofelems) {*p = n*sizeof(long); p++; n++;} + *p = - (nofelems + 1) * sizeof(long); /* sentinel */ + x[-1] -= nofelems * sizeof(long); + } + else { + /* element type is a record that contains pointers */ + ptab = typ + 1; nofptrs = 0; + while (ptab[nofptrs] >= 0) {nofptrs++;} /* number of pointers per element */ + nptr = nofelems * nofptrs; /* total number of pointers */ + x = SYSTEM_NEWBLK(size + nptr * sizeof(long)); + p = (long*)x[- 1]; + p[-nptr] = *p; /* build new type desc in situ; 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nptr - 1; n = 0; off = dataoff; + while (n < nofelems) {i = 0; + while (i < nofptrs) {*p = off + ptab[i]; p++; i++;} + off += elemsz; n++; + } + *p = - (nptr + 1) * sizeof(long); /* sentinel */ + x[-1] -= nptr * sizeof(long); + } + if (nofdyn != 0) { + /* setup len vector for index checks */ +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + p = x; + while (nofdyn > 0) {*p = va_arg(ap, long); p++, nofdyn--;} + va_end(ap); + } + Unlock; + return x; +} + +/* ----------- end of SYSTEM.co ------------- */ + diff --git a/src/lib/system/linux/clang/armv6j_hardfp/SYSTEM.h b/src/lib/system/linux/clang/armv6j_hardfp/SYSTEM.h new file mode 100644 index 00000000..719a6d18 --- /dev/null +++ b/src/lib/system/linux/clang/armv6j_hardfp/SYSTEM.h @@ -0,0 +1,215 @@ +#ifndef SYSTEM__h +#define SYSTEM__h + +/* + +the Ofront runtime system interface and macros library +copyright (c) Josef Templ, 1995, 1996 + +gcc for Linux version (same as SPARC/Solaris2) +uses double # as concatenation operator + +*/ + +#include + +//extern void *memcpy(void *dest, const void *src, long n); +extern void *memcpy(void *dest, const void *src, size_t n); +extern void *malloc(long size); +extern void exit(int status); + +#define export +#define import extern + +/* constants */ +#define __MAXEXT 16 +#define NIL 0L +#define POINTER__typ (long*)1L /* not NIL and not a valid type */ + +/* basic types */ +typedef char BOOLEAN; +typedef unsigned char CHAR; +typedef signed char SHORTINT; +typedef short int INTEGER; +typedef long LONGINT; +typedef float REAL; +typedef double LONGREAL; +typedef unsigned long SET; +typedef void *SYSTEM_PTR; +typedef unsigned char SYSTEM_BYTE; + +/* runtime system routines */ +extern long SYSTEM_DIV(); +extern long SYSTEM_MOD(); +extern long SYSTEM_ENTIER(); +extern long SYSTEM_ASH(); +extern long SYSTEM_ABS(); +extern long SYSTEM_XCHK(); +extern long SYSTEM_RCHK(); +extern double SYSTEM_ABSD(); +extern SYSTEM_PTR SYSTEM_NEWREC(); +extern SYSTEM_PTR SYSTEM_NEWBLK(); +#ifdef __STDC__ +extern SYSTEM_PTR SYSTEM_NEWARR(long*, long, int, int, int, ...); +#else +extern SYSTEM_PTR SYSTEM_NEWARR(); +#endif +extern SYSTEM_PTR SYSTEM_REGMOD(); +extern void SYSTEM_INCREF(); +extern void SYSTEM_REGCMD(); +extern void SYSTEM_REGTYP(); +extern void SYSTEM_REGFIN(); +extern void SYSTEM_FINALL(); +extern void SYSTEM_INIT(); +extern void SYSTEM_FINI(); +extern void SYSTEM_HALT(); +extern void SYSTEM_INHERIT(); +extern void SYSTEM_ENUMP(); +extern void SYSTEM_ENUMR(); + +/* module registry */ +#define __DEFMOD static void *m; if(m!=0)return m +#define __REGMOD(name, enum) if(m==0)m=SYSTEM_REGMOD((CHAR*)name,enum); else return m +#define __ENDMOD return m +#define __INIT(argc, argv) static void *m; SYSTEM_INIT(argc, (long)&argv); +#define __REGMAIN(name, enum) m=SYSTEM_REGMOD(name,enum) +#define __FINI SYSTEM_FINI(); return 0 +#define __IMPORT(name) SYSTEM_INCREF(name##__init()) +#define __REGCMD(name, cmd) SYSTEM_REGCMD(m, name, cmd) + +/* SYSTEM ops */ +#define __SYSNEW(p, len) p=SYSTEM_NEWBLK((long)(len)) +#define __VAL(t, x) (*(t*)&(x)) +#define __GET(a, x, t) x= *(t*)(a) +#define __PUT(a, x, t) *(t*)(a)=x +#define __LSHL(x, n, t) ((t)((unsigned)(x)<<(n))) +#define __LSHR(x, n, t) ((t)((unsigned)(x)>>(n))) +#define __LSH(x, n, t) ((n)>=0? __LSHL(x, n, t): __LSHR(x, -(n), t)) +#define __ROTL(x, n, t) ((t)((unsigned)(x)<<(n)|(unsigned)(x)>>(8*sizeof(t)-(n)))) +#define __ROTR(x, n, t) ((t)((unsigned)(x)>>(n)|(unsigned)(x)<<(8*sizeof(t)-(n)))) +#define __ROT(x, n, t) ((n)>=0? __ROTL(x, n, t): __ROTR(x, -(n), t)) +#define __BIT(x, n) (*(unsigned long*)(x)>>(n)&1) +#define __MOVE(s, d, n) memcpy((char*)(d),(char*)(s),n) + +/* std procs and operator mappings */ +#define __SHORT(x, y) ((int)((unsigned long)(x)+(y)<(y)+(y)?(x):(__HALT(-8),0))) +#define __SHORTF(x, y) ((int)(__RF((x)+(y),(y)+(y))-(y))) +#define __CHR(x) ((CHAR)__R(x, 256)) +#define __CHRF(x) ((CHAR)__RF(x, 256)) +#define __DIV(x, y) ((x)>=0?(x)/(y):-(((y)-1-(x))/(y))) +#define __DIVF(x, y) SYSTEM_DIV((long)(x),(long)(y)) +#define __MOD(x, y) ((x)>=0?(x)%(y):__MODF(x,y)) +#define __MODF(x, y) SYSTEM_MOD((long)(x),(long)(y)) +#define __NEW(p, t) p=SYSTEM_NEWREC((long)t##__typ) +#define __NEWARR SYSTEM_NEWARR +#define __HALT(x) SYSTEM_HALT(x) +#define __ASSERT(cond, x) if (!(cond)) {SYSTEM_assert = x; SYSTEM_HALT(-1);} +#define __ENTIER(x) SYSTEM_ENTIER(x) +#define __ABS(x) (((x)<0)?-(x):(x)) +#define __ABSF(x) SYSTEM_ABS((long)(x)) +#define __ABSFD(x) SYSTEM_ABSD((double)(x)) +#define __CAP(ch) ((CHAR)((ch)&0x5f)) +#define __ODD(x) ((x)&1) +#define __IN(x, s) (((s)>>(x))&1) +#define __SETOF(x) ((SET)1<<(x)) +#define __SETRNG(l, h) ((~(SET)0<<(l))&~(SET)0>>(8*sizeof(SET)-1-(h))) +#define __MASK(x, m) ((x)&~(m)) +#define __COPY(s, d, n) {char*_a=(void*)s,*_b=(void*)d;long _i=0,_t=n-1;while(_i<_t&&((_b[_i]=_a[_i])!=0)){_i++;};_b[_i]=0;} +static int __STRCMP(x, y) + CHAR *x, *y; +{long i = 0; CHAR ch1, ch2; + do {ch1 = x[i]; ch2 = y[i]; i++; + if (!ch1) return -(int)ch2; + } while (ch1==ch2); + return (int)ch1 - (int)ch2; +} +#define __ASH(x, n) ((n)>=0?__ASHL(x,n):__ASHR(x,-(n))) +#define __ASHL(x, n) ((long)(x)<<(n)) +#define __ASHR(x, n) ((long)(x)>>(n)) +#define __ASHF(x, n) SYSTEM_ASH((long)(x), (long)(n)) +#define __DUP(x, l, t) x=(void*)memcpy(alloca(l*sizeof(t)),x,l*sizeof(t)) +#define __DUPARR(v, t) v=(void*)memcpy(v##__copy,v,sizeof(t)) +#define __DEL(x) /* DUP with alloca frees storage automatically */ +#define __IS(tag, typ, level) (*(tag-(__BASEOFF-level))==(long)typ##__typ) +#define __TYPEOF(p) (*(((long**)(p))-1)) +#define __ISP(p, typ, level) __IS(__TYPEOF(p),typ,level) + +/* runtime checks */ +#define __X(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-2),0)) +#define __XF(i, ub) SYSTEM_XCHK((long)(i), (long)(ub)) +#define __RETCHK __retchk: __HALT(-3) +#define __CASECHK __HALT(-4) +#define __GUARDP(p, typ, level) ((typ*)(__ISP(p,typ,level)?p:(__HALT(-5),p))) +#define __GUARDR(r, typ, level) (*((typ*)(__IS(r##__typ,typ,level)?r:(__HALT(-5),r)))) +#define __GUARDA(p, typ, level) ((struct typ*)(__IS(__TYPEOF(p),typ,level)?p:(__HALT(-5),p))) +#define __GUARDEQR(p, dyntyp, typ) if(dyntyp!=typ##__typ) __HALT(-6);*(p) +#define __GUARDEQP(p, typ) if(__TYPEOF(p)!=typ##__typ)__HALT(-6);*(p) +#define __WITHCHK __HALT(-7) +#define __R(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-8),0)) +#define __RF(i, ub) SYSTEM_RCHK((long)(i),(long)(ub)) + +/* record type descriptors */ +#define __TDESC(t, m, n) \ + static struct t##__desc {\ + long tproc[m]; \ + long tag, next, level, module; \ + char name[24]; \ + long *base[__MAXEXT]; \ + char *rsrvd; \ + long blksz, ptr[n+1]; \ + } t##__desc + +#define __BASEOFF (__MAXEXT+1) +#define __TPROC0OFF (__BASEOFF+24/sizeof(long)+5) +#define __EOM 1 +#define __TDFLDS(name, size) {__EOM}, 1, 0, 0, 0, name, {0}, 0, size +#define __ENUMP(adr, n, P) SYSTEM_ENUMP(adr, (long)(n), P) +#define __ENUMR(adr, typ, size, n, P) SYSTEM_ENUMR(adr, typ, (long)(size), (long)(n), P) + +#define __INITYP(t, t0, level) \ + t##__typ= &t##__desc.blksz; \ + memcpy(t##__desc.base, t0##__typ - __BASEOFF, level*sizeof(long)); \ + t##__desc.base[level]=t##__typ; \ + t##__desc.module=(long)m; \ + if(t##__desc.blksz!=sizeof(struct t)) __HALT(-15); \ + t##__desc.blksz=(t##__desc.blksz+5*sizeof(long)-1)/(4*sizeof(long))*(4*sizeof(long)); \ + SYSTEM_REGTYP(m, (long)&t##__desc.next); \ + SYSTEM_INHERIT(t##__typ, t0##__typ) + +/* Oberon-2 type bound procedures support */ +#define __INITBP(t, proc, num) *(t##__typ-(__TPROC0OFF+num))=(long)proc +#define __SEND(typ, num, funtyp, parlist) ((funtyp)(*(typ-(__TPROC0OFF+num))))parlist + +/* runtime system variables */ +extern LONGINT SYSTEM_argc; +extern LONGINT SYSTEM_argv; +extern void (*SYSTEM_Halt)(); +extern LONGINT SYSTEM_halt; +extern LONGINT SYSTEM_assert; +extern SYSTEM_PTR SYSTEM_modules; +extern LONGINT SYSTEM_heapsize; +extern LONGINT SYSTEM_allocated; +extern LONGINT SYSTEM_lock; +extern SHORTINT SYSTEM_gclock; +extern BOOLEAN SYSTEM_interrupted; + +/* ANSI prototypes; not used so far +static int __STRCMP(CHAR *x, CHAR *y); +void SYSTEM_INIT(int argc, long argvadr); +void SYSTEM_FINI(void); +long SYSTEM_XCHK(long i, long ub); +long SYSTEM_RCHK(long i, long ub); +long SYSTEM_ASH(long i, long n); +long SYSTEM_ABS(long i); +double SYSTEM_ABSD(double i); +void SYSTEM_INHERIT(long *t, long *t0); +void SYSTEM_ENUMP(long *adr, long n, void (*P)(void*)); +void SYSTEM_ENUMR(char *adr, long *typ, long size, long n, void (*P)(void*)); +long SYSTEM_DIV(unsigned long x, unsigned long y); +long SYSTEM_MOD(unsigned long x, unsigned long y); +long SYSTEM_ENTIER(double x); +void SYSTEM_HALT(int n); +*/ + +#endif + diff --git a/src/lib/system/linux/clang/armv6j_hardfp/Unix.Mod b/src/lib/system/linux/clang/armv6j_hardfp/Unix.Mod new file mode 100644 index 00000000..9e46278e --- /dev/null +++ b/src/lib/system/linux/clang/armv6j_hardfp/Unix.Mod @@ -0,0 +1,419 @@ +MODULE Unix; (* Josef Templ, 5.3.90 Linux system calls *) +(* system procedure added by noch *) +(* Module Unix provides a system call interface to Linux. + Naming conventions: + Procedure and Type-names always start with a capital letter. + error numbers as defined in Unix + other constants start with lower case letters *) + +IMPORT SYSTEM; + +CONST + +(* various important constants *) + + stdin* = 0; stdout* =1; stderr* = 2; + + LOCKEX* = 2; LOCKUN* = 8; (* /usr/include/file.h *) + AFINET* = 2; (* /usr/include/sys/socket.h *) + PFINET* = AFINET; (* /usr/include/linux/socket.h *) + SOCKSTREAM* = 1; (* /usr/include/linux/socket.h *) + FIONREAD* = 541BH; (* in /usr/include/asm/termios.h *) + SETFL* = 4; (* set file descriptor flags; in asm/fcntl.h *) + TCP* = 0; + +(* flag sets, cf. /usr/include/asm/fcntl.h *) + rdonly* = {}; wronly* = {0}; rdwr* = {1}; creat* = {6}; excl* = {7}; trunc* = {9}; append* = {10}; ndelay = {11}; + +(* error numbers *) + + EPERM* = 1; (* Not owner *) + ENOENT* = 2; (* No such file or directory *) + ESRCH* = 3; (* No such process *) + EINTR* = 4; (* Interrupted system call *) + EIO* = 5; (* I/O error *) + ENXIO* = 6; (* No such device or address *) + E2BIG* = 7; (* Arg list too long *) + ENOEXEC* = 8; (* Exec format error *) + EBADF* = 9; (* Bad file number *) + ECHILD* = 10; (* No children *) + EAGAIN* = 11; (* No more processes *) + ENOMEM* = 12; (* Not enough core *) + EACCES* = 13; (* Permission denied *) + EFAULT* = 14; (* Bad address *) + ENOTBLK* = 15; (* Block device required *) + EBUSY* = 16; (* Mount device busy *) + EEXIST* = 17; (* File exists *) + EXDEV* = 18; (* Cross-device link *) + ENODEV* = 19; (* No such device *) + ENOTDIR* = 20; (* Not a directory*) + EISDIR* = 21; (* Is a directory *) + EINVAL* = 22; (* Invalid argument *) + ENFILE* = 23; (* File table overflow *) + EMFILE* = 24; (* Too many open files *) + ENOTTY* = 25; (* Not a typewriter *) + ETXTBSY* = 26; (* Text file busy *) + EFBIG* = 27; (* File too large *) + ENOSPC* = 28; (* No space left on device *) + ESPIPE* = 29; (* Illegal seek *) + EROFS* = 30; (* Read-only file system *) + EMLINK* = 31; (* Too many links *) + EPIPE* = 32; (* Broken pipe *) + EDOM* = 33; (* Argument too large *) + ERANGE* = 34; (* Result too large *) + EDEADLK* = 35; (* Resource deadlock would occur *) + ENAMETOOLONG* = 36; (* File name too long *) + ENOLCK* = 37; (* No record locks available *) + ENOSYS* = 38; (* Function not implemented *) + ENOTEMPTY* = 39; (* Directory not empty *) + ELOOP* = 40; (* Too many symbolic links encountered *) + EWOULDBLOCK* = EAGAIN; (* Operation would block *) + ENOMSG* = 42; (* No message of desired type *) + EIDRM* = 43; (* Identifier removed *) + ECHRNG* = 44; (* Channel number out of range *) + EL2NSYNC* = 45; (* Level 2 not synchronized *) + EL3HLT* = 46; (* Level 3 halted *) + EL3RST* = 47; (* Level 3 reset *) + ELNRNG* = 48; (* Link number out of range *) + EUNATCH* = 49; (* Protocol driver not attached *) + ENOCSI* = 50; (* No CSI structure available *) + EL2HLT* = 51; (* Level 2 halted *) + EBADE* = 52; (* Invalid exchange *) + EBADR* = 53; (* Invalid request descriptor *) + EXFULL* = 54; (* Exchange full *) + ENOANO* = 55; (* No anode *) + EBADRQC* = 56; (* Invalid request code *) + EBADSLT* = 57; (* Invalid slot *) + EDEADLOCK* = 58; (* File locking deadlock error *) + EBFONT* = 59; (* Bad font file format *) + ENOSTR* = 60; (* Device not a stream *) + ENODATA* = 61; (* No data available *) + ETIME* = 62; (* Timer expired *) + ENOSR* = 63; (* Out of streams resources *) + ENONET* = 64; (* Machine is not on the network *) + ENOPKG* = 65; (* Package not installed *) + EREMOTE* = 66; (* Object is remote *) + ENOLINK* = 67; (* Link has been severed *) + EADV* = 68; (* Advertise error *) + ESRMNT* = 69; (* Srmount error *) + ECOMM* = 70; (* Communication error on send *) + EPROTO* = 71; (* Protocol error *) + EMULTIHOP* = 72; (* Multihop attempted *) + EDOTDOT* = 73; (* RFS specific error *) + EBADMSG* = 74; (* Not a data message *) + EOVERFLOW* = 75; (* Value too large for defined data type *) + ENOTUNIQ* = 76; (* Name not unique on network *) + EBADFD* = 77; (* File descriptor in bad state *) + EREMCHG* = 78; (* Remote address changed *) + ELIBACC* = 79; (* Can not access a needed shared library *) + ELIBBAD* = 80; (* Accessing a corrupted shared library *) + ELIBSCN* = 81; (* .lib section in a.out corrupted *) + ELIBMAX* = 82; (* Attempting to link in too many shared libraries *) + ELIBEXEC* = 83; (* Cannot exec a shared library directly *) + EILSEQ* = 84; (* Illegal byte sequence *) + ERESTART* = 85; (* Interrupted system call should be restarted *) + ESTRPIPE* = 86; (* Streams pipe error *) + EUSERS* = 87; (* Too many users *) + ENOTSOCK* = 88; (* Socket operation on non-socket *) + EDESTADDRREQ* = 89; (* Destination address required *) + EMSGSIZE* = 90; (* Message too long *) + EPROTOTYPE* = 91; (* Protocol wrong type for socket *) + ENOPROTOOPT* = 92; (* Protocol not available *) + EPROTONOSUPPORT* = 93; (* Protocol not supported *) + ESOCKTNOSUPPORT* = 94; (* Socket type not supported *) + EOPNOTSUPP* = 95; (* Operation not supported on transport endpoint *) + EPFNOSUPPORT* = 96; (* Protocol family not supported *) + EAFNOSUPPORT* = 97; (* Address family not supported by protocol *) + EADDRINUSE* = 98; (* Address already in use *) + EADDRNOTAVAIL* = 99; (* Cannot assign requested address *) + ENETDOWN* = 100; (* Network is down *) + ENETUNREACH* = 101; (* Network is unreachable *) + ENETRESET* = 102; (* Network dropped connection because of reset *) + ECONNABORTED* = 103; (* Software caused connection abort *) + ECONNRESET* = 104; (* Connection reset by peer *) + ENOBUFS* = 105; (* No buffer space available *) + EISCONN* = 106; (* Transport endpoint is already connected *) + ENOTCONN* = 107; (* Transport endpoint is not connected *) + ESHUTDOWN* = 108; (* Cannot send after transport endpoint shutdown *) + ETOOMANYREFS* = 109; (* Too many references: cannot splice *) + ETIMEDOUT* = 110; (* Connection timed out *) + ECONNREFUSED* = 111; (* Connection refused *) + EHOSTDOWN* = 112; (* Host is down *) + EHOSTUNREACH* = 113; (* No route to host *) + EALREADY* = 114; (* Operation already in progress *) + EINPROGRESS* = 115; (* Operation now in progress *) + ESTALE* = 116; (* Stale NFS file handle *) + EUCLEAN* = 117; (* Structure needs cleaning *) + ENOTNAM* = 118; (* Not a XENIX named type file *) + ENAVAIL* = 119; (* No XENIX semaphores available *) + EISNAM* = 120; (* Is a named type file *) + EREMOTEIO* = 121; (* Remote I/O error *) + EDQUOT* = 122; (* Quota exceeded *) + + +TYPE + JmpBuf* = RECORD + bx*, si*, di*, bp*, sp*, pc*: LONGINT; + maskWasSaved*, savedMask*: LONGINT; + END ; + + Status* = RECORD (* struct stat *) + dev*, devX*: LONGINT; (* 64 bit in Linux 2.2 *) + pad1: INTEGER; + ino*, mode*, nlink*, uid*, gid*: LONGINT; + rdev*, rdevX*: LONGINT; (* 64 bit in Linux 2.2 *) + pad2: INTEGER; + size*, blksize*, blocks*, atime*, unused1*, mtime*, unused2*, ctime*, + unused3*, unused4*, unused5*: LONGINT; + END ; + + Timeval* = RECORD + sec*, usec*: LONGINT + END ; + + Timezone* = RECORD + minuteswest*, dsttime*: LONGINT + END ; + + Itimerval* = RECORD + interval*, value*: Timeval + END ; + + FdSet* = ARRAY 8 OF SET; + + SigCtxPtr* = POINTER TO SigContext; + SigContext* = RECORD + END ; + + SignalHandler* = PROCEDURE (sig, code: LONGINT; scp: SigCtxPtr); + + Dirent* = RECORD + ino, off: LONGINT; + reclen: INTEGER; + name: ARRAY 256 OF CHAR; + END ; + + Rusage* = RECORD + utime*, stime*: Timeval; + maxrss*, ixrss*, idrss*, isrss*, + minflt*, majflt*, nswap*, inblock*, + oublock*, msgsnd*, msgrcv*, nsignals*, + nvcsw*, nivcsw*: LONGINT + END ; + + Iovec* = RECORD + base*, len*: LONGINT + END ; + + SocketPair* = ARRAY 2 OF LONGINT; + + Pollfd* = RECORD + fd*: LONGINT; + events*, revents*: INTEGER + END ; + + Sockaddr* = RECORD + family*: INTEGER; + port*: INTEGER; + internetAddr*: LONGINT; + pad*: ARRAY 8 OF CHAR; + END ; + + HostEntry* = POINTER [1] TO Hostent; + Hostent* = RECORD + name*, aliases*: LONGINT; + addrtype*, length*: LONGINT; + addrlist*: LONGINT; (*POINTER TO POINTER TO LONGINT, network byte order*) + END; + + Name* = ARRAY OF CHAR; + + PROCEDURE -includeStat() + "#include "; + + PROCEDURE -includeErrno() + "#include "; + + PROCEDURE -err(): LONGINT + "errno"; + + PROCEDURE errno*(): LONGINT; + BEGIN + RETURN err() + END errno; + + PROCEDURE -Exit*(n: LONGINT) + "exit(n)"; + + PROCEDURE -Fork*(): LONGINT + "fork()"; + + PROCEDURE -Wait*(VAR status: LONGINT): LONGINT + "wait(status)"; + + PROCEDURE -Select*(width: LONGINT; VAR readfds, writefds, exceptfds: FdSet; VAR timeout: Timeval): LONGINT + "select(width, readfds, writefds, exceptfds, timeout)"; + + PROCEDURE -Gettimeofday* (VAR tv: Timeval; VAR tz: Timezone) : LONGINT + "gettimeofday(tv, tz)"; + + PROCEDURE -Read* (fd, buf, nbyte: LONGINT): LONGINT + "read(fd, buf, nbyte)"; + + PROCEDURE -ReadBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "read(fd, buf, buf__len)"; + + PROCEDURE -Write* (fd, buf, nbyte: LONGINT): LONGINT + "write(fd, buf, nbyte)"; + + PROCEDURE -WriteBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "write(fd, buf, buf__len)"; + + PROCEDURE -Dup*(fd: LONGINT): LONGINT + "dup(fd)"; + + PROCEDURE -Dup2*(fd1, fd2: LONGINT): LONGINT + "dup(fd1, fd2)"; + + PROCEDURE -Pipe*(fds : LONGINT): LONGINT + "pipe(fds)"; + + PROCEDURE -Getpid*(): LONGINT + "getpid()"; + + PROCEDURE -Getuid*(): LONGINT + "getuid()"; + + PROCEDURE -Geteuid*(): LONGINT + "geteuid()"; + + PROCEDURE -Getgid*(): LONGINT + "getgid()"; + + PROCEDURE -Getegid*(): LONGINT + "getegid()"; + + PROCEDURE -Unlink*(name: Name): LONGINT + "unlink(name)"; + + PROCEDURE -Open*(name: Name; flag, mode: SET): LONGINT + "open(name, flag, mode)"; + + PROCEDURE -Close*(fd: LONGINT): LONGINT + "close(fd)"; + + PROCEDURE -stat(name: Name; VAR statbuf: Status): LONGINT + "stat((const char*)name, (struct stat*)statbuf)"; + + PROCEDURE Stat*(name: Name; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := stat(name, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); + RETURN res; + END Stat; + + PROCEDURE -fstat(fd: LONGINT; VAR statbuf: Status): LONGINT + "fstat(fd, (struct stat*)statbuf)"; + + PROCEDURE Fstat*(fd: LONGINT; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := fstat(fd, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); + RETURN res; + END Fstat; + + PROCEDURE -Fchmod*(fd, mode: LONGINT): LONGINT + "fchmod(fd, mode)"; + + PROCEDURE -Chmod*(path: Name; mode: LONGINT): LONGINT + "chmod(path, mode)"; + + PROCEDURE -Lseek*(fd, offset, origin: LONGINT): LONGINT + "lseek(fd, offset, origin)"; + + PROCEDURE -Fsync*(fd: LONGINT): LONGINT + "fsync(fd)"; + + PROCEDURE -Fcntl*(fd, cmd, arg: LONGINT ): LONGINT + "fcntl(fd, cmd, arg)"; + + PROCEDURE -Flock*(fd, operation: LONGINT): LONGINT + "flock(fd, operation)"; + + PROCEDURE -Ftruncate*(fd, length: LONGINT): LONGINT + "ftruncate(fd, length)"; + + PROCEDURE -Readblk*(fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE; len: LONGINT): LONGINT + "read(fd, buf, len)"; + + PROCEDURE -Rename*(old, new: Name): LONGINT + "rename(old, new)"; + + PROCEDURE -Chdir*(path: Name): LONGINT + "chdir(path)"; + + PROCEDURE -Ioctl*(fd, request, arg: LONGINT): LONGINT + "ioctl(fd, request, arg)"; + + PROCEDURE -Kill*(pid, sig: LONGINT): LONGINT + "kill(pid, sig)"; + + PROCEDURE -Sigsetmask*(mask: LONGINT): LONGINT + "sigsetmask(mask)"; + + + (* TCP/IP networking *) + + PROCEDURE -Gethostbyname*(name: Name): HostEntry + "(Unix_HostEntry)gethostbyname(name)"; + + PROCEDURE -Gethostname*(VAR name: Name): LONGINT + "gethostname(name, name__len)"; + + PROCEDURE -Socket*(af, type, protocol: LONGINT): LONGINT + "socket(af, type, protocol)"; + + PROCEDURE -Connect*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "connect(socket, &(name), namelen)"; + + PROCEDURE -Getsockname*(socket: LONGINT; VAR name: Sockaddr; VAR namelen: LONGINT): LONGINT + "getsockname(socket, name, namelen)"; + + PROCEDURE -Bind*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "bind(socket, &(name), namelen)"; + + PROCEDURE -Listen*(socket, backlog: LONGINT): LONGINT + "listen(socket, backlog)"; + + PROCEDURE -Accept*(socket: LONGINT; VAR addr: Sockaddr; VAR addrlen: LONGINT): LONGINT + "accept(socket, addr, addrlen)"; + + PROCEDURE -Recv*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "recv(socket, bufadr, buflen, flags)"; + + PROCEDURE -Send*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "send(socket, bufadr, buflen, flags)"; + + PROCEDURE -sys(str: ARRAY OF CHAR): INTEGER (* need this to call external tools like gcc or gas; noch *) + "system(str)"; + + PROCEDURE system*(cmd : ARRAY OF CHAR); + VAR r : INTEGER; + BEGIN + r := sys(cmd); + END system; + + PROCEDURE System*(cmd : ARRAY OF CHAR): INTEGER; + VAR r : INTEGER; + BEGIN + r := sys(cmd); + RETURN r + END System; + +END Unix. diff --git a/src/lib/system/linux/clang/armv7a_hardfp/Args.Mod b/src/lib/system/linux/clang/armv7a_hardfp/Args.Mod new file mode 100644 index 00000000..e8cd2a3c --- /dev/null +++ b/src/lib/system/linux/clang/armv7a_hardfp/Args.Mod @@ -0,0 +1,64 @@ +MODULE Args; (* jt, 8.12.94 *) + + (* command line argument handling for ofront *) + + + IMPORT SYSTEM; + + TYPE + ArgPtr = POINTER TO ARRAY 1024 OF CHAR; + ArgVec = POINTER TO ARRAY 1024 OF ArgPtr; + + VAR argc-, argv-: LONGINT; + + PROCEDURE -Argc(): INTEGER "SYSTEM_argc"; + PROCEDURE -Argv(): LONGINT "(long)SYSTEM_argv"; + PROCEDURE -getenv(var: ARRAY OF CHAR): ArgPtr + "(Args_ArgPtr)getenv(var)"; + + PROCEDURE Get*(n: INTEGER; VAR val: ARRAY OF CHAR); + VAR av: ArgVec; + BEGIN + IF n < argc THEN av := SYSTEM.VAL(ArgVec, argv); COPY(av[n]^, val) END + END Get; + + PROCEDURE GetInt*(n: INTEGER; VAR val: LONGINT); + VAR s: ARRAY 64 OF CHAR; k, d, i: LONGINT; + BEGIN + s := ""; Get(n, s); i := 0; + IF s[0] = "-" THEN i := 1 END ; + k := 0; d := ORD(s[i]) - ORD("0"); + WHILE (d >= 0 ) & (d <= 9) DO k := k*10 + d; INC(i); d := ORD(s[i]) - ORD("0") END ; + IF s[0] = "-" THEN d := -d; DEC(i) END ; + IF i > 0 THEN val := k END + END GetInt; + + PROCEDURE Pos*(s: ARRAY OF CHAR): INTEGER; + VAR i: INTEGER; arg: ARRAY 256 OF CHAR; + BEGIN + i := 0; Get(i, arg); + WHILE (i < argc) & (s # arg) DO INC(i); Get(i, arg) END ; + RETURN i + END Pos; + + PROCEDURE GetEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR); + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN COPY(p^, val) END + END GetEnv; + + PROCEDURE getEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR): BOOLEAN; + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN + COPY(p^, val); + RETURN TRUE + ELSE + RETURN FALSE + END + END getEnv; + +BEGIN argc := Argc(); argv := Argv() +END Args. diff --git a/src/lib/system/linux/clang/armv7a_hardfp/SYSTEM.c0 b/src/lib/system/linux/clang/armv7a_hardfp/SYSTEM.c0 new file mode 100644 index 00000000..580449aa --- /dev/null +++ b/src/lib/system/linux/clang/armv7a_hardfp/SYSTEM.c0 @@ -0,0 +1,205 @@ +/* +* The body prefix file of the Ofront runtime system, Version 1.0 +* +* Copyright (c) Software Templ, 1994, 1995 +* +* Module SYSTEM is subject to change any time without prior notification. +* Software Templ disclaims all warranties with regard to module SYSTEM, +* in particular shall Software Templ not be liable for any damage resulting +* from inappropriate use or modification of module SYSTEM. +* +* Version 1.1 jt, 24.11.95 fixes for correct pointer arithmetic on Cray computers +* jt 31.1.2007 ANSI prototypes for malloc and exit in order to avoid cc warnings +* +*/ + +#include "SYSTEM.h" +#ifdef __STDC__ +#include "stdarg.h" +#else +#include "varargs.h" +#endif + +extern void *malloc(long size); +extern void exit(int status); + +void (*SYSTEM_Halt)(); +LONGINT SYSTEM_halt; /* x in HALT(x) */ +LONGINT SYSTEM_assert; /* x in ASSERT(cond, x) */ +LONGINT SYSTEM_argc; +LONGINT SYSTEM_argv; +LONGINT SYSTEM_lock; +BOOLEAN SYSTEM_interrupted; +static LONGINT SYSTEM_mainfrm; /* adr of main proc stack frame, used for stack collection */ + +#define Lock SYSTEM_lock++ +#define Unlock SYSTEM_lock--; if (SYSTEM_interrupted && (SYSTEM_lock == 0)) __HALT(-9) + + +static void SYSTEM_InitHeap(); +void *SYSTEM__init(); + +void SYSTEM_INIT(argc, argvadr) + int argc; long argvadr; +{ + SYSTEM_mainfrm = argvadr; + SYSTEM_argc = argc; + SYSTEM_argv = *(long*)argvadr; + SYSTEM_InitHeap(); + SYSTEM_halt = -128; + SYSTEM__init(); +} + +void SYSTEM_FINI() +{ + SYSTEM_FINALL(); +} + +long SYSTEM_XCHK(i, ub) long i, ub; {return __X(i, ub);} +long SYSTEM_RCHK(i, ub) long i, ub; {return __R(i, ub);} +long SYSTEM_ASH(i, n) long i, n; {return __ASH(i, n);} +long SYSTEM_ABS(i) long i; {return __ABS(i);} +double SYSTEM_ABSD(i) double i; {return __ABS(i);} + +void SYSTEM_INHERIT(t, t0) + long *t, *t0; +{ + t -= __TPROC0OFF; + t0 -= __TPROC0OFF; + while (*t0 != __EOM) {*t = *t0; t--; t0--;} +} + +void SYSTEM_ENUMP(adr, n, P) + long *adr; + long n; + void (*P)(); +{ + while (n > 0) {P(*adr); adr++; n--;} +} + +void SYSTEM_ENUMR(adr, typ, size, n, P) + char *adr; + long *typ, size, n; + void (*P)(); +{ + long *t, off; + typ++; + while (n > 0) { + t = typ; + off = *t; + while (off >= 0) {P(*(long*)(adr+off)); t++; off = *t;} + adr += size; n--; + } +} + +long SYSTEM_DIV(x, y) + unsigned long x, y; +{ if ((long) x >= 0) return (x / y); + else return -((y - 1 - x) / y); +} + +long SYSTEM_MOD(x, y) + unsigned long x, y; +{ unsigned long m; + if ((long) x >= 0) return (x % y); + else { m = (-x) % y; + if (m != 0) return (y - m); else return 0; + } +} + +long SYSTEM_ENTIER(x) + double x; +{ + long y; + if (x >= 0) + return (long)x; + else { + y = (long)x; + if (y <= x) return y; else return y - 1; + } +} + +void SYSTEM_HALT(n) + int n; +{ + SYSTEM_halt = n; + if (SYSTEM_Halt!=0) SYSTEM_Halt(n); + exit(n); +} + +#ifdef __STDC__ +SYSTEM_PTR SYSTEM_NEWARR(long *typ, long elemsz, int elemalgn, int nofdim, int nofdyn, ...) +#else +SYSTEM_PTR SYSTEM_NEWARR(typ, elemsz, elemalgn, nofdim, nofdyn, va_alist) + long *typ, elemsz; + int elemalgn, nofdim, nofdyn; + va_dcl +#endif +{ + long nofelems, size, dataoff, n, nptr, *x, *p, nofptrs, i, *ptab, off; + va_list ap; +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + nofelems = 1; + while (nofdim > 0) { + nofelems = nofelems * va_arg(ap, long); nofdim--; + if (nofelems <= 0) __HALT(-20); + } + va_end(ap); + dataoff = nofdyn * sizeof(long); + if (elemalgn > sizeof(long)) { + n = dataoff % elemalgn; + if (n != 0) dataoff += elemalgn - n; + } + size = dataoff + nofelems * elemsz; + Lock; + if (typ == NIL) { + /* element typ does not contain pointers */ + x = SYSTEM_NEWBLK(size); + } + else if (typ == POINTER__typ) { + /* element type is a pointer */ + x = SYSTEM_NEWBLK(size + nofelems * sizeof(long)); + p = (long*)x[-1]; + p[-nofelems] = *p; /* build new type desc in situ: 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nofelems - 1; n = 1; /* n =1 for skipping the size field */ + while (n <= nofelems) {*p = n*sizeof(long); p++; n++;} + *p = - (nofelems + 1) * sizeof(long); /* sentinel */ + x[-1] -= nofelems * sizeof(long); + } + else { + /* element type is a record that contains pointers */ + ptab = typ + 1; nofptrs = 0; + while (ptab[nofptrs] >= 0) {nofptrs++;} /* number of pointers per element */ + nptr = nofelems * nofptrs; /* total number of pointers */ + x = SYSTEM_NEWBLK(size + nptr * sizeof(long)); + p = (long*)x[- 1]; + p[-nptr] = *p; /* build new type desc in situ; 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nptr - 1; n = 0; off = dataoff; + while (n < nofelems) {i = 0; + while (i < nofptrs) {*p = off + ptab[i]; p++; i++;} + off += elemsz; n++; + } + *p = - (nptr + 1) * sizeof(long); /* sentinel */ + x[-1] -= nptr * sizeof(long); + } + if (nofdyn != 0) { + /* setup len vector for index checks */ +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + p = x; + while (nofdyn > 0) {*p = va_arg(ap, long); p++, nofdyn--;} + va_end(ap); + } + Unlock; + return x; +} + +/* ----------- end of SYSTEM.co ------------- */ + diff --git a/src/lib/system/linux/clang/armv7a_hardfp/SYSTEM.h b/src/lib/system/linux/clang/armv7a_hardfp/SYSTEM.h new file mode 100644 index 00000000..719a6d18 --- /dev/null +++ b/src/lib/system/linux/clang/armv7a_hardfp/SYSTEM.h @@ -0,0 +1,215 @@ +#ifndef SYSTEM__h +#define SYSTEM__h + +/* + +the Ofront runtime system interface and macros library +copyright (c) Josef Templ, 1995, 1996 + +gcc for Linux version (same as SPARC/Solaris2) +uses double # as concatenation operator + +*/ + +#include + +//extern void *memcpy(void *dest, const void *src, long n); +extern void *memcpy(void *dest, const void *src, size_t n); +extern void *malloc(long size); +extern void exit(int status); + +#define export +#define import extern + +/* constants */ +#define __MAXEXT 16 +#define NIL 0L +#define POINTER__typ (long*)1L /* not NIL and not a valid type */ + +/* basic types */ +typedef char BOOLEAN; +typedef unsigned char CHAR; +typedef signed char SHORTINT; +typedef short int INTEGER; +typedef long LONGINT; +typedef float REAL; +typedef double LONGREAL; +typedef unsigned long SET; +typedef void *SYSTEM_PTR; +typedef unsigned char SYSTEM_BYTE; + +/* runtime system routines */ +extern long SYSTEM_DIV(); +extern long SYSTEM_MOD(); +extern long SYSTEM_ENTIER(); +extern long SYSTEM_ASH(); +extern long SYSTEM_ABS(); +extern long SYSTEM_XCHK(); +extern long SYSTEM_RCHK(); +extern double SYSTEM_ABSD(); +extern SYSTEM_PTR SYSTEM_NEWREC(); +extern SYSTEM_PTR SYSTEM_NEWBLK(); +#ifdef __STDC__ +extern SYSTEM_PTR SYSTEM_NEWARR(long*, long, int, int, int, ...); +#else +extern SYSTEM_PTR SYSTEM_NEWARR(); +#endif +extern SYSTEM_PTR SYSTEM_REGMOD(); +extern void SYSTEM_INCREF(); +extern void SYSTEM_REGCMD(); +extern void SYSTEM_REGTYP(); +extern void SYSTEM_REGFIN(); +extern void SYSTEM_FINALL(); +extern void SYSTEM_INIT(); +extern void SYSTEM_FINI(); +extern void SYSTEM_HALT(); +extern void SYSTEM_INHERIT(); +extern void SYSTEM_ENUMP(); +extern void SYSTEM_ENUMR(); + +/* module registry */ +#define __DEFMOD static void *m; if(m!=0)return m +#define __REGMOD(name, enum) if(m==0)m=SYSTEM_REGMOD((CHAR*)name,enum); else return m +#define __ENDMOD return m +#define __INIT(argc, argv) static void *m; SYSTEM_INIT(argc, (long)&argv); +#define __REGMAIN(name, enum) m=SYSTEM_REGMOD(name,enum) +#define __FINI SYSTEM_FINI(); return 0 +#define __IMPORT(name) SYSTEM_INCREF(name##__init()) +#define __REGCMD(name, cmd) SYSTEM_REGCMD(m, name, cmd) + +/* SYSTEM ops */ +#define __SYSNEW(p, len) p=SYSTEM_NEWBLK((long)(len)) +#define __VAL(t, x) (*(t*)&(x)) +#define __GET(a, x, t) x= *(t*)(a) +#define __PUT(a, x, t) *(t*)(a)=x +#define __LSHL(x, n, t) ((t)((unsigned)(x)<<(n))) +#define __LSHR(x, n, t) ((t)((unsigned)(x)>>(n))) +#define __LSH(x, n, t) ((n)>=0? __LSHL(x, n, t): __LSHR(x, -(n), t)) +#define __ROTL(x, n, t) ((t)((unsigned)(x)<<(n)|(unsigned)(x)>>(8*sizeof(t)-(n)))) +#define __ROTR(x, n, t) ((t)((unsigned)(x)>>(n)|(unsigned)(x)<<(8*sizeof(t)-(n)))) +#define __ROT(x, n, t) ((n)>=0? __ROTL(x, n, t): __ROTR(x, -(n), t)) +#define __BIT(x, n) (*(unsigned long*)(x)>>(n)&1) +#define __MOVE(s, d, n) memcpy((char*)(d),(char*)(s),n) + +/* std procs and operator mappings */ +#define __SHORT(x, y) ((int)((unsigned long)(x)+(y)<(y)+(y)?(x):(__HALT(-8),0))) +#define __SHORTF(x, y) ((int)(__RF((x)+(y),(y)+(y))-(y))) +#define __CHR(x) ((CHAR)__R(x, 256)) +#define __CHRF(x) ((CHAR)__RF(x, 256)) +#define __DIV(x, y) ((x)>=0?(x)/(y):-(((y)-1-(x))/(y))) +#define __DIVF(x, y) SYSTEM_DIV((long)(x),(long)(y)) +#define __MOD(x, y) ((x)>=0?(x)%(y):__MODF(x,y)) +#define __MODF(x, y) SYSTEM_MOD((long)(x),(long)(y)) +#define __NEW(p, t) p=SYSTEM_NEWREC((long)t##__typ) +#define __NEWARR SYSTEM_NEWARR +#define __HALT(x) SYSTEM_HALT(x) +#define __ASSERT(cond, x) if (!(cond)) {SYSTEM_assert = x; SYSTEM_HALT(-1);} +#define __ENTIER(x) SYSTEM_ENTIER(x) +#define __ABS(x) (((x)<0)?-(x):(x)) +#define __ABSF(x) SYSTEM_ABS((long)(x)) +#define __ABSFD(x) SYSTEM_ABSD((double)(x)) +#define __CAP(ch) ((CHAR)((ch)&0x5f)) +#define __ODD(x) ((x)&1) +#define __IN(x, s) (((s)>>(x))&1) +#define __SETOF(x) ((SET)1<<(x)) +#define __SETRNG(l, h) ((~(SET)0<<(l))&~(SET)0>>(8*sizeof(SET)-1-(h))) +#define __MASK(x, m) ((x)&~(m)) +#define __COPY(s, d, n) {char*_a=(void*)s,*_b=(void*)d;long _i=0,_t=n-1;while(_i<_t&&((_b[_i]=_a[_i])!=0)){_i++;};_b[_i]=0;} +static int __STRCMP(x, y) + CHAR *x, *y; +{long i = 0; CHAR ch1, ch2; + do {ch1 = x[i]; ch2 = y[i]; i++; + if (!ch1) return -(int)ch2; + } while (ch1==ch2); + return (int)ch1 - (int)ch2; +} +#define __ASH(x, n) ((n)>=0?__ASHL(x,n):__ASHR(x,-(n))) +#define __ASHL(x, n) ((long)(x)<<(n)) +#define __ASHR(x, n) ((long)(x)>>(n)) +#define __ASHF(x, n) SYSTEM_ASH((long)(x), (long)(n)) +#define __DUP(x, l, t) x=(void*)memcpy(alloca(l*sizeof(t)),x,l*sizeof(t)) +#define __DUPARR(v, t) v=(void*)memcpy(v##__copy,v,sizeof(t)) +#define __DEL(x) /* DUP with alloca frees storage automatically */ +#define __IS(tag, typ, level) (*(tag-(__BASEOFF-level))==(long)typ##__typ) +#define __TYPEOF(p) (*(((long**)(p))-1)) +#define __ISP(p, typ, level) __IS(__TYPEOF(p),typ,level) + +/* runtime checks */ +#define __X(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-2),0)) +#define __XF(i, ub) SYSTEM_XCHK((long)(i), (long)(ub)) +#define __RETCHK __retchk: __HALT(-3) +#define __CASECHK __HALT(-4) +#define __GUARDP(p, typ, level) ((typ*)(__ISP(p,typ,level)?p:(__HALT(-5),p))) +#define __GUARDR(r, typ, level) (*((typ*)(__IS(r##__typ,typ,level)?r:(__HALT(-5),r)))) +#define __GUARDA(p, typ, level) ((struct typ*)(__IS(__TYPEOF(p),typ,level)?p:(__HALT(-5),p))) +#define __GUARDEQR(p, dyntyp, typ) if(dyntyp!=typ##__typ) __HALT(-6);*(p) +#define __GUARDEQP(p, typ) if(__TYPEOF(p)!=typ##__typ)__HALT(-6);*(p) +#define __WITHCHK __HALT(-7) +#define __R(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-8),0)) +#define __RF(i, ub) SYSTEM_RCHK((long)(i),(long)(ub)) + +/* record type descriptors */ +#define __TDESC(t, m, n) \ + static struct t##__desc {\ + long tproc[m]; \ + long tag, next, level, module; \ + char name[24]; \ + long *base[__MAXEXT]; \ + char *rsrvd; \ + long blksz, ptr[n+1]; \ + } t##__desc + +#define __BASEOFF (__MAXEXT+1) +#define __TPROC0OFF (__BASEOFF+24/sizeof(long)+5) +#define __EOM 1 +#define __TDFLDS(name, size) {__EOM}, 1, 0, 0, 0, name, {0}, 0, size +#define __ENUMP(adr, n, P) SYSTEM_ENUMP(adr, (long)(n), P) +#define __ENUMR(adr, typ, size, n, P) SYSTEM_ENUMR(adr, typ, (long)(size), (long)(n), P) + +#define __INITYP(t, t0, level) \ + t##__typ= &t##__desc.blksz; \ + memcpy(t##__desc.base, t0##__typ - __BASEOFF, level*sizeof(long)); \ + t##__desc.base[level]=t##__typ; \ + t##__desc.module=(long)m; \ + if(t##__desc.blksz!=sizeof(struct t)) __HALT(-15); \ + t##__desc.blksz=(t##__desc.blksz+5*sizeof(long)-1)/(4*sizeof(long))*(4*sizeof(long)); \ + SYSTEM_REGTYP(m, (long)&t##__desc.next); \ + SYSTEM_INHERIT(t##__typ, t0##__typ) + +/* Oberon-2 type bound procedures support */ +#define __INITBP(t, proc, num) *(t##__typ-(__TPROC0OFF+num))=(long)proc +#define __SEND(typ, num, funtyp, parlist) ((funtyp)(*(typ-(__TPROC0OFF+num))))parlist + +/* runtime system variables */ +extern LONGINT SYSTEM_argc; +extern LONGINT SYSTEM_argv; +extern void (*SYSTEM_Halt)(); +extern LONGINT SYSTEM_halt; +extern LONGINT SYSTEM_assert; +extern SYSTEM_PTR SYSTEM_modules; +extern LONGINT SYSTEM_heapsize; +extern LONGINT SYSTEM_allocated; +extern LONGINT SYSTEM_lock; +extern SHORTINT SYSTEM_gclock; +extern BOOLEAN SYSTEM_interrupted; + +/* ANSI prototypes; not used so far +static int __STRCMP(CHAR *x, CHAR *y); +void SYSTEM_INIT(int argc, long argvadr); +void SYSTEM_FINI(void); +long SYSTEM_XCHK(long i, long ub); +long SYSTEM_RCHK(long i, long ub); +long SYSTEM_ASH(long i, long n); +long SYSTEM_ABS(long i); +double SYSTEM_ABSD(double i); +void SYSTEM_INHERIT(long *t, long *t0); +void SYSTEM_ENUMP(long *adr, long n, void (*P)(void*)); +void SYSTEM_ENUMR(char *adr, long *typ, long size, long n, void (*P)(void*)); +long SYSTEM_DIV(unsigned long x, unsigned long y); +long SYSTEM_MOD(unsigned long x, unsigned long y); +long SYSTEM_ENTIER(double x); +void SYSTEM_HALT(int n); +*/ + +#endif + diff --git a/src/lib/system/linux/clang/armv7a_hardfp/Unix.Mod b/src/lib/system/linux/clang/armv7a_hardfp/Unix.Mod new file mode 100644 index 00000000..9e46278e --- /dev/null +++ b/src/lib/system/linux/clang/armv7a_hardfp/Unix.Mod @@ -0,0 +1,419 @@ +MODULE Unix; (* Josef Templ, 5.3.90 Linux system calls *) +(* system procedure added by noch *) +(* Module Unix provides a system call interface to Linux. + Naming conventions: + Procedure and Type-names always start with a capital letter. + error numbers as defined in Unix + other constants start with lower case letters *) + +IMPORT SYSTEM; + +CONST + +(* various important constants *) + + stdin* = 0; stdout* =1; stderr* = 2; + + LOCKEX* = 2; LOCKUN* = 8; (* /usr/include/file.h *) + AFINET* = 2; (* /usr/include/sys/socket.h *) + PFINET* = AFINET; (* /usr/include/linux/socket.h *) + SOCKSTREAM* = 1; (* /usr/include/linux/socket.h *) + FIONREAD* = 541BH; (* in /usr/include/asm/termios.h *) + SETFL* = 4; (* set file descriptor flags; in asm/fcntl.h *) + TCP* = 0; + +(* flag sets, cf. /usr/include/asm/fcntl.h *) + rdonly* = {}; wronly* = {0}; rdwr* = {1}; creat* = {6}; excl* = {7}; trunc* = {9}; append* = {10}; ndelay = {11}; + +(* error numbers *) + + EPERM* = 1; (* Not owner *) + ENOENT* = 2; (* No such file or directory *) + ESRCH* = 3; (* No such process *) + EINTR* = 4; (* Interrupted system call *) + EIO* = 5; (* I/O error *) + ENXIO* = 6; (* No such device or address *) + E2BIG* = 7; (* Arg list too long *) + ENOEXEC* = 8; (* Exec format error *) + EBADF* = 9; (* Bad file number *) + ECHILD* = 10; (* No children *) + EAGAIN* = 11; (* No more processes *) + ENOMEM* = 12; (* Not enough core *) + EACCES* = 13; (* Permission denied *) + EFAULT* = 14; (* Bad address *) + ENOTBLK* = 15; (* Block device required *) + EBUSY* = 16; (* Mount device busy *) + EEXIST* = 17; (* File exists *) + EXDEV* = 18; (* Cross-device link *) + ENODEV* = 19; (* No such device *) + ENOTDIR* = 20; (* Not a directory*) + EISDIR* = 21; (* Is a directory *) + EINVAL* = 22; (* Invalid argument *) + ENFILE* = 23; (* File table overflow *) + EMFILE* = 24; (* Too many open files *) + ENOTTY* = 25; (* Not a typewriter *) + ETXTBSY* = 26; (* Text file busy *) + EFBIG* = 27; (* File too large *) + ENOSPC* = 28; (* No space left on device *) + ESPIPE* = 29; (* Illegal seek *) + EROFS* = 30; (* Read-only file system *) + EMLINK* = 31; (* Too many links *) + EPIPE* = 32; (* Broken pipe *) + EDOM* = 33; (* Argument too large *) + ERANGE* = 34; (* Result too large *) + EDEADLK* = 35; (* Resource deadlock would occur *) + ENAMETOOLONG* = 36; (* File name too long *) + ENOLCK* = 37; (* No record locks available *) + ENOSYS* = 38; (* Function not implemented *) + ENOTEMPTY* = 39; (* Directory not empty *) + ELOOP* = 40; (* Too many symbolic links encountered *) + EWOULDBLOCK* = EAGAIN; (* Operation would block *) + ENOMSG* = 42; (* No message of desired type *) + EIDRM* = 43; (* Identifier removed *) + ECHRNG* = 44; (* Channel number out of range *) + EL2NSYNC* = 45; (* Level 2 not synchronized *) + EL3HLT* = 46; (* Level 3 halted *) + EL3RST* = 47; (* Level 3 reset *) + ELNRNG* = 48; (* Link number out of range *) + EUNATCH* = 49; (* Protocol driver not attached *) + ENOCSI* = 50; (* No CSI structure available *) + EL2HLT* = 51; (* Level 2 halted *) + EBADE* = 52; (* Invalid exchange *) + EBADR* = 53; (* Invalid request descriptor *) + EXFULL* = 54; (* Exchange full *) + ENOANO* = 55; (* No anode *) + EBADRQC* = 56; (* Invalid request code *) + EBADSLT* = 57; (* Invalid slot *) + EDEADLOCK* = 58; (* File locking deadlock error *) + EBFONT* = 59; (* Bad font file format *) + ENOSTR* = 60; (* Device not a stream *) + ENODATA* = 61; (* No data available *) + ETIME* = 62; (* Timer expired *) + ENOSR* = 63; (* Out of streams resources *) + ENONET* = 64; (* Machine is not on the network *) + ENOPKG* = 65; (* Package not installed *) + EREMOTE* = 66; (* Object is remote *) + ENOLINK* = 67; (* Link has been severed *) + EADV* = 68; (* Advertise error *) + ESRMNT* = 69; (* Srmount error *) + ECOMM* = 70; (* Communication error on send *) + EPROTO* = 71; (* Protocol error *) + EMULTIHOP* = 72; (* Multihop attempted *) + EDOTDOT* = 73; (* RFS specific error *) + EBADMSG* = 74; (* Not a data message *) + EOVERFLOW* = 75; (* Value too large for defined data type *) + ENOTUNIQ* = 76; (* Name not unique on network *) + EBADFD* = 77; (* File descriptor in bad state *) + EREMCHG* = 78; (* Remote address changed *) + ELIBACC* = 79; (* Can not access a needed shared library *) + ELIBBAD* = 80; (* Accessing a corrupted shared library *) + ELIBSCN* = 81; (* .lib section in a.out corrupted *) + ELIBMAX* = 82; (* Attempting to link in too many shared libraries *) + ELIBEXEC* = 83; (* Cannot exec a shared library directly *) + EILSEQ* = 84; (* Illegal byte sequence *) + ERESTART* = 85; (* Interrupted system call should be restarted *) + ESTRPIPE* = 86; (* Streams pipe error *) + EUSERS* = 87; (* Too many users *) + ENOTSOCK* = 88; (* Socket operation on non-socket *) + EDESTADDRREQ* = 89; (* Destination address required *) + EMSGSIZE* = 90; (* Message too long *) + EPROTOTYPE* = 91; (* Protocol wrong type for socket *) + ENOPROTOOPT* = 92; (* Protocol not available *) + EPROTONOSUPPORT* = 93; (* Protocol not supported *) + ESOCKTNOSUPPORT* = 94; (* Socket type not supported *) + EOPNOTSUPP* = 95; (* Operation not supported on transport endpoint *) + EPFNOSUPPORT* = 96; (* Protocol family not supported *) + EAFNOSUPPORT* = 97; (* Address family not supported by protocol *) + EADDRINUSE* = 98; (* Address already in use *) + EADDRNOTAVAIL* = 99; (* Cannot assign requested address *) + ENETDOWN* = 100; (* Network is down *) + ENETUNREACH* = 101; (* Network is unreachable *) + ENETRESET* = 102; (* Network dropped connection because of reset *) + ECONNABORTED* = 103; (* Software caused connection abort *) + ECONNRESET* = 104; (* Connection reset by peer *) + ENOBUFS* = 105; (* No buffer space available *) + EISCONN* = 106; (* Transport endpoint is already connected *) + ENOTCONN* = 107; (* Transport endpoint is not connected *) + ESHUTDOWN* = 108; (* Cannot send after transport endpoint shutdown *) + ETOOMANYREFS* = 109; (* Too many references: cannot splice *) + ETIMEDOUT* = 110; (* Connection timed out *) + ECONNREFUSED* = 111; (* Connection refused *) + EHOSTDOWN* = 112; (* Host is down *) + EHOSTUNREACH* = 113; (* No route to host *) + EALREADY* = 114; (* Operation already in progress *) + EINPROGRESS* = 115; (* Operation now in progress *) + ESTALE* = 116; (* Stale NFS file handle *) + EUCLEAN* = 117; (* Structure needs cleaning *) + ENOTNAM* = 118; (* Not a XENIX named type file *) + ENAVAIL* = 119; (* No XENIX semaphores available *) + EISNAM* = 120; (* Is a named type file *) + EREMOTEIO* = 121; (* Remote I/O error *) + EDQUOT* = 122; (* Quota exceeded *) + + +TYPE + JmpBuf* = RECORD + bx*, si*, di*, bp*, sp*, pc*: LONGINT; + maskWasSaved*, savedMask*: LONGINT; + END ; + + Status* = RECORD (* struct stat *) + dev*, devX*: LONGINT; (* 64 bit in Linux 2.2 *) + pad1: INTEGER; + ino*, mode*, nlink*, uid*, gid*: LONGINT; + rdev*, rdevX*: LONGINT; (* 64 bit in Linux 2.2 *) + pad2: INTEGER; + size*, blksize*, blocks*, atime*, unused1*, mtime*, unused2*, ctime*, + unused3*, unused4*, unused5*: LONGINT; + END ; + + Timeval* = RECORD + sec*, usec*: LONGINT + END ; + + Timezone* = RECORD + minuteswest*, dsttime*: LONGINT + END ; + + Itimerval* = RECORD + interval*, value*: Timeval + END ; + + FdSet* = ARRAY 8 OF SET; + + SigCtxPtr* = POINTER TO SigContext; + SigContext* = RECORD + END ; + + SignalHandler* = PROCEDURE (sig, code: LONGINT; scp: SigCtxPtr); + + Dirent* = RECORD + ino, off: LONGINT; + reclen: INTEGER; + name: ARRAY 256 OF CHAR; + END ; + + Rusage* = RECORD + utime*, stime*: Timeval; + maxrss*, ixrss*, idrss*, isrss*, + minflt*, majflt*, nswap*, inblock*, + oublock*, msgsnd*, msgrcv*, nsignals*, + nvcsw*, nivcsw*: LONGINT + END ; + + Iovec* = RECORD + base*, len*: LONGINT + END ; + + SocketPair* = ARRAY 2 OF LONGINT; + + Pollfd* = RECORD + fd*: LONGINT; + events*, revents*: INTEGER + END ; + + Sockaddr* = RECORD + family*: INTEGER; + port*: INTEGER; + internetAddr*: LONGINT; + pad*: ARRAY 8 OF CHAR; + END ; + + HostEntry* = POINTER [1] TO Hostent; + Hostent* = RECORD + name*, aliases*: LONGINT; + addrtype*, length*: LONGINT; + addrlist*: LONGINT; (*POINTER TO POINTER TO LONGINT, network byte order*) + END; + + Name* = ARRAY OF CHAR; + + PROCEDURE -includeStat() + "#include "; + + PROCEDURE -includeErrno() + "#include "; + + PROCEDURE -err(): LONGINT + "errno"; + + PROCEDURE errno*(): LONGINT; + BEGIN + RETURN err() + END errno; + + PROCEDURE -Exit*(n: LONGINT) + "exit(n)"; + + PROCEDURE -Fork*(): LONGINT + "fork()"; + + PROCEDURE -Wait*(VAR status: LONGINT): LONGINT + "wait(status)"; + + PROCEDURE -Select*(width: LONGINT; VAR readfds, writefds, exceptfds: FdSet; VAR timeout: Timeval): LONGINT + "select(width, readfds, writefds, exceptfds, timeout)"; + + PROCEDURE -Gettimeofday* (VAR tv: Timeval; VAR tz: Timezone) : LONGINT + "gettimeofday(tv, tz)"; + + PROCEDURE -Read* (fd, buf, nbyte: LONGINT): LONGINT + "read(fd, buf, nbyte)"; + + PROCEDURE -ReadBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "read(fd, buf, buf__len)"; + + PROCEDURE -Write* (fd, buf, nbyte: LONGINT): LONGINT + "write(fd, buf, nbyte)"; + + PROCEDURE -WriteBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "write(fd, buf, buf__len)"; + + PROCEDURE -Dup*(fd: LONGINT): LONGINT + "dup(fd)"; + + PROCEDURE -Dup2*(fd1, fd2: LONGINT): LONGINT + "dup(fd1, fd2)"; + + PROCEDURE -Pipe*(fds : LONGINT): LONGINT + "pipe(fds)"; + + PROCEDURE -Getpid*(): LONGINT + "getpid()"; + + PROCEDURE -Getuid*(): LONGINT + "getuid()"; + + PROCEDURE -Geteuid*(): LONGINT + "geteuid()"; + + PROCEDURE -Getgid*(): LONGINT + "getgid()"; + + PROCEDURE -Getegid*(): LONGINT + "getegid()"; + + PROCEDURE -Unlink*(name: Name): LONGINT + "unlink(name)"; + + PROCEDURE -Open*(name: Name; flag, mode: SET): LONGINT + "open(name, flag, mode)"; + + PROCEDURE -Close*(fd: LONGINT): LONGINT + "close(fd)"; + + PROCEDURE -stat(name: Name; VAR statbuf: Status): LONGINT + "stat((const char*)name, (struct stat*)statbuf)"; + + PROCEDURE Stat*(name: Name; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := stat(name, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); + RETURN res; + END Stat; + + PROCEDURE -fstat(fd: LONGINT; VAR statbuf: Status): LONGINT + "fstat(fd, (struct stat*)statbuf)"; + + PROCEDURE Fstat*(fd: LONGINT; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := fstat(fd, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); + RETURN res; + END Fstat; + + PROCEDURE -Fchmod*(fd, mode: LONGINT): LONGINT + "fchmod(fd, mode)"; + + PROCEDURE -Chmod*(path: Name; mode: LONGINT): LONGINT + "chmod(path, mode)"; + + PROCEDURE -Lseek*(fd, offset, origin: LONGINT): LONGINT + "lseek(fd, offset, origin)"; + + PROCEDURE -Fsync*(fd: LONGINT): LONGINT + "fsync(fd)"; + + PROCEDURE -Fcntl*(fd, cmd, arg: LONGINT ): LONGINT + "fcntl(fd, cmd, arg)"; + + PROCEDURE -Flock*(fd, operation: LONGINT): LONGINT + "flock(fd, operation)"; + + PROCEDURE -Ftruncate*(fd, length: LONGINT): LONGINT + "ftruncate(fd, length)"; + + PROCEDURE -Readblk*(fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE; len: LONGINT): LONGINT + "read(fd, buf, len)"; + + PROCEDURE -Rename*(old, new: Name): LONGINT + "rename(old, new)"; + + PROCEDURE -Chdir*(path: Name): LONGINT + "chdir(path)"; + + PROCEDURE -Ioctl*(fd, request, arg: LONGINT): LONGINT + "ioctl(fd, request, arg)"; + + PROCEDURE -Kill*(pid, sig: LONGINT): LONGINT + "kill(pid, sig)"; + + PROCEDURE -Sigsetmask*(mask: LONGINT): LONGINT + "sigsetmask(mask)"; + + + (* TCP/IP networking *) + + PROCEDURE -Gethostbyname*(name: Name): HostEntry + "(Unix_HostEntry)gethostbyname(name)"; + + PROCEDURE -Gethostname*(VAR name: Name): LONGINT + "gethostname(name, name__len)"; + + PROCEDURE -Socket*(af, type, protocol: LONGINT): LONGINT + "socket(af, type, protocol)"; + + PROCEDURE -Connect*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "connect(socket, &(name), namelen)"; + + PROCEDURE -Getsockname*(socket: LONGINT; VAR name: Sockaddr; VAR namelen: LONGINT): LONGINT + "getsockname(socket, name, namelen)"; + + PROCEDURE -Bind*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "bind(socket, &(name), namelen)"; + + PROCEDURE -Listen*(socket, backlog: LONGINT): LONGINT + "listen(socket, backlog)"; + + PROCEDURE -Accept*(socket: LONGINT; VAR addr: Sockaddr; VAR addrlen: LONGINT): LONGINT + "accept(socket, addr, addrlen)"; + + PROCEDURE -Recv*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "recv(socket, bufadr, buflen, flags)"; + + PROCEDURE -Send*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "send(socket, bufadr, buflen, flags)"; + + PROCEDURE -sys(str: ARRAY OF CHAR): INTEGER (* need this to call external tools like gcc or gas; noch *) + "system(str)"; + + PROCEDURE system*(cmd : ARRAY OF CHAR); + VAR r : INTEGER; + BEGIN + r := sys(cmd); + END system; + + PROCEDURE System*(cmd : ARRAY OF CHAR): INTEGER; + VAR r : INTEGER; + BEGIN + r := sys(cmd); + RETURN r + END System; + +END Unix. diff --git a/src/lib/system/linux/clang/powerpc/Args.Mod b/src/lib/system/linux/clang/powerpc/Args.Mod new file mode 100644 index 00000000..e8cd2a3c --- /dev/null +++ b/src/lib/system/linux/clang/powerpc/Args.Mod @@ -0,0 +1,64 @@ +MODULE Args; (* jt, 8.12.94 *) + + (* command line argument handling for ofront *) + + + IMPORT SYSTEM; + + TYPE + ArgPtr = POINTER TO ARRAY 1024 OF CHAR; + ArgVec = POINTER TO ARRAY 1024 OF ArgPtr; + + VAR argc-, argv-: LONGINT; + + PROCEDURE -Argc(): INTEGER "SYSTEM_argc"; + PROCEDURE -Argv(): LONGINT "(long)SYSTEM_argv"; + PROCEDURE -getenv(var: ARRAY OF CHAR): ArgPtr + "(Args_ArgPtr)getenv(var)"; + + PROCEDURE Get*(n: INTEGER; VAR val: ARRAY OF CHAR); + VAR av: ArgVec; + BEGIN + IF n < argc THEN av := SYSTEM.VAL(ArgVec, argv); COPY(av[n]^, val) END + END Get; + + PROCEDURE GetInt*(n: INTEGER; VAR val: LONGINT); + VAR s: ARRAY 64 OF CHAR; k, d, i: LONGINT; + BEGIN + s := ""; Get(n, s); i := 0; + IF s[0] = "-" THEN i := 1 END ; + k := 0; d := ORD(s[i]) - ORD("0"); + WHILE (d >= 0 ) & (d <= 9) DO k := k*10 + d; INC(i); d := ORD(s[i]) - ORD("0") END ; + IF s[0] = "-" THEN d := -d; DEC(i) END ; + IF i > 0 THEN val := k END + END GetInt; + + PROCEDURE Pos*(s: ARRAY OF CHAR): INTEGER; + VAR i: INTEGER; arg: ARRAY 256 OF CHAR; + BEGIN + i := 0; Get(i, arg); + WHILE (i < argc) & (s # arg) DO INC(i); Get(i, arg) END ; + RETURN i + END Pos; + + PROCEDURE GetEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR); + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN COPY(p^, val) END + END GetEnv; + + PROCEDURE getEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR): BOOLEAN; + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN + COPY(p^, val); + RETURN TRUE + ELSE + RETURN FALSE + END + END getEnv; + +BEGIN argc := Argc(); argv := Argv() +END Args. diff --git a/src/lib/system/linux/clang/powerpc/SYSTEM.c0 b/src/lib/system/linux/clang/powerpc/SYSTEM.c0 new file mode 100644 index 00000000..580449aa --- /dev/null +++ b/src/lib/system/linux/clang/powerpc/SYSTEM.c0 @@ -0,0 +1,205 @@ +/* +* The body prefix file of the Ofront runtime system, Version 1.0 +* +* Copyright (c) Software Templ, 1994, 1995 +* +* Module SYSTEM is subject to change any time without prior notification. +* Software Templ disclaims all warranties with regard to module SYSTEM, +* in particular shall Software Templ not be liable for any damage resulting +* from inappropriate use or modification of module SYSTEM. +* +* Version 1.1 jt, 24.11.95 fixes for correct pointer arithmetic on Cray computers +* jt 31.1.2007 ANSI prototypes for malloc and exit in order to avoid cc warnings +* +*/ + +#include "SYSTEM.h" +#ifdef __STDC__ +#include "stdarg.h" +#else +#include "varargs.h" +#endif + +extern void *malloc(long size); +extern void exit(int status); + +void (*SYSTEM_Halt)(); +LONGINT SYSTEM_halt; /* x in HALT(x) */ +LONGINT SYSTEM_assert; /* x in ASSERT(cond, x) */ +LONGINT SYSTEM_argc; +LONGINT SYSTEM_argv; +LONGINT SYSTEM_lock; +BOOLEAN SYSTEM_interrupted; +static LONGINT SYSTEM_mainfrm; /* adr of main proc stack frame, used for stack collection */ + +#define Lock SYSTEM_lock++ +#define Unlock SYSTEM_lock--; if (SYSTEM_interrupted && (SYSTEM_lock == 0)) __HALT(-9) + + +static void SYSTEM_InitHeap(); +void *SYSTEM__init(); + +void SYSTEM_INIT(argc, argvadr) + int argc; long argvadr; +{ + SYSTEM_mainfrm = argvadr; + SYSTEM_argc = argc; + SYSTEM_argv = *(long*)argvadr; + SYSTEM_InitHeap(); + SYSTEM_halt = -128; + SYSTEM__init(); +} + +void SYSTEM_FINI() +{ + SYSTEM_FINALL(); +} + +long SYSTEM_XCHK(i, ub) long i, ub; {return __X(i, ub);} +long SYSTEM_RCHK(i, ub) long i, ub; {return __R(i, ub);} +long SYSTEM_ASH(i, n) long i, n; {return __ASH(i, n);} +long SYSTEM_ABS(i) long i; {return __ABS(i);} +double SYSTEM_ABSD(i) double i; {return __ABS(i);} + +void SYSTEM_INHERIT(t, t0) + long *t, *t0; +{ + t -= __TPROC0OFF; + t0 -= __TPROC0OFF; + while (*t0 != __EOM) {*t = *t0; t--; t0--;} +} + +void SYSTEM_ENUMP(adr, n, P) + long *adr; + long n; + void (*P)(); +{ + while (n > 0) {P(*adr); adr++; n--;} +} + +void SYSTEM_ENUMR(adr, typ, size, n, P) + char *adr; + long *typ, size, n; + void (*P)(); +{ + long *t, off; + typ++; + while (n > 0) { + t = typ; + off = *t; + while (off >= 0) {P(*(long*)(adr+off)); t++; off = *t;} + adr += size; n--; + } +} + +long SYSTEM_DIV(x, y) + unsigned long x, y; +{ if ((long) x >= 0) return (x / y); + else return -((y - 1 - x) / y); +} + +long SYSTEM_MOD(x, y) + unsigned long x, y; +{ unsigned long m; + if ((long) x >= 0) return (x % y); + else { m = (-x) % y; + if (m != 0) return (y - m); else return 0; + } +} + +long SYSTEM_ENTIER(x) + double x; +{ + long y; + if (x >= 0) + return (long)x; + else { + y = (long)x; + if (y <= x) return y; else return y - 1; + } +} + +void SYSTEM_HALT(n) + int n; +{ + SYSTEM_halt = n; + if (SYSTEM_Halt!=0) SYSTEM_Halt(n); + exit(n); +} + +#ifdef __STDC__ +SYSTEM_PTR SYSTEM_NEWARR(long *typ, long elemsz, int elemalgn, int nofdim, int nofdyn, ...) +#else +SYSTEM_PTR SYSTEM_NEWARR(typ, elemsz, elemalgn, nofdim, nofdyn, va_alist) + long *typ, elemsz; + int elemalgn, nofdim, nofdyn; + va_dcl +#endif +{ + long nofelems, size, dataoff, n, nptr, *x, *p, nofptrs, i, *ptab, off; + va_list ap; +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + nofelems = 1; + while (nofdim > 0) { + nofelems = nofelems * va_arg(ap, long); nofdim--; + if (nofelems <= 0) __HALT(-20); + } + va_end(ap); + dataoff = nofdyn * sizeof(long); + if (elemalgn > sizeof(long)) { + n = dataoff % elemalgn; + if (n != 0) dataoff += elemalgn - n; + } + size = dataoff + nofelems * elemsz; + Lock; + if (typ == NIL) { + /* element typ does not contain pointers */ + x = SYSTEM_NEWBLK(size); + } + else if (typ == POINTER__typ) { + /* element type is a pointer */ + x = SYSTEM_NEWBLK(size + nofelems * sizeof(long)); + p = (long*)x[-1]; + p[-nofelems] = *p; /* build new type desc in situ: 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nofelems - 1; n = 1; /* n =1 for skipping the size field */ + while (n <= nofelems) {*p = n*sizeof(long); p++; n++;} + *p = - (nofelems + 1) * sizeof(long); /* sentinel */ + x[-1] -= nofelems * sizeof(long); + } + else { + /* element type is a record that contains pointers */ + ptab = typ + 1; nofptrs = 0; + while (ptab[nofptrs] >= 0) {nofptrs++;} /* number of pointers per element */ + nptr = nofelems * nofptrs; /* total number of pointers */ + x = SYSTEM_NEWBLK(size + nptr * sizeof(long)); + p = (long*)x[- 1]; + p[-nptr] = *p; /* build new type desc in situ; 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nptr - 1; n = 0; off = dataoff; + while (n < nofelems) {i = 0; + while (i < nofptrs) {*p = off + ptab[i]; p++; i++;} + off += elemsz; n++; + } + *p = - (nptr + 1) * sizeof(long); /* sentinel */ + x[-1] -= nptr * sizeof(long); + } + if (nofdyn != 0) { + /* setup len vector for index checks */ +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + p = x; + while (nofdyn > 0) {*p = va_arg(ap, long); p++, nofdyn--;} + va_end(ap); + } + Unlock; + return x; +} + +/* ----------- end of SYSTEM.co ------------- */ + diff --git a/src/lib/system/linux/clang/powerpc/SYSTEM.h b/src/lib/system/linux/clang/powerpc/SYSTEM.h new file mode 100644 index 00000000..719a6d18 --- /dev/null +++ b/src/lib/system/linux/clang/powerpc/SYSTEM.h @@ -0,0 +1,215 @@ +#ifndef SYSTEM__h +#define SYSTEM__h + +/* + +the Ofront runtime system interface and macros library +copyright (c) Josef Templ, 1995, 1996 + +gcc for Linux version (same as SPARC/Solaris2) +uses double # as concatenation operator + +*/ + +#include + +//extern void *memcpy(void *dest, const void *src, long n); +extern void *memcpy(void *dest, const void *src, size_t n); +extern void *malloc(long size); +extern void exit(int status); + +#define export +#define import extern + +/* constants */ +#define __MAXEXT 16 +#define NIL 0L +#define POINTER__typ (long*)1L /* not NIL and not a valid type */ + +/* basic types */ +typedef char BOOLEAN; +typedef unsigned char CHAR; +typedef signed char SHORTINT; +typedef short int INTEGER; +typedef long LONGINT; +typedef float REAL; +typedef double LONGREAL; +typedef unsigned long SET; +typedef void *SYSTEM_PTR; +typedef unsigned char SYSTEM_BYTE; + +/* runtime system routines */ +extern long SYSTEM_DIV(); +extern long SYSTEM_MOD(); +extern long SYSTEM_ENTIER(); +extern long SYSTEM_ASH(); +extern long SYSTEM_ABS(); +extern long SYSTEM_XCHK(); +extern long SYSTEM_RCHK(); +extern double SYSTEM_ABSD(); +extern SYSTEM_PTR SYSTEM_NEWREC(); +extern SYSTEM_PTR SYSTEM_NEWBLK(); +#ifdef __STDC__ +extern SYSTEM_PTR SYSTEM_NEWARR(long*, long, int, int, int, ...); +#else +extern SYSTEM_PTR SYSTEM_NEWARR(); +#endif +extern SYSTEM_PTR SYSTEM_REGMOD(); +extern void SYSTEM_INCREF(); +extern void SYSTEM_REGCMD(); +extern void SYSTEM_REGTYP(); +extern void SYSTEM_REGFIN(); +extern void SYSTEM_FINALL(); +extern void SYSTEM_INIT(); +extern void SYSTEM_FINI(); +extern void SYSTEM_HALT(); +extern void SYSTEM_INHERIT(); +extern void SYSTEM_ENUMP(); +extern void SYSTEM_ENUMR(); + +/* module registry */ +#define __DEFMOD static void *m; if(m!=0)return m +#define __REGMOD(name, enum) if(m==0)m=SYSTEM_REGMOD((CHAR*)name,enum); else return m +#define __ENDMOD return m +#define __INIT(argc, argv) static void *m; SYSTEM_INIT(argc, (long)&argv); +#define __REGMAIN(name, enum) m=SYSTEM_REGMOD(name,enum) +#define __FINI SYSTEM_FINI(); return 0 +#define __IMPORT(name) SYSTEM_INCREF(name##__init()) +#define __REGCMD(name, cmd) SYSTEM_REGCMD(m, name, cmd) + +/* SYSTEM ops */ +#define __SYSNEW(p, len) p=SYSTEM_NEWBLK((long)(len)) +#define __VAL(t, x) (*(t*)&(x)) +#define __GET(a, x, t) x= *(t*)(a) +#define __PUT(a, x, t) *(t*)(a)=x +#define __LSHL(x, n, t) ((t)((unsigned)(x)<<(n))) +#define __LSHR(x, n, t) ((t)((unsigned)(x)>>(n))) +#define __LSH(x, n, t) ((n)>=0? __LSHL(x, n, t): __LSHR(x, -(n), t)) +#define __ROTL(x, n, t) ((t)((unsigned)(x)<<(n)|(unsigned)(x)>>(8*sizeof(t)-(n)))) +#define __ROTR(x, n, t) ((t)((unsigned)(x)>>(n)|(unsigned)(x)<<(8*sizeof(t)-(n)))) +#define __ROT(x, n, t) ((n)>=0? __ROTL(x, n, t): __ROTR(x, -(n), t)) +#define __BIT(x, n) (*(unsigned long*)(x)>>(n)&1) +#define __MOVE(s, d, n) memcpy((char*)(d),(char*)(s),n) + +/* std procs and operator mappings */ +#define __SHORT(x, y) ((int)((unsigned long)(x)+(y)<(y)+(y)?(x):(__HALT(-8),0))) +#define __SHORTF(x, y) ((int)(__RF((x)+(y),(y)+(y))-(y))) +#define __CHR(x) ((CHAR)__R(x, 256)) +#define __CHRF(x) ((CHAR)__RF(x, 256)) +#define __DIV(x, y) ((x)>=0?(x)/(y):-(((y)-1-(x))/(y))) +#define __DIVF(x, y) SYSTEM_DIV((long)(x),(long)(y)) +#define __MOD(x, y) ((x)>=0?(x)%(y):__MODF(x,y)) +#define __MODF(x, y) SYSTEM_MOD((long)(x),(long)(y)) +#define __NEW(p, t) p=SYSTEM_NEWREC((long)t##__typ) +#define __NEWARR SYSTEM_NEWARR +#define __HALT(x) SYSTEM_HALT(x) +#define __ASSERT(cond, x) if (!(cond)) {SYSTEM_assert = x; SYSTEM_HALT(-1);} +#define __ENTIER(x) SYSTEM_ENTIER(x) +#define __ABS(x) (((x)<0)?-(x):(x)) +#define __ABSF(x) SYSTEM_ABS((long)(x)) +#define __ABSFD(x) SYSTEM_ABSD((double)(x)) +#define __CAP(ch) ((CHAR)((ch)&0x5f)) +#define __ODD(x) ((x)&1) +#define __IN(x, s) (((s)>>(x))&1) +#define __SETOF(x) ((SET)1<<(x)) +#define __SETRNG(l, h) ((~(SET)0<<(l))&~(SET)0>>(8*sizeof(SET)-1-(h))) +#define __MASK(x, m) ((x)&~(m)) +#define __COPY(s, d, n) {char*_a=(void*)s,*_b=(void*)d;long _i=0,_t=n-1;while(_i<_t&&((_b[_i]=_a[_i])!=0)){_i++;};_b[_i]=0;} +static int __STRCMP(x, y) + CHAR *x, *y; +{long i = 0; CHAR ch1, ch2; + do {ch1 = x[i]; ch2 = y[i]; i++; + if (!ch1) return -(int)ch2; + } while (ch1==ch2); + return (int)ch1 - (int)ch2; +} +#define __ASH(x, n) ((n)>=0?__ASHL(x,n):__ASHR(x,-(n))) +#define __ASHL(x, n) ((long)(x)<<(n)) +#define __ASHR(x, n) ((long)(x)>>(n)) +#define __ASHF(x, n) SYSTEM_ASH((long)(x), (long)(n)) +#define __DUP(x, l, t) x=(void*)memcpy(alloca(l*sizeof(t)),x,l*sizeof(t)) +#define __DUPARR(v, t) v=(void*)memcpy(v##__copy,v,sizeof(t)) +#define __DEL(x) /* DUP with alloca frees storage automatically */ +#define __IS(tag, typ, level) (*(tag-(__BASEOFF-level))==(long)typ##__typ) +#define __TYPEOF(p) (*(((long**)(p))-1)) +#define __ISP(p, typ, level) __IS(__TYPEOF(p),typ,level) + +/* runtime checks */ +#define __X(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-2),0)) +#define __XF(i, ub) SYSTEM_XCHK((long)(i), (long)(ub)) +#define __RETCHK __retchk: __HALT(-3) +#define __CASECHK __HALT(-4) +#define __GUARDP(p, typ, level) ((typ*)(__ISP(p,typ,level)?p:(__HALT(-5),p))) +#define __GUARDR(r, typ, level) (*((typ*)(__IS(r##__typ,typ,level)?r:(__HALT(-5),r)))) +#define __GUARDA(p, typ, level) ((struct typ*)(__IS(__TYPEOF(p),typ,level)?p:(__HALT(-5),p))) +#define __GUARDEQR(p, dyntyp, typ) if(dyntyp!=typ##__typ) __HALT(-6);*(p) +#define __GUARDEQP(p, typ) if(__TYPEOF(p)!=typ##__typ)__HALT(-6);*(p) +#define __WITHCHK __HALT(-7) +#define __R(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-8),0)) +#define __RF(i, ub) SYSTEM_RCHK((long)(i),(long)(ub)) + +/* record type descriptors */ +#define __TDESC(t, m, n) \ + static struct t##__desc {\ + long tproc[m]; \ + long tag, next, level, module; \ + char name[24]; \ + long *base[__MAXEXT]; \ + char *rsrvd; \ + long blksz, ptr[n+1]; \ + } t##__desc + +#define __BASEOFF (__MAXEXT+1) +#define __TPROC0OFF (__BASEOFF+24/sizeof(long)+5) +#define __EOM 1 +#define __TDFLDS(name, size) {__EOM}, 1, 0, 0, 0, name, {0}, 0, size +#define __ENUMP(adr, n, P) SYSTEM_ENUMP(adr, (long)(n), P) +#define __ENUMR(adr, typ, size, n, P) SYSTEM_ENUMR(adr, typ, (long)(size), (long)(n), P) + +#define __INITYP(t, t0, level) \ + t##__typ= &t##__desc.blksz; \ + memcpy(t##__desc.base, t0##__typ - __BASEOFF, level*sizeof(long)); \ + t##__desc.base[level]=t##__typ; \ + t##__desc.module=(long)m; \ + if(t##__desc.blksz!=sizeof(struct t)) __HALT(-15); \ + t##__desc.blksz=(t##__desc.blksz+5*sizeof(long)-1)/(4*sizeof(long))*(4*sizeof(long)); \ + SYSTEM_REGTYP(m, (long)&t##__desc.next); \ + SYSTEM_INHERIT(t##__typ, t0##__typ) + +/* Oberon-2 type bound procedures support */ +#define __INITBP(t, proc, num) *(t##__typ-(__TPROC0OFF+num))=(long)proc +#define __SEND(typ, num, funtyp, parlist) ((funtyp)(*(typ-(__TPROC0OFF+num))))parlist + +/* runtime system variables */ +extern LONGINT SYSTEM_argc; +extern LONGINT SYSTEM_argv; +extern void (*SYSTEM_Halt)(); +extern LONGINT SYSTEM_halt; +extern LONGINT SYSTEM_assert; +extern SYSTEM_PTR SYSTEM_modules; +extern LONGINT SYSTEM_heapsize; +extern LONGINT SYSTEM_allocated; +extern LONGINT SYSTEM_lock; +extern SHORTINT SYSTEM_gclock; +extern BOOLEAN SYSTEM_interrupted; + +/* ANSI prototypes; not used so far +static int __STRCMP(CHAR *x, CHAR *y); +void SYSTEM_INIT(int argc, long argvadr); +void SYSTEM_FINI(void); +long SYSTEM_XCHK(long i, long ub); +long SYSTEM_RCHK(long i, long ub); +long SYSTEM_ASH(long i, long n); +long SYSTEM_ABS(long i); +double SYSTEM_ABSD(double i); +void SYSTEM_INHERIT(long *t, long *t0); +void SYSTEM_ENUMP(long *adr, long n, void (*P)(void*)); +void SYSTEM_ENUMR(char *adr, long *typ, long size, long n, void (*P)(void*)); +long SYSTEM_DIV(unsigned long x, unsigned long y); +long SYSTEM_MOD(unsigned long x, unsigned long y); +long SYSTEM_ENTIER(double x); +void SYSTEM_HALT(int n); +*/ + +#endif + diff --git a/src/lib/system/linux/clang/powerpc/Unix.Mod b/src/lib/system/linux/clang/powerpc/Unix.Mod new file mode 100644 index 00000000..9e46278e --- /dev/null +++ b/src/lib/system/linux/clang/powerpc/Unix.Mod @@ -0,0 +1,419 @@ +MODULE Unix; (* Josef Templ, 5.3.90 Linux system calls *) +(* system procedure added by noch *) +(* Module Unix provides a system call interface to Linux. + Naming conventions: + Procedure and Type-names always start with a capital letter. + error numbers as defined in Unix + other constants start with lower case letters *) + +IMPORT SYSTEM; + +CONST + +(* various important constants *) + + stdin* = 0; stdout* =1; stderr* = 2; + + LOCKEX* = 2; LOCKUN* = 8; (* /usr/include/file.h *) + AFINET* = 2; (* /usr/include/sys/socket.h *) + PFINET* = AFINET; (* /usr/include/linux/socket.h *) + SOCKSTREAM* = 1; (* /usr/include/linux/socket.h *) + FIONREAD* = 541BH; (* in /usr/include/asm/termios.h *) + SETFL* = 4; (* set file descriptor flags; in asm/fcntl.h *) + TCP* = 0; + +(* flag sets, cf. /usr/include/asm/fcntl.h *) + rdonly* = {}; wronly* = {0}; rdwr* = {1}; creat* = {6}; excl* = {7}; trunc* = {9}; append* = {10}; ndelay = {11}; + +(* error numbers *) + + EPERM* = 1; (* Not owner *) + ENOENT* = 2; (* No such file or directory *) + ESRCH* = 3; (* No such process *) + EINTR* = 4; (* Interrupted system call *) + EIO* = 5; (* I/O error *) + ENXIO* = 6; (* No such device or address *) + E2BIG* = 7; (* Arg list too long *) + ENOEXEC* = 8; (* Exec format error *) + EBADF* = 9; (* Bad file number *) + ECHILD* = 10; (* No children *) + EAGAIN* = 11; (* No more processes *) + ENOMEM* = 12; (* Not enough core *) + EACCES* = 13; (* Permission denied *) + EFAULT* = 14; (* Bad address *) + ENOTBLK* = 15; (* Block device required *) + EBUSY* = 16; (* Mount device busy *) + EEXIST* = 17; (* File exists *) + EXDEV* = 18; (* Cross-device link *) + ENODEV* = 19; (* No such device *) + ENOTDIR* = 20; (* Not a directory*) + EISDIR* = 21; (* Is a directory *) + EINVAL* = 22; (* Invalid argument *) + ENFILE* = 23; (* File table overflow *) + EMFILE* = 24; (* Too many open files *) + ENOTTY* = 25; (* Not a typewriter *) + ETXTBSY* = 26; (* Text file busy *) + EFBIG* = 27; (* File too large *) + ENOSPC* = 28; (* No space left on device *) + ESPIPE* = 29; (* Illegal seek *) + EROFS* = 30; (* Read-only file system *) + EMLINK* = 31; (* Too many links *) + EPIPE* = 32; (* Broken pipe *) + EDOM* = 33; (* Argument too large *) + ERANGE* = 34; (* Result too large *) + EDEADLK* = 35; (* Resource deadlock would occur *) + ENAMETOOLONG* = 36; (* File name too long *) + ENOLCK* = 37; (* No record locks available *) + ENOSYS* = 38; (* Function not implemented *) + ENOTEMPTY* = 39; (* Directory not empty *) + ELOOP* = 40; (* Too many symbolic links encountered *) + EWOULDBLOCK* = EAGAIN; (* Operation would block *) + ENOMSG* = 42; (* No message of desired type *) + EIDRM* = 43; (* Identifier removed *) + ECHRNG* = 44; (* Channel number out of range *) + EL2NSYNC* = 45; (* Level 2 not synchronized *) + EL3HLT* = 46; (* Level 3 halted *) + EL3RST* = 47; (* Level 3 reset *) + ELNRNG* = 48; (* Link number out of range *) + EUNATCH* = 49; (* Protocol driver not attached *) + ENOCSI* = 50; (* No CSI structure available *) + EL2HLT* = 51; (* Level 2 halted *) + EBADE* = 52; (* Invalid exchange *) + EBADR* = 53; (* Invalid request descriptor *) + EXFULL* = 54; (* Exchange full *) + ENOANO* = 55; (* No anode *) + EBADRQC* = 56; (* Invalid request code *) + EBADSLT* = 57; (* Invalid slot *) + EDEADLOCK* = 58; (* File locking deadlock error *) + EBFONT* = 59; (* Bad font file format *) + ENOSTR* = 60; (* Device not a stream *) + ENODATA* = 61; (* No data available *) + ETIME* = 62; (* Timer expired *) + ENOSR* = 63; (* Out of streams resources *) + ENONET* = 64; (* Machine is not on the network *) + ENOPKG* = 65; (* Package not installed *) + EREMOTE* = 66; (* Object is remote *) + ENOLINK* = 67; (* Link has been severed *) + EADV* = 68; (* Advertise error *) + ESRMNT* = 69; (* Srmount error *) + ECOMM* = 70; (* Communication error on send *) + EPROTO* = 71; (* Protocol error *) + EMULTIHOP* = 72; (* Multihop attempted *) + EDOTDOT* = 73; (* RFS specific error *) + EBADMSG* = 74; (* Not a data message *) + EOVERFLOW* = 75; (* Value too large for defined data type *) + ENOTUNIQ* = 76; (* Name not unique on network *) + EBADFD* = 77; (* File descriptor in bad state *) + EREMCHG* = 78; (* Remote address changed *) + ELIBACC* = 79; (* Can not access a needed shared library *) + ELIBBAD* = 80; (* Accessing a corrupted shared library *) + ELIBSCN* = 81; (* .lib section in a.out corrupted *) + ELIBMAX* = 82; (* Attempting to link in too many shared libraries *) + ELIBEXEC* = 83; (* Cannot exec a shared library directly *) + EILSEQ* = 84; (* Illegal byte sequence *) + ERESTART* = 85; (* Interrupted system call should be restarted *) + ESTRPIPE* = 86; (* Streams pipe error *) + EUSERS* = 87; (* Too many users *) + ENOTSOCK* = 88; (* Socket operation on non-socket *) + EDESTADDRREQ* = 89; (* Destination address required *) + EMSGSIZE* = 90; (* Message too long *) + EPROTOTYPE* = 91; (* Protocol wrong type for socket *) + ENOPROTOOPT* = 92; (* Protocol not available *) + EPROTONOSUPPORT* = 93; (* Protocol not supported *) + ESOCKTNOSUPPORT* = 94; (* Socket type not supported *) + EOPNOTSUPP* = 95; (* Operation not supported on transport endpoint *) + EPFNOSUPPORT* = 96; (* Protocol family not supported *) + EAFNOSUPPORT* = 97; (* Address family not supported by protocol *) + EADDRINUSE* = 98; (* Address already in use *) + EADDRNOTAVAIL* = 99; (* Cannot assign requested address *) + ENETDOWN* = 100; (* Network is down *) + ENETUNREACH* = 101; (* Network is unreachable *) + ENETRESET* = 102; (* Network dropped connection because of reset *) + ECONNABORTED* = 103; (* Software caused connection abort *) + ECONNRESET* = 104; (* Connection reset by peer *) + ENOBUFS* = 105; (* No buffer space available *) + EISCONN* = 106; (* Transport endpoint is already connected *) + ENOTCONN* = 107; (* Transport endpoint is not connected *) + ESHUTDOWN* = 108; (* Cannot send after transport endpoint shutdown *) + ETOOMANYREFS* = 109; (* Too many references: cannot splice *) + ETIMEDOUT* = 110; (* Connection timed out *) + ECONNREFUSED* = 111; (* Connection refused *) + EHOSTDOWN* = 112; (* Host is down *) + EHOSTUNREACH* = 113; (* No route to host *) + EALREADY* = 114; (* Operation already in progress *) + EINPROGRESS* = 115; (* Operation now in progress *) + ESTALE* = 116; (* Stale NFS file handle *) + EUCLEAN* = 117; (* Structure needs cleaning *) + ENOTNAM* = 118; (* Not a XENIX named type file *) + ENAVAIL* = 119; (* No XENIX semaphores available *) + EISNAM* = 120; (* Is a named type file *) + EREMOTEIO* = 121; (* Remote I/O error *) + EDQUOT* = 122; (* Quota exceeded *) + + +TYPE + JmpBuf* = RECORD + bx*, si*, di*, bp*, sp*, pc*: LONGINT; + maskWasSaved*, savedMask*: LONGINT; + END ; + + Status* = RECORD (* struct stat *) + dev*, devX*: LONGINT; (* 64 bit in Linux 2.2 *) + pad1: INTEGER; + ino*, mode*, nlink*, uid*, gid*: LONGINT; + rdev*, rdevX*: LONGINT; (* 64 bit in Linux 2.2 *) + pad2: INTEGER; + size*, blksize*, blocks*, atime*, unused1*, mtime*, unused2*, ctime*, + unused3*, unused4*, unused5*: LONGINT; + END ; + + Timeval* = RECORD + sec*, usec*: LONGINT + END ; + + Timezone* = RECORD + minuteswest*, dsttime*: LONGINT + END ; + + Itimerval* = RECORD + interval*, value*: Timeval + END ; + + FdSet* = ARRAY 8 OF SET; + + SigCtxPtr* = POINTER TO SigContext; + SigContext* = RECORD + END ; + + SignalHandler* = PROCEDURE (sig, code: LONGINT; scp: SigCtxPtr); + + Dirent* = RECORD + ino, off: LONGINT; + reclen: INTEGER; + name: ARRAY 256 OF CHAR; + END ; + + Rusage* = RECORD + utime*, stime*: Timeval; + maxrss*, ixrss*, idrss*, isrss*, + minflt*, majflt*, nswap*, inblock*, + oublock*, msgsnd*, msgrcv*, nsignals*, + nvcsw*, nivcsw*: LONGINT + END ; + + Iovec* = RECORD + base*, len*: LONGINT + END ; + + SocketPair* = ARRAY 2 OF LONGINT; + + Pollfd* = RECORD + fd*: LONGINT; + events*, revents*: INTEGER + END ; + + Sockaddr* = RECORD + family*: INTEGER; + port*: INTEGER; + internetAddr*: LONGINT; + pad*: ARRAY 8 OF CHAR; + END ; + + HostEntry* = POINTER [1] TO Hostent; + Hostent* = RECORD + name*, aliases*: LONGINT; + addrtype*, length*: LONGINT; + addrlist*: LONGINT; (*POINTER TO POINTER TO LONGINT, network byte order*) + END; + + Name* = ARRAY OF CHAR; + + PROCEDURE -includeStat() + "#include "; + + PROCEDURE -includeErrno() + "#include "; + + PROCEDURE -err(): LONGINT + "errno"; + + PROCEDURE errno*(): LONGINT; + BEGIN + RETURN err() + END errno; + + PROCEDURE -Exit*(n: LONGINT) + "exit(n)"; + + PROCEDURE -Fork*(): LONGINT + "fork()"; + + PROCEDURE -Wait*(VAR status: LONGINT): LONGINT + "wait(status)"; + + PROCEDURE -Select*(width: LONGINT; VAR readfds, writefds, exceptfds: FdSet; VAR timeout: Timeval): LONGINT + "select(width, readfds, writefds, exceptfds, timeout)"; + + PROCEDURE -Gettimeofday* (VAR tv: Timeval; VAR tz: Timezone) : LONGINT + "gettimeofday(tv, tz)"; + + PROCEDURE -Read* (fd, buf, nbyte: LONGINT): LONGINT + "read(fd, buf, nbyte)"; + + PROCEDURE -ReadBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "read(fd, buf, buf__len)"; + + PROCEDURE -Write* (fd, buf, nbyte: LONGINT): LONGINT + "write(fd, buf, nbyte)"; + + PROCEDURE -WriteBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "write(fd, buf, buf__len)"; + + PROCEDURE -Dup*(fd: LONGINT): LONGINT + "dup(fd)"; + + PROCEDURE -Dup2*(fd1, fd2: LONGINT): LONGINT + "dup(fd1, fd2)"; + + PROCEDURE -Pipe*(fds : LONGINT): LONGINT + "pipe(fds)"; + + PROCEDURE -Getpid*(): LONGINT + "getpid()"; + + PROCEDURE -Getuid*(): LONGINT + "getuid()"; + + PROCEDURE -Geteuid*(): LONGINT + "geteuid()"; + + PROCEDURE -Getgid*(): LONGINT + "getgid()"; + + PROCEDURE -Getegid*(): LONGINT + "getegid()"; + + PROCEDURE -Unlink*(name: Name): LONGINT + "unlink(name)"; + + PROCEDURE -Open*(name: Name; flag, mode: SET): LONGINT + "open(name, flag, mode)"; + + PROCEDURE -Close*(fd: LONGINT): LONGINT + "close(fd)"; + + PROCEDURE -stat(name: Name; VAR statbuf: Status): LONGINT + "stat((const char*)name, (struct stat*)statbuf)"; + + PROCEDURE Stat*(name: Name; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := stat(name, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); + RETURN res; + END Stat; + + PROCEDURE -fstat(fd: LONGINT; VAR statbuf: Status): LONGINT + "fstat(fd, (struct stat*)statbuf)"; + + PROCEDURE Fstat*(fd: LONGINT; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := fstat(fd, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); + RETURN res; + END Fstat; + + PROCEDURE -Fchmod*(fd, mode: LONGINT): LONGINT + "fchmod(fd, mode)"; + + PROCEDURE -Chmod*(path: Name; mode: LONGINT): LONGINT + "chmod(path, mode)"; + + PROCEDURE -Lseek*(fd, offset, origin: LONGINT): LONGINT + "lseek(fd, offset, origin)"; + + PROCEDURE -Fsync*(fd: LONGINT): LONGINT + "fsync(fd)"; + + PROCEDURE -Fcntl*(fd, cmd, arg: LONGINT ): LONGINT + "fcntl(fd, cmd, arg)"; + + PROCEDURE -Flock*(fd, operation: LONGINT): LONGINT + "flock(fd, operation)"; + + PROCEDURE -Ftruncate*(fd, length: LONGINT): LONGINT + "ftruncate(fd, length)"; + + PROCEDURE -Readblk*(fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE; len: LONGINT): LONGINT + "read(fd, buf, len)"; + + PROCEDURE -Rename*(old, new: Name): LONGINT + "rename(old, new)"; + + PROCEDURE -Chdir*(path: Name): LONGINT + "chdir(path)"; + + PROCEDURE -Ioctl*(fd, request, arg: LONGINT): LONGINT + "ioctl(fd, request, arg)"; + + PROCEDURE -Kill*(pid, sig: LONGINT): LONGINT + "kill(pid, sig)"; + + PROCEDURE -Sigsetmask*(mask: LONGINT): LONGINT + "sigsetmask(mask)"; + + + (* TCP/IP networking *) + + PROCEDURE -Gethostbyname*(name: Name): HostEntry + "(Unix_HostEntry)gethostbyname(name)"; + + PROCEDURE -Gethostname*(VAR name: Name): LONGINT + "gethostname(name, name__len)"; + + PROCEDURE -Socket*(af, type, protocol: LONGINT): LONGINT + "socket(af, type, protocol)"; + + PROCEDURE -Connect*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "connect(socket, &(name), namelen)"; + + PROCEDURE -Getsockname*(socket: LONGINT; VAR name: Sockaddr; VAR namelen: LONGINT): LONGINT + "getsockname(socket, name, namelen)"; + + PROCEDURE -Bind*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "bind(socket, &(name), namelen)"; + + PROCEDURE -Listen*(socket, backlog: LONGINT): LONGINT + "listen(socket, backlog)"; + + PROCEDURE -Accept*(socket: LONGINT; VAR addr: Sockaddr; VAR addrlen: LONGINT): LONGINT + "accept(socket, addr, addrlen)"; + + PROCEDURE -Recv*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "recv(socket, bufadr, buflen, flags)"; + + PROCEDURE -Send*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "send(socket, bufadr, buflen, flags)"; + + PROCEDURE -sys(str: ARRAY OF CHAR): INTEGER (* need this to call external tools like gcc or gas; noch *) + "system(str)"; + + PROCEDURE system*(cmd : ARRAY OF CHAR); + VAR r : INTEGER; + BEGIN + r := sys(cmd); + END system; + + PROCEDURE System*(cmd : ARRAY OF CHAR): INTEGER; + VAR r : INTEGER; + BEGIN + r := sys(cmd); + RETURN r + END System; + +END Unix. diff --git a/src/lib/system/linux/clang/x86/Args.Mod b/src/lib/system/linux/clang/x86/Args.Mod new file mode 100644 index 00000000..e8cd2a3c --- /dev/null +++ b/src/lib/system/linux/clang/x86/Args.Mod @@ -0,0 +1,64 @@ +MODULE Args; (* jt, 8.12.94 *) + + (* command line argument handling for ofront *) + + + IMPORT SYSTEM; + + TYPE + ArgPtr = POINTER TO ARRAY 1024 OF CHAR; + ArgVec = POINTER TO ARRAY 1024 OF ArgPtr; + + VAR argc-, argv-: LONGINT; + + PROCEDURE -Argc(): INTEGER "SYSTEM_argc"; + PROCEDURE -Argv(): LONGINT "(long)SYSTEM_argv"; + PROCEDURE -getenv(var: ARRAY OF CHAR): ArgPtr + "(Args_ArgPtr)getenv(var)"; + + PROCEDURE Get*(n: INTEGER; VAR val: ARRAY OF CHAR); + VAR av: ArgVec; + BEGIN + IF n < argc THEN av := SYSTEM.VAL(ArgVec, argv); COPY(av[n]^, val) END + END Get; + + PROCEDURE GetInt*(n: INTEGER; VAR val: LONGINT); + VAR s: ARRAY 64 OF CHAR; k, d, i: LONGINT; + BEGIN + s := ""; Get(n, s); i := 0; + IF s[0] = "-" THEN i := 1 END ; + k := 0; d := ORD(s[i]) - ORD("0"); + WHILE (d >= 0 ) & (d <= 9) DO k := k*10 + d; INC(i); d := ORD(s[i]) - ORD("0") END ; + IF s[0] = "-" THEN d := -d; DEC(i) END ; + IF i > 0 THEN val := k END + END GetInt; + + PROCEDURE Pos*(s: ARRAY OF CHAR): INTEGER; + VAR i: INTEGER; arg: ARRAY 256 OF CHAR; + BEGIN + i := 0; Get(i, arg); + WHILE (i < argc) & (s # arg) DO INC(i); Get(i, arg) END ; + RETURN i + END Pos; + + PROCEDURE GetEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR); + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN COPY(p^, val) END + END GetEnv; + + PROCEDURE getEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR): BOOLEAN; + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN + COPY(p^, val); + RETURN TRUE + ELSE + RETURN FALSE + END + END getEnv; + +BEGIN argc := Argc(); argv := Argv() +END Args. diff --git a/src/lib/system/linux/clang/x86/SYSTEM.c0 b/src/lib/system/linux/clang/x86/SYSTEM.c0 new file mode 100644 index 00000000..580449aa --- /dev/null +++ b/src/lib/system/linux/clang/x86/SYSTEM.c0 @@ -0,0 +1,205 @@ +/* +* The body prefix file of the Ofront runtime system, Version 1.0 +* +* Copyright (c) Software Templ, 1994, 1995 +* +* Module SYSTEM is subject to change any time without prior notification. +* Software Templ disclaims all warranties with regard to module SYSTEM, +* in particular shall Software Templ not be liable for any damage resulting +* from inappropriate use or modification of module SYSTEM. +* +* Version 1.1 jt, 24.11.95 fixes for correct pointer arithmetic on Cray computers +* jt 31.1.2007 ANSI prototypes for malloc and exit in order to avoid cc warnings +* +*/ + +#include "SYSTEM.h" +#ifdef __STDC__ +#include "stdarg.h" +#else +#include "varargs.h" +#endif + +extern void *malloc(long size); +extern void exit(int status); + +void (*SYSTEM_Halt)(); +LONGINT SYSTEM_halt; /* x in HALT(x) */ +LONGINT SYSTEM_assert; /* x in ASSERT(cond, x) */ +LONGINT SYSTEM_argc; +LONGINT SYSTEM_argv; +LONGINT SYSTEM_lock; +BOOLEAN SYSTEM_interrupted; +static LONGINT SYSTEM_mainfrm; /* adr of main proc stack frame, used for stack collection */ + +#define Lock SYSTEM_lock++ +#define Unlock SYSTEM_lock--; if (SYSTEM_interrupted && (SYSTEM_lock == 0)) __HALT(-9) + + +static void SYSTEM_InitHeap(); +void *SYSTEM__init(); + +void SYSTEM_INIT(argc, argvadr) + int argc; long argvadr; +{ + SYSTEM_mainfrm = argvadr; + SYSTEM_argc = argc; + SYSTEM_argv = *(long*)argvadr; + SYSTEM_InitHeap(); + SYSTEM_halt = -128; + SYSTEM__init(); +} + +void SYSTEM_FINI() +{ + SYSTEM_FINALL(); +} + +long SYSTEM_XCHK(i, ub) long i, ub; {return __X(i, ub);} +long SYSTEM_RCHK(i, ub) long i, ub; {return __R(i, ub);} +long SYSTEM_ASH(i, n) long i, n; {return __ASH(i, n);} +long SYSTEM_ABS(i) long i; {return __ABS(i);} +double SYSTEM_ABSD(i) double i; {return __ABS(i);} + +void SYSTEM_INHERIT(t, t0) + long *t, *t0; +{ + t -= __TPROC0OFF; + t0 -= __TPROC0OFF; + while (*t0 != __EOM) {*t = *t0; t--; t0--;} +} + +void SYSTEM_ENUMP(adr, n, P) + long *adr; + long n; + void (*P)(); +{ + while (n > 0) {P(*adr); adr++; n--;} +} + +void SYSTEM_ENUMR(adr, typ, size, n, P) + char *adr; + long *typ, size, n; + void (*P)(); +{ + long *t, off; + typ++; + while (n > 0) { + t = typ; + off = *t; + while (off >= 0) {P(*(long*)(adr+off)); t++; off = *t;} + adr += size; n--; + } +} + +long SYSTEM_DIV(x, y) + unsigned long x, y; +{ if ((long) x >= 0) return (x / y); + else return -((y - 1 - x) / y); +} + +long SYSTEM_MOD(x, y) + unsigned long x, y; +{ unsigned long m; + if ((long) x >= 0) return (x % y); + else { m = (-x) % y; + if (m != 0) return (y - m); else return 0; + } +} + +long SYSTEM_ENTIER(x) + double x; +{ + long y; + if (x >= 0) + return (long)x; + else { + y = (long)x; + if (y <= x) return y; else return y - 1; + } +} + +void SYSTEM_HALT(n) + int n; +{ + SYSTEM_halt = n; + if (SYSTEM_Halt!=0) SYSTEM_Halt(n); + exit(n); +} + +#ifdef __STDC__ +SYSTEM_PTR SYSTEM_NEWARR(long *typ, long elemsz, int elemalgn, int nofdim, int nofdyn, ...) +#else +SYSTEM_PTR SYSTEM_NEWARR(typ, elemsz, elemalgn, nofdim, nofdyn, va_alist) + long *typ, elemsz; + int elemalgn, nofdim, nofdyn; + va_dcl +#endif +{ + long nofelems, size, dataoff, n, nptr, *x, *p, nofptrs, i, *ptab, off; + va_list ap; +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + nofelems = 1; + while (nofdim > 0) { + nofelems = nofelems * va_arg(ap, long); nofdim--; + if (nofelems <= 0) __HALT(-20); + } + va_end(ap); + dataoff = nofdyn * sizeof(long); + if (elemalgn > sizeof(long)) { + n = dataoff % elemalgn; + if (n != 0) dataoff += elemalgn - n; + } + size = dataoff + nofelems * elemsz; + Lock; + if (typ == NIL) { + /* element typ does not contain pointers */ + x = SYSTEM_NEWBLK(size); + } + else if (typ == POINTER__typ) { + /* element type is a pointer */ + x = SYSTEM_NEWBLK(size + nofelems * sizeof(long)); + p = (long*)x[-1]; + p[-nofelems] = *p; /* build new type desc in situ: 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nofelems - 1; n = 1; /* n =1 for skipping the size field */ + while (n <= nofelems) {*p = n*sizeof(long); p++; n++;} + *p = - (nofelems + 1) * sizeof(long); /* sentinel */ + x[-1] -= nofelems * sizeof(long); + } + else { + /* element type is a record that contains pointers */ + ptab = typ + 1; nofptrs = 0; + while (ptab[nofptrs] >= 0) {nofptrs++;} /* number of pointers per element */ + nptr = nofelems * nofptrs; /* total number of pointers */ + x = SYSTEM_NEWBLK(size + nptr * sizeof(long)); + p = (long*)x[- 1]; + p[-nptr] = *p; /* build new type desc in situ; 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nptr - 1; n = 0; off = dataoff; + while (n < nofelems) {i = 0; + while (i < nofptrs) {*p = off + ptab[i]; p++; i++;} + off += elemsz; n++; + } + *p = - (nptr + 1) * sizeof(long); /* sentinel */ + x[-1] -= nptr * sizeof(long); + } + if (nofdyn != 0) { + /* setup len vector for index checks */ +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + p = x; + while (nofdyn > 0) {*p = va_arg(ap, long); p++, nofdyn--;} + va_end(ap); + } + Unlock; + return x; +} + +/* ----------- end of SYSTEM.co ------------- */ + diff --git a/src/lib/system/linux/clang/x86/SYSTEM.h b/src/lib/system/linux/clang/x86/SYSTEM.h new file mode 100644 index 00000000..719a6d18 --- /dev/null +++ b/src/lib/system/linux/clang/x86/SYSTEM.h @@ -0,0 +1,215 @@ +#ifndef SYSTEM__h +#define SYSTEM__h + +/* + +the Ofront runtime system interface and macros library +copyright (c) Josef Templ, 1995, 1996 + +gcc for Linux version (same as SPARC/Solaris2) +uses double # as concatenation operator + +*/ + +#include + +//extern void *memcpy(void *dest, const void *src, long n); +extern void *memcpy(void *dest, const void *src, size_t n); +extern void *malloc(long size); +extern void exit(int status); + +#define export +#define import extern + +/* constants */ +#define __MAXEXT 16 +#define NIL 0L +#define POINTER__typ (long*)1L /* not NIL and not a valid type */ + +/* basic types */ +typedef char BOOLEAN; +typedef unsigned char CHAR; +typedef signed char SHORTINT; +typedef short int INTEGER; +typedef long LONGINT; +typedef float REAL; +typedef double LONGREAL; +typedef unsigned long SET; +typedef void *SYSTEM_PTR; +typedef unsigned char SYSTEM_BYTE; + +/* runtime system routines */ +extern long SYSTEM_DIV(); +extern long SYSTEM_MOD(); +extern long SYSTEM_ENTIER(); +extern long SYSTEM_ASH(); +extern long SYSTEM_ABS(); +extern long SYSTEM_XCHK(); +extern long SYSTEM_RCHK(); +extern double SYSTEM_ABSD(); +extern SYSTEM_PTR SYSTEM_NEWREC(); +extern SYSTEM_PTR SYSTEM_NEWBLK(); +#ifdef __STDC__ +extern SYSTEM_PTR SYSTEM_NEWARR(long*, long, int, int, int, ...); +#else +extern SYSTEM_PTR SYSTEM_NEWARR(); +#endif +extern SYSTEM_PTR SYSTEM_REGMOD(); +extern void SYSTEM_INCREF(); +extern void SYSTEM_REGCMD(); +extern void SYSTEM_REGTYP(); +extern void SYSTEM_REGFIN(); +extern void SYSTEM_FINALL(); +extern void SYSTEM_INIT(); +extern void SYSTEM_FINI(); +extern void SYSTEM_HALT(); +extern void SYSTEM_INHERIT(); +extern void SYSTEM_ENUMP(); +extern void SYSTEM_ENUMR(); + +/* module registry */ +#define __DEFMOD static void *m; if(m!=0)return m +#define __REGMOD(name, enum) if(m==0)m=SYSTEM_REGMOD((CHAR*)name,enum); else return m +#define __ENDMOD return m +#define __INIT(argc, argv) static void *m; SYSTEM_INIT(argc, (long)&argv); +#define __REGMAIN(name, enum) m=SYSTEM_REGMOD(name,enum) +#define __FINI SYSTEM_FINI(); return 0 +#define __IMPORT(name) SYSTEM_INCREF(name##__init()) +#define __REGCMD(name, cmd) SYSTEM_REGCMD(m, name, cmd) + +/* SYSTEM ops */ +#define __SYSNEW(p, len) p=SYSTEM_NEWBLK((long)(len)) +#define __VAL(t, x) (*(t*)&(x)) +#define __GET(a, x, t) x= *(t*)(a) +#define __PUT(a, x, t) *(t*)(a)=x +#define __LSHL(x, n, t) ((t)((unsigned)(x)<<(n))) +#define __LSHR(x, n, t) ((t)((unsigned)(x)>>(n))) +#define __LSH(x, n, t) ((n)>=0? __LSHL(x, n, t): __LSHR(x, -(n), t)) +#define __ROTL(x, n, t) ((t)((unsigned)(x)<<(n)|(unsigned)(x)>>(8*sizeof(t)-(n)))) +#define __ROTR(x, n, t) ((t)((unsigned)(x)>>(n)|(unsigned)(x)<<(8*sizeof(t)-(n)))) +#define __ROT(x, n, t) ((n)>=0? __ROTL(x, n, t): __ROTR(x, -(n), t)) +#define __BIT(x, n) (*(unsigned long*)(x)>>(n)&1) +#define __MOVE(s, d, n) memcpy((char*)(d),(char*)(s),n) + +/* std procs and operator mappings */ +#define __SHORT(x, y) ((int)((unsigned long)(x)+(y)<(y)+(y)?(x):(__HALT(-8),0))) +#define __SHORTF(x, y) ((int)(__RF((x)+(y),(y)+(y))-(y))) +#define __CHR(x) ((CHAR)__R(x, 256)) +#define __CHRF(x) ((CHAR)__RF(x, 256)) +#define __DIV(x, y) ((x)>=0?(x)/(y):-(((y)-1-(x))/(y))) +#define __DIVF(x, y) SYSTEM_DIV((long)(x),(long)(y)) +#define __MOD(x, y) ((x)>=0?(x)%(y):__MODF(x,y)) +#define __MODF(x, y) SYSTEM_MOD((long)(x),(long)(y)) +#define __NEW(p, t) p=SYSTEM_NEWREC((long)t##__typ) +#define __NEWARR SYSTEM_NEWARR +#define __HALT(x) SYSTEM_HALT(x) +#define __ASSERT(cond, x) if (!(cond)) {SYSTEM_assert = x; SYSTEM_HALT(-1);} +#define __ENTIER(x) SYSTEM_ENTIER(x) +#define __ABS(x) (((x)<0)?-(x):(x)) +#define __ABSF(x) SYSTEM_ABS((long)(x)) +#define __ABSFD(x) SYSTEM_ABSD((double)(x)) +#define __CAP(ch) ((CHAR)((ch)&0x5f)) +#define __ODD(x) ((x)&1) +#define __IN(x, s) (((s)>>(x))&1) +#define __SETOF(x) ((SET)1<<(x)) +#define __SETRNG(l, h) ((~(SET)0<<(l))&~(SET)0>>(8*sizeof(SET)-1-(h))) +#define __MASK(x, m) ((x)&~(m)) +#define __COPY(s, d, n) {char*_a=(void*)s,*_b=(void*)d;long _i=0,_t=n-1;while(_i<_t&&((_b[_i]=_a[_i])!=0)){_i++;};_b[_i]=0;} +static int __STRCMP(x, y) + CHAR *x, *y; +{long i = 0; CHAR ch1, ch2; + do {ch1 = x[i]; ch2 = y[i]; i++; + if (!ch1) return -(int)ch2; + } while (ch1==ch2); + return (int)ch1 - (int)ch2; +} +#define __ASH(x, n) ((n)>=0?__ASHL(x,n):__ASHR(x,-(n))) +#define __ASHL(x, n) ((long)(x)<<(n)) +#define __ASHR(x, n) ((long)(x)>>(n)) +#define __ASHF(x, n) SYSTEM_ASH((long)(x), (long)(n)) +#define __DUP(x, l, t) x=(void*)memcpy(alloca(l*sizeof(t)),x,l*sizeof(t)) +#define __DUPARR(v, t) v=(void*)memcpy(v##__copy,v,sizeof(t)) +#define __DEL(x) /* DUP with alloca frees storage automatically */ +#define __IS(tag, typ, level) (*(tag-(__BASEOFF-level))==(long)typ##__typ) +#define __TYPEOF(p) (*(((long**)(p))-1)) +#define __ISP(p, typ, level) __IS(__TYPEOF(p),typ,level) + +/* runtime checks */ +#define __X(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-2),0)) +#define __XF(i, ub) SYSTEM_XCHK((long)(i), (long)(ub)) +#define __RETCHK __retchk: __HALT(-3) +#define __CASECHK __HALT(-4) +#define __GUARDP(p, typ, level) ((typ*)(__ISP(p,typ,level)?p:(__HALT(-5),p))) +#define __GUARDR(r, typ, level) (*((typ*)(__IS(r##__typ,typ,level)?r:(__HALT(-5),r)))) +#define __GUARDA(p, typ, level) ((struct typ*)(__IS(__TYPEOF(p),typ,level)?p:(__HALT(-5),p))) +#define __GUARDEQR(p, dyntyp, typ) if(dyntyp!=typ##__typ) __HALT(-6);*(p) +#define __GUARDEQP(p, typ) if(__TYPEOF(p)!=typ##__typ)__HALT(-6);*(p) +#define __WITHCHK __HALT(-7) +#define __R(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-8),0)) +#define __RF(i, ub) SYSTEM_RCHK((long)(i),(long)(ub)) + +/* record type descriptors */ +#define __TDESC(t, m, n) \ + static struct t##__desc {\ + long tproc[m]; \ + long tag, next, level, module; \ + char name[24]; \ + long *base[__MAXEXT]; \ + char *rsrvd; \ + long blksz, ptr[n+1]; \ + } t##__desc + +#define __BASEOFF (__MAXEXT+1) +#define __TPROC0OFF (__BASEOFF+24/sizeof(long)+5) +#define __EOM 1 +#define __TDFLDS(name, size) {__EOM}, 1, 0, 0, 0, name, {0}, 0, size +#define __ENUMP(adr, n, P) SYSTEM_ENUMP(adr, (long)(n), P) +#define __ENUMR(adr, typ, size, n, P) SYSTEM_ENUMR(adr, typ, (long)(size), (long)(n), P) + +#define __INITYP(t, t0, level) \ + t##__typ= &t##__desc.blksz; \ + memcpy(t##__desc.base, t0##__typ - __BASEOFF, level*sizeof(long)); \ + t##__desc.base[level]=t##__typ; \ + t##__desc.module=(long)m; \ + if(t##__desc.blksz!=sizeof(struct t)) __HALT(-15); \ + t##__desc.blksz=(t##__desc.blksz+5*sizeof(long)-1)/(4*sizeof(long))*(4*sizeof(long)); \ + SYSTEM_REGTYP(m, (long)&t##__desc.next); \ + SYSTEM_INHERIT(t##__typ, t0##__typ) + +/* Oberon-2 type bound procedures support */ +#define __INITBP(t, proc, num) *(t##__typ-(__TPROC0OFF+num))=(long)proc +#define __SEND(typ, num, funtyp, parlist) ((funtyp)(*(typ-(__TPROC0OFF+num))))parlist + +/* runtime system variables */ +extern LONGINT SYSTEM_argc; +extern LONGINT SYSTEM_argv; +extern void (*SYSTEM_Halt)(); +extern LONGINT SYSTEM_halt; +extern LONGINT SYSTEM_assert; +extern SYSTEM_PTR SYSTEM_modules; +extern LONGINT SYSTEM_heapsize; +extern LONGINT SYSTEM_allocated; +extern LONGINT SYSTEM_lock; +extern SHORTINT SYSTEM_gclock; +extern BOOLEAN SYSTEM_interrupted; + +/* ANSI prototypes; not used so far +static int __STRCMP(CHAR *x, CHAR *y); +void SYSTEM_INIT(int argc, long argvadr); +void SYSTEM_FINI(void); +long SYSTEM_XCHK(long i, long ub); +long SYSTEM_RCHK(long i, long ub); +long SYSTEM_ASH(long i, long n); +long SYSTEM_ABS(long i); +double SYSTEM_ABSD(double i); +void SYSTEM_INHERIT(long *t, long *t0); +void SYSTEM_ENUMP(long *adr, long n, void (*P)(void*)); +void SYSTEM_ENUMR(char *adr, long *typ, long size, long n, void (*P)(void*)); +long SYSTEM_DIV(unsigned long x, unsigned long y); +long SYSTEM_MOD(unsigned long x, unsigned long y); +long SYSTEM_ENTIER(double x); +void SYSTEM_HALT(int n); +*/ + +#endif + diff --git a/src/lib/system/linux/clang/x86/Unix.Mod b/src/lib/system/linux/clang/x86/Unix.Mod new file mode 100644 index 00000000..9e46278e --- /dev/null +++ b/src/lib/system/linux/clang/x86/Unix.Mod @@ -0,0 +1,419 @@ +MODULE Unix; (* Josef Templ, 5.3.90 Linux system calls *) +(* system procedure added by noch *) +(* Module Unix provides a system call interface to Linux. + Naming conventions: + Procedure and Type-names always start with a capital letter. + error numbers as defined in Unix + other constants start with lower case letters *) + +IMPORT SYSTEM; + +CONST + +(* various important constants *) + + stdin* = 0; stdout* =1; stderr* = 2; + + LOCKEX* = 2; LOCKUN* = 8; (* /usr/include/file.h *) + AFINET* = 2; (* /usr/include/sys/socket.h *) + PFINET* = AFINET; (* /usr/include/linux/socket.h *) + SOCKSTREAM* = 1; (* /usr/include/linux/socket.h *) + FIONREAD* = 541BH; (* in /usr/include/asm/termios.h *) + SETFL* = 4; (* set file descriptor flags; in asm/fcntl.h *) + TCP* = 0; + +(* flag sets, cf. /usr/include/asm/fcntl.h *) + rdonly* = {}; wronly* = {0}; rdwr* = {1}; creat* = {6}; excl* = {7}; trunc* = {9}; append* = {10}; ndelay = {11}; + +(* error numbers *) + + EPERM* = 1; (* Not owner *) + ENOENT* = 2; (* No such file or directory *) + ESRCH* = 3; (* No such process *) + EINTR* = 4; (* Interrupted system call *) + EIO* = 5; (* I/O error *) + ENXIO* = 6; (* No such device or address *) + E2BIG* = 7; (* Arg list too long *) + ENOEXEC* = 8; (* Exec format error *) + EBADF* = 9; (* Bad file number *) + ECHILD* = 10; (* No children *) + EAGAIN* = 11; (* No more processes *) + ENOMEM* = 12; (* Not enough core *) + EACCES* = 13; (* Permission denied *) + EFAULT* = 14; (* Bad address *) + ENOTBLK* = 15; (* Block device required *) + EBUSY* = 16; (* Mount device busy *) + EEXIST* = 17; (* File exists *) + EXDEV* = 18; (* Cross-device link *) + ENODEV* = 19; (* No such device *) + ENOTDIR* = 20; (* Not a directory*) + EISDIR* = 21; (* Is a directory *) + EINVAL* = 22; (* Invalid argument *) + ENFILE* = 23; (* File table overflow *) + EMFILE* = 24; (* Too many open files *) + ENOTTY* = 25; (* Not a typewriter *) + ETXTBSY* = 26; (* Text file busy *) + EFBIG* = 27; (* File too large *) + ENOSPC* = 28; (* No space left on device *) + ESPIPE* = 29; (* Illegal seek *) + EROFS* = 30; (* Read-only file system *) + EMLINK* = 31; (* Too many links *) + EPIPE* = 32; (* Broken pipe *) + EDOM* = 33; (* Argument too large *) + ERANGE* = 34; (* Result too large *) + EDEADLK* = 35; (* Resource deadlock would occur *) + ENAMETOOLONG* = 36; (* File name too long *) + ENOLCK* = 37; (* No record locks available *) + ENOSYS* = 38; (* Function not implemented *) + ENOTEMPTY* = 39; (* Directory not empty *) + ELOOP* = 40; (* Too many symbolic links encountered *) + EWOULDBLOCK* = EAGAIN; (* Operation would block *) + ENOMSG* = 42; (* No message of desired type *) + EIDRM* = 43; (* Identifier removed *) + ECHRNG* = 44; (* Channel number out of range *) + EL2NSYNC* = 45; (* Level 2 not synchronized *) + EL3HLT* = 46; (* Level 3 halted *) + EL3RST* = 47; (* Level 3 reset *) + ELNRNG* = 48; (* Link number out of range *) + EUNATCH* = 49; (* Protocol driver not attached *) + ENOCSI* = 50; (* No CSI structure available *) + EL2HLT* = 51; (* Level 2 halted *) + EBADE* = 52; (* Invalid exchange *) + EBADR* = 53; (* Invalid request descriptor *) + EXFULL* = 54; (* Exchange full *) + ENOANO* = 55; (* No anode *) + EBADRQC* = 56; (* Invalid request code *) + EBADSLT* = 57; (* Invalid slot *) + EDEADLOCK* = 58; (* File locking deadlock error *) + EBFONT* = 59; (* Bad font file format *) + ENOSTR* = 60; (* Device not a stream *) + ENODATA* = 61; (* No data available *) + ETIME* = 62; (* Timer expired *) + ENOSR* = 63; (* Out of streams resources *) + ENONET* = 64; (* Machine is not on the network *) + ENOPKG* = 65; (* Package not installed *) + EREMOTE* = 66; (* Object is remote *) + ENOLINK* = 67; (* Link has been severed *) + EADV* = 68; (* Advertise error *) + ESRMNT* = 69; (* Srmount error *) + ECOMM* = 70; (* Communication error on send *) + EPROTO* = 71; (* Protocol error *) + EMULTIHOP* = 72; (* Multihop attempted *) + EDOTDOT* = 73; (* RFS specific error *) + EBADMSG* = 74; (* Not a data message *) + EOVERFLOW* = 75; (* Value too large for defined data type *) + ENOTUNIQ* = 76; (* Name not unique on network *) + EBADFD* = 77; (* File descriptor in bad state *) + EREMCHG* = 78; (* Remote address changed *) + ELIBACC* = 79; (* Can not access a needed shared library *) + ELIBBAD* = 80; (* Accessing a corrupted shared library *) + ELIBSCN* = 81; (* .lib section in a.out corrupted *) + ELIBMAX* = 82; (* Attempting to link in too many shared libraries *) + ELIBEXEC* = 83; (* Cannot exec a shared library directly *) + EILSEQ* = 84; (* Illegal byte sequence *) + ERESTART* = 85; (* Interrupted system call should be restarted *) + ESTRPIPE* = 86; (* Streams pipe error *) + EUSERS* = 87; (* Too many users *) + ENOTSOCK* = 88; (* Socket operation on non-socket *) + EDESTADDRREQ* = 89; (* Destination address required *) + EMSGSIZE* = 90; (* Message too long *) + EPROTOTYPE* = 91; (* Protocol wrong type for socket *) + ENOPROTOOPT* = 92; (* Protocol not available *) + EPROTONOSUPPORT* = 93; (* Protocol not supported *) + ESOCKTNOSUPPORT* = 94; (* Socket type not supported *) + EOPNOTSUPP* = 95; (* Operation not supported on transport endpoint *) + EPFNOSUPPORT* = 96; (* Protocol family not supported *) + EAFNOSUPPORT* = 97; (* Address family not supported by protocol *) + EADDRINUSE* = 98; (* Address already in use *) + EADDRNOTAVAIL* = 99; (* Cannot assign requested address *) + ENETDOWN* = 100; (* Network is down *) + ENETUNREACH* = 101; (* Network is unreachable *) + ENETRESET* = 102; (* Network dropped connection because of reset *) + ECONNABORTED* = 103; (* Software caused connection abort *) + ECONNRESET* = 104; (* Connection reset by peer *) + ENOBUFS* = 105; (* No buffer space available *) + EISCONN* = 106; (* Transport endpoint is already connected *) + ENOTCONN* = 107; (* Transport endpoint is not connected *) + ESHUTDOWN* = 108; (* Cannot send after transport endpoint shutdown *) + ETOOMANYREFS* = 109; (* Too many references: cannot splice *) + ETIMEDOUT* = 110; (* Connection timed out *) + ECONNREFUSED* = 111; (* Connection refused *) + EHOSTDOWN* = 112; (* Host is down *) + EHOSTUNREACH* = 113; (* No route to host *) + EALREADY* = 114; (* Operation already in progress *) + EINPROGRESS* = 115; (* Operation now in progress *) + ESTALE* = 116; (* Stale NFS file handle *) + EUCLEAN* = 117; (* Structure needs cleaning *) + ENOTNAM* = 118; (* Not a XENIX named type file *) + ENAVAIL* = 119; (* No XENIX semaphores available *) + EISNAM* = 120; (* Is a named type file *) + EREMOTEIO* = 121; (* Remote I/O error *) + EDQUOT* = 122; (* Quota exceeded *) + + +TYPE + JmpBuf* = RECORD + bx*, si*, di*, bp*, sp*, pc*: LONGINT; + maskWasSaved*, savedMask*: LONGINT; + END ; + + Status* = RECORD (* struct stat *) + dev*, devX*: LONGINT; (* 64 bit in Linux 2.2 *) + pad1: INTEGER; + ino*, mode*, nlink*, uid*, gid*: LONGINT; + rdev*, rdevX*: LONGINT; (* 64 bit in Linux 2.2 *) + pad2: INTEGER; + size*, blksize*, blocks*, atime*, unused1*, mtime*, unused2*, ctime*, + unused3*, unused4*, unused5*: LONGINT; + END ; + + Timeval* = RECORD + sec*, usec*: LONGINT + END ; + + Timezone* = RECORD + minuteswest*, dsttime*: LONGINT + END ; + + Itimerval* = RECORD + interval*, value*: Timeval + END ; + + FdSet* = ARRAY 8 OF SET; + + SigCtxPtr* = POINTER TO SigContext; + SigContext* = RECORD + END ; + + SignalHandler* = PROCEDURE (sig, code: LONGINT; scp: SigCtxPtr); + + Dirent* = RECORD + ino, off: LONGINT; + reclen: INTEGER; + name: ARRAY 256 OF CHAR; + END ; + + Rusage* = RECORD + utime*, stime*: Timeval; + maxrss*, ixrss*, idrss*, isrss*, + minflt*, majflt*, nswap*, inblock*, + oublock*, msgsnd*, msgrcv*, nsignals*, + nvcsw*, nivcsw*: LONGINT + END ; + + Iovec* = RECORD + base*, len*: LONGINT + END ; + + SocketPair* = ARRAY 2 OF LONGINT; + + Pollfd* = RECORD + fd*: LONGINT; + events*, revents*: INTEGER + END ; + + Sockaddr* = RECORD + family*: INTEGER; + port*: INTEGER; + internetAddr*: LONGINT; + pad*: ARRAY 8 OF CHAR; + END ; + + HostEntry* = POINTER [1] TO Hostent; + Hostent* = RECORD + name*, aliases*: LONGINT; + addrtype*, length*: LONGINT; + addrlist*: LONGINT; (*POINTER TO POINTER TO LONGINT, network byte order*) + END; + + Name* = ARRAY OF CHAR; + + PROCEDURE -includeStat() + "#include "; + + PROCEDURE -includeErrno() + "#include "; + + PROCEDURE -err(): LONGINT + "errno"; + + PROCEDURE errno*(): LONGINT; + BEGIN + RETURN err() + END errno; + + PROCEDURE -Exit*(n: LONGINT) + "exit(n)"; + + PROCEDURE -Fork*(): LONGINT + "fork()"; + + PROCEDURE -Wait*(VAR status: LONGINT): LONGINT + "wait(status)"; + + PROCEDURE -Select*(width: LONGINT; VAR readfds, writefds, exceptfds: FdSet; VAR timeout: Timeval): LONGINT + "select(width, readfds, writefds, exceptfds, timeout)"; + + PROCEDURE -Gettimeofday* (VAR tv: Timeval; VAR tz: Timezone) : LONGINT + "gettimeofday(tv, tz)"; + + PROCEDURE -Read* (fd, buf, nbyte: LONGINT): LONGINT + "read(fd, buf, nbyte)"; + + PROCEDURE -ReadBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "read(fd, buf, buf__len)"; + + PROCEDURE -Write* (fd, buf, nbyte: LONGINT): LONGINT + "write(fd, buf, nbyte)"; + + PROCEDURE -WriteBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "write(fd, buf, buf__len)"; + + PROCEDURE -Dup*(fd: LONGINT): LONGINT + "dup(fd)"; + + PROCEDURE -Dup2*(fd1, fd2: LONGINT): LONGINT + "dup(fd1, fd2)"; + + PROCEDURE -Pipe*(fds : LONGINT): LONGINT + "pipe(fds)"; + + PROCEDURE -Getpid*(): LONGINT + "getpid()"; + + PROCEDURE -Getuid*(): LONGINT + "getuid()"; + + PROCEDURE -Geteuid*(): LONGINT + "geteuid()"; + + PROCEDURE -Getgid*(): LONGINT + "getgid()"; + + PROCEDURE -Getegid*(): LONGINT + "getegid()"; + + PROCEDURE -Unlink*(name: Name): LONGINT + "unlink(name)"; + + PROCEDURE -Open*(name: Name; flag, mode: SET): LONGINT + "open(name, flag, mode)"; + + PROCEDURE -Close*(fd: LONGINT): LONGINT + "close(fd)"; + + PROCEDURE -stat(name: Name; VAR statbuf: Status): LONGINT + "stat((const char*)name, (struct stat*)statbuf)"; + + PROCEDURE Stat*(name: Name; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := stat(name, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); + RETURN res; + END Stat; + + PROCEDURE -fstat(fd: LONGINT; VAR statbuf: Status): LONGINT + "fstat(fd, (struct stat*)statbuf)"; + + PROCEDURE Fstat*(fd: LONGINT; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := fstat(fd, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); + RETURN res; + END Fstat; + + PROCEDURE -Fchmod*(fd, mode: LONGINT): LONGINT + "fchmod(fd, mode)"; + + PROCEDURE -Chmod*(path: Name; mode: LONGINT): LONGINT + "chmod(path, mode)"; + + PROCEDURE -Lseek*(fd, offset, origin: LONGINT): LONGINT + "lseek(fd, offset, origin)"; + + PROCEDURE -Fsync*(fd: LONGINT): LONGINT + "fsync(fd)"; + + PROCEDURE -Fcntl*(fd, cmd, arg: LONGINT ): LONGINT + "fcntl(fd, cmd, arg)"; + + PROCEDURE -Flock*(fd, operation: LONGINT): LONGINT + "flock(fd, operation)"; + + PROCEDURE -Ftruncate*(fd, length: LONGINT): LONGINT + "ftruncate(fd, length)"; + + PROCEDURE -Readblk*(fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE; len: LONGINT): LONGINT + "read(fd, buf, len)"; + + PROCEDURE -Rename*(old, new: Name): LONGINT + "rename(old, new)"; + + PROCEDURE -Chdir*(path: Name): LONGINT + "chdir(path)"; + + PROCEDURE -Ioctl*(fd, request, arg: LONGINT): LONGINT + "ioctl(fd, request, arg)"; + + PROCEDURE -Kill*(pid, sig: LONGINT): LONGINT + "kill(pid, sig)"; + + PROCEDURE -Sigsetmask*(mask: LONGINT): LONGINT + "sigsetmask(mask)"; + + + (* TCP/IP networking *) + + PROCEDURE -Gethostbyname*(name: Name): HostEntry + "(Unix_HostEntry)gethostbyname(name)"; + + PROCEDURE -Gethostname*(VAR name: Name): LONGINT + "gethostname(name, name__len)"; + + PROCEDURE -Socket*(af, type, protocol: LONGINT): LONGINT + "socket(af, type, protocol)"; + + PROCEDURE -Connect*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "connect(socket, &(name), namelen)"; + + PROCEDURE -Getsockname*(socket: LONGINT; VAR name: Sockaddr; VAR namelen: LONGINT): LONGINT + "getsockname(socket, name, namelen)"; + + PROCEDURE -Bind*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "bind(socket, &(name), namelen)"; + + PROCEDURE -Listen*(socket, backlog: LONGINT): LONGINT + "listen(socket, backlog)"; + + PROCEDURE -Accept*(socket: LONGINT; VAR addr: Sockaddr; VAR addrlen: LONGINT): LONGINT + "accept(socket, addr, addrlen)"; + + PROCEDURE -Recv*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "recv(socket, bufadr, buflen, flags)"; + + PROCEDURE -Send*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "send(socket, bufadr, buflen, flags)"; + + PROCEDURE -sys(str: ARRAY OF CHAR): INTEGER (* need this to call external tools like gcc or gas; noch *) + "system(str)"; + + PROCEDURE system*(cmd : ARRAY OF CHAR); + VAR r : INTEGER; + BEGIN + r := sys(cmd); + END system; + + PROCEDURE System*(cmd : ARRAY OF CHAR): INTEGER; + VAR r : INTEGER; + BEGIN + r := sys(cmd); + RETURN r + END System; + +END Unix. diff --git a/src/lib/system/linux/clang/x86_64/Args.Mod b/src/lib/system/linux/clang/x86_64/Args.Mod new file mode 100644 index 00000000..c6b7b56e --- /dev/null +++ b/src/lib/system/linux/clang/x86_64/Args.Mod @@ -0,0 +1,65 @@ +MODULE Args; (* jt, 8.12.94 *) + + (* command line argument handling for voc (jet backend) *) + + + IMPORT SYSTEM; + + TYPE + ArgPtr = POINTER TO ARRAY 1024 OF CHAR; + ArgVec = POINTER TO ARRAY 1024 OF ArgPtr; + + VAR argc-, argv-: LONGINT; + (*PROCEDURE -includestdlib() "#include ";*) + PROCEDURE -externgetenv() "extern char *getenv(const char *name);"; (* took this from stdlib.h*) + PROCEDURE -Argc(): INTEGER "SYSTEM_argc"; + PROCEDURE -Argv(): LONGINT "(long)SYSTEM_argv"; + PROCEDURE -getenv(var: ARRAY OF CHAR): ArgPtr + "(Args_ArgPtr)getenv(var)"; + + PROCEDURE Get*(n: INTEGER; VAR val: ARRAY OF CHAR); + VAR av: ArgVec; + BEGIN + IF n < argc THEN av := SYSTEM.VAL(ArgVec, argv); COPY(av[n]^, val) END + END Get; + + PROCEDURE GetInt*(n: INTEGER; VAR val: LONGINT); + VAR s: ARRAY 64 OF CHAR; k, d, i: LONGINT; + BEGIN + s := ""; Get(n, s); i := 0; + IF s[0] = "-" THEN i := 1 END ; + k := 0; d := ORD(s[i]) - ORD("0"); + WHILE (d >= 0 ) & (d <= 9) DO k := k*10 + d; INC(i); d := ORD(s[i]) - ORD("0") END ; + IF s[0] = "-" THEN d := -d; DEC(i) END ; + IF i > 0 THEN val := k END + END GetInt; + + PROCEDURE Pos*(s: ARRAY OF CHAR): INTEGER; + VAR i: INTEGER; arg: ARRAY 256 OF CHAR; + BEGIN + i := 0; Get(i, arg); + WHILE (i < argc) & (s # arg) DO INC(i); Get(i, arg) END ; + RETURN i + END Pos; + + PROCEDURE GetEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR); + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN COPY(p^, val) END + END GetEnv; + + PROCEDURE getEnv*(var: ARRAY OF CHAR; VAR val: ARRAY OF CHAR): BOOLEAN; + VAR p: ArgPtr; + BEGIN + p := getenv(var); + IF p # NIL THEN + COPY(p^, val); + RETURN TRUE + ELSE + RETURN FALSE + END + END getEnv; + +BEGIN argc := Argc(); argv := Argv() +END Args. diff --git a/src/lib/system/linux/clang/x86_64/SYSTEM.c0 b/src/lib/system/linux/clang/x86_64/SYSTEM.c0 new file mode 100644 index 00000000..bb8ee442 --- /dev/null +++ b/src/lib/system/linux/clang/x86_64/SYSTEM.c0 @@ -0,0 +1,205 @@ +/* +* The body prefix file of the voc(jet backend) runtime system, Version 1.0 +* +* Copyright (c) Software Templ, 1994, 1995 +* +* Module SYSTEM is subject to change any time without prior notification. +* Software Templ disclaims all warranties with regard to module SYSTEM, +* in particular shall Software Templ not be liable for any damage resulting +* from inappropriate use or modification of module SYSTEM. +* +* Version 1.1 jt, 24.11.95 fixes for correct pointer arithmetic on Cray computers +* jt 31.1.2007 ANSI prototypes for malloc and exit in order to avoid cc warnings +* +*/ + +#include "SYSTEM.h" +#ifdef __STDC__ +#include "stdarg.h" +#else +#include "varargs.h" +#endif + +extern void *malloc(long size); +extern void exit(int status); + +void (*SYSTEM_Halt)(); +LONGINT SYSTEM_halt; /* x in HALT(x) */ +LONGINT SYSTEM_assert; /* x in ASSERT(cond, x) */ +LONGINT SYSTEM_argc; +LONGINT SYSTEM_argv; +LONGINT SYSTEM_lock; +BOOLEAN SYSTEM_interrupted; +static LONGINT SYSTEM_mainfrm; /* adr of main proc stack frame, used for stack collection */ + +#define Lock SYSTEM_lock++ +#define Unlock SYSTEM_lock--; if (SYSTEM_interrupted && (SYSTEM_lock == 0)) __HALT(-9) + + +static void SYSTEM_InitHeap(); +void *SYSTEM__init(); + +void SYSTEM_INIT(argc, argvadr) + int argc; long argvadr; +{ + SYSTEM_mainfrm = argvadr; + SYSTEM_argc = argc; + SYSTEM_argv = *(long*)argvadr; + SYSTEM_InitHeap(); + SYSTEM_halt = -128; + SYSTEM__init(); +} + +void SYSTEM_FINI() +{ + SYSTEM_FINALL(); +} + +long SYSTEM_XCHK(i, ub) long i, ub; {return __X(i, ub);} +long SYSTEM_RCHK(i, ub) long i, ub; {return __R(i, ub);} +long SYSTEM_ASH(i, n) long i, n; {return __ASH(i, n);} +long SYSTEM_ABS(i) long i; {return __ABS(i);} +double SYSTEM_ABSD(i) double i; {return __ABS(i);} + +void SYSTEM_INHERIT(t, t0) + long *t, *t0; +{ + t -= __TPROC0OFF; + t0 -= __TPROC0OFF; + while (*t0 != __EOM) {*t = *t0; t--; t0--;} +} + +void SYSTEM_ENUMP(adr, n, P) + long *adr; + long n; + void (*P)(); +{ + while (n > 0) {P(*adr); adr++; n--;} +} + +void SYSTEM_ENUMR(adr, typ, size, n, P) + char *adr; + long *typ, size, n; + void (*P)(); +{ + long *t, off; + typ++; + while (n > 0) { + t = typ; + off = *t; + while (off >= 0) {P(*(long*)(adr+off)); t++; off = *t;} + adr += size; n--; + } +} + +long SYSTEM_DIV(x, y) + unsigned long x, y; +{ if ((long) x >= 0) return (x / y); + else return -((y - 1 - x) / y); +} + +long SYSTEM_MOD(x, y) + unsigned long x, y; +{ unsigned long m; + if ((long) x >= 0) return (x % y); + else { m = (-x) % y; + if (m != 0) return (y - m); else return 0; + } +} + +long SYSTEM_ENTIER(x) + double x; +{ + long y; + if (x >= 0) + return (long)x; + else { + y = (long)x; + if (y <= x) return y; else return y - 1; + } +} + +void SYSTEM_HALT(n) + int n; +{ + SYSTEM_halt = n; + if (SYSTEM_Halt!=0) SYSTEM_Halt(n); + exit(n); +} + +#ifdef __STDC__ +SYSTEM_PTR SYSTEM_NEWARR(long *typ, long elemsz, int elemalgn, int nofdim, int nofdyn, ...) +#else +SYSTEM_PTR SYSTEM_NEWARR(typ, elemsz, elemalgn, nofdim, nofdyn, va_alist) + long *typ, elemsz; + int elemalgn, nofdim, nofdyn; + va_dcl +#endif +{ + long nofelems, size, dataoff, n, nptr, *x, *p, nofptrs, i, *ptab, off; + va_list ap; +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + nofelems = 1; + while (nofdim > 0) { + nofelems = nofelems * va_arg(ap, long); nofdim--; + if (nofelems <= 0) __HALT(-20); + } + va_end(ap); + dataoff = nofdyn * sizeof(long); + if (elemalgn > sizeof(long)) { + n = dataoff % elemalgn; + if (n != 0) dataoff += elemalgn - n; + } + size = dataoff + nofelems * elemsz; + Lock; + if (typ == NIL) { + /* element typ does not contain pointers */ + x = SYSTEM_NEWBLK(size); + } + else if (typ == POINTER__typ) { + /* element type is a pointer */ + x = SYSTEM_NEWBLK(size + nofelems * sizeof(long)); + p = (long*)x[-1]; + p[-nofelems] = *p; /* build new type desc in situ: 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nofelems - 1; n = 1; /* n =1 for skipping the size field */ + while (n <= nofelems) {*p = n*sizeof(long); p++; n++;} + *p = - (nofelems + 1) * sizeof(long); /* sentinel */ + x[-1] -= nofelems * sizeof(long); + } + else { + /* element type is a record that contains pointers */ + ptab = typ + 1; nofptrs = 0; + while (ptab[nofptrs] >= 0) {nofptrs++;} /* number of pointers per element */ + nptr = nofelems * nofptrs; /* total number of pointers */ + x = SYSTEM_NEWBLK(size + nptr * sizeof(long)); + p = (long*)x[- 1]; + p[-nptr] = *p; /* build new type desc in situ; 1. copy block size; 2. setup ptr tab; 3. set sentinel; 4. patch tag */ + p -= nptr - 1; n = 0; off = dataoff; + while (n < nofelems) {i = 0; + while (i < nofptrs) {*p = off + ptab[i]; p++; i++;} + off += elemsz; n++; + } + *p = - (nptr + 1) * sizeof(long); /* sentinel */ + x[-1] -= nptr * sizeof(long); + } + if (nofdyn != 0) { + /* setup len vector for index checks */ +#ifdef __STDC__ + va_start(ap, nofdyn); +#else + va_start(ap); +#endif + p = x; + while (nofdyn > 0) {*p = va_arg(ap, long); p++, nofdyn--;} + va_end(ap); + } + Unlock; + return x; +} + +/* ----------- end of SYSTEM.co ------------- */ + diff --git a/src/lib/system/linux/clang/x86_64/SYSTEM.h b/src/lib/system/linux/clang/x86_64/SYSTEM.h new file mode 100644 index 00000000..e9a246b7 --- /dev/null +++ b/src/lib/system/linux/clang/x86_64/SYSTEM.h @@ -0,0 +1,233 @@ +#ifndef SYSTEM__h +#define SYSTEM__h + +/* + +voc (jet backend) runtime system interface and macros library +copyright (c) Josef Templ, 1995, 1996 + +gcc for Linux version (same as SPARC/Solaris2) +uses double # as concatenation operator + +*/ + +#include + +extern void *memcpy(void *dest, const void *src, long n); +extern void *malloc(long size); +extern void exit(int status); + +#define export +#define import extern + +/* constants */ +#define __MAXEXT 16 +#define NIL 0L +#define POINTER__typ (long*)1L /* not NIL and not a valid type */ + +/* basic types */ +//typedef char BOOLEAN; +#define BOOLEAN char +//typedef unsigned char CHAR; +#define CHAR unsigned char +//exactly two bytes +#define LONGCHAR unsigned short int +//typedef signed char SHORTINT; +#define SHORTINT signed char +//for x86 GNU/Linux +//typedef short int INTEGER; +//for x86_64 GNU/Linux +//typedef int INTEGER; +#define INTEGER int +//typedef long LONGINT; +#define LONGINT long +//typedef float REAL; +#define REAL float +//typedef double LONGREAL; +#define LONGREAL double +//typedef unsigned long SET; +#define SET unsigned long +typedef void *SYSTEM_PTR; +//#define *SYSTEM_PTR void +//typedef unsigned char SYSTEM_BYTE; +#define SYSTEM_BYTE unsigned char + +/* runtime system routines */ +extern long SYSTEM_DIV(); +extern long SYSTEM_MOD(); +extern long SYSTEM_ENTIER(); +extern long SYSTEM_ASH(); +extern long SYSTEM_ABS(); +extern long SYSTEM_XCHK(); +extern long SYSTEM_RCHK(); +extern double SYSTEM_ABSD(); +extern SYSTEM_PTR SYSTEM_NEWREC(); +extern SYSTEM_PTR SYSTEM_NEWBLK(); +#ifdef __STDC__ +extern SYSTEM_PTR SYSTEM_NEWARR(long*, long, int, int, int, ...); +#else +extern SYSTEM_PTR SYSTEM_NEWARR(); +#endif +extern SYSTEM_PTR SYSTEM_REGMOD(); +extern void SYSTEM_INCREF(); +extern void SYSTEM_REGCMD(); +extern void SYSTEM_REGTYP(); +extern void SYSTEM_REGFIN(); +extern void SYSTEM_FINALL(); +extern void SYSTEM_INIT(); +extern void SYSTEM_FINI(); +extern void SYSTEM_HALT(); +extern void SYSTEM_INHERIT(); +extern void SYSTEM_ENUMP(); +extern void SYSTEM_ENUMR(); + +/* module registry */ +#define __DEFMOD static void *m; if(m!=0)return m +#define __REGMOD(name, enum) if(m==0)m=SYSTEM_REGMOD((CHAR*)name,enum); else return m +#define __ENDMOD return m +#define __INIT(argc, argv) static void *m; SYSTEM_INIT(argc, (long)&argv); +#define __REGMAIN(name, enum) m=SYSTEM_REGMOD(name,enum) +#define __FINI SYSTEM_FINI(); return 0 +#define __IMPORT(name) SYSTEM_INCREF(name##__init()) +#define __REGCMD(name, cmd) SYSTEM_REGCMD(m, name, cmd) + +/* SYSTEM ops */ +#define __SYSNEW(p, len) p=SYSTEM_NEWBLK((long)(len)) +#define __VAL(t, x) (*(t*)&(x)) +#define __GET(a, x, t) x= *(t*)(a) +#define __PUT(a, x, t) *(t*)(a)=x +#define __LSHL(x, n, t) ((t)((unsigned t)(x)<<(n))) +#define __LSHR(x, n, t) ((t)((unsigned t)(x)>>(n))) +#define __LSH(x, n, t) ((n)>=0? __LSHL(x, n, t): __LSHR(x, -(n), t)) +#define __ROTL(x, n, t) ((t)((unsigned t)(x)<<(n)|(unsigned t)(x)>>(8*sizeof(t)-(n)))) +#define __ROTR(x, n, t) ((t)((unsigned t)(x)>>(n)|(unsigned t)(x)<<(8*sizeof(t)-(n)))) +#define __LSHR(x, n, t) ((t)((unsigned t)(x)>>(n))) +#define __LSH(x, n, t) ((n)>=0? __LSHL(x, n, t): __LSHR(x, -(n), t)) +#define __ROTL(x, n, t) ((t)((unsigned t)(x)<<(n)|(unsigned t)(x)>>(8*sizeof(t)-(n)))) +#define __ROTR(x, n, t) ((t)((unsigned t)(x)>>(n)|(unsigned t)(x)<<(8*sizeof(t)-(n)))) +#define __ROT(x, n, t) ((n)>=0? __ROTL(x, n, t): __ROTR(x, -(n), t)) +#define __BIT(x, n) (*(unsigned long*)(x)>>(n)&1) +#define __MOVE(s, d, n) memcpy((char*)(d),(char*)(s),n) + +/* std procs and operator mappings */ +#define __SHORT(x, y) ((int)((unsigned long)(x)+(y)<(y)+(y)?(x):(__HALT(-8),0))) +#define __SHORTF(x, y) ((int)(__RF((x)+(y),(y)+(y))-(y))) +#define __CHR(x) ((CHAR)__R(x, 256)) +#define __CHRF(x) ((CHAR)__RF(x, 256)) +#define __DIV(x, y) ((x)>=0?(x)/(y):-(((y)-1-(x))/(y))) +#define __DIVF(x, y) SYSTEM_DIV((long)(x),(long)(y)) +#define __MOD(x, y) ((x)>=0?(x)%(y):__MODF(x,y)) +#define __MODF(x, y) SYSTEM_MOD((long)(x),(long)(y)) +#define __NEW(p, t) p=SYSTEM_NEWREC((long)t##__typ) +#define __NEWARR SYSTEM_NEWARR +#define __HALT(x) SYSTEM_HALT(x) +#define __ASSERT(cond, x) if (!(cond)) {SYSTEM_assert = x; SYSTEM_HALT(-1);} +#define __ENTIER(x) SYSTEM_ENTIER(x) +#define __ABS(x) (((x)<0)?-(x):(x)) +#define __ABSF(x) SYSTEM_ABS((long)(x)) +#define __ABSFD(x) SYSTEM_ABSD((double)(x)) +#define __CAP(ch) ((CHAR)((ch)&0x5f)) +#define __ODD(x) ((x)&1) +#define __IN(x, s) (((s)>>(x))&1) +#define __SETOF(x) ((SET)1<<(x)) +#define __SETRNG(l, h) ((~(SET)0<<(l))&~(SET)0>>(8*sizeof(SET)-1-(h))) +#define __MASK(x, m) ((x)&~(m)) +#define __COPY(s, d, n) {char*_a=(void*)s,*_b=(void*)d;long _i=0,_t=n-1;while(_i<_t&&((_b[_i]=_a[_i])!=0)){_i++;};_b[_i]=0;} +static int __STRCMP(x, y) + CHAR *x, *y; +{long i = 0; CHAR ch1, ch2; + do {ch1 = x[i]; ch2 = y[i]; i++; + if (!ch1) return -(int)ch2; + } while (ch1==ch2); + return (int)ch1 - (int)ch2; +} +#define __ASH(x, n) ((n)>=0?__ASHL(x,n):__ASHR(x,-(n))) +#define __ASHL(x, n) ((long)(x)<<(n)) +#define __ASHR(x, n) ((long)(x)>>(n)) +#define __ASHF(x, n) SYSTEM_ASH((long)(x), (long)(n)) +#define __DUP(x, l, t) x=(void*)memcpy(alloca(l*sizeof(t)),x,l*sizeof(t)) +#define __DUPARR(v, t) v=(void*)memcpy(v##__copy,v,sizeof(t)) +#define __DEL(x) /* DUP with alloca frees storage automatically */ +#define __IS(tag, typ, level) (*(tag-(__BASEOFF-level))==(long)typ##__typ) +#define __TYPEOF(p) (*(((long**)(p))-1)) +#define __ISP(p, typ, level) __IS(__TYPEOF(p),typ,level) + +/* runtime checks */ +#define __X(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-2),0)) +#define __XF(i, ub) SYSTEM_XCHK((long)(i), (long)(ub)) +#define __RETCHK __retchk: __HALT(-3) +#define __CASECHK __HALT(-4) +#define __GUARDP(p, typ, level) ((typ*)(__ISP(p,typ,level)?p:(__HALT(-5),p))) +#define __GUARDR(r, typ, level) (*((typ*)(__IS(r##__typ,typ,level)?r:(__HALT(-5),r)))) +#define __GUARDA(p, typ, level) ((struct typ*)(__IS(__TYPEOF(p),typ,level)?p:(__HALT(-5),p))) +#define __GUARDEQR(p, dyntyp, typ) if(dyntyp!=typ##__typ) __HALT(-6);*(p) +#define __GUARDEQP(p, typ) if(__TYPEOF(p)!=typ##__typ)__HALT(-6);*(p) +#define __WITHCHK __HALT(-7) +#define __R(i, ub) (((unsigned)(long)(i)<(unsigned long)(ub))?i:(__HALT(-8),0)) +#define __RF(i, ub) SYSTEM_RCHK((long)(i),(long)(ub)) + +/* record type descriptors */ +#define __TDESC(t, m, n) \ + static struct t##__desc {\ + long tproc[m]; \ + long tag, next, level, module; \ + char name[24]; \ + long *base[__MAXEXT]; \ + char *rsrvd; \ + long blksz, ptr[n+1]; \ + } t##__desc + +#define __BASEOFF (__MAXEXT+1) +#define __TPROC0OFF (__BASEOFF+24/sizeof(long)+5) +#define __EOM 1 +#define __TDFLDS(name, size) {__EOM}, 1, 0, 0, 0, name, {0}, 0, size +#define __ENUMP(adr, n, P) SYSTEM_ENUMP(adr, (long)(n), P) +#define __ENUMR(adr, typ, size, n, P) SYSTEM_ENUMR(adr, typ, (long)(size), (long)(n), P) + +#define __INITYP(t, t0, level) \ + t##__typ= &t##__desc.blksz; \ + memcpy(t##__desc.base, t0##__typ - __BASEOFF, level*sizeof(long)); \ + t##__desc.base[level]=t##__typ; \ + t##__desc.module=(long)m; \ + if(t##__desc.blksz!=sizeof(struct t)) __HALT(-15); \ + t##__desc.blksz=(t##__desc.blksz+5*sizeof(long)-1)/(4*sizeof(long))*(4*sizeof(long)); \ + SYSTEM_REGTYP(m, (long)&t##__desc.next); \ + SYSTEM_INHERIT(t##__typ, t0##__typ) + +/* Oberon-2 type bound procedures support */ +#define __INITBP(t, proc, num) *(t##__typ-(__TPROC0OFF+num))=(long)proc +#define __SEND(typ, num, funtyp, parlist) ((funtyp)(*(typ-(__TPROC0OFF+num))))parlist + +/* runtime system variables */ +extern LONGINT SYSTEM_argc; +extern LONGINT SYSTEM_argv; +extern void (*SYSTEM_Halt)(); +extern LONGINT SYSTEM_halt; +extern LONGINT SYSTEM_assert; +extern SYSTEM_PTR SYSTEM_modules; +extern LONGINT SYSTEM_heapsize; +extern LONGINT SYSTEM_allocated; +extern LONGINT SYSTEM_lock; +extern SHORTINT SYSTEM_gclock; +extern BOOLEAN SYSTEM_interrupted; + +/* ANSI prototypes; not used so far +static int __STRCMP(CHAR *x, CHAR *y); +void SYSTEM_INIT(int argc, long argvadr); +void SYSTEM_FINI(void); +long SYSTEM_XCHK(long i, long ub); +long SYSTEM_RCHK(long i, long ub); +long SYSTEM_ASH(long i, long n); +long SYSTEM_ABS(long i); +double SYSTEM_ABSD(double i); +void SYSTEM_INHERIT(long *t, long *t0); +void SYSTEM_ENUMP(long *adr, long n, void (*P)(void*)); +void SYSTEM_ENUMR(char *adr, long *typ, long size, long n, void (*P)(void*)); +long SYSTEM_DIV(unsigned long x, unsigned long y); +long SYSTEM_MOD(unsigned long x, unsigned long y); +long SYSTEM_ENTIER(double x); +void SYSTEM_HALT(int n); +*/ + +#endif + diff --git a/src/lib/system/linux/clang/x86_64/Unix.Mod b/src/lib/system/linux/clang/x86_64/Unix.Mod new file mode 100644 index 00000000..7dfde70d --- /dev/null +++ b/src/lib/system/linux/clang/x86_64/Unix.Mod @@ -0,0 +1,501 @@ +MODULE Unix; (* Josef Templ, 5.3.90 Linux system calls *) +(* ported to gnu x86_64 and added system function, noch *) +(* Module Unix provides a system call interface to Linux. + Naming conventions: + Procedure and Type-names always start with a capital letter. + error numbers as defined in Unix + other constants start with lower case letters *) + +IMPORT SYSTEM; + +CONST + +(* various important constants *) + + stdin* = 0; stdout* =1; stderr* = 2; + + LOCKEX* = 2; LOCKUN* = 8; (* /usr/include/file.h *) + AFINET* = 2; (* /usr/include/sys/socket.h *) + PFINET* = AFINET; (* /usr/include/linux/socket.h *) + SOCKSTREAM* = 1; (* /usr/include/linux/socket.h *) + FIONREAD* = 541BH; (* in /usr/include/asm/termios.h *) + SETFL* = 4; (* set file descriptor flags; in asm/fcntl.h *) + TCP* = 0; + +(* flag sets, cf. /usr/include/asm/fcntl.h *) + rdonly* = {}; wronly* = {0}; rdwr* = {1}; creat* = {6}; excl* = {7}; trunc* = {9}; append* = {10}; ndelay = {11}; + +(* error numbers *) + + EPERM* = 1; (* Not owner *) + ENOENT* = 2; (* No such file or directory *) + ESRCH* = 3; (* No such process *) + EINTR* = 4; (* Interrupted system call *) + EIO* = 5; (* I/O error *) + ENXIO* = 6; (* No such device or address *) + E2BIG* = 7; (* Arg list too long *) + ENOEXEC* = 8; (* Exec format error *) + EBADF* = 9; (* Bad file number *) + ECHILD* = 10; (* No children *) + EAGAIN* = 11; (* No more processes *) + ENOMEM* = 12; (* Not enough core *) + EACCES* = 13; (* Permission denied *) + EFAULT* = 14; (* Bad address *) + ENOTBLK* = 15; (* Block device required *) + EBUSY* = 16; (* Mount device busy *) + EEXIST* = 17; (* File exists *) + EXDEV* = 18; (* Cross-device link *) + ENODEV* = 19; (* No such device *) + ENOTDIR* = 20; (* Not a directory*) + EISDIR* = 21; (* Is a directory *) + EINVAL* = 22; (* Invalid argument *) + ENFILE* = 23; (* File table overflow *) + EMFILE* = 24; (* Too many open files *) + ENOTTY* = 25; (* Not a typewriter *) + ETXTBSY* = 26; (* Text file busy *) + EFBIG* = 27; (* File too large *) + ENOSPC* = 28; (* No space left on device *) + ESPIPE* = 29; (* Illegal seek *) + EROFS* = 30; (* Read-only file system *) + EMLINK* = 31; (* Too many links *) + EPIPE* = 32; (* Broken pipe *) + EDOM* = 33; (* Argument too large *) + ERANGE* = 34; (* Result too large *) + EDEADLK* = 35; (* Resource deadlock would occur *) + ENAMETOOLONG* = 36; (* File name too long *) + ENOLCK* = 37; (* No record locks available *) + ENOSYS* = 38; (* Function not implemented *) + ENOTEMPTY* = 39; (* Directory not empty *) + ELOOP* = 40; (* Too many symbolic links encountered *) + EWOULDBLOCK* = EAGAIN; (* Operation would block *) + ENOMSG* = 42; (* No message of desired type *) + EIDRM* = 43; (* Identifier removed *) + ECHRNG* = 44; (* Channel number out of range *) + EL2NSYNC* = 45; (* Level 2 not synchronized *) + EL3HLT* = 46; (* Level 3 halted *) + EL3RST* = 47; (* Level 3 reset *) + ELNRNG* = 48; (* Link number out of range *) + EUNATCH* = 49; (* Protocol driver not attached *) + ENOCSI* = 50; (* No CSI structure available *) + EL2HLT* = 51; (* Level 2 halted *) + EBADE* = 52; (* Invalid exchange *) + EBADR* = 53; (* Invalid request descriptor *) + EXFULL* = 54; (* Exchange full *) + ENOANO* = 55; (* No anode *) + EBADRQC* = 56; (* Invalid request code *) + EBADSLT* = 57; (* Invalid slot *) + EDEADLOCK* = 58; (* File locking deadlock error *) + EBFONT* = 59; (* Bad font file format *) + ENOSTR* = 60; (* Device not a stream *) + ENODATA* = 61; (* No data available *) + ETIME* = 62; (* Timer expired *) + ENOSR* = 63; (* Out of streams resources *) + ENONET* = 64; (* Machine is not on the network *) + ENOPKG* = 65; (* Package not installed *) + EREMOTE* = 66; (* Object is remote *) + ENOLINK* = 67; (* Link has been severed *) + EADV* = 68; (* Advertise error *) + ESRMNT* = 69; (* Srmount error *) + ECOMM* = 70; (* Communication error on send *) + EPROTO* = 71; (* Protocol error *) + EMULTIHOP* = 72; (* Multihop attempted *) + EDOTDOT* = 73; (* RFS specific error *) + EBADMSG* = 74; (* Not a data message *) + EOVERFLOW* = 75; (* Value too large for defined data type *) + ENOTUNIQ* = 76; (* Name not unique on network *) + EBADFD* = 77; (* File descriptor in bad state *) + EREMCHG* = 78; (* Remote address changed *) + ELIBACC* = 79; (* Can not access a needed shared library *) + ELIBBAD* = 80; (* Accessing a corrupted shared library *) + ELIBSCN* = 81; (* .lib section in a.out corrupted *) + ELIBMAX* = 82; (* Attempting to link in too many shared libraries *) + ELIBEXEC* = 83; (* Cannot exec a shared library directly *) + EILSEQ* = 84; (* Illegal byte sequence *) + ERESTART* = 85; (* Interrupted system call should be restarted *) + ESTRPIPE* = 86; (* Streams pipe error *) + EUSERS* = 87; (* Too many users *) + ENOTSOCK* = 88; (* Socket operation on non-socket *) + EDESTADDRREQ* = 89; (* Destination address required *) + EMSGSIZE* = 90; (* Message too long *) + EPROTOTYPE* = 91; (* Protocol wrong type for socket *) + ENOPROTOOPT* = 92; (* Protocol not available *) + EPROTONOSUPPORT* = 93; (* Protocol not supported *) + ESOCKTNOSUPPORT* = 94; (* Socket type not supported *) + EOPNOTSUPP* = 95; (* Operation not supported on transport endpoint *) + EPFNOSUPPORT* = 96; (* Protocol family not supported *) + EAFNOSUPPORT* = 97; (* Address family not supported by protocol *) + EADDRINUSE* = 98; (* Address already in use *) + EADDRNOTAVAIL* = 99; (* Cannot assign requested address *) + ENETDOWN* = 100; (* Network is down *) + ENETUNREACH* = 101; (* Network is unreachable *) + ENETRESET* = 102; (* Network dropped connection because of reset *) + ECONNABORTED* = 103; (* Software caused connection abort *) + ECONNRESET* = 104; (* Connection reset by peer *) + ENOBUFS* = 105; (* No buffer space available *) + EISCONN* = 106; (* Transport endpoint is already connected *) + ENOTCONN* = 107; (* Transport endpoint is not connected *) + ESHUTDOWN* = 108; (* Cannot send after transport endpoint shutdown *) + ETOOMANYREFS* = 109; (* Too many references: cannot splice *) + ETIMEDOUT* = 110; (* Connection timed out *) + ECONNREFUSED* = 111; (* Connection refused *) + EHOSTDOWN* = 112; (* Host is down *) + EHOSTUNREACH* = 113; (* No route to host *) + EALREADY* = 114; (* Operation already in progress *) + EINPROGRESS* = 115; (* Operation now in progress *) + ESTALE* = 116; (* Stale NFS file handle *) + EUCLEAN* = 117; (* Structure needs cleaning *) + ENOTNAM* = 118; (* Not a XENIX named type file *) + ENAVAIL* = 119; (* No XENIX semaphores available *) + EISNAM* = 120; (* Is a named type file *) + EREMOTEIO* = 121; (* Remote I/O error *) + EDQUOT* = 122; (* Quota exceeded *) + +CONST sigsetarrlength = 1024 / 8 * SIZE(LONGINT); + + +TYPE +(* bits/sigset.h + _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) + + 1024 / 8*8 = 16 + 1024 / 8*4 = 32 +*) + sigsett* = RECORD + val : ARRAY 16 OF LONGINT (* 32 for 32 bit *) + (*val : ARRAY sigsetarrlength OF LONGINT *) + END; + + JmpBuf* = RECORD + (*bx*, si*, di*, bp*, sp*, pc*: LONGINT;*) + (* bits/setjmp.h sets up longer array in GNU libc *) + (* + # if __WORDSIZE == 64 + typedef long int __jmp_buf[8]; + # else + typedef int __jmp_buf[6]; + # endif + *) + bx*, si*, di*, bp*, sp*, pc*, ki*, ku*: LONGINT; + (* setjmp.h +/* Calling environment, plus possibly a saved signal mask. */ +struct __jmp_buf_tag + { + /* NOTE: The machine-dependent definitions of `__sigsetjmp' + assume that a `jmp_buf' begins with a `__jmp_buf' and that + `__mask_was_saved' follows it. Do not move these members + or add others before it. */ + __jmp_buf __jmpbuf; /* Calling environment. */ + int __mask_was_saved; /* Saved the signal mask? */ + __sigset_t __saved_mask; /* Saved signal mask. */ + }; + + *) + (*maskWasSaved*, savedMask*: LONGINT;*) + maskWasSaved*: INTEGER; + (* + # define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) +typedef struct + { + unsigned long int __val[_SIGSET_NWORDS]; + } __sigset_t; + + *) + savedMask*: sigsett; + END ; + + Status* = RECORD (* struct stat *) + dev* : LONGINT; (* dev_t 8 *) + ino* : LONGINT; (* ino 8 *) + nlink* : LONGINT; + mode* : INTEGER; + uid*, gid*: INTEGER; + pad0* : INTEGER; + rdev* : LONGINT; + size* : LONGINT; + blksize* : LONGINT; + blocks* : LONGINT; + atime* : LONGINT; + atimences* : LONGINT; + mtime* : LONGINT; + mtimensec* : LONGINT; + ctime* : LONGINT; + ctimensec* : LONGINT; + unused0*, unused1*, unused2*: LONGINT; + END ; + +(* from /usr/include/bits/time.h + +struct timeval + { + __time_t tv_sec; /* Seconds. */ //__time_t 8 + __suseconds_t tv_usec; /* Microseconds. */ __suseconds_t 8 + }; + + +*) + + Timeval* = RECORD + sec*, usec*: LONGINT + END ; + + +(* +from man gettimeofday + + struct timezone { + int tz_minuteswest; /* minutes west of Greenwich */ int 4 + int tz_dsttime; /* type of DST correction */ int 4 + }; +*) + + + Timezone* = RECORD + (*minuteswest*, dsttime*: LONGINT*) + minuteswest*, dsttime*: INTEGER + END ; + + Itimerval* = RECORD + interval*, value*: Timeval + END ; + + FdSet* = ARRAY 8 OF SET; + + SigCtxPtr* = POINTER TO SigContext; + SigContext* = RECORD + END ; + + SignalHandler* = PROCEDURE (sig, code: LONGINT; scp: SigCtxPtr); + + Dirent* = RECORD + ino, off: LONGINT; + reclen: INTEGER; + name: ARRAY 256 OF CHAR; + END ; + + Rusage* = RECORD + utime*, stime*: Timeval; + maxrss*, ixrss*, idrss*, isrss*, + minflt*, majflt*, nswap*, inblock*, + oublock*, msgsnd*, msgrcv*, nsignals*, + nvcsw*, nivcsw*: LONGINT + END ; + + Iovec* = RECORD + base*, len*: LONGINT + END ; + + SocketPair* = ARRAY 2 OF LONGINT; + + Pollfd* = RECORD + fd*: LONGINT; + events*, revents*: INTEGER + END ; + + Sockaddr* = RECORD + family*: INTEGER; + port*: INTEGER; + internetAddr*: LONGINT; + pad*: ARRAY 8 OF CHAR; + END ; + + HostEntry* = POINTER [1] TO Hostent; + Hostent* = RECORD + name*, aliases*: LONGINT; + addrtype*, length*: LONGINT; + addrlist*: LONGINT; (*POINTER TO POINTER TO LONGINT, network byte order*) + END; + + Name* = ARRAY OF CHAR; + + PROCEDURE -includeStat() + "#include "; + + PROCEDURE -includeErrno() + "#include "; + + PROCEDURE -err(): LONGINT + "errno"; + + PROCEDURE errno*(): LONGINT; + BEGIN + RETURN err() + END errno; + + PROCEDURE -Exit*(n: LONGINT) + "exit(n)"; + + PROCEDURE -Fork*(): LONGINT + "fork()"; + + PROCEDURE -Wait*(VAR status: LONGINT): LONGINT + "wait(status)"; + + PROCEDURE -Select*(width: LONGINT; VAR readfds, writefds, exceptfds: FdSet; VAR timeout: Timeval): LONGINT + "select(width, readfds, writefds, exceptfds, timeout)"; + + PROCEDURE -Gettimeofday* (VAR tv: Timeval; VAR tz: Timezone) : LONGINT + "gettimeofday(tv, tz)"; + + PROCEDURE -Read* (fd, buf, nbyte: LONGINT): LONGINT + "read(fd, buf, nbyte)"; + + PROCEDURE -ReadBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "read(fd, buf, buf__len)"; + + PROCEDURE -Write* (fd, buf, nbyte: LONGINT): LONGINT + "write(fd, buf, nbyte)"; + + PROCEDURE -WriteBlk* (fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE): LONGINT + "write(fd, buf, buf__len)"; + + PROCEDURE -Dup*(fd: LONGINT): LONGINT + "dup(fd)"; + + PROCEDURE -Dup2*(fd1, fd2: LONGINT): LONGINT + "dup(fd1, fd2)"; + + PROCEDURE -Pipe*(fds : LONGINT): LONGINT + "pipe(fds)"; + + PROCEDURE -Getpid*(): LONGINT + "getpid()"; + + PROCEDURE -Getuid*(): LONGINT + "getuid()"; + + PROCEDURE -Geteuid*(): LONGINT + "geteuid()"; + + PROCEDURE -Getgid*(): LONGINT + "getgid()"; + + PROCEDURE -Getegid*(): LONGINT + "getegid()"; + + PROCEDURE -Unlink*(name: Name): LONGINT + "unlink(name)"; + + PROCEDURE -Open*(name: Name; flag, mode: SET): LONGINT + "open(name, flag, mode)"; + + PROCEDURE -Close*(fd: LONGINT): LONGINT + "close(fd)"; + + PROCEDURE -stat(name: Name; VAR statbuf: Status): LONGINT + "stat((const char*)name, (struct stat*)statbuf)"; + + PROCEDURE Stat*(name: Name; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := stat(name, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + (* don't understand this + INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); *) + RETURN res; + END Stat; + + PROCEDURE -fstat(fd: LONGINT; VAR statbuf: Status): LONGINT + "fstat(fd, (struct stat*)statbuf)"; + + PROCEDURE Fstat*(fd: LONGINT; VAR statbuf: Status): LONGINT; + VAR res: LONGINT; + BEGIN + res := fstat(fd, statbuf); + (* make the first 4 bytes as unique as possible (used in module Files for caching!) *) + (*INC(statbuf.dev, statbuf.devX); + INC(statbuf.rdev, statbuf.rdevX); *) + RETURN res; + END Fstat; + + PROCEDURE -Fchmod*(fd, mode: LONGINT): LONGINT + "fchmod(fd, mode)"; + + PROCEDURE -Chmod*(path: Name; mode: LONGINT): LONGINT + "chmod(path, mode)"; + + PROCEDURE -Lseek*(fd, offset, origin: LONGINT): LONGINT + "lseek(fd, offset, origin)"; + + PROCEDURE -Fsync*(fd: LONGINT): LONGINT + "fsync(fd)"; + + PROCEDURE -Fcntl*(fd, cmd, arg: LONGINT ): LONGINT + "fcntl(fd, cmd, arg)"; + + PROCEDURE -Flock*(fd, operation: LONGINT): LONGINT + "flock(fd, operation)"; + + PROCEDURE -Ftruncate*(fd, length: LONGINT): LONGINT + "ftruncate(fd, length)"; + + PROCEDURE -Readblk*(fd: LONGINT; VAR buf: ARRAY OF SYSTEM.BYTE; len: LONGINT): LONGINT + "read(fd, buf, len)"; + + PROCEDURE -Rename*(old, new: Name): LONGINT + "rename(old, new)"; + + PROCEDURE -Chdir*(path: Name): LONGINT + "chdir(path)"; + + PROCEDURE -Ioctl*(fd, request, arg: LONGINT): LONGINT + "ioctl(fd, request, arg)"; + + PROCEDURE -Kill*(pid, sig: LONGINT): LONGINT + "kill(pid, sig)"; + + PROCEDURE -Sigsetmask*(mask: LONGINT): LONGINT + "sigsetmask(mask)"; + + + (* TCP/IP networking *) + + PROCEDURE -Gethostbyname*(name: Name): HostEntry + "(Unix_HostEntry)gethostbyname(name)"; + + PROCEDURE -Gethostname*(VAR name: Name): LONGINT + "gethostname(name, name__len)"; + + PROCEDURE -Socket*(af, type, protocol: LONGINT): LONGINT + "socket(af, type, protocol)"; + + PROCEDURE -Connect*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "connect(socket, &(name), namelen)"; + + PROCEDURE -Getsockname*(socket: LONGINT; VAR name: Sockaddr; VAR namelen: LONGINT): LONGINT + "getsockname(socket, name, namelen)"; + + PROCEDURE -Bind*(socket: LONGINT; name: Sockaddr; namelen: LONGINT): LONGINT + "bind(socket, &(name), namelen)"; + + PROCEDURE -Listen*(socket, backlog: LONGINT): LONGINT + "listen(socket, backlog)"; + + PROCEDURE -Accept*(socket: LONGINT; VAR addr: Sockaddr; VAR addrlen: LONGINT): LONGINT + "accept(socket, addr, addrlen)"; + + PROCEDURE -Recv*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "recv(socket, bufadr, buflen, flags)"; + + PROCEDURE -Send*(socket, bufadr, buflen, flags: LONGINT): LONGINT + "send(socket, bufadr, buflen, flags)"; + + PROCEDURE -sys(str: ARRAY OF CHAR): INTEGER (* need this to call external tools like gcc or gas; noch *) + "system(str)"; + + PROCEDURE system*(cmd : ARRAY OF CHAR); + VAR r : INTEGER; + BEGIN + r := sys(cmd); + END system; + + PROCEDURE System*(cmd : ARRAY OF CHAR): INTEGER; + VAR r : INTEGER; + BEGIN + r := sys(cmd); + RETURN r + END System; + + + +END Unix. diff --git a/src/voc/linux/clang/armv6j/architecture.Mod b/src/voc/linux/clang/armv6j/architecture.Mod new file mode 100644 index 00000000..d8409c34 --- /dev/null +++ b/src/voc/linux/clang/armv6j/architecture.Mod @@ -0,0 +1,4 @@ +MODULE architecture; +CONST arch* = "armv6j"; + +END architecture. diff --git a/src/voc/linux/clang/armv6j_hardfp/architecture.Mod b/src/voc/linux/clang/armv6j_hardfp/architecture.Mod new file mode 100644 index 00000000..761f8c99 --- /dev/null +++ b/src/voc/linux/clang/armv6j_hardfp/architecture.Mod @@ -0,0 +1,4 @@ +MODULE architecture; +CONST arch* = "armv6j_hardfp"; + +END architecture. diff --git a/src/voc/linux/clang/armv7a_hardfp/architecture.Mod b/src/voc/linux/clang/armv7a_hardfp/architecture.Mod new file mode 100644 index 00000000..fab9a0e2 --- /dev/null +++ b/src/voc/linux/clang/armv7a_hardfp/architecture.Mod @@ -0,0 +1,4 @@ +MODULE architecture; +CONST arch* = "armv7a_hardfp"; + +END architecture. diff --git a/src/voc/linux/clang/extTools.Mod b/src/voc/linux/clang/extTools.Mod new file mode 100644 index 00000000..92b08077 --- /dev/null +++ b/src/voc/linux/clang/extTools.Mod @@ -0,0 +1,82 @@ +MODULE extTools; + IMPORT Args, Unix, Strings := oocOakStrings, Console, version; +(* +INCLUDEPATH = -Isrc/lib/system/gnuc/x86_64 +CCOPT = -fPIC $(INCLUDEPATH) -g +CLOBERONOPTS = -fPIC $(INCLUDEPATH) -L. -L/usr/lib -lOberon -static -g +CC = cc $(CCOPT) -c +*) + +VAR incPath0, incPath1, ccOpt, ccString, CFLAGS, tmp0, tmp1 : ARRAY 1023 OF CHAR; + +PROCEDURE Assemble*(m : ARRAY OF CHAR); +VAR cmd : ARRAY 1023 OF CHAR; +cc : ARRAY 1023 OF CHAR; +ext : ARRAY 5 OF CHAR; +BEGIN +COPY (ccString, cc); +Strings.Append (" -c ", cc); +COPY(cc, cmd); +Strings.Append (" ", cmd); +Strings.Append (ccOpt, cmd); +ext := ".c"; +Strings.Append (ext, m); +Strings.Append(m, cmd); +(*Console.Ln; Console.String (cmd); Console.Ln;*) +Unix.system(cmd); +END Assemble; + + +PROCEDURE LinkMain*(VAR m : ARRAY OF CHAR; statically : BOOLEAN; additionalopts : ARRAY OF CHAR); +VAR lpath : ARRAY 1023 OF CHAR; +cc : ARRAY 1023 OF CHAR; +ccopt : ARRAY 1023 OF CHAR; +cmd : ARRAY 1023 OF CHAR; +ext : ARRAY 5 OF CHAR; +BEGIN +(* +gcc -g -o hello hello.c -I $RPATH/src/lib/system/gnuc/x86_64 -I. -I$RPATH -lOberon -L. -L$RPATH -static +*) +cmd := ""; +cc := ""; +ext := ".c"; +COPY(ccString, cc); +COPY (cc, cmd); +Strings.Append(" ", cmd); +Strings.Append(m, cmd); +Strings.Append(ext, cmd); +Strings.Append(additionalopts, cmd); +IF statically THEN Strings.Append(" -static ", cmd) END; +Strings.Append(" -o ", cmd); +Strings.Append(m, cmd); +Strings.Append(" ", cmd); +Strings.Append(ccOpt, cmd); +Console.Ln; Console.String(cmd); Console.Ln; (* may be it's feasible to add debug mode later *) +Unix.system(cmd); +END LinkMain; + +BEGIN + +incPath0 := "src/lib/system/linux/gnuc"; +incPath1 := "lib/voc/obj "; +ccOpt := " -fPIC -g -I "; +COPY (version.prefix, tmp1); +Strings.Append("/", tmp1); +Strings.Append(incPath0, tmp1); +Strings.Append("/", tmp1); +Strings.Append(version.arch, tmp1); +Strings.Append(" -I ", tmp1); +Strings.Append(version.prefix, tmp1); +Strings.Append("/", tmp1); +Strings.Append(incPath1, tmp1); +Strings.Append(tmp1, ccOpt); +Strings.Append ("-lVishapOberon -L. -L", ccOpt); +Strings.Append (version.prefix, ccOpt); +Strings.Append ("/lib ", ccOpt); +Args.GetEnv("CFLAGS", CFLAGS); +Strings.Append (CFLAGS, ccOpt); +Strings.Append (" ", ccOpt); +ccString := "cc "; +(*Strings.Append (ccOpt, ccString);*) + +END extTools. diff --git a/src/voc/linux/clang/powerpc/architecture.Mod b/src/voc/linux/clang/powerpc/architecture.Mod new file mode 100644 index 00000000..1cd033d5 --- /dev/null +++ b/src/voc/linux/clang/powerpc/architecture.Mod @@ -0,0 +1,4 @@ +MODULE architecture; +CONST arch* = "powerpc"; + +END architecture. diff --git a/src/voc/linux/clang/x86/architecture.Mod b/src/voc/linux/clang/x86/architecture.Mod new file mode 100644 index 00000000..84835238 --- /dev/null +++ b/src/voc/linux/clang/x86/architecture.Mod @@ -0,0 +1,4 @@ +MODULE architecture; +CONST arch* = "x86"; + +END architecture. diff --git a/src/voc/linux/clang/x86_64/architecture.Mod b/src/voc/linux/clang/x86_64/architecture.Mod new file mode 100644 index 00000000..1f95d2fd --- /dev/null +++ b/src/voc/linux/clang/x86_64/architecture.Mod @@ -0,0 +1,4 @@ +MODULE architecture; +CONST arch* = "x86_64"; + +END architecture. diff --git a/src/voc/prf.Mod b/src/voc/prf.Mod index d97f3ae5..2f4d8f24 100644 --- a/src/voc/prf.Mod +++ b/src/voc/prf.Mod @@ -1,5 +1,5 @@ MODULE prf; -CONST prefix* = "/Users/noch/local"; +CONST prefix* = "/opt"; END prf. diff --git a/voc.REMOVED.git-id b/voc.REMOVED.git-id index 2dbf24f0..dbde7f3e 100644 --- a/voc.REMOVED.git-id +++ b/voc.REMOVED.git-id @@ -1 +1 @@ -e91f0b6f185262ec480f9e15ef238542f7c6f09c \ No newline at end of file +010bb6a817032246428fa9066e43fbdecb07cfb5 \ No newline at end of file diff --git a/vocstatic.linux.clang.x86_64.REMOVED.git-id b/vocstatic.linux.clang.x86_64.REMOVED.git-id new file mode 100644 index 00000000..dbde7f3e --- /dev/null +++ b/vocstatic.linux.clang.x86_64.REMOVED.git-id @@ -0,0 +1 @@ +010bb6a817032246428fa9066e43fbdecb07cfb5 \ No newline at end of file