├── .gitattributes ├── .gitignore ├── .nojekyll ├── CITATION.cff ├── CONTRIBUTORS.html ├── CONTRIBUTORS.md ├── Chars.Mod ├── CharsTest.Mod ├── DStrings.Mod ├── DStringsTest.Mod ├── INSTALL.md ├── JSON.Mod ├── JSONTest.Mod ├── LICENSE ├── Makefile ├── Obn2.Mod ├── Obn2Test.Mod ├── OfrontPlus.mak ├── Path.Mod ├── PathLists.Mod ├── PathListsTest.Mod ├── PathTest.Mod ├── README.md ├── Scanner.Mod ├── ScannerTest.Mod ├── TODO.html ├── TODO.md ├── Tests.Mod ├── clean.bat ├── codemeta.json ├── css ├── prettify.css ├── site.css └── tables.css ├── development-notes.html ├── development-notes.md ├── examples └── ofrontplus │ ├── Artemis.a │ ├── Mod │ ├── Chars.Mod │ ├── CharsTest.Mod │ ├── DStrings.Mod │ ├── DStringsTest.Mod │ ├── Math.Def │ ├── Obn2.Mod │ ├── Obn2Test.Mod │ ├── Out.Def │ ├── Path.Mod │ ├── PathLists.Mod │ ├── PathListsTest.Mod │ ├── PathTest.Mod │ ├── Strings.Def │ ├── Tests.Mod │ └── extConvert.Def │ ├── Obj │ ├── Chars.c │ ├── Chars.oh │ ├── CharsTest.c │ ├── CharsTest.oh │ ├── DStrings.c │ ├── DStrings.oh │ ├── DStringsTest.c │ ├── DStringsTest.oh │ ├── Math.oh │ ├── Obn2.c │ ├── Obn2.oh │ ├── Obn2Test.c │ ├── Obn2Test.oh │ ├── Out.oh │ ├── Path.c │ ├── Path.oh │ ├── PathLists.c │ ├── PathLists.oh │ ├── PathListsTest.c │ ├── PathListsTest.oh │ ├── PathTest.c │ ├── PathTest.oh │ ├── SYSTEM.oh │ ├── Strings.oh │ ├── Tests.c │ ├── Tests.oh │ └── extConvert.oh │ ├── README.md │ ├── Sym │ ├── Chars.sym │ ├── CharsTest.sym │ ├── DStrings.sym │ ├── DStringsTest.sym │ ├── Math.sym │ ├── Obn2.sym │ ├── Obn2Test.sym │ ├── Out.sym │ ├── Path.sym │ ├── PathLists.sym │ ├── PathListsTest.sym │ ├── PathTest.sym │ ├── Strings.sym │ ├── Tests.sym │ └── extConvert.sym │ ├── build.bat │ ├── cc.bat │ ├── index.html │ └── o2c.bat ├── index.html ├── install.html ├── license.html ├── make.bat ├── mk_website.py ├── nav.md ├── note-system.bit-oberon-list.txt ├── obnc ├── C │ ├── Clock.GetRtcTime.inc │ ├── Clock.SetRtcTime.inc │ ├── Unix.Exit.inc │ ├── Unix.includes.inc │ ├── Unix.uname.inc │ └── time_example_1.c ├── ClockTest.obn ├── Makefile ├── README.md ├── UnixTest.obn ├── artClock.c ├── artClock.obn ├── artTextCmdLn.obn ├── artUnix.c ├── artUnix.obn ├── index.html ├── nav.md └── ocat.obn ├── obncdoc ├── Chars.def ├── CharsTest.def ├── DStrings.def ├── DStringsTest.def ├── JSON.def ├── JSONTest.def ├── Obn2.def ├── Obn2Test.def ├── Path.def ├── PathLists.def ├── PathListsTest.def ├── PathTest.def ├── Scanner.def ├── ScannerTest.def ├── Tests.def ├── index.html └── style.css ├── ofrontplus ├── README.md ├── TODO.html ├── TODO.md ├── index.html └── nav.md ├── oxford ├── ArgsTest.m ├── ClockTest.m ├── ConvertTest.m ├── EnvTest.m ├── Makefile ├── README.md ├── Tests.m ├── UnixTest.m ├── artArgs.m ├── artClock.c ├── artClock.m ├── artConvert.c ├── artConvert.m ├── artEnv.m ├── artTextsCmdLn.m ├── artUnix.m ├── helloworld.m ├── index.html ├── nav.md └── ocat.m ├── page.tmpl ├── ports ├── Oberon-2_to_Oberon-07.html ├── Oberon-2_to_Oberon-07.md ├── README.md ├── index.html ├── nav.md ├── s3 │ ├── Conversions.Mod │ ├── Files.Mod │ ├── Fonts.mod │ ├── Modules.Mod │ ├── OFS.Mod │ ├── Objects.Mod │ ├── README.md │ ├── Reals.Mod │ ├── Texts.Mod │ └── index.html └── v4 │ ├── README.md │ └── index.html ├── posix ├── Display.Mod └── Kernel.Mod ├── publish.bash └── setup.bat /.gitattributes: -------------------------------------------------------------------------------- 1 | *.Mod linguist-language=Oberon-7 2 | *.m linguist-language=Oberon-7 3 | *.obn linguist-language=Oberon-7 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | a.out 2 | *.exe 3 | *.bak 4 | *~ 5 | *.swp 6 | *.k 7 | *.o 8 | *.so 9 | *test 10 | helloworld 11 | .obnc 12 | Tests.m 13 | *Test 14 | -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/.nojekyll -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | 2 | cff-version: 1.1.0 3 | message: "If you use this software, please cite it as below." 4 | authors: 5 | - family-names: Doiel 6 | given-names: Robert 7 | orcid: https://orcid.org/0000-0003-0900-6903 8 | version: 0.0.0 9 | title: Artemis 10 | date-released: 2022-03-26 11 | -------------------------------------------------------------------------------- /CONTRIBUTORS.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | … 12 |
13 |
14 |

15 | Contributors 16 |

17 |

18 | This is a list of people who have helped out in making Artemis possible. I apoligize for anyone I have missed. 19 |

20 | 25 |
26 | 57 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | Contributors 2 | ============ 3 | 4 | This is a list of people who have helped out in making Artemis possible. 5 | I apoligize for anyone I have missed. 6 | 7 | - [Oleg-N-Cher](https://github.com/Oleg-N-Cher/) -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Installation 3 | --- 4 | 5 | Installation 6 | ============ 7 | 8 | Installing a released version 9 | 10 | 1. Change into that directory you want to place Artemis 11 | 2. Unzip the release Zip file 12 | 3. Make sure the "Artemis" "bin" sub-directory is in your PATH 13 | 14 | Example 15 | ------- 16 | 17 | ``` 18 | mkdir -p $HOME/tools 19 | cd $HOME/tools 20 | unzip $HOME/Download/Artemis-0.0.1-Linux-x86_64.zip 21 | export PATH="$HOME/tools/Artimis/bin:$PATH" 22 | ``` 23 | 24 | From source 25 | ----------- 26 | 27 | Compiling from source requires [OBNC](https://miasap.se/obnc), Git, 28 | GNU Make, a C compiler and linker. 29 | 30 | 1. Clone the Git repository for the project 31 | 2. Change into the repository directory 32 | 3. Run `make`, `make test`, and `sudo make install` 33 | 34 | Example install: 35 | 36 | ``` 37 | git clone git@github.com:rsdoiel/Artemis 38 | cd Artemis 39 | make 40 | make full_test 41 | sudo make install 42 | ``` 43 | 44 | Example uninstall 45 | 46 | ``` 47 | cd Artemis 48 | sudo make uninstall 49 | ``` 50 | 51 | The Makefile supports an installation prefix. If 52 | you install with a prefix you need to uninstall with 53 | the same prefix. E.g. 54 | 55 | ``` 56 | sudo make install prefix=/opt/local 57 | sudo make uninstall prefix=/opt/local 58 | ``` 59 | 60 | 61 | -------------------------------------------------------------------------------- /JSON.Mod: -------------------------------------------------------------------------------- 1 | MODULE JSON; 2 | 3 | IMPORT Chars; 4 | 5 | CONST 6 | NullType* = 0; 7 | BooleanType* = 1; 8 | NumberType* = 2; 9 | StringType* = 3; 10 | ArrayType* = 4; 11 | ObjectType* = 5; 12 | 13 | TYPE 14 | (* Self services as an interface to JSON types, 15 | all JSON types extend it. *) 16 | Self* = RECORD 17 | type: INTEGER 18 | END; 19 | 20 | Boolean* = POINTER TO BooleanDesc; 21 | BooleanDesc = RECORD (Self) 22 | value: BOOLEAN 23 | END; 24 | 25 | Number* = POINTER TO NumberDesc; 26 | NumberDesc* = RECORD (Self) 27 | value : REAL; 28 | NaN : BOOLEAN 29 | END; 30 | 31 | String* = POINTER TO StringDesc; 32 | StringDesc* = RECORD (Self) 33 | value : CHAR; 34 | next : String 35 | END; 36 | 37 | List* = POINTER TO ListDesc; 38 | ListDesc* = RECORD (Self) 39 | value : Self; 40 | next: List 41 | END; 42 | 43 | Object* = POINTER TO ObjectDesc; 44 | ObjectDesc* = RECORD (Self) 45 | key : String; 46 | value: Self; 47 | next : Object 48 | END; 49 | 50 | (* Base methods available to all JSON types via Self type definition *) 51 | PROCEDURE IsNull*(o : Self) : BOOLEAN; 52 | BEGIN 53 | RETURN (o.type = NullType) 54 | END IsNull; 55 | 56 | (* IsType compares a JSON object agaist a type constant. Returns TRUE 57 | if they match or FALSE otherwise *) 58 | PROCEDURE IsType*(o : Self; checkType : INTEGER) : BOOLEAN; 59 | RETURN (o.type = checkType) 60 | END IsType; 61 | 62 | (* TypeName exams a type setting the value of the typeName array of char *) 63 | PROCEDURE TypeName*(o : Self; VAR typeName : ARRAY OF CHAR); 64 | BEGIN 65 | Chars.Clear(typeName); 66 | IF o.type = NullType THEN 67 | typeName := "null"; 68 | ELSIF o.type = BooleanType THEN 69 | typeName := "boolean"; 70 | ELSIF o.type = NumberType THEN 71 | typeName := "number"; 72 | ELSIF o.type = StringType THEN 73 | typeName := "string"; 74 | ELSIF o.type = ArrayType THEN 75 | typeName := "array"; 76 | ELSIF o.type = ObjectType THEN 77 | typeName := "object"; 78 | ELSE 79 | typeName := "undefined"; 80 | END; 81 | END TypeName; 82 | 83 | END JSON. 84 | -------------------------------------------------------------------------------- /JSONTest.Mod: -------------------------------------------------------------------------------- 1 | MODULE JSONTest; 2 | 3 | IMPORT JSON, Out, T := Tests; 4 | 5 | VAR 6 | ts : T.TestSet; 7 | 8 | PROCEDURE TestSelf() : BOOLEAN; 9 | VAR test : BOOLEAN; self : JSON.Self; str : ARRAY 256 OF CHAR; 10 | BEGIN test := FALSE; 11 | JSON.TypeName(self, str);Out.String(str);Out.Ln; (* DEBUG *) 12 | 13 | 14 | Out.String("DEBUG TestSelf() not implemented");Out.Ln; 15 | RETURN test 16 | END TestSelf; 17 | 18 | BEGIN 19 | (* Initialize our TestSet *) 20 | T.Init(ts, "JSON Test"); 21 | T.Add(ts, TestSelf); 22 | (* Run our tests *) 23 | ASSERT(T.Run(ts)); 24 | END JSONTest. 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2021, R. S. Doiel 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Simple Makefile for compiling Oberon-7 programs using OBNC. 3 | # Set the list of executables in PROG_NAMES. The rest can probably 4 | # stay as is if all modules are in the same directory. 5 | # 6 | VERSION = $(shell jq .version codemeta.json | cut -d \" -f 2) 7 | BUILD_NAME = Artemis-Modules 8 | PROG_NAMES = #$(shell ls -1 *CmdLn.Mod | sed -E 's/CmdLn\.Mod') 9 | TEST_NAMES = $(shell ls -1 *Test.Mod | sed -E 's/\.Mod//g' ) 10 | MODULES = $(shell ls -1 *.Mod) 11 | DOCS= codemeta.json CITATION.cff README.md LICENSE INSTALL.txt 12 | HTML_FILES=$(shell find . -type f | grep -E '.html') 13 | 14 | #OC = env OBNC_IMPORT_PATH="." obnc 15 | # Defaults 16 | OC = obnc 17 | OS = $(shell uname) 18 | ARCH = $(shell uname -m) 19 | PREFIX = /usr/local 20 | LIBDIR = $(PREFIX)/lib 21 | BINDIR = $(PREFIX)/bin 22 | 23 | # Handle Git and commit messages 24 | BRANCH = $(shell git branch | grep '* ' | cut -d\ -f 2) 25 | MSG = Quick Save 26 | ifneq ($(msg),) 27 | MSG = $(msg) 28 | endif 29 | 30 | # Overrides 31 | oc = 32 | ifneq ($(oc),) 33 | OC = $(oc) 34 | endif 35 | 36 | os = 37 | ifneq ($(os),) 38 | OS = $(os) 39 | endif 40 | 41 | EXT = 42 | ifeq ($(OS),Windows) 43 | EXT = .exe 44 | endif 45 | 46 | arch = 47 | ifneq ($(arch),) 48 | ARCH = $(arch) 49 | endif 50 | 51 | prefix = 52 | ifneq ($(prefix),) 53 | PREFIX = $(prefix) 54 | LIBDIR = $(prefix)/lib 55 | BINDIR = $(prefix)/bin 56 | endif 57 | 58 | libdir = 59 | ifneq ($(libdir),) 60 | LIBDIR = $(libdir) 61 | endif 62 | 63 | bindir = 64 | ifneq ($(bindir),) 65 | BINDIR = $(bindir) 66 | endif 67 | 68 | build: $(TEST_NAMES) # $(PROG_NAMES) 69 | 70 | $(PROG_NAMES): $(MODULES) 71 | @mkdir -p bin 72 | $(OC) -o "bin/$@$(EXT)" "$@.Mod" 73 | 74 | $(TEST_NAMES): .FORCE 75 | $(OC) -o "$@$(EXT)" "$@.Mod" 76 | 77 | full_test: .FORCE clean test 78 | 79 | test: Tests.Mod $(TEST_NAMES) 80 | @for FNAME in $(TEST_NAMES); do env OS=$(OS) ARCH=$(ARCH) "./$${FNAME}"; done 81 | 82 | docs: .FORCE 83 | obncdoc 84 | 85 | clean: .FORCE 86 | @if [ -d dist ]; then rm -fR dist; fi 87 | @if [ -d .obnc ]; then rm -fR .obnc; fi 88 | @for FNAME in $(PROG_NAMES); do if [ -f "bin/$${FNAME}$(EXT)" ]; then rm -v "bin/$${FNAME}"; fi; done 89 | @for FNAME in $(TEST_NAMES); do if [ -f "$${FNAME}$(EXT)" ]; then rm -v "$${FNAME}"; fi; done 90 | 91 | web_clean: 92 | @for FNAME in $(HTML_FILES) ; do if [ -f "$${FNAME}" ]; then rm -v "$${FNAME}"; fi; done 93 | 94 | install: $(PROG_NAMES) 95 | @if [ ! -d $(BINDIR) ]; then mkdir -p $(BINDIR); fi 96 | @for FNAME in $(PROG_NAMES); do cp -v "bin/$${FNAME}$(EXT)" $(BINDIR)/; done 97 | 98 | uninstall: .FORCE 99 | @for FNAME in $(PROG_NAMES); do if [ -f "$(BINDIR)/$${FNAME}$(EXT)" ]; then rm "$(BINDIR)/$${FNAME}$(EXT)"; fi; done 100 | 101 | dist: $(PROG_NAMES) 102 | @if [ ! -d dist/$(BUILD_NAME) ]; then mkdir -p dist/$(BUILD_NAME); fi 103 | @if [ ! -d dist/$(BUILD_NAME)/bin ]; then mkdir -p dist/$(BUILD_NAME)/bin; fi 104 | @for FNAME in $(PROG_NAMES); do cp -p $$FNAME dist/$(BUILD_NAME)/bin/; done 105 | @for FNAME in $(MODULES) $(DOCS) Makefile; do cp -p $$FNAME dist/$(BUILD_NAME)/;done 106 | @cd dist && zip -r $(BUILD_NAME)-$(OS)-$(ARCH).zip $(BUILD_NAME)/* 107 | 108 | 109 | save: 110 | git commit -am "$(MSG)" 111 | git push origin $(BRANCH) 112 | 113 | status: 114 | git status 115 | 116 | website: web_clean README.md page.tmpl css/site.css 117 | obncdoc 118 | cp -vp css/site.css obncdoc/style.css 119 | ./mk_website.py 120 | 121 | publish: web_clean clean 122 | obncdoc 123 | cp -vp css/site.css obncdoc/style.css 124 | ./mk_website.py 125 | ./publish.bash 126 | 127 | 128 | .FORCE: 129 | -------------------------------------------------------------------------------- /Obn2.Mod: -------------------------------------------------------------------------------- 1 | (** Obn2.Mod is a module to help port Oberon-2 modules to Oberon-7. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE Obn2; 10 | 11 | (** ASH provides the Oberon-2 built-in ASH functionilty for 12 | Oberon-7. See description of providing ASH in documentation 13 | on Oberon-7 for positive and negative values *) 14 | PROCEDURE ASH*(x, n : INTEGER) : INTEGER; 15 | VAR res : INTEGER; 16 | BEGIN 17 | IF n > 0 THEN 18 | res := LSL(x, n); 19 | ELSE 20 | res := ASR(x, n); 21 | END; 22 | RETURN res 23 | END ASH; 24 | 25 | (** MAX returns the maximum of two integers *) 26 | PROCEDURE MAX*(x, y : INTEGER) : INTEGER; 27 | VAR res : INTEGER; 28 | BEGIN 29 | IF x > y THEN 30 | res := x; 31 | ELSE 32 | res := y; 33 | END; 34 | RETURN res 35 | END MAX; 36 | 37 | (** MIN provides the minimum of two integers *) 38 | PROCEDURE MIN*(x, y : INTEGER) : INTEGER; 39 | VAR res : INTEGER; 40 | BEGIN 41 | IF x < y THEN 42 | res := x; 43 | ELSE 44 | res := y; 45 | END; 46 | RETURN res 47 | END MIN; 48 | 49 | (** ENTIER is a wrapper around FLOOR, you should really just use 50 | FLOOR. *) 51 | PROCEDURE ENTIER*(r : REAL) : INTEGER; 52 | BEGIN 53 | RETURN FLOOR(r) 54 | END ENTIER; 55 | 56 | (** HALT is a wrapper around ASSERT(FALSE), you should just replace 57 | ASSERT(FALSE) *) 58 | PROCEDURE HALT*(); 59 | BEGIN 60 | ASSERT(FALSE); 61 | END HALT; 62 | 63 | (** ROT is a wrapper around ROR, you should just replace ROT with ROR *) 64 | PROCEDURE ROT*(x, n : INTEGER) : INTEGER; 65 | BEGIN 66 | RETURN ROR(x, n) 67 | END ROT; 68 | 69 | END Obn2. 70 | -------------------------------------------------------------------------------- /Obn2Test.Mod: -------------------------------------------------------------------------------- 1 | (** Obn2Test modules provides testing for Obn2 module. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE Obn2Test; 10 | 11 | IMPORT T := Tests, Obn2; 12 | 13 | VAR ts : T.TestSet; 14 | 15 | PROCEDURE TestMinMax() : BOOLEAN; 16 | VAR test : BOOLEAN; x, y, got, expected : INTEGER; 17 | BEGIN test := TRUE; 18 | x := 11; y := 12; 19 | expected := x; 20 | got := Obn2.MIN(x,y); 21 | T.ExpectedInt(expected, got, "Test Min(x,y)", test); 22 | expected := y; 23 | got := Obn2.MAX(x, y); 24 | T.ExpectedInt(expected, got, "Test Mac(x,y)", test); 25 | RETURN test 26 | END TestMinMax; 27 | 28 | PROCEDURE TestShifts() : BOOLEAN; 29 | VAR test : BOOLEAN; 30 | BEGIN test := TRUE; 31 | T.ExpectedBool(TRUE, FALSE, "TestShifts() not implemented.", test); 32 | RETURN test 33 | END TestShifts; 34 | 35 | BEGIN 36 | T.Init(ts, "Obn2"); 37 | T.Add(ts, TestMinMax); 38 | T.Add(ts, TestShifts); 39 | ASSERT(T.Run(ts)); 40 | END Obn2Test. 41 | -------------------------------------------------------------------------------- /OfrontPlus.mak: -------------------------------------------------------------------------------- 1 | # 2 | # Simple Makefile for using with Ofront+ compiler. 3 | # 4 | 5 | # FIXME: Need to figure out how to detect the information 6 | # needed to set the flags correctly for Ofront+ 7 | # Questions to get sorted: 8 | # 9 | # 1. Set up import paths for modules (e.g. pure Oberon, Ofront specific) 10 | # 2. Where are the standard modules or do I need to write them? 11 | # 12 | 13 | # Defaults 14 | #OC = ofont+ 15 | OC=$(shell which ofront+) 16 | 17 | OPT = -7 18 | 19 | MODULES = $(shell ls -1 *.Mod | grep -v -E Test.Mod | sed -E "s/.Mod$$//") 20 | 21 | TEST_NAMES = $(shell ls -1 *.Mod | grep -E Test.Mod | sed -E "s/.Mod$$//") 22 | 23 | PROG_NAMES = #$(shell ls -1 *CmdLn.Mod | sed -E "s/.CmdLn.Mod$$//") 24 | 25 | PLATFORM = $(shell uname -i) 26 | 27 | OS = $(shell uname) 28 | 29 | OPT = 30 | 31 | ifeq ($(PLATFORM), x86_64) 32 | OPT = -7 -88 -s 33 | else ifeq ($(PLATFORM), x86_32) 34 | OPT = -7 -44 -s 35 | else ifeq ($(PLATFORM), arm7) 36 | OPT = -7 -48 -s 37 | endif 38 | 39 | EXT = 40 | 41 | ifeq ($(OS), Windows) 42 | EXT = .exe 43 | OPT = -7 -s -48 44 | endif 45 | 46 | 47 | build: modules test programs 48 | 49 | modules: $(MODULES) 50 | 51 | programs: $(PROG_NAMES) 52 | 53 | $(MODULES): 54 | @mkdir -p bin 55 | $(OC) $(OPT) $@.Mod 56 | 57 | $(PROG_NAMES): $(MODULES) 58 | @mkdir -p bin 59 | $(OC) $(OPT) $@.Mod 60 | 61 | $(TEST_NAMES): .FORCE 62 | $(OC) $(OPT) "$@.Mod" -m 63 | 64 | full_test: .FORCE clean test 65 | 66 | test: ../Tests.Mod $(TEST_NAMES) 67 | @for FNAME in $(TEST_NAMES); do "./$${FNAME}"; done 68 | 69 | clean: .FORCE 70 | @for FNAME in $(PROG_NAMES); do if [ -f "$${FNAME}$(EXT)" ]; then rm -v "$${FNAME}$(EXT)"; fi; done 71 | @for FNAME in $(PROG_NAMES); do if [ -f "$${FNAME}.c" ] || [ -f "$${FNAME}.h" ] || [ -f "$${FNAME}.sym" ]; then rm -v "$${FNAME}.(c|h|sym)"; fi; done 72 | @for FNAME in $(TEST_NAMES); do if [ -f "$${FNAME}$(EXT)" ]; then rm -v "$${FNAME}$(EXT)"; fi; done 73 | @for FNAME in $(TEST_NAMES); do if [ -f "$${FNAME}.c" ] || [ -f "$${FNAME}.h" ] || [ -f "$${FNAME}.sym" ]; then rm -v "$${FNAME}.(c|h|sym)"; fi; done 74 | @for FNAME in $(MODULES); do if [ -f "$${FNAME}.c" ] || [ -f "$${FNAME}.h" ] || [ -f "$${FNAME}.sym" ]; then rm -v "$${FNAME}.(c|h|sym)"; fi; done 75 | 76 | save: 77 | git commit -am "$(MSG)" 78 | git push origin $(BRANCH) 79 | 80 | status: 81 | git status 82 | 83 | .FORCE: 84 | -------------------------------------------------------------------------------- /PathLists.Mod: -------------------------------------------------------------------------------- 1 | (** PathLists is a module for working with a delimited list of paths. *) 2 | MODULE PathLists; 3 | IMPORT Chars, Path; 4 | 5 | CONST 6 | (** Merge operations *) 7 | PREPEND = 1; (** Insert into path list *) 8 | APPEND = 2; (** Add to end of path list *) 9 | CUT = 3; (** Remove from path from path list *) 10 | 11 | TYPE 12 | PathList* = POINTER TO PathListDesc; 13 | PathListDesc* = RECORD 14 | part : ARRAY Path.MAXLENGTH OF CHAR; 15 | next : PathList 16 | END; 17 | 18 | VAR 19 | delimiter : CHAR; 20 | 21 | (** Length returns the length of the PathList *) 22 | PROCEDURE Length*(pathList : PathList) : INTEGER; 23 | VAR res : INTEGER; cur : PathList; 24 | BEGIN res := 0; cur := pathList; 25 | WHILE cur # NIL DO INC(res); cur := cur.next; END; 26 | RETURN res 27 | END Length; 28 | 29 | (** Find takes a path and searches a path list return -1 if not found 30 | or the position where it was found (zero indexed) *) 31 | PROCEDURE Find*(path : ARRAY OF CHAR; pathList : PathList) : INTEGER; 32 | VAR res, pos : INTEGER; cur : PathList; 33 | BEGIN res := -1; pos := 0; cur := pathList; 34 | WHILE (cur # NIL) & (res = -1) DO 35 | IF Chars.Equal(cur.part, path) THEN 36 | res := pos; 37 | END; 38 | INC(pos); cur := cur.next; 39 | END; 40 | RETURN res 41 | END Find; 42 | 43 | (** Prepend takes a path and a path list and prepends path to path list updating 44 | path list. *) 45 | PROCEDURE Prepend*(path : ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN); 46 | BEGIN 47 | success := FALSE; (* FIXME: Prepend not implemented. *) 48 | END Prepend; 49 | 50 | (** Append takes a path and path list and adds the path to the end of path list *) 51 | PROCEDURE Append*(path: ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN); 52 | BEGIN 53 | success := FALSE; (* FIXME: Append not implemented. *) 54 | END Append; 55 | 56 | (** Cut takes a path and a path list and removes the path element from path list. *) 57 | PROCEDURE Cut*(path : ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN); 58 | BEGIN 59 | success := FALSE; (* FIXME: Cut not implemented *) 60 | END Cut; 61 | 62 | (** SetDelimiter sets the delimiter to be used for encoding and decoding paths *) 63 | PROCEDURE SetDelimiter(c : CHAR); 64 | BEGIN delimiter := c; 65 | END SetDelimiter; 66 | 67 | (** Encode takes a PathList and encodes it into pathListString using the delimiter provided *) 68 | PROCEDURE Encode*(pathList : PathList; delimiter: CHAR; VAR pathListString : ARRAY OF CHAR; VAR success : BOOLEAN); 69 | BEGIN 70 | success := FALSE; (* FIXME: Not implemented *) 71 | END Encode; 72 | 73 | (** Decode takes a path list string and decodes it into a PathList data structure *) 74 | PROCEDURE Decode*(pathListString : ARRAY OF CHAR; VAR pathList : PathList; success : BOOLEAN); 75 | BEGIN 76 | success := FALSE; (* FIXME: Not implemented *) 77 | END Decode; 78 | 79 | (** Apply takes a path, an operation and a path list string. It applies the operation 80 | using the path and pathList updating pathList. Return TRUE of successful, 81 | FALSE otherwise. *) 82 | PROCEDURE Apply*(path: ARRAY OF CHAR; operation: INTEGER; VAR pathListString: ARRAY OF CHAR): BOOLEAN; 83 | VAR success : BOOLEAN; pathList : PathList; 84 | BEGIN 85 | Decode(pathListString, pathList, success); 86 | IF success THEN 87 | IF operation = PREPEND THEN 88 | Prepend(path, pathList, success) 89 | ELSIF operation = APPEND THEN 90 | Append(path, pathList, success) 91 | ELSIF operation = CUT THEN 92 | Cut(path, pathList, success) 93 | END; 94 | END; 95 | RETURN success 96 | END Apply; 97 | 98 | BEGIN 99 | SetDelimiter(":"); (** NOTE: The colon is the default delimiter. *) 100 | END PathLists. -------------------------------------------------------------------------------- /PathListsTest.Mod: -------------------------------------------------------------------------------- 1 | MODULE PathListsTest; 2 | 3 | IMPORT PathLists, T := Tests; 4 | 5 | VAR ts : T.TestSet; 6 | 7 | PROCEDURE TestEncodeDecode() : BOOLEAN; 8 | VAR test, ok : BOOLEAN; src : ARRAY 1024 OF CHAR; 9 | pl : PathLists.PathList; 10 | BEGIN test := TRUE; 11 | src := "/bin:/usr/bin:/usr/local/bin:/home/jane.doe/bin"; 12 | PathLists.Decode(src, pl, ok); 13 | T.ExpectedBool(TRUE, ok, "Expected to decode src", test); 14 | RETURN test 15 | END TestEncodeDecode; 16 | 17 | PROCEDURE TestLengthSetDelimiterFind() : BOOLEAN; 18 | VAR test : BOOLEAN; 19 | BEGIN test := TRUE; 20 | T.ExpectedBool(TRUE, FALSE, "TestLengthSetDelimiterFind() not implemented.", test); 21 | RETURN test 22 | END TestLengthSetDelimiterFind; 23 | 24 | PROCEDURE TestPrepend() : BOOLEAN; 25 | VAR test : BOOLEAN; 26 | BEGIN test := TRUE; 27 | T.ExpectedBool(TRUE, FALSE, "TestPrepend() not implemented.", test); 28 | RETURN test 29 | END TestPrepend; 30 | 31 | PROCEDURE TestAppend() : BOOLEAN; 32 | VAR test : BOOLEAN; 33 | BEGIN test := TRUE; 34 | T.ExpectedBool(TRUE, FALSE, "TestAppend() not implemented. ", test); 35 | RETURN test 36 | END TestAppend; 37 | 38 | PROCEDURE TestCut() : BOOLEAN; 39 | VAR test : BOOLEAN; 40 | BEGIN test := TRUE; 41 | T.ExpectedBool(TRUE, FALSE, "TestCut() not implemented. ", test); 42 | RETURN test 43 | END TestCut; 44 | 45 | PROCEDURE TestApply() : BOOLEAN; 46 | VAR test : BOOLEAN; 47 | BEGIN test := TRUE; 48 | T.ExpectedBool(TRUE,FALSE, "TestApply() not implemented.", test); 49 | RETURN test 50 | END TestApply; 51 | 52 | BEGIN 53 | T.Init(ts, "Test PathLists"); 54 | T.Add(ts, TestEncodeDecode); 55 | T.Add(ts, TestLengthSetDelimiterFind); 56 | T.Add(ts, TestPrepend); 57 | T.Add(ts, TestAppend); 58 | T.Add(ts, TestCut); 59 | T.Add(ts, TestApply); 60 | ASSERT(T.Run(ts)); 61 | END PathListsTest. 62 | -------------------------------------------------------------------------------- /PathTest.Mod: -------------------------------------------------------------------------------- 1 | MODULE PathTest; 2 | 3 | IMPORT T := Tests, Path, Chars; 4 | 5 | VAR ts : T.TestSet; 6 | 7 | PROCEDURE TestMaxPath() : BOOLEAN; 8 | VAR test : BOOLEAN; 9 | BEGIN test := TRUE; 10 | T.ExpectedInt(1024, Path.MAXLENGTH, "Current path maximum assumption", test); 11 | RETURN test 12 | END TestMaxPath; 13 | 14 | PROCEDURE TestSetDelimiter() : BOOLEAN; 15 | VAR test : BOOLEAN; 16 | BEGIN test := TRUE; 17 | T.ExpectedChar(Chars.SLASH, Path.delimiter, "Checking default delimiter", test); 18 | Path.SetDelimiter(Chars.BSLASH); 19 | T.ExpectedChar(Chars.BSLASH, Path.delimiter, "Checking set delimiter to ';'", test); 20 | Path.SetDelimiter(Chars.SLASH); 21 | T.ExpectedChar(Chars.SLASH, Path.delimiter, "Checking set delimiter to ':'", test); 22 | RETURN test 23 | END TestSetDelimiter; 24 | 25 | PROCEDURE TestPrepend() : BOOLEAN; 26 | VAR test, ok : BOOLEAN; a : ARRAY Path.MAXLENGTH OF CHAR; 27 | BEGIN test := TRUE; 28 | a[0] := 0X; 29 | Path.Prepend("", a, ok); 30 | T.ExpectedBool(TRUE, ok, "Path.Prepend('', a) ok -> ''", test); 31 | T.ExpectedString("", a, "Path.Prepend('', a)", test); 32 | Path.Prepend("/me", a, ok); 33 | T.ExpectedBool(TRUE, ok, "Path.Prepend('/me', a) ok -> /me", test); 34 | T.ExpectedString("/me", a, "Path.Prepend('/me', a)", test); 35 | Path.Prepend("/home", a, ok); 36 | T.ExpectedBool(TRUE, ok, "Path.Prepend('/home', a) ok -> /home/me", test); 37 | T.ExpectedString("/home/me", a, "Path.Prepend('home', a)", test); 38 | RETURN test 39 | END TestPrepend; 40 | 41 | PROCEDURE TestAppend() : BOOLEAN; 42 | VAR test, ok : BOOLEAN; a : ARRAY Path.MAXLENGTH OF CHAR; 43 | BEGIN test := TRUE; 44 | a := ""; 45 | Path.Append("", a, ok); 46 | T.ExpectedBool(TRUE, ok, "Path.Append('', a) ok -> ''", test); 47 | T.ExpectedString("", a, "Path.Append('', a)", test); 48 | Path.Append("/", a, ok); 49 | T.ExpectedBool(TRUE, ok, "Path.Append('/', a) ok -> '/'", test); 50 | T.ExpectedString("/", a, "Path.Append('/', a)", test); 51 | Path.Append("home", a, ok); 52 | T.ExpectedBool(TRUE, ok, "Path.Append('home', a) ok -> /home", test); 53 | T.ExpectedString("/home", a, "Path.Append('home', a)", test); 54 | Path.Append("me", a, ok); 55 | T.ExpectedBool(TRUE, ok, "Path.Append('', a) ok -> /home/me", test); 56 | T.ExpectedString("/home/me", a, "Path.Append('me', a) ok -> /home/me", test); 57 | RETURN test 58 | END TestAppend; 59 | 60 | PROCEDURE TestBasename() : BOOLEAN; 61 | VAR test, ok : BOOLEAN; a, expected, got : ARRAY Path.MAXLENGTH OF CHAR; 62 | BEGIN test := TRUE; 63 | a := "/home/me/.profile"; 64 | expected := ".profile"; 65 | Path.Basename(a, got, ok); 66 | T.ExpectedBool(TRUE, ok, "Basename(a, got, ok) ok -> ?", test); 67 | T.ExpectedString(expected, got, "Path.Basename(a, got, ok)", test); 68 | RETURN test 69 | END TestBasename; 70 | 71 | PROCEDURE TestDirname() : BOOLEAN; 72 | VAR test, ok : BOOLEAN; a, expected, got : ARRAY Path.MAXLENGTH OF CHAR; 73 | BEGIN test := TRUE; 74 | a := "/home/me/.profile"; 75 | expected := "/home/me"; 76 | Path.Dirname(a, got, ok); 77 | T.ExpectedBool(TRUE, ok, "Dirname(a, got, ok) ok -> ?", test); 78 | T.ExpectedString(expected, got, "Path.Dirname(a, got, ok)", test); 79 | RETURN test 80 | END TestDirname; 81 | 82 | PROCEDURE TestExt() : BOOLEAN; 83 | VAR test, ok : BOOLEAN; a, expected, got : ARRAY Path.MAXLENGTH OF CHAR; 84 | BEGIN test := TRUE; 85 | a := "/home/me/README.txt"; 86 | expected := ".txt"; 87 | Path.Ext(a, got, ok); 88 | T.ExpectedBool(TRUE, ok, "Ext(a, got, ok) ok -> ?", test); 89 | T.ExpectedString(expected, got, "Path.Ext(a, got, ok)", test); 90 | RETURN test 91 | END TestExt; 92 | 93 | BEGIN 94 | T.Init(ts, "Test Path"); 95 | T.Add(ts, TestMaxPath); 96 | T.Add(ts, TestSetDelimiter); 97 | T.Add(ts, TestPrepend); 98 | T.Add(ts, TestAppend); 99 | T.Add(ts, TestDirname); 100 | T.Add(ts, TestBasename); 101 | T.Add(ts, TestExt); 102 | ASSERT(T.Run(ts)); 103 | END PathTest. 104 | -------------------------------------------------------------------------------- /Scanner.Mod: -------------------------------------------------------------------------------- 1 | MODULE Scanner; 2 | 3 | CONST 4 | (* ERROR in scan, e.g. string start found without end string, position in scan not updated *) 5 | ERROR* = 0; 6 | (* OK scan successful, not at end of text, position in scan updated *) 7 | OK* = 1; 8 | (* EOS, end of scan, scan successful but at end of text, position in scan not updated *) 9 | EOS* = 2; 10 | 11 | (* Common String Delimiters *) 12 | EOT* = 0X; (* end of text *) 13 | TAB* = 9X; (* tab *) 14 | LF* = 10X; (* line feed *) 15 | FF* = 11X; (* form feed *) 16 | CR* = 13X; (* charriage return *) 17 | SPACE* = 32X; (* space *) 18 | DQUOTE* = 34X; (* double quote *) 19 | SQUOTE* = 39X; (* single quote *) 20 | SLASH* = 47X; (* slash or div symbol *) 21 | BSLASH* = 92X; (* backslash *) 22 | 23 | (** Character constants *) 24 | DASH* = "-"; (* dash *) 25 | LODASH* = "_"; (* underscore or low dash *) 26 | CARET* = "^"; (* caret *) 27 | TILDE* = "~"; (* tilde *) 28 | 29 | TYPE 30 | Scanner* = POINTER TO ScannerDesc; 31 | ScannerDesc* = RECORD 32 | delimiter: CHAR; 33 | startString: CHAR; 34 | endString: CHAR; 35 | inString: BOOLEAN; 36 | escape: CHAR; 37 | Pos*: INTEGER 38 | END; 39 | 40 | PROCEDURE Init*(VAR scanner: Scanner; delimiter: CHAR; startString: CHAR; endString: CHAR; Escape: CHAR); 41 | BEGIN 42 | scanner.delimiter := delimiter; 43 | scanner.startString := startString; 44 | scanner.endString := endString; 45 | scanner.escape := Escape; 46 | scanner.inString := FALSE; 47 | scanner.Pos := 0; 48 | END Init; 49 | 50 | PROCEDURE ScanChars*(VAR scanner: Scanner; src : ARRAY OF CHAR; VAR value: ARRAY OF CHAR; VAR OK: BOOLEAN); 51 | BEGIN 52 | END ScanChars; 53 | 54 | 55 | END Scanner. 56 | 57 | Scanner 58 | ======= 59 | 60 | Scanner models a simple text scanner like that needed to process Oberon language files or Pascal. 61 | 62 | 63 | -------------------------------------------------------------------------------- /ScannerTest.Mod: -------------------------------------------------------------------------------- 1 | MODULE ScannerTest; 2 | 3 | IMPORT Scanner, T := Tests; 4 | 5 | VAR ts : T.TestSet; 6 | 7 | PROCEDURE TestScanner() : BOOLEAN; 8 | VAR s : Scanner.Scanner; 9 | txt, token, expected : ARRAY 256 OF CHAR; 10 | test, OK : BOOLEAN; 11 | BEGIN test := FALSE; 12 | txt := "I think pi is about 3.145"; 13 | Scanner.Init(s, Scanner.SPACE, Scanner.DQUOTE, Scanner.DQUOTE, Scanner.BSLASH); 14 | expected := "I"; 15 | Scanner.ScanChars(s, txt, token, OK); 16 | T.ExpectedBool(TRUE, OK, "Scanner.Chars(s, txt, token, OK) should be true", test); 17 | T.ExpectedString(expected, token, "Expected 'I', got something else", test); 18 | 19 | RETURN test 20 | END TestScanner; 21 | 22 | BEGIN 23 | T.Init(ts, "Test Scanner"); 24 | T.Add(ts, TestScanner); 25 | ASSERT(T.Run(ts)); 26 | END ScannerTest. 27 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: To do 3 | --- 4 | 5 | 6 | Action Items 7 | ============ 8 | 9 | Next 10 | ---- 11 | 12 | - [ ] Need a module for working with UTF-8 encoded strings, Scanner need to support UTF-8 encoded files 13 | - [ ] Tests.Mod 14 | - rename ExpectedString to ExpectedChars (for consistency in Artemis) 15 | - Conform the const CHAR descriptions between Scanner.Mod and Chars.Mod 16 | - [ ] Chars.Mod 17 | - QUOTE should be DQUOTE 34X 18 | - Add SQUOTE 39X 19 | - [ ] Add Scanner.Mod implementing a simple text scanner supporting ARRAY OF CHAR and plain text files 20 | - [x] Clock.Mod should wrap host system clock for use by a more general purpose DateTime.Mod. 21 | - [x] Refactor CharsTest.Mod to test Strings compatible procedures 22 | - [x] Tests module for easily writing tests of modules 23 | - [ ] Reals.Mod should provide easy conversion to/from String for Real with exponential or fixed notations without reliance on extConvert. 24 | - [x] Chars should provide a more modern approach to text processing that the Oakwood Strings module 25 | - [x] Chars module should work as a drop in replacement for Oakwood Strings 26 | - [x] DStrings module for dynamic strings, compatible with Chars and Strings where it makes sense, it should include Rider suppport since we lack index notation for working in the string object 27 | - [ ] JSON module for working with JSON data 28 | - [ ] Document coding conventions on when to use snake, camel case in variables and procedure names. 29 | - [ ] Use the `curl --libcurl` option to assemble a C module for handling HTTP/HTTPS and possibly other curl supported protocols 30 | 31 | Requested Ports from Native Oberon 32 | ---------------------------------- 33 | 34 | 35 | + [ ] Files.Mod (Confirm Can I use OBNC's implementation, confirm PO 2013 Files.Mod works as replacement) 36 | + [ ] Objects.Mod (Port needed for POSIX, port needed for PO 2013) 37 | + [ ] Display.Mod (Port needed for POSIX, confirm PO 2013 Display.Mod works as replacement) 38 | + [ ] Fonts.Mod (Port needed for POSIX, confirm PO 2013 Fonts.Mod works as replacement) 39 | + [ ] Reals.Mod (Port needed for POSIX and for PO 2013) 40 | + [ ] Texts.Mod, see https://en.wikibooks.org/wiki/Oberon/ETH_Oberon/2003-01-05/Texts.Mod 41 | + Depends on: Files, Objects, Display, Fonts, and Reals 42 | + [ ] Figure out if the other Native Oberon modules like Kernel, Modules, Displays.Display.Mod, etc. need to be ported or we can use PO 2013 modules 43 | 44 | Someday, maybe 45 | -------------- 46 | 47 | + [ ] Reals.Mod 48 | + [ ] EBNF.Mod and ebnfc.Mod 49 | + [ ] Scanner.Mod implementing a Texts like Scanner 50 | + [ ] RISC5 emulator (based on Compiler Construction RISC0 emulator) 51 | + [ ] Create a Ofront/V4 like dev environment with direct access to host file system 52 | + [ ] Re-implement Fonts.Mod so Oberon System can use ADA friendly fonts like Open Dyslexia and Atikson Hyperledgable 53 | + [ ] Rename String.Init() to something that both suggests both initialization AND assignment. NOTE: Set/Get/Put are taken by the Rider procedures to remain signature compatible with Files.Rider 54 | + [ ] Refactor StringDesc record for holding CHAR to hold INTEGER to allow support for difference character sets (e.g. UTF-8/UTF-32) 55 | + [ ] Portable Convert module, look at V4 and OBNC implementations as well as Oxford compiler and VOC 56 | + [ ] RegExp module is needed 57 | + [ ] CSV module for working with CSV data 58 | + [ ] XML module for working with XML data 59 | + [ ] HTML review A2 and Native Oberon-7, evaluate a port to Oberon-7 60 | + [ ] OBNC ext modules used need to be re-implemented as pure Oberon-7 to allow Artemis to be Oberon-7 compiler agnostic. 61 | + [ ] Need to test under Oberon Project 2013 in DeWachter's emulator as well as Extended Oberon and IO Core 62 | + [ ] Cli modules (e.g. OCat) need to be clearly marked as non-portable between Oberon Systems and POSIX 63 | + [ ] Makefile needs to handle compile Cli modules to sensible lowercase names based on Oberon-7 compiler used 64 | - [ ] Look at FLTK's Go bindings as well as Fyne's and see if there are some insights for a general purpose set of GUI bindings for Artemis 65 | 66 | 67 | -------------------------------------------------------------------------------- /clean.bat: -------------------------------------------------------------------------------- 1 | REM A simple batch file to cleanip our compile process and remove any stale exe 2 | del *.exe 3 | -------------------------------------------------------------------------------- /codemeta.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": "https://doi.org/10.5063/schema/codemeta-2.0", 3 | "@type": "SoftwareSourceCode", 4 | "description": "Artemis is a collection of Oberon-07 modules for use on Oberon-07 compilers are available.", 5 | "name": "Artemis", 6 | "codeRepository": "https://github.com/rsdoiel/Artemis", 7 | "issueTracker": "https://github.com/rsdoiel/Artemis/issues", 8 | "license": "https://rsdoiel.github.io/Artemis/license.html", 9 | "version": "0.0.0", 10 | "author": [ 11 | { 12 | "@type": "Person", 13 | "givenName": "Robert", 14 | "familyName": "Doiel", 15 | "email": "rsdoiel@gmail.com", 16 | "@id": "https://orcid.org/0000-0003-0900-6903" 17 | } 18 | ], 19 | "developmentStatus": "Concept", 20 | "keywords": [ 21 | "Oberon-07", 22 | "portable", 23 | "Oberon-System" 24 | ], 25 | "maintainer": "https://orcid.org/0000-0003-0900-6903", 26 | "programmingLanguage": [ 27 | "Oberon-07" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /css/prettify.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /** 5 | * @license 6 | * Copyright (C) 2015 Google Inc. 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | /* Pretty printing styles. Used with prettify.js. */ 22 | 23 | 24 | /* SPAN elements with the classes below are added by prettyprint. */ 25 | .pln { color: #000 } /* plain text */ 26 | 27 | @media screen { 28 | .str { color: #080 } /* string content */ 29 | .kwd { color: #008 } /* a keyword */ 30 | .com { color: #800 } /* a comment */ 31 | .typ { color: #606 } /* a type name */ 32 | .lit { color: #066 } /* a literal value */ 33 | /* punctuation, lisp open bracket, lisp close bracket */ 34 | .pun, .opn, .clo { color: #660 } 35 | .tag { color: #008 } /* a markup tag name */ 36 | .atn { color: #606 } /* a markup attribute name */ 37 | .atv { color: #080 } /* a markup attribute value */ 38 | .dec, .var { color: #606 } /* a declaration; a variable name */ 39 | .fun { color: red } /* a function name */ 40 | } 41 | 42 | /* Use higher contrast and text-weight for printable form. */ 43 | @media print, projection { 44 | .str { color: #060 } 45 | .kwd { color: #006; font-weight: bold } 46 | .com { color: #600; font-style: italic } 47 | .typ { color: #404; font-weight: bold } 48 | .lit { color: #044 } 49 | .pun, .opn, .clo { color: #440 } 50 | .tag { color: #006; font-weight: bold } 51 | .atn { color: #404 } 52 | .atv { color: #060 } 53 | } 54 | 55 | /* Put a border around prettyprinted code snippets. */ 56 | pre.prettyprint { padding: 2px; border: 1px solid #888 } 57 | 58 | /* Specify class=linenums on a pre to get line numbering */ 59 | ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */ 60 | li.L0, 61 | li.L1, 62 | li.L2, 63 | li.L3, 64 | li.L5, 65 | li.L6, 66 | li.L7, 67 | li.L8 { 68 | list-style-type: decimal !important; 69 | } 70 | /* Alternate shading for lines */ 71 | li.L1, 72 | li.L3, 73 | li.L5, 74 | li.L7, 75 | li.L9 { background: #eee } 76 | -------------------------------------------------------------------------------- /css/site.css: -------------------------------------------------------------------------------- 1 | /* @import 'https://fonts.googleapis.com/css?family=Concert+One|Dosis'; */ 2 | 3 | body { 4 | font-family: 'Atkinson-Hyperlegible', 'Open Sans', sans-serif; 5 | font-size: calc(1em+1vw); 6 | padding: 0; 7 | margin: 0; 8 | width: 100%; 9 | height: auto; 10 | color: black; 11 | background-color: white; 12 | } 13 | 14 | a, a:link, a:visited { 15 | color: forestgreen; 16 | text-decoration: none; 17 | } 18 | 19 | a:active, a:focus, a:hover { 20 | color: maroon; 21 | text-decoration: underline; 22 | } 23 | 24 | 25 | 26 | ul { 27 | padding: 0; 28 | margin-left: 1.24em; 29 | /* list-style-type: disc;*/ 30 | } 31 | 32 | nav { 33 | position:fixed; 34 | top:0; 35 | display: block; 36 | width: 100%; 37 | height: auto; 38 | padding: 0; 39 | padding: 0.20em; 40 | /* caltech orange, white and black 41 | color: white; 42 | background-color: #FF6E1E; 43 | */ 44 | /* white on deep red */ 45 | color: white; 46 | background-color: #5f0202; 47 | } 48 | 49 | nav a, nav a:link, nav a:visited { 50 | font-weight: lighter; 51 | color: white; 52 | text-decoration: none; 53 | } 54 | 55 | nav a:active, nav a:focus, nav a:hover { 56 | font-weight: lighter; 57 | color: orange; 58 | text-decoration: none; 59 | text-transform: uppercase; 60 | } 61 | 62 | 63 | nav ul { 64 | display: block; 65 | width: 100%; 66 | height: auto; 67 | list-style: none; 68 | list-style-type: none; 69 | padding: 0; 70 | margin: 0; 71 | } 72 | 73 | nav ul li { 74 | display: inline-block; 75 | text-align: left; 76 | padding-top: 0em; 77 | padding-left: 0.82em; 78 | padding-right: 0.24em; 79 | padding-bottom: 0em; 80 | margin: 0; 81 | } 82 | 83 | section, article { 84 | display: block; 85 | max-width: 90%; 86 | height: auto; 87 | padding: 1.24em; 88 | margin-top: 1.24em; 89 | margin-bottom: 0.24em; 90 | } 91 | 92 | 93 | img.rss-valid { 94 | display: inline; 95 | width: auto; 96 | height: 0.82em; 97 | } 98 | 99 | h1 { 100 | font-size: 200%; 101 | } 102 | 103 | h2 { 104 | font-weight: lighter; 105 | font-size: 170%; 106 | } 107 | 108 | h3 { 109 | font-weight: lighter; 110 | font-size: 120%; 111 | text-transform: uppercase; 112 | } 113 | 114 | h4 { 115 | font-weight: lighter; 116 | font-size: 100%; 117 | text-transform: lowercase; 118 | } 119 | 120 | h1 code, h2 code, h3 code, h4 code { 121 | text-transform:none; 122 | } 123 | 124 | 125 | footer { 126 | position: fixed; 127 | bottom: 0; 128 | font-size: 0.82em; 129 | font-weight: lighter; 130 | padding: 0; 131 | margin: 0; 132 | width: 100%; 133 | height: auto; 134 | color: white; 135 | background-color: black; 136 | } 137 | 138 | /* NOTE: Ingnore a P tag inserted by Markdown when rendering headers */ 139 | footer p { 140 | display: block; 141 | width: 100%; 142 | height: auto; 143 | padding: 0; 144 | margin: 0; 145 | font-family: 'Dosis', sans-serif; 146 | font-size: 0.82em; 147 | font-weight: lighter; 148 | margin-top: 0.32em; 149 | margin-left: 0; 150 | margin-right: 0; 151 | margin-bottom: 0; 152 | } 153 | 154 | footer img { 155 | display: block; 156 | float: left; 157 | vertical-align: top; 158 | border: 1px solid black; 159 | border-top-left-radius: 1.2em; 160 | border-top-right-radius: 1.2em; 161 | box-shadow: inset 0.12em 0.12em black; 162 | width: 3.2em; 163 | height: auto; 164 | margin: 0.24em; 165 | } 166 | 167 | footer a, footer a:link, footer a:visited { 168 | font-weight: lighter; 169 | /* caltech orange */ 170 | color: #FF6E1E; 171 | } 172 | 173 | footer a:active, footer a:focus, footer a:hover { 174 | font-weight: lighter; 175 | color: lightgreen; 176 | } 177 | 178 | /* color injections for AndOr */ 179 | .red { 180 | color: red; 181 | } 182 | 183 | /* Google prittyprint customizaions CSS */ 184 | li.L0, li.L1, li.L2, li.L3, li.L4, li.L5, li.L6, li.L7, li.L8, li.L9 185 | { 186 | color: #555; 187 | list-style-type: decimal; 188 | } 189 | 190 | 191 | /* Mmark css */ 192 | #footnote-section { 193 | font-size: 80%; 194 | display: none; 195 | } 196 | 197 | .footnotes { 198 | font-size: 80%; 199 | } 200 | 201 | /* 202 | * Project Customizations 203 | */ 204 | div.project-name { 205 | display: block; 206 | width: 100%; 207 | height: auto; 208 | padding-top: 1.24em; 209 | padding-left: 1.24em; 210 | margin-top: 1.24em; 211 | } 212 | 213 | header blockquote { 214 | display: block; 215 | width: 100%; 216 | height: auto; 217 | padding: 0em; 218 | margin-left: 2.48em; 219 | } 220 | 221 | -------------------------------------------------------------------------------- /css/tables.css: -------------------------------------------------------------------------------- 1 | table { 2 | table-layout: fixed; 3 | width: 80%; 4 | border-collapse: collapse; 5 | color: white; 6 | background-color: darkblue; 7 | /* border: 3px solid #5f0202; */ 8 | caption-side: bottom; 9 | } 10 | 11 | th, td { 12 | font-family: comic, cursive, helvetica; 13 | padding: 0.72em; 14 | } 15 | 16 | tr, td { 17 | font-family: monospace, courier, serif; 18 | } 19 | 20 | tbody tr:nth-child(odd) { 21 | color: blue; 22 | background-color: white; 23 | } 24 | 25 | tbody tr:nth-child(even) { 26 | color: white; 27 | background-color: blue; 28 | } 29 | 30 | caption { 31 | color: black; 32 | background-color: white; 33 | text-align: left; 34 | text-transform: lowercase; 35 | font-size: smaller; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /development-notes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | Development notes 12 |
13 |
14 |

15 | Development Notes 16 |

17 |

18 | Display & Fonts Modules 19 |

20 |

21 | Two module that are used by Texts.Mod are Display and Fonts. In the Oberon System these are standard modules. In the POSIX environment they are not. The closest is the XYPlane module from the Oakwood Guidelines. 22 |

23 |

24 | There are two approaches for replicating Display and Fonts in a POSIX setting. They could be made headless, meaning they would never attach to a real viewer or they could be integrate into the GUI of the host system. I am currently exploring SDL2 as an option for integrating them into a host environment. 25 |

26 |

27 | It is possible that copilation options could be chosen (e.g. the module search path) to pick which approach was appropriate for compiling in a POSIX environment. As an example a command line tool which is using Texts for compatibility with Oberon Texts but not for displaying them might be better off with a headless implementation. On the otherhand if you wanted to recreate the Oberon Edit command then headless doesn’t do much for you. 28 |

29 |

30 | The primary difference between a headless Texts and a displayable one is how it is hooked in to the actual rendering process. So a Display0.Mod could be the headless one while Display.Mod extended Display0 to provide real GUI rendering via a portable framework like SDL2. 31 |

32 |
33 | 64 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /development-notes.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Development notes 3 | --- 4 | 5 | Development Notes 6 | ================= 7 | 8 | Display & Fonts Modules 9 | ----------------------- 10 | 11 | Two module that are used by Texts.Mod are Display and Fonts. In the 12 | Oberon System these are standard modules. In the POSIX environment they 13 | are not. The closest is the XYPlane module from the Oakwood Guidelines. 14 | 15 | There are two approaches for replicating Display and Fonts in a 16 | POSIX setting. They could be made headless, meaning they would never 17 | attach to a real viewer or they could be integrate into the GUI of 18 | the host system. I am currently exploring SDL2 as an option 19 | for integrating them into a host environment. 20 | 21 | It is possible that copilation options could be chosen (e.g. the 22 | module search path) to pick which approach was appropriate for compiling 23 | in a POSIX environment. As an example a command line tool which is 24 | using Texts for compatibility with Oberon Texts but not for displaying 25 | them might be better off with a headless implementation. On the otherhand 26 | if you wanted to recreate the Oberon Edit command then headless doesn't 27 | do much for you. 28 | 29 | The primary difference between a headless Texts and a displayable one 30 | is how it is hooked in to the actual rendering process. So a Display0.Mod 31 | could be the headless one while Display.Mod extended Display0 to provide 32 | real GUI rendering via a portable framework like SDL2. 33 | 34 | -------------------------------------------------------------------------------- /examples/ofrontplus/Artemis.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Artemis.a -------------------------------------------------------------------------------- /examples/ofrontplus/Mod/Math.Def: -------------------------------------------------------------------------------- 1 | MODULE [foreign] Math; 2 | 3 | PROCEDURE power* (x, y: REAL) : REAL; 4 | 5 | END Math. 6 | -------------------------------------------------------------------------------- /examples/ofrontplus/Mod/Obn2.Mod: -------------------------------------------------------------------------------- 1 | (** Obn2.Mod is a module to help port Oberon-2 modules to Oberon-7. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE Obn2; 10 | 11 | (** ASH provides the Oberon-2 built-in ASH functionilty for 12 | Oberon-7. See description of providing ASH in documentation 13 | on Oberon-7 for positive and negative values *) 14 | PROCEDURE ASH*(x, n : INTEGER) : INTEGER; 15 | VAR res : INTEGER; 16 | BEGIN 17 | IF n > 0 THEN 18 | res := LSL(x, n); 19 | ELSE 20 | res := ASR(x, n); 21 | END; 22 | RETURN res 23 | END ASH; 24 | 25 | (** MAX returns the maximum of two integers *) 26 | PROCEDURE MAX*(x, y : INTEGER) : INTEGER; 27 | VAR res : INTEGER; 28 | BEGIN 29 | IF x > y THEN 30 | res := x; 31 | ELSE 32 | res := y; 33 | END; 34 | RETURN res 35 | END MAX; 36 | 37 | (** MIN provides the minimum of two integers *) 38 | PROCEDURE MIN(x, y : INTEGER) : INTEGER; 39 | VAR res : INTEGER; 40 | BEGIN 41 | IF x < y THEN 42 | res := x; 43 | ELSE 44 | res := y; 45 | END; 46 | RETURN res 47 | END MIN; 48 | 49 | (** ENTIER is a wrapper around FLOOR, you should really just use 50 | FLOOR. *) 51 | PROCEDURE ENTIER(r : REAL) : INTEGER; 52 | BEGIN 53 | RETURN FLOOR(r) 54 | END ENTIER; 55 | 56 | (** HALT is a wrapper around ASSERT(FALSE), you should just replace 57 | ASSERT(FALSE) *) 58 | PROCEDURE HALT(); 59 | BEGIN 60 | ASSERT(FALSE); 61 | END HALT; 62 | 63 | (** ROT is a wrapper around ROR, you should just replace ROT with ROR *) 64 | PROCEDURE ROT(x, n : INTEGER) : INTEGER; 65 | BEGIN 66 | RETURN ROR(x, n) 67 | END ROT; 68 | 69 | END Obn2. 70 | -------------------------------------------------------------------------------- /examples/ofrontplus/Mod/Obn2Test.Mod: -------------------------------------------------------------------------------- 1 | (** Obn2Test modules provides testing for Obn2 module. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE Obn2Test; 10 | 11 | IMPORT T := Tests; 12 | 13 | VAR ts : T.TestSet; 14 | 15 | PROCEDURE TestMinMax() : BOOLEAN; 16 | VAR test : BOOLEAN; 17 | BEGIN test := TRUE; 18 | T.ExpectedBool(TRUE, FALSE, "TestMinMax() not implemented.", test); 19 | RETURN test 20 | END TestMinMax; 21 | 22 | PROCEDURE TestShifts() : BOOLEAN; 23 | VAR test : BOOLEAN; 24 | BEGIN test := TRUE; 25 | T.ExpectedBool(TRUE, FALSE, "TestShifts() not implemented.", test); 26 | RETURN test 27 | END TestShifts; 28 | 29 | BEGIN 30 | T.Init(ts, "Obn2"); 31 | T.Add(ts, TestMinMax); 32 | T.Add(ts, TestShifts); 33 | ASSERT(T.Run(ts)); 34 | END Obn2Test. 35 | -------------------------------------------------------------------------------- /examples/ofrontplus/Mod/Out.Def: -------------------------------------------------------------------------------- 1 | MODULE [foreign] Out; 2 | 3 | PROCEDURE Char (ch: CHAR); 4 | PROCEDURE Int (i, n: INTEGER); 5 | PROCEDURE Ln; 6 | PROCEDURE Real (r: REAL; n: INTEGER); 7 | PROCEDURE String (s: ARRAY OF CHAR); 8 | 9 | END Out. 10 | -------------------------------------------------------------------------------- /examples/ofrontplus/Mod/Path.Mod: -------------------------------------------------------------------------------- 1 | MODULE Path; 2 | 3 | IMPORT Chars, Out; 4 | 5 | CONST 6 | (** Maximum path length *) 7 | MAXLENGTH* = 1024; 8 | 9 | VAR 10 | delimiter* : CHAR; 11 | 12 | (** SetDelimiter used for parsing paths *) 13 | PROCEDURE SetDelimiter*(c : CHAR); 14 | BEGIN delimiter := c; 15 | END SetDelimiter; 16 | 17 | (** Prepend insert the path fragement into the path adding 18 | the delimiter appropriately. 19 | 20 | NOTE: Prepend is limited by the temporary path used in assembling data. 21 | If the length of the prefix and path is too long then success will be 22 | set to FALSE and path will remain unchanged. *) 23 | PROCEDURE Prepend*(prefix : ARRAY OF CHAR; VAR path : ARRAY OF CHAR; VAR success : BOOLEAN); 24 | VAR tmp : ARRAY MAXLENGTH OF CHAR; l1, l2 : INTEGER; delim : ARRAY 2 OF CHAR; 25 | BEGIN success := FALSE; 26 | tmp[0] := 0X; delim[0] := delimiter; delim[1] := 0X; 27 | l1 := Chars.Length(prefix); l2 := Chars.Length(path); 28 | IF (l1 + l2 + 1) < MAXLENGTH THEN 29 | IF l1 > 0 THEN 30 | Chars.Copy(prefix, tmp); 31 | END; 32 | IF (l2 > 0) & (Chars.EndsWith(delim, tmp) = FALSE) & (Chars.StartsWith(delim, path) = FALSE) THEN 33 | Chars.AppendChar(delimiter, tmp); 34 | END; 35 | IF (l2 > 0) THEN 36 | Chars.Append(path, tmp); 37 | END; 38 | IF Chars.Length(tmp) > 0 THEN 39 | Chars.Copy(tmp, path); 40 | END; 41 | success := TRUE; 42 | END; 43 | END Prepend; 44 | 45 | (** Append appends the path fragment onto the path adding a delimiter appropriately. 46 | 47 | NOTE: The size of path limits how long the suffix can be. If it is too long then 48 | path remains unchanged and success is set to FALSE. *) 49 | PROCEDURE Append*(suffix : ARRAY OF CHAR; VAR path : ARRAY OF CHAR; VAR success : BOOLEAN); 50 | VAR l1, l2 : INTEGER; delim : ARRAY 2 OF CHAR; 51 | BEGIN success := FALSE; 52 | l1 := Chars.Length(suffix); l2 := Chars.Length(path); 53 | delim[0] := delimiter; delim[1] := 0X; 54 | IF (l1 + l2 + 1) < LEN(path) THEN 55 | IF l1 > 0 THEN 56 | IF (Chars.StartsWith(delim, suffix) = FALSE) & (Chars.EndsWith(delim, path) = FALSE) THEN 57 | Chars.Append(delim, path); 58 | END; 59 | Chars.Append(suffix, path); 60 | END; 61 | success := TRUE; 62 | END; 63 | END Append; 64 | 65 | (** Basename scans source and writes the last path segment to dest based on the path delimiter set *) 66 | PROCEDURE Basename*(source : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR; success : BOOLEAN); 67 | VAR offset, l, i : INTEGER; c : CHAR; 68 | BEGIN l := Chars.Length(source); 69 | success := l < LEN(dest); 70 | IF success THEN 71 | dest[0] := 0X; 72 | offset := -1; 73 | WHILE (i > 0) & (offset = -1) DO 74 | IF c = delimiter THEN 75 | offset := i + 1; 76 | END; 77 | DEC(i); 78 | END; 79 | IF (offset > -1) & (offset < l) THEN 80 | l := l - offset; 81 | FOR i := 0 TO l DO 82 | dest[i] := source[offset]; 83 | INC(offset); 84 | END; 85 | dest[l] := 0X; 86 | ELSE 87 | Chars.Copy(source, dest); 88 | END; 89 | END; 90 | 91 | END Basename; 92 | 93 | BEGIN SetDelimiter(Chars.SLASH); 94 | END Path. 95 | -------------------------------------------------------------------------------- /examples/ofrontplus/Mod/PathLists.Mod: -------------------------------------------------------------------------------- 1 | (** PathLists is a module for working with a delimited list of paths. *) 2 | MODULE PathLists; 3 | IMPORT Chars, Path; 4 | 5 | CONST 6 | (** Merge operations *) 7 | PREPEND = 1; (** Insert into path list *) 8 | APPEND = 2; (** Add to end of path list *) 9 | CUT = 3; (** Remove from path from path list *) 10 | 11 | TYPE 12 | PathList* = POINTER TO PathListDesc; 13 | PathListDesc* = RECORD 14 | part : ARRAY Path.MAXLENGTH OF CHAR; 15 | next : PathList 16 | END; 17 | 18 | VAR 19 | delimiter : CHAR; 20 | 21 | (** Length returns the length of the PathList *) 22 | PROCEDURE Length*(pathList : PathList) : INTEGER; 23 | VAR res : INTEGER; cur : PathList; 24 | BEGIN res := 0; cur := pathList; 25 | WHILE cur # NIL DO INC(res); cur := cur.next; END; 26 | RETURN res 27 | END Length; 28 | 29 | (** Find takes a path and searches a path list return -1 if not found 30 | or the position where it was found (zero indexed) *) 31 | PROCEDURE Find*(path : ARRAY OF CHAR; pathList : PathList) : INTEGER; 32 | VAR res, pos : INTEGER; cur : PathList; 33 | BEGIN res := -1; pos := 0; cur := pathList; 34 | WHILE (cur # NIL) & (res = -1) DO 35 | IF Chars.Equal(cur.part, path) THEN 36 | res := pos; 37 | END; 38 | INC(pos); cur := cur.next; 39 | END; 40 | RETURN res 41 | END Find; 42 | 43 | (** Prepend takes a path and a path list and prepends path to path list updating 44 | path list. *) 45 | PROCEDURE Prepend*(path : ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN); 46 | BEGIN 47 | success := FALSE; (* FIXME: Prepend not implemented. *) 48 | END Prepend; 49 | 50 | (** Append takes a path and path list and adds the path to the end of path list *) 51 | PROCEDURE Append*(path: ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN); 52 | BEGIN 53 | success := FALSE; (* FIXME: Append not implemented. *) 54 | END Append; 55 | 56 | (** Cut takes a path and a path list and removes the path element from path list. *) 57 | PROCEDURE Cut*(path : ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN); 58 | BEGIN 59 | success := FALSE; (* FIXME: Cut not implemented *) 60 | END Cut; 61 | 62 | (** SetDelimiter sets the delimiter to be used for encoding and decoding paths *) 63 | PROCEDURE SetDelimiter(c : CHAR); 64 | BEGIN delimiter := c; 65 | END SetDelimiter; 66 | 67 | (** Encode takes a PathList and encodes it into pathListString using the delimiter provided *) 68 | PROCEDURE Encode*(pathList : PathList; delimiter: CHAR; VAR pathListString : ARRAY OF CHAR; VAR success : BOOLEAN); 69 | BEGIN 70 | success := FALSE; (* FIXME: Not implemented *) 71 | END Encode; 72 | 73 | (** Decode takes a path list string and decodes it into a PathList data structure *) 74 | PROCEDURE Decode*(pathListString : ARRAY OF CHAR; VAR pathList : PathList; success : BOOLEAN); 75 | BEGIN 76 | success := FALSE; (* FIXME: Not implemented *) 77 | END Decode; 78 | 79 | (** Apply takes a path, an operation and a path list string. It applies the operation 80 | using the path and pathList updating pathList. Return TRUE of successful, 81 | FALSE otherwise. *) 82 | PROCEDURE Apply*(path: ARRAY OF CHAR; operation: INTEGER; VAR pathListString: ARRAY OF CHAR): BOOLEAN; 83 | VAR success : BOOLEAN; pathList : PathList; 84 | BEGIN 85 | Decode(pathListString, pathList, success); 86 | IF success THEN 87 | IF operation = PREPEND THEN 88 | Prepend(path, pathList, success) 89 | ELSIF operation = APPEND THEN 90 | Append(path, pathList, success) 91 | ELSIF operation = CUT THEN 92 | Cut(path, pathList, success) 93 | END; 94 | END; 95 | RETURN success 96 | END Apply; 97 | 98 | BEGIN 99 | SetDelimiter(":"); (** NOTE: The colon is the default delimiter. *) 100 | END PathLists. -------------------------------------------------------------------------------- /examples/ofrontplus/Mod/PathListsTest.Mod: -------------------------------------------------------------------------------- 1 | MODULE PathListsTest; 2 | 3 | IMPORT PathLists, T := Tests; 4 | 5 | VAR ts : T.TestSet; 6 | 7 | PROCEDURE TestEncodeDecode() : BOOLEAN; 8 | VAR test : BOOLEAN; 9 | BEGIN test := TRUE; 10 | T.ExpectedBool(TRUE, FALSE, "TestEncodeDecode() not implemented", test); 11 | RETURN test 12 | END TestEncodeDecode; 13 | 14 | PROCEDURE TestLengthSetDelimiterFind() : BOOLEAN; 15 | VAR test : BOOLEAN; 16 | BEGIN test := TRUE; 17 | T.ExpectedBool(TRUE, FALSE, "TestLengthSetDelimiterFind() not implemented.", test); 18 | RETURN test 19 | END TestLengthSetDelimiterFind; 20 | 21 | PROCEDURE TestPrepend() : BOOLEAN; 22 | VAR test : BOOLEAN; 23 | BEGIN test := TRUE; 24 | T.ExpectedBool(TRUE, FALSE, "TestPrepend() not implemented.", test); 25 | RETURN test 26 | END TestPrepend; 27 | 28 | PROCEDURE TestAppend() : BOOLEAN; 29 | VAR test : BOOLEAN; 30 | BEGIN test := TRUE; 31 | T.ExpectedBool(TRUE, FALSE, "TestAppend() not implemented. ", test); 32 | RETURN test 33 | END TestAppend; 34 | 35 | PROCEDURE TestCut() : BOOLEAN; 36 | VAR test : BOOLEAN; 37 | BEGIN test := TRUE; 38 | T.ExpectedBool(TRUE, FALSE, "TestCut() not implemented. ", test); 39 | RETURN test 40 | END TestCut; 41 | 42 | PROCEDURE TestApply() : BOOLEAN; 43 | VAR test : BOOLEAN; 44 | BEGIN test := TRUE; 45 | T.ExpectedBool(TRUE,FALSE, "TestApply() not implemented.", test); 46 | RETURN test 47 | END TestApply; 48 | 49 | BEGIN 50 | T.Init(ts, "Test PathLists"); 51 | T.Add(ts, TestEncodeDecode); 52 | T.Add(ts, TestLengthSetDelimiterFind); 53 | T.Add(ts, TestPrepend); 54 | T.Add(ts, TestAppend); 55 | T.Add(ts, TestCut); 56 | T.Add(ts, TestApply); 57 | ASSERT(T.Run(ts)); 58 | END PathListsTest. -------------------------------------------------------------------------------- /examples/ofrontplus/Mod/PathTest.Mod: -------------------------------------------------------------------------------- 1 | MODULE PathTest; 2 | 3 | IMPORT T := Tests, Path, Chars; 4 | 5 | VAR ts : T.TestSet; 6 | 7 | PROCEDURE TestMaxPath() : BOOLEAN; 8 | VAR test : BOOLEAN; 9 | BEGIN test := TRUE; 10 | T.ExpectedInt(1024, Path.MAXLENGTH, "Current path maximum assumption", test); 11 | RETURN test 12 | END TestMaxPath; 13 | 14 | PROCEDURE TestSetDelimiter() : BOOLEAN; 15 | VAR test : BOOLEAN; 16 | BEGIN test := TRUE; 17 | T.ExpectedChar(Chars.SLASH, Path.delimiter, "Checking default delimiter", test); 18 | Path.SetDelimiter(Chars.BSLASH); 19 | T.ExpectedChar(Chars.BSLASH, Path.delimiter, "Checking set delimiter to ';'", test); 20 | Path.SetDelimiter(Chars.SLASH); 21 | T.ExpectedChar(Chars.SLASH, Path.delimiter, "Checking set delimiter to ':'", test); 22 | RETURN test 23 | END TestSetDelimiter; 24 | 25 | PROCEDURE TestPrepend() : BOOLEAN; 26 | VAR test, ok : BOOLEAN; a : ARRAY Path.MAXLENGTH OF CHAR; 27 | BEGIN test := TRUE; 28 | a[0] := 0X; 29 | Path.Prepend("", a, ok); 30 | T.ExpectedBool(TRUE, ok, "Path.Prepend('', a) ok -> ''", test); 31 | T.ExpectedString("", a, "Path.Prepend('', a)", test); 32 | Path.Prepend("/me", a, ok); 33 | T.ExpectedBool(TRUE, ok, "Path.Prepend('/me', a) ok -> /me", test); 34 | T.ExpectedString("/me", a, "Path.Prepend('/me', a)", test); 35 | Path.Prepend("/home", a, ok); 36 | T.ExpectedBool(TRUE, ok, "Path.Prepend('/home', a) ok -> /home/me", test); 37 | T.ExpectedString("/home/me", a, "Path.Prepend('home', a)", test); 38 | RETURN test 39 | END TestPrepend; 40 | 41 | PROCEDURE TestAppend() : BOOLEAN; 42 | VAR test, ok : BOOLEAN; a : ARRAY Path.MAXLENGTH OF CHAR; 43 | BEGIN test := TRUE; 44 | a := ""; 45 | Path.Append("", a, ok); 46 | T.ExpectedBool(TRUE, ok, "Path.Append('', a) ok -> ''", test); 47 | T.ExpectedString("", a, "Path.Append('', a)", test); 48 | Path.Append("/", a, ok); 49 | T.ExpectedBool(TRUE, ok, "Path.Append('/', a) ok -> '/'", test); 50 | T.ExpectedString("/", a, "Path.Append('/', a)", test); 51 | Path.Append("home", a, ok); 52 | T.ExpectedBool(TRUE, ok, "Path.Append('home', a) ok -> /home", test); 53 | T.ExpectedString("/home", a, "Path.Append('home', a)", test); 54 | Path.Append("me", a, ok); 55 | T.ExpectedBool(TRUE, ok, "Path.Append('', a) ok -> /home/me", test); 56 | T.ExpectedString("/home/me", a, "Path.Append('me', a) ok -> /home/me", test); 57 | RETURN test 58 | END TestAppend; 59 | 60 | PROCEDURE TestBasename() : BOOLEAN; 61 | VAR test, ok : BOOLEAN; a, expected, got : ARRAY Path.MAXLENGTH OF CHAR; 62 | BEGIN test := TRUE; 63 | a := "/home/me/.profile"; 64 | expected := ".profile"; 65 | Path.Basename(a, got, ok); 66 | T.ExpectedBool(TRUE, ok, "Basename(a, got, ok) ok -> ?", test); 67 | T.ExpectedString(".profile", got, "Path.Basename(a, got, ok)", test); 68 | RETURN test 69 | END TestBasename; 70 | 71 | PROCEDURE TestDirname() : BOOLEAN; 72 | VAR test : BOOLEAN; 73 | BEGIN test := TRUE; 74 | T.ExpectedBool(TRUE, FALSE, "TestDirname() not implemented.", test); 75 | RETURN test 76 | END TestDirname; 77 | 78 | PROCEDURE TestExt() : BOOLEAN; 79 | VAR test : BOOLEAN; 80 | BEGIN test := TRUE; 81 | T.ExpectedBool(TRUE, FALSE, "TestExt() not implemented.", test); 82 | RETURN test 83 | END TestExt; 84 | 85 | BEGIN 86 | T.Init(ts, "Test Path"); 87 | T.Add(ts, TestMaxPath); 88 | T.Add(ts, TestSetDelimiter); 89 | T.Add(ts, TestPrepend); 90 | T.Add(ts, TestAppend); 91 | T.Add(ts, TestDirname); 92 | T.Add(ts, TestBasename); 93 | T.Add(ts, TestExt); 94 | ASSERT(T.Run(ts)); 95 | END PathTest. -------------------------------------------------------------------------------- /examples/ofrontplus/Mod/Strings.Def: -------------------------------------------------------------------------------- 1 | MODULE [foreign] Strings; 2 | 3 | PROCEDURE Length* (s: ARRAY OF CHAR) : INTEGER; 4 | 5 | END Strings. 6 | -------------------------------------------------------------------------------- /examples/ofrontplus/Mod/extConvert.Def: -------------------------------------------------------------------------------- 1 | MODULE [foreign] extConvert; 2 | 3 | PROCEDURE StringToInt (s: ARRAY OF CHAR; VAR res: INTEGER; VAR done: BOOLEAN); 4 | PROCEDURE StringToReal (s: ARRAY OF CHAR; VAR res: REAL; VAR done: BOOLEAN); 5 | 6 | END extConvert. 7 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/Chars.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef Chars__oh 4 | #define Chars__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | import CHAR Chars_spaces[6]; 10 | import CHAR Chars_punctuation[33]; 11 | 12 | 13 | import void Chars_Append (CHAR *source, INTEGER source__len, CHAR *dest, INTEGER dest__len); 14 | import void Chars_AppendChar (CHAR c, CHAR *dest, INTEGER dest__len); 15 | import void Chars_BoolToString (BOOLEAN val, CHAR *dest, INTEGER dest__len); 16 | import void Chars_Cap (CHAR *source, INTEGER source__len); 17 | import CHAR Chars_CapChar (CHAR source); 18 | import void Chars_Clear (CHAR *a, INTEGER a__len); 19 | import void Chars_Copy (CHAR *source, INTEGER source__len, CHAR *dest, INTEGER dest__len); 20 | import void Chars_Delete (CHAR *source, INTEGER source__len, INTEGER pos, INTEGER n); 21 | import BOOLEAN Chars_EndsWith (CHAR *suffix, INTEGER suffix__len, CHAR *source, INTEGER source__len); 22 | import BOOLEAN Chars_Equal (CHAR *a, INTEGER a__len, CHAR *b, INTEGER b__len); 23 | import void Chars_Extract (CHAR *source, INTEGER source__len, INTEGER pos, INTEGER n, CHAR *dest, INTEGER dest__len); 24 | import void Chars_FixedToString (SHORTREAL value, INTEGER n, CHAR *dest, INTEGER dest__len, BOOLEAN *ok); 25 | import BOOLEAN Chars_InCharList (CHAR c, CHAR *list, INTEGER list__len); 26 | import BOOLEAN Chars_InRange (CHAR c, CHAR lower, CHAR upper); 27 | import void Chars_Insert (CHAR *source, INTEGER source__len, INTEGER pos, CHAR *dest, INTEGER dest__len); 28 | import void Chars_InsertChar (CHAR c, INTEGER pos, CHAR *dest, INTEGER dest__len); 29 | import void Chars_IntToString (INTEGER value, CHAR *dest, INTEGER dest__len, BOOLEAN *ok); 30 | import BOOLEAN Chars_IsAlpha (CHAR c); 31 | import BOOLEAN Chars_IsAlphaNum (CHAR c); 32 | import BOOLEAN Chars_IsDigit (CHAR c); 33 | import BOOLEAN Chars_IsLower (CHAR c); 34 | import BOOLEAN Chars_IsPrintable (CHAR c); 35 | import BOOLEAN Chars_IsPunctuation (CHAR c); 36 | import BOOLEAN Chars_IsSpace (CHAR c); 37 | import BOOLEAN Chars_IsUpper (CHAR c); 38 | import void Chars_LeftPad (CHAR pad, INTEGER width, CHAR *dest, INTEGER dest__len); 39 | import INTEGER Chars_Length (CHAR *source, INTEGER source__len); 40 | import void Chars_Pad (CHAR pad, INTEGER width, CHAR *dest, INTEGER dest__len); 41 | import CHAR Chars_Pop (CHAR *source, INTEGER source__len); 42 | import INTEGER Chars_Pos (CHAR *pattern, INTEGER pattern__len, CHAR *source, INTEGER source__len, INTEGER pos); 43 | import void Chars_Quote (CHAR leftQuote, CHAR rightQuote, CHAR *dest, INTEGER dest__len); 44 | import void Chars_RealToString (SHORTREAL r, CHAR *dest, INTEGER dest__len, BOOLEAN *ok); 45 | import void Chars_Replace (CHAR *source, INTEGER source__len, INTEGER pos, CHAR *dest, INTEGER dest__len); 46 | import void Chars_RightPad (CHAR pad, INTEGER width, CHAR *dest, INTEGER dest__len); 47 | import void Chars_SetToString (SET set, CHAR *dest, INTEGER dest__len); 48 | import CHAR Chars_Shift (CHAR *source, INTEGER source__len); 49 | import BOOLEAN Chars_StartsWith (CHAR *prefix, INTEGER prefix__len, CHAR *source, INTEGER source__len); 50 | import void Chars_Trim (CHAR *cutset, INTEGER cutset__len, CHAR *source, INTEGER source__len); 51 | import void Chars_TrimLeft (CHAR *cutset, INTEGER cutset__len, CHAR *source, INTEGER source__len); 52 | import void Chars_TrimLeftSpace (CHAR *source, INTEGER source__len); 53 | import void Chars_TrimPrefix (CHAR *prefix, INTEGER prefix__len, CHAR *source, INTEGER source__len); 54 | import void Chars_TrimRight (CHAR *cutset, INTEGER cutset__len, CHAR *source, INTEGER source__len); 55 | import void Chars_TrimRightSpace (CHAR *source, INTEGER source__len); 56 | import void Chars_TrimSpace (CHAR *source, INTEGER source__len); 57 | import void Chars_TrimString (CHAR *cutString, INTEGER cutString__len, CHAR *source, INTEGER source__len); 58 | import void Chars_TrimSuffix (CHAR *suffix, INTEGER suffix__len, CHAR *source, INTEGER source__len); 59 | import void *Chars__init (void); 60 | 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/CharsTest.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef CharsTest__oh 4 | #define CharsTest__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | 10 | 11 | import void *CharsTest__init (void); 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/DStrings.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef DStrings__oh 4 | #define DStrings__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | typedef 9 | struct DStrings_Rider { 10 | char _prvt0[8]; 11 | INTEGER pos; 12 | BOOLEAN eot; 13 | } DStrings_Rider; 14 | 15 | typedef 16 | struct DStrings_StringDesc *DStrings_String; 17 | 18 | typedef 19 | struct DStrings_StringDesc { 20 | INTEGER _prvt0; 21 | char _prvt1[4]; 22 | } DStrings_StringDesc; 23 | 24 | 25 | 26 | import SYSTEM_ADRINT *DStrings_StringDesc__typ; 27 | import SYSTEM_ADRINT *DStrings_Rider__typ; 28 | 29 | import void DStrings_Append (DStrings_String extra, DStrings_String *dest); 30 | import DStrings_String DStrings_Base (DStrings_Rider *r, SYSTEM_ADRINT *r__typ); 31 | import void DStrings_Cap (DStrings_String *s); 32 | import void DStrings_Clear (DStrings_String *dest); 33 | import void DStrings_Copy (DStrings_String source, DStrings_String *dest); 34 | import void DStrings_CopyChars (CHAR *source, INTEGER source__len, DStrings_String *dest); 35 | import void DStrings_Delete (DStrings_String *s, INTEGER pos, INTEGER n); 36 | import BOOLEAN DStrings_EndsWith (DStrings_String suffix, DStrings_String source); 37 | import BOOLEAN DStrings_Equal (DStrings_String s1, DStrings_String s2); 38 | import void DStrings_Extract (DStrings_String source, INTEGER pos, INTEGER n, DStrings_String *dest); 39 | import CHAR DStrings_Get (DStrings_Rider *r, SYSTEM_ADRINT *r__typ); 40 | import void DStrings_Init (CHAR *str, INTEGER str__len, DStrings_String *s); 41 | import void DStrings_Insert (DStrings_String source, INTEGER pos, DStrings_String *dest); 42 | import INTEGER DStrings_Length (DStrings_String s); 43 | import CHAR DStrings_Peek (DStrings_Rider *r, SYSTEM_ADRINT *r__typ); 44 | import INTEGER DStrings_Pos (DStrings_String pattern, DStrings_String source, INTEGER pos); 45 | import void DStrings_Prune (DStrings_String *s); 46 | import void DStrings_Put (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, CHAR c); 47 | import void DStrings_Quote (CHAR leftQuote, CHAR rightQuote, DStrings_String *source); 48 | import void DStrings_Read (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, CHAR *value); 49 | import void DStrings_ReadBool (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, BOOLEAN *value); 50 | import void DStrings_ReadBytes (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, CHAR *buf, INTEGER buf__len, INTEGER n); 51 | import void DStrings_ReadChar (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, CHAR *value); 52 | import void DStrings_ReadDString (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, DStrings_String *dest); 53 | import void DStrings_ReadFixed (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, SHORTREAL *value, INTEGER n); 54 | import void DStrings_ReadInt (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, INTEGER *value); 55 | import void DStrings_ReadReal (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, SHORTREAL *value); 56 | import void DStrings_ReadSet (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, SET *value); 57 | import void DStrings_ReadString (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, CHAR *dest, INTEGER dest__len); 58 | import void DStrings_Replace (DStrings_String source, INTEGER pos, DStrings_String *dest); 59 | import void DStrings_Set (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, DStrings_String s, INTEGER pos); 60 | import BOOLEAN DStrings_StartsWith (DStrings_String prefix, DStrings_String source); 61 | import void DStrings_ToChars (DStrings_String s, CHAR *str, INTEGER str__len, INTEGER *res); 62 | import void DStrings_Trim (CHAR *cutset, INTEGER cutset__len, DStrings_String *source); 63 | import void DStrings_TrimLeft (CHAR *cutset, INTEGER cutset__len, DStrings_String *source); 64 | import void DStrings_TrimPrefix (DStrings_String prefix, DStrings_String *source); 65 | import void DStrings_TrimRight (CHAR *cutset, INTEGER cutset__len, DStrings_String *source); 66 | import void DStrings_TrimSpace (DStrings_String *source); 67 | import void DStrings_TrimSpaceLeft (DStrings_String *source); 68 | import void DStrings_TrimSpaceRight (DStrings_String *source); 69 | import void DStrings_TrimString (DStrings_String cutString, DStrings_String *source); 70 | import void DStrings_TrimSuffix (DStrings_String suffix, DStrings_String *source); 71 | import void DStrings_Write (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, CHAR value); 72 | import void DStrings_WriteBool (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, BOOLEAN value); 73 | import void DStrings_WriteBytes (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, CHAR *buf, INTEGER buf__len, INTEGER n); 74 | import void DStrings_WriteChar (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, CHAR value); 75 | import void DStrings_WriteDString (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, DStrings_String source); 76 | import void DStrings_WriteFixed (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, SHORTREAL value, INTEGER n); 77 | import void DStrings_WriteInt (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, INTEGER value); 78 | import void DStrings_WriteReal (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, SHORTREAL value); 79 | import void DStrings_WriteSet (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, SET value); 80 | import void DStrings_WriteString (DStrings_Rider *r, SYSTEM_ADRINT *r__typ, CHAR *value, INTEGER value__len); 81 | import void *DStrings__init (void); 82 | 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/DStringsTest.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef DStringsTest__oh 4 | #define DStringsTest__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | 10 | 11 | import void *DStringsTest__init (void); 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/Math.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef Math__oh 4 | #define Math__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | 10 | 11 | __EXTERN SHORTREAL power (SHORTREAL x, SHORTREAL y); 12 | #define Math__init() 13 | 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/Obn2.c: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | #include "SYSTEM.oh" 3 | 4 | 5 | 6 | 7 | export INTEGER Obn2_ASH (INTEGER x, INTEGER n); 8 | static INTEGER Obn2_ENTIER (SHORTREAL r); 9 | static void Obn2_HALT (void); 10 | export INTEGER Obn2_MAX (INTEGER x, INTEGER y); 11 | static INTEGER Obn2_MIN (INTEGER x, INTEGER y); 12 | static INTEGER Obn2_ROT (INTEGER x, INTEGER n); 13 | 14 | 15 | /*============================================================================*/ 16 | 17 | INTEGER Obn2_ASH (INTEGER x, INTEGER n) 18 | { 19 | INTEGER res; 20 | if (n > 0) { 21 | res = __LSHL(x, n, INTEGER); 22 | } else { 23 | res = __ASHR(x, n, INTEGER); 24 | } 25 | return res; 26 | } 27 | 28 | /*----------------------------------------------------------------------------*/ 29 | INTEGER Obn2_MAX (INTEGER x, INTEGER y) 30 | { 31 | INTEGER res; 32 | if (x > y) { 33 | res = x; 34 | } else { 35 | res = y; 36 | } 37 | return res; 38 | } 39 | 40 | /*----------------------------------------------------------------------------*/ 41 | static INTEGER Obn2_MIN (INTEGER x, INTEGER y) 42 | { 43 | INTEGER res; 44 | if (x < y) { 45 | res = x; 46 | } else { 47 | res = y; 48 | } 49 | return res; 50 | } 51 | 52 | static INTEGER Obn2_ENTIER (SHORTREAL r) 53 | { 54 | return (INTEGER)__ENTIER(r); 55 | } 56 | 57 | static void Obn2_HALT (void) 58 | { 59 | __HALT(0, (CHAR*)"Obn2", 15375); 60 | } 61 | 62 | static INTEGER Obn2_ROT (INTEGER x, INTEGER n) 63 | { 64 | return __ROTR(x, n, INTEGER); 65 | } 66 | 67 | 68 | export void *Obn2__init (void) 69 | { 70 | __DEFMOD; 71 | __REGMOD("Obn2", 0); 72 | /* BEGIN */ 73 | __ENDMOD; 74 | } 75 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/Obn2.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef Obn2__oh 4 | #define Obn2__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | 10 | 11 | import INTEGER Obn2_ASH (INTEGER x, INTEGER n); 12 | import INTEGER Obn2_MAX (INTEGER x, INTEGER y); 13 | import void *Obn2__init (void); 14 | 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/Obn2Test.c: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | #include "SYSTEM.oh" 3 | #include "Tests.oh" 4 | 5 | 6 | static Tests_TestSet Obn2Test_ts; 7 | 8 | 9 | static BOOLEAN Obn2Test_TestMinMax (void); 10 | static BOOLEAN Obn2Test_TestShifts (void); 11 | 12 | 13 | /*============================================================================*/ 14 | 15 | static BOOLEAN Obn2Test_TestMinMax (void) 16 | { 17 | BOOLEAN test; 18 | test = 1; 19 | Tests_ExpectedBool(1, 0, (CHAR*)"TestMinMax() not implemented.", 30, &test); 20 | return test; 21 | } 22 | 23 | static BOOLEAN Obn2Test_TestShifts (void) 24 | { 25 | BOOLEAN test; 26 | test = 1; 27 | Tests_ExpectedBool(1, 0, (CHAR*)"TestShifts() not implemented.", 30, &test); 28 | return test; 29 | } 30 | 31 | static void EnumPtrs(void (*P)(void*)) 32 | { 33 | P(Obn2Test_ts); 34 | } 35 | 36 | 37 | export void *Obn2Test__init (void) 38 | { 39 | __DEFMOD; 40 | __IMPORT(Tests__init); 41 | __REGMOD("Obn2Test", EnumPtrs); 42 | /* BEGIN */ 43 | Tests_Init(&Obn2Test_ts, (CHAR*)"Obn2", 5); 44 | Tests_Add(&Obn2Test_ts, Obn2Test_TestMinMax); 45 | Tests_Add(&Obn2Test_ts, Obn2Test_TestShifts); 46 | __ASSERT(Tests_Run(Obn2Test_ts), 0, (CHAR*)"Obn2Test", 8467); 47 | __ENDMOD; 48 | } 49 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/Obn2Test.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef Obn2Test__oh 4 | #define Obn2Test__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | 10 | 11 | import void *Obn2Test__init (void); 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/Out.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef Out__oh 4 | #define Out__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | 10 | 11 | __EXTERN void Char (CHAR ch); 12 | __EXTERN void Int (INTEGER i, INTEGER n); 13 | __EXTERN void Ln (void); 14 | __EXTERN void Real (SHORTREAL r, INTEGER n); 15 | __EXTERN void String (CHAR *s, INTEGER s__len); 16 | #define Out__init() 17 | 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/Path.c: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | #include "SYSTEM.oh" 3 | #include "Chars.oh" 4 | #include "Out.oh" 5 | 6 | 7 | export CHAR Path_delimiter; 8 | 9 | 10 | export void Path_Append (CHAR *suffix, INTEGER suffix__len, CHAR *path, INTEGER path__len, BOOLEAN *success); 11 | export void Path_Basename (CHAR *source, INTEGER source__len, CHAR *dest, INTEGER dest__len, BOOLEAN success); 12 | export void Path_Prepend (CHAR *prefix, INTEGER prefix__len, CHAR *path, INTEGER path__len, BOOLEAN *success); 13 | export void Path_SetDelimiter (CHAR c); 14 | 15 | 16 | /*============================================================================*/ 17 | 18 | void Path_SetDelimiter (CHAR c) 19 | { 20 | Path_delimiter = c; 21 | } 22 | 23 | /*----------------------------------------------------------------------------*/ 24 | void Path_Prepend (CHAR *prefix, INTEGER prefix__len, CHAR *path, INTEGER path__len, BOOLEAN *success) 25 | { 26 | CHAR tmp[1024]; 27 | INTEGER l1, l2; 28 | CHAR delim[2]; 29 | *success = 0; 30 | tmp[0] = 0x00; 31 | delim[0] = Path_delimiter; 32 | delim[1] = 0x00; 33 | l1 = Chars_Length((void*)prefix, prefix__len); 34 | l2 = Chars_Length((void*)path, path__len); 35 | if ((l1 + l2) + 1 < 1024) { 36 | if (l1 > 0) { 37 | Chars_Copy((void*)prefix, prefix__len, (void*)tmp, 1024); 38 | } 39 | if ((l2 > 0 && Chars_EndsWith((void*)delim, 2, (void*)tmp, 1024) == 0) && Chars_StartsWith((void*)delim, 2, (void*)path, path__len) == 0) { 40 | Chars_AppendChar(Path_delimiter, (void*)tmp, 1024); 41 | } 42 | if (l2 > 0) { 43 | Chars_Append((void*)path, path__len, (void*)tmp, 1024); 44 | } 45 | if (Chars_Length((void*)tmp, 1024) > 0) { 46 | Chars_Copy((void*)tmp, 1024, (void*)path, path__len); 47 | } 48 | *success = 1; 49 | } 50 | } 51 | 52 | /*----------------------------------------------------------------------------*/ 53 | void Path_Append (CHAR *suffix, INTEGER suffix__len, CHAR *path, INTEGER path__len, BOOLEAN *success) 54 | { 55 | INTEGER l1, l2; 56 | CHAR delim[2]; 57 | *success = 0; 58 | l1 = Chars_Length((void*)suffix, suffix__len); 59 | l2 = Chars_Length((void*)path, path__len); 60 | delim[0] = Path_delimiter; 61 | delim[1] = 0x00; 62 | if ((l1 + l2) + 1 < path__len) { 63 | if (l1 > 0) { 64 | if (Chars_StartsWith((void*)delim, 2, (void*)suffix, suffix__len) == 0 && Chars_EndsWith((void*)delim, 2, (void*)path, path__len) == 0) { 65 | Chars_Append((void*)delim, 2, (void*)path, path__len); 66 | } 67 | Chars_Append((void*)suffix, suffix__len, (void*)path, path__len); 68 | } 69 | *success = 1; 70 | } 71 | } 72 | 73 | /*----------------------------------------------------------------------------*/ 74 | void Path_Basename (CHAR *source, INTEGER source__len, CHAR *dest, INTEGER dest__len, BOOLEAN success) 75 | { 76 | INTEGER offset, l, i; 77 | CHAR c; 78 | l = Chars_Length((void*)source, source__len); 79 | success = l < dest__len; 80 | if (success) { 81 | dest[0] = 0x00; 82 | offset = -1; 83 | while (i > 0 && offset == -1) { 84 | if (c == Path_delimiter) { 85 | offset = i + 1; 86 | } 87 | i -= 1; 88 | } 89 | if (offset > -1 && offset < l) { 90 | l = l - offset; 91 | i = 0; 92 | while (i <= l) { 93 | dest[__X(i, dest__len, (CHAR*)"Path", 21033)] = source[__X(offset, source__len, (CHAR*)"Path", 21033)]; 94 | offset += 1; 95 | i += 1; 96 | } 97 | dest[__X(l, dest__len, (CHAR*)"Path", 21785)] = 0x00; 98 | } else { 99 | Chars_Copy((void*)source, source__len, (void*)dest, dest__len); 100 | } 101 | } 102 | } 103 | 104 | /*----------------------------------------------------------------------------*/ 105 | 106 | export void *Path__init (void) 107 | { 108 | __DEFMOD; 109 | __IMPORT(Chars__init); 110 | __IMPORT(Out__init); 111 | __REGMOD("Path", 0); 112 | /* BEGIN */ 113 | Path_SetDelimiter('/'); 114 | __ENDMOD; 115 | } 116 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/Path.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef Path__oh 4 | #define Path__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | import CHAR Path_delimiter; 10 | 11 | 12 | import void Path_Append (CHAR *suffix, INTEGER suffix__len, CHAR *path, INTEGER path__len, BOOLEAN *success); 13 | import void Path_Basename (CHAR *source, INTEGER source__len, CHAR *dest, INTEGER dest__len, BOOLEAN success); 14 | import void Path_Prepend (CHAR *prefix, INTEGER prefix__len, CHAR *path, INTEGER path__len, BOOLEAN *success); 15 | import void Path_SetDelimiter (CHAR c); 16 | import void *Path__init (void); 17 | 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/PathLists.c: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | #include "SYSTEM.oh" 3 | #include "Chars.oh" 4 | #include "Path.oh" 5 | 6 | typedef 7 | struct PathLists_PathListDesc *PathLists_PathList; 8 | 9 | typedef 10 | struct PathLists_PathListDesc { 11 | CHAR part[1024]; 12 | PathLists_PathList next; 13 | } PathLists_PathListDesc; 14 | 15 | 16 | static CHAR PathLists_delimiter; 17 | 18 | export SYSTEM_ADRINT *PathLists_PathListDesc__typ; 19 | 20 | export void PathLists_Append (CHAR *path, INTEGER path__len, PathLists_PathList *pathList, BOOLEAN *success); 21 | export BOOLEAN PathLists_Apply (CHAR *path, INTEGER path__len, INTEGER operation, CHAR *pathListString, INTEGER pathListString__len); 22 | export void PathLists_Cut (CHAR *path, INTEGER path__len, PathLists_PathList *pathList, BOOLEAN *success); 23 | export void PathLists_Decode (CHAR *pathListString, INTEGER pathListString__len, PathLists_PathList *pathList, BOOLEAN success); 24 | export void PathLists_Encode (PathLists_PathList pathList, CHAR delimiter, CHAR *pathListString, INTEGER pathListString__len, BOOLEAN *success); 25 | export INTEGER PathLists_Find (CHAR *path, INTEGER path__len, PathLists_PathList pathList); 26 | export INTEGER PathLists_Length (PathLists_PathList pathList); 27 | export void PathLists_Prepend (CHAR *path, INTEGER path__len, PathLists_PathList *pathList, BOOLEAN *success); 28 | static void PathLists_SetDelimiter (CHAR c); 29 | 30 | 31 | /*============================================================================*/ 32 | 33 | INTEGER PathLists_Length (PathLists_PathList pathList) 34 | { 35 | INTEGER res; 36 | PathLists_PathList cur = NIL; 37 | res = 0; 38 | cur = pathList; 39 | while (cur != NIL) { 40 | res += 1; 41 | cur = cur->next; 42 | } 43 | return res; 44 | } 45 | 46 | /*----------------------------------------------------------------------------*/ 47 | INTEGER PathLists_Find (CHAR *path, INTEGER path__len, PathLists_PathList pathList) 48 | { 49 | INTEGER res, pos; 50 | PathLists_PathList cur = NIL; 51 | res = -1; 52 | pos = 0; 53 | cur = pathList; 54 | while (cur != NIL && res == -1) { 55 | if (Chars_Equal((void*)cur->part, 1024, (void*)path, path__len)) { 56 | res = pos; 57 | } 58 | pos += 1; 59 | cur = cur->next; 60 | } 61 | return res; 62 | } 63 | 64 | /*----------------------------------------------------------------------------*/ 65 | void PathLists_Prepend (CHAR *path, INTEGER path__len, PathLists_PathList *pathList, BOOLEAN *success) 66 | { 67 | *success = 0; 68 | } 69 | 70 | /*----------------------------------------------------------------------------*/ 71 | void PathLists_Append (CHAR *path, INTEGER path__len, PathLists_PathList *pathList, BOOLEAN *success) 72 | { 73 | *success = 0; 74 | } 75 | 76 | /*----------------------------------------------------------------------------*/ 77 | void PathLists_Cut (CHAR *path, INTEGER path__len, PathLists_PathList *pathList, BOOLEAN *success) 78 | { 79 | *success = 0; 80 | } 81 | 82 | /*----------------------------------------------------------------------------*/ 83 | static void PathLists_SetDelimiter (CHAR c) 84 | { 85 | PathLists_delimiter = c; 86 | } 87 | 88 | void PathLists_Encode (PathLists_PathList pathList, CHAR delimiter, CHAR *pathListString, INTEGER pathListString__len, BOOLEAN *success) 89 | { 90 | *success = 0; 91 | } 92 | 93 | /*----------------------------------------------------------------------------*/ 94 | void PathLists_Decode (CHAR *pathListString, INTEGER pathListString__len, PathLists_PathList *pathList, BOOLEAN success) 95 | { 96 | success = 0; 97 | } 98 | 99 | /*----------------------------------------------------------------------------*/ 100 | BOOLEAN PathLists_Apply (CHAR *path, INTEGER path__len, INTEGER operation, CHAR *pathListString, INTEGER pathListString__len) 101 | { 102 | BOOLEAN success; 103 | PathLists_PathList pathList = NIL; 104 | PathLists_Decode((void*)pathListString, pathListString__len, &pathList, success); 105 | if (success) { 106 | if (operation == 1) { 107 | PathLists_Prepend((void*)path, path__len, &pathList, &success); 108 | } else if (operation == 2) { 109 | PathLists_Append((void*)path, path__len, &pathList, &success); 110 | } else if (operation == 3) { 111 | PathLists_Cut((void*)path, path__len, &pathList, &success); 112 | } 113 | } 114 | return success; 115 | } 116 | 117 | /*----------------------------------------------------------------------------*/ 118 | __TDESC(PathLists_PathListDesc__desc, 2, 1) = {__TDFLDS("PathListDesc", 1028), {1024, -8}}; 119 | 120 | export void *PathLists__init (void) 121 | { 122 | __DEFMOD; 123 | __IMPORT(Chars__init); 124 | __IMPORT(Path__init); 125 | __REGMOD("PathLists", 0); 126 | __INITYP(PathLists_PathListDesc, PathLists_PathListDesc, 0); 127 | /* BEGIN */ 128 | PathLists_SetDelimiter(':'); 129 | __ENDMOD; 130 | } 131 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/PathLists.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef PathLists__oh 4 | #define PathLists__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | typedef 9 | struct PathLists_PathListDesc *PathLists_PathList; 10 | 11 | typedef 12 | struct PathLists_PathListDesc { 13 | INTEGER _prvt0; 14 | char _prvt1[1024]; 15 | } PathLists_PathListDesc; 16 | 17 | 18 | 19 | import SYSTEM_ADRINT *PathLists_PathListDesc__typ; 20 | 21 | import void PathLists_Append (CHAR *path, INTEGER path__len, PathLists_PathList *pathList, BOOLEAN *success); 22 | import BOOLEAN PathLists_Apply (CHAR *path, INTEGER path__len, INTEGER operation, CHAR *pathListString, INTEGER pathListString__len); 23 | import void PathLists_Cut (CHAR *path, INTEGER path__len, PathLists_PathList *pathList, BOOLEAN *success); 24 | import void PathLists_Decode (CHAR *pathListString, INTEGER pathListString__len, PathLists_PathList *pathList, BOOLEAN success); 25 | import void PathLists_Encode (PathLists_PathList pathList, CHAR delimiter, CHAR *pathListString, INTEGER pathListString__len, BOOLEAN *success); 26 | import INTEGER PathLists_Find (CHAR *path, INTEGER path__len, PathLists_PathList pathList); 27 | import INTEGER PathLists_Length (PathLists_PathList pathList); 28 | import void PathLists_Prepend (CHAR *path, INTEGER path__len, PathLists_PathList *pathList, BOOLEAN *success); 29 | import void *PathLists__init (void); 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/PathListsTest.c: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | #include "SYSTEM.oh" 3 | #include "PathLists.oh" 4 | #include "Tests.oh" 5 | 6 | 7 | static Tests_TestSet PathListsTest_ts; 8 | 9 | 10 | static BOOLEAN PathListsTest_TestAppend (void); 11 | static BOOLEAN PathListsTest_TestApply (void); 12 | static BOOLEAN PathListsTest_TestCut (void); 13 | static BOOLEAN PathListsTest_TestEncodeDecode (void); 14 | static BOOLEAN PathListsTest_TestLengthSetDelimiterFind (void); 15 | static BOOLEAN PathListsTest_TestPrepend (void); 16 | 17 | 18 | /*============================================================================*/ 19 | 20 | static BOOLEAN PathListsTest_TestEncodeDecode (void) 21 | { 22 | BOOLEAN test; 23 | test = 1; 24 | Tests_ExpectedBool(1, 0, (CHAR*)"TestEncodeDecode() not implemented", 35, &test); 25 | return test; 26 | } 27 | 28 | static BOOLEAN PathListsTest_TestLengthSetDelimiterFind (void) 29 | { 30 | BOOLEAN test; 31 | test = 1; 32 | Tests_ExpectedBool(1, 0, (CHAR*)"TestLengthSetDelimiterFind() not implemented.", 46, &test); 33 | return test; 34 | } 35 | 36 | static BOOLEAN PathListsTest_TestPrepend (void) 37 | { 38 | BOOLEAN test; 39 | test = 1; 40 | Tests_ExpectedBool(1, 0, (CHAR*)"TestPrepend() not implemented.", 31, &test); 41 | return test; 42 | } 43 | 44 | static BOOLEAN PathListsTest_TestAppend (void) 45 | { 46 | BOOLEAN test; 47 | test = 1; 48 | Tests_ExpectedBool(1, 0, (CHAR*)"TestAppend() not implemented. ", 31, &test); 49 | return test; 50 | } 51 | 52 | static BOOLEAN PathListsTest_TestCut (void) 53 | { 54 | BOOLEAN test; 55 | test = 1; 56 | Tests_ExpectedBool(1, 0, (CHAR*)"TestCut() not implemented. ", 28, &test); 57 | return test; 58 | } 59 | 60 | static BOOLEAN PathListsTest_TestApply (void) 61 | { 62 | BOOLEAN test; 63 | test = 1; 64 | Tests_ExpectedBool(1, 0, (CHAR*)"TestApply() not implemented.", 29, &test); 65 | return test; 66 | } 67 | 68 | static void EnumPtrs(void (*P)(void*)) 69 | { 70 | P(PathListsTest_ts); 71 | } 72 | 73 | 74 | export void *PathListsTest__init (void) 75 | { 76 | __DEFMOD; 77 | __IMPORT(PathLists__init); 78 | __IMPORT(Tests__init); 79 | __REGMOD("PathListsTest", EnumPtrs); 80 | /* BEGIN */ 81 | Tests_Init(&PathListsTest_ts, (CHAR*)"Test PathLists", 15); 82 | Tests_Add(&PathListsTest_ts, PathListsTest_TestEncodeDecode); 83 | Tests_Add(&PathListsTest_ts, PathListsTest_TestLengthSetDelimiterFind); 84 | Tests_Add(&PathListsTest_ts, PathListsTest_TestPrepend); 85 | Tests_Add(&PathListsTest_ts, PathListsTest_TestAppend); 86 | Tests_Add(&PathListsTest_ts, PathListsTest_TestCut); 87 | Tests_Add(&PathListsTest_ts, PathListsTest_TestApply); 88 | __ASSERT(Tests_Run(PathListsTest_ts), 0, (CHAR*)"PathListsTest", 14613); 89 | __ENDMOD; 90 | } 91 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/PathListsTest.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef PathListsTest__oh 4 | #define PathListsTest__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | 10 | 11 | import void *PathListsTest__init (void); 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/PathTest.c: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | #include "SYSTEM.oh" 3 | #include "Tests.oh" 4 | #include "Path.oh" 5 | #include "Chars.oh" 6 | 7 | 8 | static Tests_TestSet PathTest_ts; 9 | 10 | 11 | static BOOLEAN PathTest_TestAppend (void); 12 | static BOOLEAN PathTest_TestBasename (void); 13 | static BOOLEAN PathTest_TestDirname (void); 14 | static BOOLEAN PathTest_TestExt (void); 15 | static BOOLEAN PathTest_TestMaxPath (void); 16 | static BOOLEAN PathTest_TestPrepend (void); 17 | static BOOLEAN PathTest_TestSetDelimiter (void); 18 | 19 | 20 | /*============================================================================*/ 21 | 22 | static BOOLEAN PathTest_TestMaxPath (void) 23 | { 24 | BOOLEAN test; 25 | test = 1; 26 | Tests_ExpectedInt(1024, 1024, (CHAR*)"Current path maximum assumption", 32, &test); 27 | return test; 28 | } 29 | 30 | static BOOLEAN PathTest_TestSetDelimiter (void) 31 | { 32 | BOOLEAN test; 33 | test = 1; 34 | Tests_ExpectedChar('/', Path_delimiter, (CHAR*)"Checking default delimiter", 27, &test); 35 | Path_SetDelimiter(0x92); 36 | Tests_ExpectedChar(0x92, Path_delimiter, (CHAR*)"Checking set delimiter to \';\'", 30, &test); 37 | Path_SetDelimiter('/'); 38 | Tests_ExpectedChar('/', Path_delimiter, (CHAR*)"Checking set delimiter to \':\'", 30, &test); 39 | return test; 40 | } 41 | 42 | static BOOLEAN PathTest_TestPrepend (void) 43 | { 44 | BOOLEAN test, ok; 45 | CHAR a[1024]; 46 | test = 1; 47 | a[0] = 0x00; 48 | Path_Prepend((CHAR*)"", 1, (void*)a, 1024, &ok); 49 | Tests_ExpectedBool(1, ok, (CHAR*)"Path.Prepend(\'\', a) ok -> \'\'", 29, &test); 50 | Tests_ExpectedString((CHAR*)"", 1, (void*)a, 1024, (CHAR*)"Path.Prepend(\'\', a)", 20, &test); 51 | Path_Prepend((CHAR*)"/me", 4, (void*)a, 1024, &ok); 52 | Tests_ExpectedBool(1, ok, (CHAR*)"Path.Prepend(\'/me\', a) ok -> /me", 33, &test); 53 | Tests_ExpectedString((CHAR*)"/me", 4, (void*)a, 1024, (CHAR*)"Path.Prepend(\'/me\', a)", 23, &test); 54 | Path_Prepend((CHAR*)"/home", 6, (void*)a, 1024, &ok); 55 | Tests_ExpectedBool(1, ok, (CHAR*)"Path.Prepend(\'/home\', a) ok -> /home/me", 40, &test); 56 | Tests_ExpectedString((CHAR*)"/home/me", 9, (void*)a, 1024, (CHAR*)"Path.Prepend(\'home\', a)", 24, &test); 57 | return test; 58 | } 59 | 60 | static BOOLEAN PathTest_TestAppend (void) 61 | { 62 | BOOLEAN test, ok; 63 | CHAR a[1024]; 64 | test = 1; 65 | a[0] = 0x00; 66 | Path_Append((CHAR*)"", 1, (void*)a, 1024, &ok); 67 | Tests_ExpectedBool(1, ok, (CHAR*)"Path.Append(\'\', a) ok -> \'\'", 28, &test); 68 | Tests_ExpectedString((CHAR*)"", 1, (void*)a, 1024, (CHAR*)"Path.Append(\'\', a)", 19, &test); 69 | Path_Append((CHAR*)"/", 2, (void*)a, 1024, &ok); 70 | Tests_ExpectedBool(1, ok, (CHAR*)"Path.Append(\'/\', a) ok -> \'/\'", 30, &test); 71 | Tests_ExpectedString((CHAR*)"/", 2, (void*)a, 1024, (CHAR*)"Path.Append(\'/\', a)", 20, &test); 72 | Path_Append((CHAR*)"home", 5, (void*)a, 1024, &ok); 73 | Tests_ExpectedBool(1, ok, (CHAR*)"Path.Append(\'home\', a) ok -> /home", 35, &test); 74 | Tests_ExpectedString((CHAR*)"/home", 6, (void*)a, 1024, (CHAR*)"Path.Append(\'home\', a)", 23, &test); 75 | Path_Append((CHAR*)"me", 3, (void*)a, 1024, &ok); 76 | Tests_ExpectedBool(1, ok, (CHAR*)"Path.Append(\'\', a) ok -> /home/me", 34, &test); 77 | Tests_ExpectedString((CHAR*)"/home/me", 9, (void*)a, 1024, (CHAR*)"Path.Append(\'me\', a) ok -> /home/me", 36, &test); 78 | return test; 79 | } 80 | 81 | static BOOLEAN PathTest_TestBasename (void) 82 | { 83 | BOOLEAN test, ok; 84 | CHAR a[1024], expected[1024], got[1024]; 85 | test = 1; 86 | __MOVE("/home/me/.profile", a, 18); 87 | __MOVE(".profile", expected, 9); 88 | Path_Basename((void*)a, 1024, (void*)got, 1024, ok); 89 | Tests_ExpectedBool(1, ok, (CHAR*)"Basename(a, got, ok) ok -> \?", 29, &test); 90 | Tests_ExpectedString((CHAR*)".profile", 9, (void*)got, 1024, (CHAR*)"Path.Basename(a, got, ok)", 26, &test); 91 | return test; 92 | } 93 | 94 | static BOOLEAN PathTest_TestDirname (void) 95 | { 96 | BOOLEAN test; 97 | test = 1; 98 | Tests_ExpectedBool(1, 0, (CHAR*)"TestDirname() not implemented.", 31, &test); 99 | return test; 100 | } 101 | 102 | static BOOLEAN PathTest_TestExt (void) 103 | { 104 | BOOLEAN test; 105 | test = 1; 106 | Tests_ExpectedBool(1, 0, (CHAR*)"TestExt() not implemented.", 27, &test); 107 | return test; 108 | } 109 | 110 | static void EnumPtrs(void (*P)(void*)) 111 | { 112 | P(PathTest_ts); 113 | } 114 | 115 | 116 | export void *PathTest__init (void) 117 | { 118 | __DEFMOD; 119 | __IMPORT(Chars__init); 120 | __IMPORT(Path__init); 121 | __IMPORT(Tests__init); 122 | __REGMOD("PathTest", EnumPtrs); 123 | /* BEGIN */ 124 | Tests_Init(&PathTest_ts, (CHAR*)"Test Path", 10); 125 | Tests_Add(&PathTest_ts, PathTest_TestMaxPath); 126 | Tests_Add(&PathTest_ts, PathTest_TestSetDelimiter); 127 | Tests_Add(&PathTest_ts, PathTest_TestPrepend); 128 | Tests_Add(&PathTest_ts, PathTest_TestAppend); 129 | Tests_Add(&PathTest_ts, PathTest_TestDirname); 130 | Tests_Add(&PathTest_ts, PathTest_TestBasename); 131 | Tests_Add(&PathTest_ts, PathTest_TestExt); 132 | __ASSERT(Tests_Run(PathTest_ts), 0, (CHAR*)"PathTest", 24085); 133 | __ENDMOD; 134 | } 135 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/PathTest.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef PathTest__oh 4 | #define PathTest__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | 10 | 11 | import void *PathTest__init (void); 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/Strings.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef Strings__oh 4 | #define Strings__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | 10 | 11 | __EXTERN INTEGER Length (CHAR *s, INTEGER s__len); 12 | #define Strings__init() 13 | 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/Tests.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef Tests__oh 4 | #define Tests__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | typedef 9 | BOOLEAN (*Tests_TestProc)(void); 10 | 11 | typedef 12 | struct Tests_TestSetDesc *Tests_TestSet; 13 | 14 | typedef 15 | struct Tests_TestSetDesc { 16 | CHAR title[1024]; 17 | Tests_TestProc fn; 18 | Tests_TestSet next; 19 | } Tests_TestSetDesc; 20 | 21 | 22 | 23 | import SYSTEM_ADRINT *Tests_TestSetDesc__typ; 24 | 25 | import void Tests_Add (Tests_TestSet *ts, Tests_TestProc fn); 26 | import void Tests_DisplayString (CHAR *msg, INTEGER msg__len, CHAR *source, INTEGER source__len); 27 | import void Tests_ExpectedBool (BOOLEAN expected, BOOLEAN got, CHAR *msg, INTEGER msg__len, BOOLEAN *test); 28 | import void Tests_ExpectedBytes (CHAR *expected, INTEGER expected__len, CHAR *got, INTEGER got__len, INTEGER n, CHAR *msg, INTEGER msg__len, BOOLEAN *test); 29 | import void Tests_ExpectedChar (CHAR expected, CHAR got, CHAR *msg, INTEGER msg__len, BOOLEAN *test); 30 | import void Tests_ExpectedInt (INTEGER expected, INTEGER got, CHAR *msg, INTEGER msg__len, BOOLEAN *test); 31 | import void Tests_ExpectedReal (SHORTREAL expected, SHORTREAL got, CHAR *msg, INTEGER msg__len, BOOLEAN *test); 32 | import void Tests_ExpectedSet (SET expected, SET got, CHAR *msg, INTEGER msg__len, BOOLEAN *test); 33 | import void Tests_ExpectedString (CHAR *s1, INTEGER s1__len, CHAR *s2, INTEGER s2__len, CHAR *msg, INTEGER msg__len, BOOLEAN *test); 34 | import void Tests_Init (Tests_TestSet *ts, CHAR *title, INTEGER title__len); 35 | import BOOLEAN Tests_Run (Tests_TestSet ts); 36 | import void Tests_ShowTitle (CHAR *s, INTEGER s__len); 37 | import void Tests_Summarize (CHAR *title, INTEGER title__len, INTEGER successes, INTEGER errors); 38 | import void Tests_Test (Tests_TestProc fn, INTEGER *success, INTEGER *errors); 39 | import void *Tests__init (void); 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /examples/ofrontplus/Obj/extConvert.oh: -------------------------------------------------------------------------------- 1 | /* Ofront+ 1.0 -s7 -48 */ 2 | 3 | #ifndef extConvert__oh 4 | #define extConvert__oh 5 | 6 | #include "SYSTEM.oh" 7 | 8 | 9 | 10 | 11 | __EXTERN void StringToInt (CHAR *s, INTEGER s__len, INTEGER *res, BOOLEAN *done); 12 | __EXTERN void StringToReal (CHAR *s, INTEGER s__len, SHORTREAL *res, BOOLEAN *done); 13 | #define extConvert__init() 14 | 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /examples/ofrontplus/README.md: -------------------------------------------------------------------------------- 1 | 2 | Ofront+ Example Compilation 3 | --------------------------- 4 | 5 | This directory holds [Oleg-N-Cher](https://github.com/Oleg-N-Cher)'s contribution to compiling Artemis under [Ofront+](https://github.com/Oleg-N-Cher/OfrontPlus). It is based on Oleg's replies to [Issue #2](https://github.com/rsdoiel/Artemis/issues/2#issuecomment-890403702). 6 | 7 | Thank you Oleg! 8 | 9 | -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/Chars.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/Chars.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/CharsTest.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/CharsTest.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/DStrings.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/DStrings.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/DStringsTest.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/DStringsTest.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/Math.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/Math.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/Obn2.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/Obn2.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/Obn2Test.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/Obn2Test.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/Out.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/Out.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/Path.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/Path.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/PathLists.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/PathLists.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/PathListsTest.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/PathListsTest.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/PathTest.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/PathTest.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/Strings.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/Strings.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/Tests.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/Tests.sym -------------------------------------------------------------------------------- /examples/ofrontplus/Sym/extConvert.sym: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rsdoiel/Artemis/f7e431df62d3169c9e602e308a8e679cd5e09847/examples/ofrontplus/Sym/extConvert.sym -------------------------------------------------------------------------------- /examples/ofrontplus/build.bat: -------------------------------------------------------------------------------- 1 | @CALL o2c.bat 2 | @CALL cc.bat 3 | -------------------------------------------------------------------------------- /examples/ofrontplus/cc.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | IF NOT "%XDev%"=="" SET PATH=%XDev%\WinDev\Bin\MinGW\bin 3 | IF EXIST Obj CD Obj 4 | 5 | SET CC=gcc.exe -m32 -fPIC -Os -g0 -fno-exceptions -ffunction-sections -c 6 | SET AR=ar.exe -rc ..\Artemis.a 7 | IF EXIST ..\Artemis.a DEL ..\Artemis.a 8 | 9 | %CC% Tests.c ^ 10 | Chars.c DStrings.c Obn2.c Path.c PathLists.c ^ 11 | CharsTest.c DStringsTest.c Obn2Test.c PathTest.c PathListsTest.c 12 | IF errorlevel 1 PAUSE 13 | 14 | %AR% Tests.o ^ 15 | Chars.o DStrings.o Obn2.o Path.o PathLists.o ^ 16 | CharsTest.o DStringsTest.o Obn2Test.o PathTest.o PathListsTest.o 17 | 18 | DEL /Q *.o 19 | -------------------------------------------------------------------------------- /examples/ofrontplus/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | … 12 |
13 |
14 |

15 | Ofront+ Example Compilation 16 |

17 |

18 | This directory holds Oleg-N-Cher’s contribution to compiling Artemis under Ofront+. It is based on Oleg’s replies to Issue #2. 19 |

20 |

21 | Thank you Oleg! 22 |

23 |
24 | 27 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /examples/ofrontplus/o2c.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | IF EXIST Obj CD Obj 3 | SET PATH=..\..\..\Target\Win32;%PATH% 4 | SET OBERON=.;..\Mod 5 | IF EXIST *.sym DEL *.sym >NUL 6 | 7 | ofront+ -s7 -48 ^ 8 | Math.Def Out.Def Strings.Def extConvert.Def Tests.Mod ^ 9 | Chars.Mod DStrings.Mod Obn2.Mod Path.Mod PathLists.Mod ^ 10 | CharsTest.Mod DStringsTest.Mod Obn2Test.Mod PathTest.Mod PathListsTest.Mod 11 | IF errorlevel 1 PAUSE 12 | 13 | FOR %%i IN (*.sym) DO MOVE /Y %%i ..\Sym >NUL 14 | CD .. 15 | -------------------------------------------------------------------------------- /install.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | Installation 12 |
13 |
14 |

15 | Installation 16 |

17 |

18 | Installing a released version 19 |

20 |
    21 |
  1. 22 | Change into that directory you want to place Artemis 23 |
  2. 24 |
  3. 25 | Unzip the release Zip file 26 |
  4. 27 |
  5. 28 | Make sure the “Artemis” “bin” sub-directory is in your PATH 29 |
  6. 30 |
31 |

32 | Example 33 |

34 |
    mkdir -p $HOME/tools
 35 |     cd $HOME/tools
 36 |     unzip $HOME/Download/Artemis-0.0.1-Linux-x86_64.zip
 37 |     export PATH="$HOME/tools/Artimis/bin:$PATH"
38 |

39 | From source 40 |

41 |

42 | Compiling from source requires OBNC, Git, GNU Make, a C compiler and linker. 43 |

44 |
    45 |
  1. 46 | Clone the Git repository for the project 47 |
  2. 48 |
  3. 49 | Change into the repository directory 50 |
  4. 51 |
  5. 52 | Run make, make test, and sudo make install 53 |
  6. 54 |
55 |

56 | Example install: 57 |

58 |
    git clone git@github.com:rsdoiel/Artemis
 59 |     cd Artemis
 60 |     make
 61 |     make full_test
 62 |     sudo make install
63 |

64 | Example uninstall 65 |

66 |
    cd Artemis
 67 |     sudo make uninstall
68 |

69 | The Makefile supports an installation prefix. If you install with a prefix you need to uninstall with the same prefix. E.g. 70 |

71 |
    sudo make install prefix=/opt/local
 72 |     sudo make uninstall prefix=/opt/local
73 |
74 | 105 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /license.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | … 12 |
13 |
14 |

15 | BSD 3-Clause License 16 |

17 |

18 | Copyright (c) 2021, R. S. Doiel All rights reserved. 19 |

20 |

21 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 22 |

23 |
    24 |
  1. 25 |

    26 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 27 |

    28 |
  2. 29 |
  3. 30 |

    31 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 32 |

    33 |
  4. 34 |
  5. 35 |

    36 | Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 37 |

    38 |
  6. 39 |
40 |

41 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 |

43 |
44 | 75 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /make.bat: -------------------------------------------------------------------------------- 1 | @REM make.bat is a simple DOS batch file for building Artemis project under Windows 11. 2 | 3 | @echo Removing stale executables. 4 | @del *.exe 5 | 6 | @echo Compiling CharsTest.Mod 7 | call obnc CharsTest.Mod 8 | @echo Compiling DStringsTest.Mod 9 | call obnc DStringsTest.Mod 10 | @echo Compiling JSONTest.Mod 11 | call obnc JSONTest.Mod 12 | @echo Compiling Obn2Test.Mod 13 | call obnc Obn2Test.Mod 14 | @echo Compiling PathListsTest.Mod 15 | call obnc PathListsTest.Mod 16 | @echo Compiling PathTest.Mod 17 | call obnc PathTest.Mod 18 | @echo Compiling ScannerTest.Mod 19 | call obnc ScannerTest.Mod 20 | 21 | @echo Running each test. 22 | CharsTest.exe 23 | DStringsTest.exe 24 | JSONTest.exe 25 | Obn2Test.exe 26 | PathListsTest.exe 27 | PathTest.exe 28 | ScannerTest.exe 29 | -------------------------------------------------------------------------------- /nav.md: -------------------------------------------------------------------------------- 1 | 2 | + [Home](/) 3 | + [README](./) 4 | + [LICENSE](license.html) 5 | + [INSTALL](install.html) 6 | + [OBNC Modules](./obnc/) 7 | + [Obc-3 Modules](./oxford/) 8 | + [Ofront+ Modules](./ofrontplus/) 9 | + [development notes](./development-notes.html) 10 | + [Github](https://github.com/rsdoiel/Artemis) 11 | 12 | -------------------------------------------------------------------------------- /note-system.bit-oberon-list.txt: -------------------------------------------------------------------------------- 1 | 2021-06-04, RSD 2 | 3 | Hello everyone, 4 | 5 | This is probably a bit of a novice question and I apologize but 6 | it has me puzzled. In the Oberon-7 language report's 7 | SYSTEM.BIT() is described as using "n" to address a specific bit. 8 | On first reading I assumed "n" zero would be the LSB and "n" 9 | thirty one would be MSB where the compiler deals with the local 10 | implementation of bit ordering. Is that the correct reading 11 | of the report? 12 | 13 | I was planning on implementing a procedure like Native Oberon's 14 | Reals.IntL() but then started having doubts about my reading of the 15 | Oberon-7 report. Have I made too simple a set of assumptions about 16 | how I should expect SYSTEM.BIT() to work under Oberon-7 17 | implementations? 18 | 19 | All the best, 20 | 21 | Robert Doiel 22 | 23 | 24 | -------------------------------------------------------------------------------- /obnc/C/Clock.GetRtcTime.inc: -------------------------------------------------------------------------------- 1 | static void GetRtcTime_(OBNC_INTEGER *second_, OBNC_INTEGER *minute_, OBNC_INTEGER *hour_, OBNC_INTEGER *day_, OBNC_INTEGER *month_, OBNC_INTEGER *year_, OBNC_INTEGER *wDay_, OBNC_INTEGER *yDay_, OBNC_INTEGER *isDST_, OBNC_INTEGER *utcOffset_, OBNC_INTEGER *seconds_, OBNC_INTEGER *nanoSeconds_, int *ok_) 2 | { 3 | struct timespec now; 4 | struct tm *dt; 5 | 6 | *ok_ = 1; /* Assume clock_gettime() successful */ 7 | if (clock_gettime(CLOCK_REALTIME, &now) == -1) { 8 | *ok_ = 0; /* clock_gettime() failed for some reason */ 9 | perror("clock_gettime(CLOCK_REALTIME, &now) failed"); 10 | } else { 11 | *seconds_ = now.tv_sec; 12 | *nanoSeconds_ = now.tv_nsec; 13 | dt = localtime(&now.tv_sec); 14 | *second_ = dt->tm_sec; 15 | *minute_ = dt->tm_min; 16 | *hour_ = dt->tm_hour; 17 | *day_ = dt->tm_mday; 18 | *month_ = dt->tm_mon + 1; /* We want 1 to 12 rather than 0 to 11 */ 19 | *year_ = dt->tm_year + 1900; /* Normalize to current year */ 20 | *wDay_ = dt->tm_wday; 21 | *yDay_ = dt->tm_yday; 22 | *isDST_ = dt->tm_isdst; 23 | *utcOffset_ = dt->tm_gmtoff; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /obnc/C/Clock.SetRtcTime.inc: -------------------------------------------------------------------------------- 1 | static void SetRtcTime_(OBNC_INTEGER second_, OBNC_INTEGER minute_, OBNC_INTEGER hour_, OBNC_INTEGER day_, OBNC_INTEGER month_, OBNC_INTEGER year_, OBNC_INTEGER wDay_, OBNC_INTEGER yDay_, OBNC_INTEGER isDST_, OBNC_INTEGER utcOffset_, int *ok_) 2 | { 3 | struct timespec nt; 4 | struct tm dt; 5 | 6 | dt.tm_sec = second_; 7 | dt.tm_min = minute_; 8 | dt.tm_hour = hour_; 9 | dt.tm_mday = day_; 10 | dt.tm_mon = (month_ - 1); /* de-normalize to 0 to 11 from 1 to 12 */ 11 | dt.tm_year = (year_ - 1900); /* adjust year to reflect POSIX value */ 12 | dt.tm_wday = wDay_; 13 | dt.tm_yday = yDay_; 14 | /* NOTE: tm_idst and tm_gmtoff are not ISO C or POSIX, they come from 15 | BSD and GNU systems. They appear to be available on macOS */ 16 | dt.tm_isdst = isDST_; 17 | dt.tm_gmtoff = utcOffset_; 18 | /* NOTE: You must have root permissions for clock_settime() to work */ 19 | nt.tv_sec = mktime(&dt); 20 | if (clock_settime(CLOCK_REALTIME, &nt) == -1) { 21 | perror("clock_gettime(CLOCK_REALTIME, &nt) failed"); 22 | *ok_ = 0; 23 | } else { 24 | *ok_ = 1; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /obnc/C/Unix.Exit.inc: -------------------------------------------------------------------------------- 1 | void Unix__Exit_(OBNC_INTEGER exitCode_) 2 | { 3 | exit(exitCode_); 4 | } 5 | 6 | -------------------------------------------------------------------------------- /obnc/C/Unix.includes.inc: -------------------------------------------------------------------------------- 1 | #include ".obnc/Unix.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | -------------------------------------------------------------------------------- /obnc/C/Unix.uname.inc: -------------------------------------------------------------------------------- 1 | 2 | static void uname_(char opt_, char dest_[], OBNC_INTEGER dest_len) 3 | { 4 | FILE *in; 5 | char ch; 6 | int i; 7 | char cmd[9]; 8 | 9 | /* Setup our POSIX command */ 10 | cmd[0] = 'u'; cmd[1] = 'n'; cmd[2] = 'a'; 11 | cmd[3] = 'm'; cmd[4] = 'e'; cmd[5] = ' '; 12 | cmd[6] = '-'; cmd[7] = opt_; 13 | cmd[8] = '\x00'; 14 | /* open a process and read stdout from a uname call */ 15 | in = popen(cmd, "r"); 16 | if (!in) return; 17 | /* for each character output by uname copy into our dest string */ 18 | i = 0; dest_[i] = '\x00'; 19 | while ( ((ch = fgetc(in)) != EOF) && (i < (dest_len - 1) ) ) { 20 | if ((ch == '\n') || (ch == '\r')) { 21 | dest_[i] = '\x00'; 22 | break; 23 | } else { 24 | dest_[i] = ch; 25 | } 26 | i = i + 1; 27 | dest_[i] = '\x00'; /* add a trailing NULL CHAR */ 28 | } 29 | /* close our pipe and done */ 30 | pclose(in); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /obnc/C/time_example_1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | NOTES: 6 | 7 | Nano to Milli second 1 milli seconds equals 1000000 nano seconds 8 | 9 | */ 10 | 11 | /* In ofront SetClock was skipped due to portability issues. I am 12 | * revisiting that in light of how C evolved. 13 | * 14 | * SetClock takes normalized year and month, i.e. If year 15 | * the year and month at 2021, January the values you pass 16 | * to SetClock for year and month should be 2021 and 1. 17 | **/ 18 | void SetClock(int second, int minute, int hour, int day, int month, int year, int is_dst, int utc_offset) { 19 | struct timespec nt; 20 | struct tm tinfo; 21 | /* time_t now; 22 | now = time(NULL); 23 | tinfo = localtime(&now); */ 24 | 25 | tinfo.tm_year = year - 1900; 26 | tinfo.tm_mon = month - 1; 27 | tinfo.tm_mday = day; 28 | tinfo.tm_hour = hour; 29 | tinfo.tm_min = minute; 30 | tinfo.tm_sec = second; 31 | tinfo.tm_isdst = is_dst; 32 | tinfo.tm_gmtoff = utc_offset; 33 | /* What goes here? stime is not avialable on macOS */ 34 | nt.tv_sec = mktime(&tinfo); 35 | if (clock_settime(CLOCK_REALTIME, &nt) == -1) { 36 | perror("clock_settime(CLOCK_REALTIME, &nt) failed"); 37 | } 38 | } 39 | 40 | /* modern way of getting time */ 41 | int GetClock() { 42 | int seconds; 43 | struct timespec now; 44 | 45 | seconds = 0; 46 | if (clock_gettime(CLOCK_REALTIME, &now) == -1) { 47 | perror("clock_gettime(CLOCK_REALTIME, now) failed"); 48 | } else { 49 | /* now now.tv_sec can be combined with localtime() to 50 | * have a useful conversion of units from EPoch */ 51 | seconds = now.tv_sec; 52 | } 53 | return seconds; 54 | } 55 | 56 | /* Let's test out the different approaches */ 57 | int main(int argc, char *argv[]) { 58 | int seconds; 59 | struct tm *nt; 60 | struct timespec saved_time; 61 | time_t now; 62 | 63 | seconds = GetClock(); 64 | printf("Get clock, in seconds %d\n", seconds); 65 | if (clock_gettime(CLOCK_REALTIME, &saved_time) != -1) { 66 | nt = localtime(&saved_time.tv_sec); 67 | /* Normalize year as SetClock expects */ 68 | nt->tm_year = nt->tm_year + 1900; 69 | /* Normalize month as SetClock expects */ 70 | nt->tm_mon = nt->tm_mon + 1; 71 | SetClock(nt->tm_sec, nt->tm_min, nt->tm_hour, nt->tm_mday, nt->tm_mon, nt->tm_year + 1, nt->tm_isdst, nt->tm_gmtoff); 72 | now = time(NULL); 73 | nt = localtime(&now); 74 | printf("%04d-%02d-%02d %02d:%02d:%02d\n", nt->tm_year + 1900, nt->tm_mon + 1, nt->tm_mday, nt->tm_hour, nt->tm_min, nt->tm_sec); 75 | if (clock_settime(CLOCK_REALTIME, &saved_time) == -1) { 76 | perror("Could not reset clock after test"); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /obnc/ClockTest.obn: -------------------------------------------------------------------------------- 1 | (** ClockTest.Mod - Tests for Clock.Mod. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE ClockTest; 10 | 11 | IMPORT T := Tests, Env := extEnv, Clock := artClock, Out, Strings; 12 | 13 | VAR ts : T.TestSet; 14 | 15 | PROCEDURE DisplayClock(ct : Clock.Clock); 16 | VAR i, hours, minutes : INTEGER; 17 | BEGIN 18 | Out.Int(ct.year, 4); 19 | Out.String("-"); 20 | IF ct.month < 10 THEN 21 | Out.String("0"); Out.Int(ct.month, 1); 22 | ELSE 23 | Out.Int(ct.month, 2); 24 | END; 25 | Out.String("-"); 26 | IF ct.day < 10 THEN 27 | Out.String("0"); Out.Int(ct.month, 1); 28 | ELSE 29 | Out.Int(ct.day, 2); 30 | END; 31 | Out.String(" "); 32 | IF ct.hour < 10 THEN 33 | Out.String("0"); Out.Int(ct.hour, 1); 34 | ELSE 35 | Out.Int(ct.hour, 2); 36 | END; 37 | Out.String(":"); 38 | IF ct.minute < 10 THEN 39 | Out.String("0"); Out.Int(ct.minute, 1); 40 | ELSE 41 | Out.Int(ct.minute, 2); 42 | END; 43 | Out.String(":"); 44 | IF ct.second < 10 THEN 45 | Out.String("0"); Out.Int(ct.second, 1); 46 | ELSE 47 | Out.Int(ct.second, 2); 48 | END; 49 | IF ct.isDST < 0 THEN 50 | Out.String(" "); (* DST info not available *) 51 | ELSIF ct.isDST = 0 THEN 52 | Out.String(" (ST)"); 53 | ELSIF ct.isDST = 1 THEN 54 | Out.String(" (DST)"); 55 | END; 56 | i := ABS(ct.utcOffset); 57 | IF (i >= 0) & (i <= 86400) THEN 58 | hours := (i DIV 3600) MOD 60; 59 | minutes := (i MOD 3600); 60 | Out.String(" UTC"); 61 | IF (ct.utcOffset >= 0) THEN 62 | Out.String("+"); 63 | IF hours < 10 THEN 64 | Out.String("0"); 65 | END; 66 | Out.Int(hours, 1); 67 | ELSE 68 | Out.String("-"); 69 | IF (ABS(hours) < 10) THEN 70 | Out.String("0"); 71 | END; 72 | Out.Int(ABS(hours), 1); 73 | END; 74 | IF minutes < 10 THEN 75 | Out.String("0"); Out.Int(minutes, 1); 76 | ELSE 77 | Out.Int(minutes, 2); 78 | END; 79 | END; 80 | Out.Ln(); 81 | END DisplayClock; 82 | 83 | PROCEDURE TestClockAndTime*() : BOOLEAN; 84 | VAR test : BOOLEAN; t1 : Clock.Clock; 85 | BEGIN test := TRUE; 86 | NEW(t1); 87 | Clock.Get(t1); 88 | T.ExpectedBool(TRUE, (t1.year > 2020), "Expected t1.year > 2020", test); 89 | T.ExpectedBool(TRUE, ((t1.month >= 1) & (t1.month <= 12)), "Expected (t1.month >= 1) & (t1.mongth <= 12)", test); 90 | T.ExpectedBool(TRUE, (t1.day > 0), "Expected t1.day > 0", test); 91 | T.ExpectedBool(TRUE, (t1.hour > -1), "Expected t1.hour > 0", test); 92 | T.ExpectedBool(TRUE, (t1.minute > -1), "Expected t1.minute > 0", test); 93 | T.ExpectedBool(TRUE, (t1.second > -1), "Expected t1.second > 0", test); 94 | 95 | RETURN test 96 | END TestClockAndTime; 97 | 98 | PROCEDURE TestClockSet*() : BOOLEAN; 99 | VAR test : BOOLEAN; ct, tt, sc : Clock.Clock; ok : BOOLEAN; 100 | uname, os : ARRAY 256 OF CHAR; res : INTEGER; 101 | BEGIN test := TRUE; 102 | Env.Get("OS", os, res); 103 | Env.Get("SUDO_USER", uname, res); 104 | IF os = "Linux" THEN 105 | Out.String("Skipping TestClockSet(), Clock.Set() is not permitted under Linux"); Out.Ln(); 106 | ELSIF (Strings.Length(uname) = 0) & (os = "Darwin") THEN 107 | Out.String(" Skipping TestSet(), Clock.Set() requires admin privilleges for Darwin (macOS)");Out.Ln(); 108 | Out.String(" You can try rerunning tests with");Out.Ln(); 109 | Out.Ln(); Out.String(" sudo make test");Out.Ln();Out.Ln(); 110 | ELSE 111 | NEW(ct); NEW(tt); NEW(sc); 112 | Clock.Get(ct); 113 | Out.String(" Current clock: ");DisplayClock(ct); 114 | tt.year := ct.year + 1; 115 | tt.month := ct.month + 1; 116 | IF tt.month > 12 THEN 117 | INC(tt.year); 118 | ct.month := 1; 119 | END; 120 | tt.day := ct.day; 121 | tt.hour := ct.hour; 122 | tt.minute := ct.minute; 123 | tt.second := ct.second; 124 | tt.isDST := ct.isDST; 125 | tt.utcOffset := ct.utcOffset; 126 | Clock.Get(sc); (* Save the time to reset later *) 127 | Clock.Set(tt, ok); 128 | T.ExpectedBool(TRUE, ok, "Clock.Set(tt, ok) failed", test); 129 | IF ok THEN 130 | Out.String(" New clock: ");DisplayClock(tt); 131 | 132 | T.ExpectedBool(TRUE, ok, "Clock.Set(tt, ok) ", test); 133 | 134 | T.ExpectedBool(TRUE, (Clock.clock.year = tt.year), "new time year", test); 135 | T.ExpectedBool(TRUE, (Clock.clock.month = tt.month), "new time month", test); 136 | T.ExpectedBool(TRUE, (Clock.clock.day = tt.day), "new time day", test); 137 | T.ExpectedBool(TRUE, (Clock.clock.hour = tt.hour), "new time hour", test); 138 | T.ExpectedBool(TRUE, (Clock.clock.minute = tt.minute), "new time minute", test); 139 | T.ExpectedBool(TRUE, (Clock.clock.second = tt.second), "new time second", test); 140 | (* Reset the clock *) 141 | Clock.Set(sc, ok); 142 | Clock.Get(ct); 143 | Out.String(" Reset clock: "); DisplayClock(ct); 144 | END; 145 | END; 146 | 147 | RETURN test 148 | END TestClockSet; 149 | 150 | BEGIN 151 | T.Init(ts, "Test Clock"); 152 | T.Add(ts, TestClockAndTime); 153 | T.Add(ts, TestClockSet); 154 | ASSERT(T.Run(ts)); 155 | END ClockTest. 156 | 157 | 158 | -------------------------------------------------------------------------------- /obnc/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Simple Makefile for compiling Oberon-7 programs using OBNC. 3 | # Set the list of executables in PROG_NAMES. The rest can probably 4 | # stay as is if all modules are in the same directory. 5 | # 6 | VERSION = $(shell if [ -f VERSION ]; then cat VERSION; else echo "0.0.0"; fi) 7 | BUILD_NAME = Artemis-Modules-NP 8 | PROG_NAMES = 9 | TEST_NAMES = ClockTest UnixTest 10 | MODULES = $(shell ls *.obn) 11 | DOCS= README.md ../LICENSE ../INSTALL.txt 12 | 13 | # Defaults 14 | #OC = obnc 15 | OC = env OBNC_IMPORT_PATH=".:../" obnc 16 | OS = $(shell uname) 17 | ARCH = $(shell uname -m) 18 | PREFIX = /usr/local 19 | LIBDIR = $(PREFIX)/lib 20 | BINDIR = $(PREFIX)/bin 21 | 22 | # Overrides 23 | oc = 24 | ifneq ($(oc), ) 25 | OC = $(oc) 26 | endif 27 | 28 | os = 29 | ifneq ($(os), ) 30 | OS = $(os) 31 | endif 32 | 33 | arch = 34 | ifneq ($(arch), ) 35 | ARCH = $(arch) 36 | endif 37 | 38 | prefix = 39 | ifneq ($(prefix), ) 40 | PREFIX = $(prefix) 41 | LIBDIR = $(prefix)/lib 42 | BINDIR = $(prefix)/bin 43 | endif 44 | 45 | libdir = 46 | ifneq ($(libdir), ) 47 | LIBDIR = $(libdir) 48 | endif 49 | 50 | bindir = 51 | ifneq ($(bindir), ) 52 | BINDIR = $(bindir) 53 | endif 54 | 55 | all: $(PROG_NAMES) 56 | 57 | $(PROG_NAMES): $(MODULES) 58 | $(OC) -o $@ $@.obn 59 | 60 | $(TEST_NAMES): $(MODULE) 61 | $(OC) -o $@ $@.obn 62 | 63 | full_test: .FORCE clean test 64 | 65 | test: $(TEST_NAMES) 66 | @for FNAME in $(TEST_NAMES); do env OS=$(OS) ARCH=$(ARCH) ./$$FNAME; done 67 | 68 | docs: .FORCE 69 | obncdoc 70 | 71 | clean: .FORCE 72 | @if [ -d dist ]; then rm -fR dist; fi 73 | @if [ -d .obnc ]; then rm -fR .obnc; fi 74 | @if [ -d ../ports/po2013/.obnc ]; then rm -fR ../ports/po2013/.obnc; fi 75 | @for FNAME in $(PROG_NAMES); do if [ -f $$FNAME ]; then rm $$FNAME; fi; done 76 | @for FNAME in $(TEST_NAMES); do if [ -f $$FNAME ]; then rm $$FNAME; fi; done 77 | 78 | install: $(PROG_NAMES) 79 | @if [ ! -d $(BINDIR) ]; then mkdir -p $(BINDIR); fi 80 | @for FNAME in $(PROG_NAMES); do cp $$FNAME $(BINDIR)/; done 81 | 82 | uninstall: .FORCE 83 | @for FNAME in $(PROG_NAMES); do if [ -f "$(BINDIR)/$$FNAME" ]; then rm "$(BINDIR)/$$FNAME"; fi; done 84 | 85 | dist: $(PROG_NAMES) 86 | @if [ ! -d dist/$(BUILD_NAME) ]; then mkdir -p dist/$(BUILD_NAME); fi 87 | @if [ ! -d dist/$(BUILD_NAME)/bin ]; then mkdir -p dist/$(BUILD_NAME)/bin; fi 88 | @for FNAME in $(PROG_NAMES); do cp -p $$FNAME dist/$(BUILD_NAME)/bin/; done 89 | @for FNAME in $(MODULES) $(DOCS) Makefile; do cp -p $$FNAME dist/$(BUILD_NAME)/;done 90 | @cd dist && zip -r $(BUILD_NAME)-$(OS)-$(ARCH).zip $(BUILD_NAME)/* 91 | 92 | .FORCE: 93 | -------------------------------------------------------------------------------- /obnc/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: OBNC modules 3 | --- 4 | 5 | OBNC - Not portable 6 | =================== 7 | 8 | This directory contains non-portable Oberon-7 modules intended 9 | for the POSIX environment and compiled with the 10 | [OBNC](http://miasap.se/obnc/) compiler. 11 | 12 | - [artUnix.obn](artUnix.obn), [artUnix.c](artUnix.c), [UnixTest.obn](UnixTest.obn) 13 | - [artClock.obn](artClock.obn), [artClock.c](artClock.c), [ClockTest.obn](ClockTest.obn) 14 | 15 | 16 | -------------------------------------------------------------------------------- /obnc/UnixTest.obn: -------------------------------------------------------------------------------- 1 | (** UnixTest provided module tests for Unix module. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE UnixTest; 10 | 11 | IMPORT T := Tests, Unix := artUnix, Out, Env := extEnv; 12 | 13 | VAR 14 | ts : T.TestSet; 15 | successes, errors : INTEGER; 16 | 17 | PROCEDURE TestKernelName() : BOOLEAN; 18 | VAR test: BOOLEAN; expected, got : ARRAY 256 OF CHAR; res : INTEGER; 19 | BEGIN test := TRUE; 20 | Env.Get("OS", expected, res); 21 | IF expected[0] = 0X THEN 22 | Out.String("Skipping TestKernelName(), missing environment"); Out.Ln(); 23 | Out.String("variable OS (aka kernel name) needed to verify Unix.Kernel()"); Out.Ln(); 24 | ELSE 25 | Unix.KernelName(got); 26 | T.ExpectedString(expected, got, "Unix.KernelName(s) should match env. OS", test); 27 | END; 28 | RETURN test 29 | END TestKernelName; 30 | 31 | PROCEDURE TestArchitectureName() : BOOLEAN; 32 | VAR test: BOOLEAN; expected, got : ARRAY 24 OF CHAR; res : INTEGER; 33 | BEGIN test := TRUE; 34 | Env.Get("ARCH", expected, res); 35 | IF expected[0] = 0X THEN 36 | Out.String("Skipping TestArchitectureName(), missing environment"); Out.Ln(); 37 | Out.String("variable ARCH needed to verify Unix.Architecture()"); Out.Ln(); 38 | ELSE 39 | Unix.Architecture(got); 40 | T.ExpectedString(expected, got, "Unix.Architecture(s) should match env. OS", test); 41 | END; 42 | RETURN test 43 | END TestArchitectureName; 44 | 45 | PROCEDURE TestExit() : BOOLEAN; 46 | BEGIN 47 | Unix.Exit(0); 48 | RETURN FALSE 49 | END TestExit; 50 | 51 | BEGIN 52 | T.Init(ts, "Test Unix"); 53 | T.Add(ts, TestKernelName); 54 | T.Add(ts, TestArchitectureName); 55 | ASSERT(T.Run(ts)); 56 | (* Testing Unix.Exit(1) is tricky *) 57 | successes := 0; errors := 0; 58 | IF ~ TestExit() THEN 59 | Out.String("Test of Unix.Exit(), failed"); Out.Ln(); 60 | ASSERT(FALSE); 61 | END; 62 | END UnixTest. 63 | -------------------------------------------------------------------------------- /obnc/artUnix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Unix.c provided an interface to C level libraries needed by Unix.Mod. 3 | * 4 | * Copyright (C) 2021 R. S. Doiel 5 | * 6 | * Released under The 3-Clause BSD License. 7 | * See https://opensource.org/licenses/BSD-3-Clause 8 | * 9 | */ 10 | 11 | #include ".obnc/artUnix.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define OBERON_SOURCE_FILENAME "artUnix.obn" 18 | 19 | static char kernel_[24], architecture_[24]; 20 | 21 | static void uname_(char opt_, char dest_[], OBNC_INTEGER dest_len) 22 | { 23 | FILE *in; 24 | char ch; 25 | int i; 26 | char cmd[9]; 27 | 28 | /* Setup our POSIX command */ 29 | cmd[0] = 'u'; cmd[1] = 'n'; cmd[2] = 'a'; 30 | cmd[3] = 'm'; cmd[4] = 'e'; cmd[5] = ' '; 31 | cmd[6] = '-'; cmd[7] = opt_; 32 | cmd[8] = '\x00'; 33 | /* open a process and read stdout from a uname call */ 34 | in = popen(cmd, "r"); 35 | if (!in) return; 36 | /* for each character output by uname copy into our dest string */ 37 | i = 0; dest_[i] = '\x00'; 38 | while ( ((ch = fgetc(in)) != EOF) && (i < (dest_len - 1) ) ) { 39 | if ((ch == '\n') || (ch == '\r')) { 40 | dest_[i] = '\x00'; 41 | break; 42 | } else { 43 | dest_[i] = ch; 44 | } 45 | i = i + 1; 46 | dest_[i] = '\x00'; /* add a trailing NULL CHAR */ 47 | } 48 | /* close our pipe and done */ 49 | pclose(in); 50 | } 51 | 52 | 53 | void artUnix__Exit_(OBNC_INTEGER exitCode_) 54 | { 55 | exit(exitCode_); 56 | } 57 | 58 | 59 | static OBNC_INTEGER minimum_(OBNC_INTEGER a_, OBNC_INTEGER b_) 60 | { 61 | OBNC_INTEGER res_; 62 | 63 | if (a_ < b_) { 64 | res_ = a_; 65 | } 66 | else { 67 | res_ = b_; 68 | } 69 | return res_; 70 | } 71 | 72 | 73 | static void copyChars_(const char source_[], OBNC_INTEGER source_len, char dest_[], OBNC_INTEGER dest_len) 74 | { 75 | OBNC_INTEGER i_, l_; 76 | 77 | l_ = minimum_(source_len, dest_len) - 2; 78 | if (l_ < 1) { 79 | l_ = 0; 80 | } 81 | i_ = 0; 82 | dest_[OBNC_IT(i_, dest_len, 49)] = '\x00'; 83 | while ((i_ < l_) && (source_[OBNC_IT(i_, source_len, 50)] != '\x00')) { 84 | dest_[OBNC_IT(i_, dest_len, 51)] = source_[OBNC_IT(i_, source_len, 51)]; 85 | OBNC_INC(i_); 86 | } 87 | dest_[OBNC_IT(i_, dest_len, 54)] = '\x00'; 88 | OBNC_DEC(i_); 89 | if ((dest_[OBNC_IT(i_, dest_len, 55)] == '\x10') || (dest_[OBNC_IT(i_, dest_len, 55)] == '\x13')) { 90 | dest_[OBNC_IT(i_, dest_len, 56)] = '\x00'; 91 | } 92 | } 93 | 94 | 95 | void artUnix__KernelName_(char dest_[], OBNC_INTEGER dest_len) 96 | { 97 | 98 | if (kernel_[0] == '\x00') { 99 | uname_('s', kernel_, 24); 100 | } 101 | copyChars_(kernel_, 24, dest_, dest_len); 102 | } 103 | 104 | 105 | void artUnix__Architecture_(char dest_[], OBNC_INTEGER dest_len) 106 | { 107 | 108 | if (architecture_[0] == '\x00') { 109 | uname_('m', architecture_, 24); 110 | } 111 | copyChars_(architecture_, 24, dest_, dest_len); 112 | } 113 | 114 | 115 | void artUnix__Init(void) 116 | { 117 | static int initialized = 0; 118 | 119 | if (! initialized) { 120 | kernel_[0] = '\x00'; 121 | architecture_[0] = '\x00'; 122 | initialized = 1; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /obnc/artUnix.obn: -------------------------------------------------------------------------------- 1 | (** Unix provides asscess to some POSIX C based libraries and services. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE artUnix; 10 | 11 | VAR 12 | kernel, architecture : ARRAY 24 OF CHAR; 13 | 14 | 15 | (* 16 | * C implemented procedures 17 | * ------------------------ 18 | *) 19 | 20 | (* uname does a popen call to `uname` *) 21 | PROCEDURE uname(opt : CHAR; VAR dest : ARRAY OF CHAR); 22 | BEGIN 23 | END uname; 24 | 25 | (** Exit performs a system exit with error number *) 26 | PROCEDURE Exit*(exitCode : INTEGER); 27 | BEGIN 28 | END Exit; 29 | 30 | (* 31 | * Oberon-7 implemented procedures 32 | * ------------------------------- 33 | *) 34 | 35 | (* mininum returns the lesser of two integer *) 36 | PROCEDURE minimum(a, b : INTEGER) : INTEGER; 37 | VAR res : INTEGER; 38 | BEGIN 39 | IF a < b THEN res := a; ELSE res := b; END; 40 | RETURN res 41 | END minimum; 42 | 43 | (* copy an array of chars, truncate dest if needed *) 44 | PROCEDURE copyChars(source : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR); 45 | VAR i, l : INTEGER; 46 | BEGIN 47 | l := minimum(LEN(source), LEN(dest)) - 2; (* leave room of 0X *) 48 | IF l < 1 THEN l := 0 END; 49 | i := 0; dest[i] := 0X; 50 | WHILE (i < l) & (source[i] # 0X) DO 51 | dest[i] := source[i]; 52 | INC(i); 53 | END; 54 | dest[i] := 0X; DEC(i); 55 | IF (dest[i] = 10X) OR (dest[i] = 13X) THEN 56 | dest[i] := 0X; 57 | END; 58 | END copyChars; 59 | 60 | 61 | (** KernelName attempts a system exec call to `uname -s` to determine the 62 | Kernel name, e.g. Linux, Darwin, Windows *) 63 | PROCEDURE KernelName*(VAR dest : ARRAY OF CHAR); 64 | BEGIN 65 | IF kernel[0] = 0X THEN 66 | uname("s", kernel); 67 | END; 68 | copyChars(kernel, dest); 69 | END KernelName; 70 | 71 | (** Architecture attempts a system exec call to `uname -m` to determine 72 | the machine archtecture, e.g. i386, x86_64 *) 73 | PROCEDURE Architecture*(VAR dest : ARRAY OF CHAR); 74 | BEGIN 75 | IF architecture[0] = 0X THEN 76 | uname("m", architecture); 77 | END; 78 | copyChars(architecture, dest); 79 | END Architecture; 80 | 81 | 82 | BEGIN kernel[0] := 0X; architecture[0] := 0X; 83 | END artUnix. 84 | -------------------------------------------------------------------------------- /obnc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | OBNC modules 12 |
13 |
14 |

15 | OBNC - Not portable 16 |

17 |

18 | This directory contains non-portable Oberon-7 modules intended for the POSIX environment and compiled with the OBNC compiler. 19 |

20 | 28 |
29 | 60 |
61 | copyright (c) 2021 all rights reserved. 62 | Released under the BSD 3-Clause license 63 | See: http://opensource.org/licenses/BSD-3-Clause 64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /obnc/nav.md: -------------------------------------------------------------------------------- 1 | 2 | + [Home](/) 3 | + [README](../) 4 | + [LICENSE](../license.html) 5 | + [INSTALL](../install.html) 6 | + [OBNC Modules](./) 7 | + [Obc-3 Modules](../oxford/) 8 | + [Ofront+ Modules](../ofrontplus/) 9 | + [development notes](../development-notes.html) 10 | + [Github](https://github.com/rsdoiel/Artemis) 11 | 12 | -------------------------------------------------------------------------------- /obnc/ocat.obn: -------------------------------------------------------------------------------- 1 | (** ocat.Mod is inspired by ocat command found in Joseph Templ's in Ofront. 2 | 3 | Copyright (C) 2021 R. S. Doiel This Source Code Form is subject to the terms of the Mozilla PublicLicense, v. 2.0. If a copy of the MPL was not distributed with thisfile, You can obtain one at http://mozilla.org/MPL/2.0/. *) 4 | MODULE ocat; 5 | 6 | (** NOTE: OCat is a POSIX command line program. *) 7 | 8 | IMPORT Args := extArgs, Out, Files, Texts := artTextsCmdLn, Chars, Convert := extConvert, Err := extErr; 9 | 10 | CONST 11 | TAB = 9X; 12 | LF = 10X; 13 | CR = 13X; 14 | SPACE = 20X; 15 | TILDE = "~"; 16 | 17 | VAR 18 | tabs : ARRAY 128 OF CHAR; 19 | 20 | (* Usage displays a help screen *) 21 | PROCEDURE Usage(); 22 | BEGIN 23 | Out.String("USAGE OCat [OPTION] FILENAME [[OPTION] FILENAME ...]"); Out.Ln(); 24 | Out.Ln(); 25 | Out.String("Read Oberon Texts and write them to standard out");Out.Ln(); 26 | Out.Ln(); 27 | Out.String("OPTIONS"); Out.Ln(); 28 | Out.Ln(); 29 | Out.String(" -h, --help"); Out.Char(Chars.TAB); Out.String("this help document"); Out.Ln();Out.Ln(); 30 | Out.String(" -t, --tabs"); Out.Char(Chars.TAB); Out.String("Allow tab characters"); Out.Ln(); 31 | Out.String(" --spaces"); Out.Char(Chars.TAB); Out.String("Convert tab characters to four spaces"); Out.Ln(); 32 | Out.String(" --spaces=X"); Out.Char(Chars.TAB); Out.String("Convert tab characters to X number of spaces"); Out.Ln(); 33 | Out.Ln(); 34 | END Usage; 35 | 36 | (* Convert Oberon texts to POSIX friendly standard out *) 37 | PROCEDURE Cat(filename : ARRAY OF CHAR); 38 | VAR T : Texts.Text; R : Texts.Reader; ch : CHAR; skipLF : BOOLEAN; 39 | BEGIN 40 | IF Files.Old(filename) # NIL THEN 41 | Texts.Open(T, filename); 42 | Texts.OpenReader(R, T, 0); 43 | (* FIXME: Need to handle case where this is an Oberon file 44 | and skip beyond the font settings to start of Text *) 45 | Texts.Read(R, ch); 46 | WHILE ~ R.eot DO 47 | IF (ch >= SPACE) & (ch <= TILDE) THEN 48 | Out.Char(ch); 49 | skipLF := FALSE; 50 | ELSIF ch = TAB THEN 51 | Out.String(tabs); 52 | skipLF := FALSE; 53 | ELSIF ch = LF THEN 54 | IF skipLF = TRUE THEN 55 | skipLF := FALSE; 56 | ELSE 57 | Out.Ln(); 58 | END; 59 | ELSIF ch = CR THEN 60 | Out.Ln(); 61 | skipLF := TRUE; 62 | END; 63 | Texts.Read(R, ch); 64 | END; 65 | Out.Ln(); 66 | ELSE 67 | Err.String("Can't open ");Err.String(filename);Err.Ln(); 68 | END; 69 | END Cat; 70 | 71 | (* Apply process POSIX command line parameters and envoke Cat.*) 72 | PROCEDURE Apply(); 73 | VAR i, j, k, res : INTEGER; arg : ARRAY 1024 OF CHAR; ok : BOOLEAN; 74 | BEGIN 75 | IF Args.count = 0 THEN 76 | Out.String("Try OCat --help for explanation of how this works"); Out.Ln(); 77 | ELSE 78 | i := 0; 79 | WHILE i < Args.count DO 80 | Args.Get(i, arg, res); 81 | IF Chars.Equal("-h", arg) OR Chars.Equal("--help", arg) THEN 82 | Usage(); 83 | ELSIF Chars.Equal("-t", arg) OR Chars.StartsWith("--tab", arg) THEN 84 | tabs[0] := Chars.TAB; tabs[1] := 0X; 85 | ELSIF Chars.StartsWith("--spaces=", arg) THEN 86 | Chars.TrimPrefix("--spaces=", arg); 87 | Convert.StringToInt(arg, k, ok); 88 | Chars.Clear(tabs); 89 | j := 0; 90 | WHILE j < k DO tabs[j] := " "; INC(j) END; 91 | tabs[j] := 0X; (* Terminate the tabs array of char *) 92 | ELSIF Chars.Equal("--spaces", arg) THEN 93 | Chars.Clear(tabs); 94 | tabs := " "; 95 | ELSE 96 | Cat(arg); 97 | END; 98 | INC(i); 99 | END; 100 | END; 101 | END Apply; 102 | 103 | BEGIN tabs[0] := Chars.TAB; tabs[1] := 0X; Apply(); 104 | END ocat. 105 | 106 | The POSIX command line version is built with 107 | 108 | obnc -o ocat ocat.Mod 109 | 110 | -------------------------------------------------------------------------------- /obncdoc/CharsTest.def: -------------------------------------------------------------------------------- 1 | (* CharsTest.Mod - test procedure the Chars.Mod. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | *) 8 | DEFINITION CharsTest; 9 | END CharsTest. 10 | -------------------------------------------------------------------------------- /obncdoc/DStringsTest.def: -------------------------------------------------------------------------------- 1 | (* DStringTest.Mod implements tests for the DStrings Module. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | *) 8 | DEFINITION DStringsTest; 9 | END DStringsTest. 10 | -------------------------------------------------------------------------------- /obncdoc/JSON.def: -------------------------------------------------------------------------------- 1 | DEFINITION JSON; 2 | 3 | CONST 4 | NullType = 0; 5 | BooleanType = 1; 6 | NumberType = 2; 7 | StringType = 3; 8 | ArrayType = 4; 9 | ObjectType = 5; 10 | 11 | TYPE 12 | Self = RECORD END; 13 | 14 | Boolean = POINTER TO BooleanDesc; 15 | 16 | Number = POINTER TO NumberDesc; 17 | NumberDesc = RECORD (Self) END; 18 | 19 | String = POINTER TO StringDesc; 20 | StringDesc = RECORD (Self) END; 21 | 22 | List = POINTER TO ListDesc; 23 | ListDesc = RECORD (Self) END; 24 | 25 | Object = POINTER TO ObjectDesc; 26 | ObjectDesc = RECORD (Self) END; 27 | 28 | PROCEDURE IsNull(o : Self) : BOOLEAN; 29 | 30 | PROCEDURE IsType(o : Self; checkType : INTEGER) : BOOLEAN; 31 | 32 | PROCEDURE TypeName(o : Self; VAR typeName : ARRAY OF CHAR); 33 | 34 | END JSON. 35 | -------------------------------------------------------------------------------- /obncdoc/JSONTest.def: -------------------------------------------------------------------------------- 1 | DEFINITION JSONTest; 2 | END JSONTest. 3 | -------------------------------------------------------------------------------- /obncdoc/Obn2.def: -------------------------------------------------------------------------------- 1 | (* Obn2.Mod is a module to help port Oberon-2 modules to Oberon-7. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | DEFINITION Obn2; 10 | 11 | (* ASH provides the Oberon-2 built-in ASH functionilty for 12 | Oberon-7. See description of providing ASH in documentation 13 | on Oberon-7 for positive and negative values *) 14 | PROCEDURE ASH(x, n : INTEGER) : INTEGER; 15 | 16 | (* MAX returns the maximum of two integers *) 17 | PROCEDURE MAX(x, y : INTEGER) : INTEGER; 18 | 19 | (* MIN provides the minimum of two integers *) 20 | PROCEDURE MIN(x, y : INTEGER) : INTEGER; 21 | 22 | (* ENTIER is a wrapper around FLOOR, you should really just use 23 | FLOOR. *) 24 | PROCEDURE ENTIER(r : REAL) : INTEGER; 25 | 26 | (* HALT is a wrapper around ASSERT(FALSE), you should just replace 27 | ASSERT(FALSE) *) 28 | PROCEDURE HALT(); 29 | 30 | (* ROT is a wrapper around ROR, you should just replace ROT with ROR *) 31 | PROCEDURE ROT(x, n : INTEGER) : INTEGER; 32 | 33 | END Obn2. 34 | -------------------------------------------------------------------------------- /obncdoc/Obn2Test.def: -------------------------------------------------------------------------------- 1 | (* Obn2Test modules provides testing for Obn2 module. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | DEFINITION Obn2Test; 10 | END Obn2Test. 11 | -------------------------------------------------------------------------------- /obncdoc/Path.def: -------------------------------------------------------------------------------- 1 | DEFINITION Path; 2 | 3 | CONST 4 | (* Maximum path length *) 5 | MAXLENGTH = 1024; 6 | 7 | VAR 8 | delimiter : CHAR; 9 | extDelimiter : CHAR; 10 | 11 | (* SetDelimiter used for parsing paths *) 12 | PROCEDURE SetDelimiter(c : CHAR); 13 | 14 | (* SetExtDelimiter used for delimiting a filename extension, e.g. .txt *) 15 | PROCEDURE SetExtDelimiter(c : CHAR); 16 | 17 | (* Prepend insert the path fragement into the path adding 18 | the delimiter appropriately. 19 | 20 | NOTE: Prepend is limited by the temporary path used in assembling data. 21 | If the length of the prefix and path is too long then success will be 22 | set to FALSE and path will remain unchanged. *) 23 | PROCEDURE Prepend(prefix : ARRAY OF CHAR; VAR path : ARRAY OF CHAR; VAR success : BOOLEAN); 24 | 25 | (* Append appends the path fragment onto the path adding a delimiter appropriately. 26 | 27 | NOTE: The size of path limits how long the suffix can be. If it is too long then 28 | path remains unchanged and success is set to FALSE. *) 29 | PROCEDURE Append(suffix : ARRAY OF CHAR; VAR path : ARRAY OF CHAR; VAR success : BOOLEAN); 30 | 31 | (* Basename scans source and writes the last path segment to dest based on the path delimiter set *) 32 | PROCEDURE Basename(source : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR; success : BOOLEAN); 33 | 34 | (* Dirname scans source and writes the all but the last path segment to dest based on the path delimiter set *) 35 | PROCEDURE Dirname(source : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR; success : BOOLEAN); 36 | 37 | (* Ext scans source and writes the file extension to dest based on the extDelimiter set *) 38 | PROCEDURE Ext(source : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR; success : BOOLEAN); 39 | 40 | END Path. 41 | -------------------------------------------------------------------------------- /obncdoc/PathLists.def: -------------------------------------------------------------------------------- 1 | (* PathLists is a module for working with a delimited list of paths. *) 2 | DEFINITION PathLists; 3 | (* Merge operations *) 4 | TYPE 5 | PathList = POINTER TO PathListDesc; 6 | PathListDesc = RECORD END; 7 | 8 | (* Length returns the length of the PathList *) 9 | PROCEDURE Length(pathList : PathList) : INTEGER; 10 | 11 | (* Find takes a path and searches a path list return -1 if not found 12 | or the position where it was found (zero indexed) *) 13 | PROCEDURE Find(path : ARRAY OF CHAR; pathList : PathList) : INTEGER; 14 | 15 | (* Prepend takes a path and a path list and prepends path to path list updating 16 | path list. *) 17 | PROCEDURE Prepend(path : ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN); 18 | 19 | (* Append takes a path and path list and adds the path to the end of path list *) 20 | PROCEDURE Append(path: ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN); 21 | 22 | (* Cut takes a path and a path list and removes the path element from path list. *) 23 | PROCEDURE Cut(path : ARRAY OF CHAR; VAR pathList : PathList; VAR success : BOOLEAN); 24 | 25 | (* SetDelimiter sets the delimiter to be used for encoding and decoding paths *) 26 | 27 | (* Encode takes a PathList and encodes it into pathListString using the delimiter provided *) 28 | PROCEDURE Encode(pathList : PathList; delimiter: CHAR; VAR pathListString : ARRAY OF CHAR; VAR success : BOOLEAN); 29 | 30 | (* Decode takes a path list string and decodes it into a PathList data structure *) 31 | PROCEDURE Decode(pathListString : ARRAY OF CHAR; VAR pathList : PathList; success : BOOLEAN); 32 | 33 | (* Apply takes a path, an operation and a path list string. It applies the operation 34 | using the path and pathList updating pathList. Return TRUE of successful, 35 | FALSE otherwise. *) 36 | PROCEDURE Apply(path: ARRAY OF CHAR; operation: INTEGER; VAR pathListString: ARRAY OF CHAR): BOOLEAN; 37 | 38 | END PathLists. 39 | -------------------------------------------------------------------------------- /obncdoc/PathListsTest.def: -------------------------------------------------------------------------------- 1 | DEFINITION PathListsTest; 2 | END PathListsTest. 3 | -------------------------------------------------------------------------------- /obncdoc/PathTest.def: -------------------------------------------------------------------------------- 1 | DEFINITION PathTest; 2 | END PathTest. 3 | -------------------------------------------------------------------------------- /obncdoc/Scanner.def: -------------------------------------------------------------------------------- 1 | DEFINITION Scanner; 2 | 3 | CONST 4 | ERROR = 0; 5 | OK = 1; 6 | EOS = 2; 7 | 8 | EOT = 0X; 9 | TAB = 9X; 10 | LF = 10X; 11 | FF = 11X; 12 | CR = 13X; 13 | SPACE = 32X; 14 | DQUOTE = 34X; 15 | SQUOTE = 39X; 16 | SLASH = 47X; 17 | BSLASH = 92X; 18 | 19 | (* Character constants *) 20 | DASH = "-"; 21 | LODASH = "_"; 22 | CARET = "^"; 23 | TILDE = "~"; 24 | 25 | TYPE 26 | Scanner = POINTER TO ScannerDesc; 27 | ScannerDesc = RECORD 28 | Pos: INTEGER 29 | END; 30 | 31 | PROCEDURE Init(VAR scanner: Scanner; delimiter: CHAR; startString: CHAR; endString: CHAR; Escape: CHAR); 32 | 33 | PROCEDURE ScanChars(VAR scanner: Scanner; src : ARRAY OF CHAR; VAR value: ARRAY OF CHAR; VAR OK: BOOLEAN); 34 | 35 | END Scanner. 36 | -------------------------------------------------------------------------------- /obncdoc/ScannerTest.def: -------------------------------------------------------------------------------- 1 | DEFINITION ScannerTest; 2 | END ScannerTest. 3 | -------------------------------------------------------------------------------- /obncdoc/Tests.def: -------------------------------------------------------------------------------- 1 | (* Tests.Mod - A module providing simple test support for Oberon-7. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | DEFINITION Tests; (* portable *) 10 | CONST 11 | MAXSTR = 1024; 12 | 13 | TYPE 14 | (* TestProc is the signature of a test procedure. It is simple. 15 | if a test successeds it returns true, otherwise it returns false. 16 | The procedure Test counts the number of test run and results 17 | updating variable parameters of success and errors. In turn 18 | these are passed to Summarize to return a summary report. *) 19 | TestProc = PROCEDURE () : BOOLEAN; 20 | 21 | TestSet = POINTER TO TestSetDesc; 22 | TestSetDesc = RECORD 23 | title : ARRAY MAXSTR OF CHAR; 24 | fn : TestProc; 25 | next : TestSet 26 | END; 27 | 28 | (* DisplayString display quoted ARRAY OF CHAR with prefixed by msg *) 29 | PROCEDURE DisplayString(msg: ARRAY OF CHAR; source : ARRAY OF CHAR); 30 | 31 | (* ExpectedInt compares to int display msg on error and updates test to 32 | FALSE if they don'y match *) 33 | PROCEDURE ExpectedInt(expected, got : INTEGER; msg : ARRAY OF CHAR; VAR test : BOOLEAN); 34 | 35 | (* ExpectedReal compares to REAL display msg on error and updates test to 36 | FALSE if they don'y match *) 37 | PROCEDURE ExpectedReal(expected, got : REAL; msg : ARRAY OF CHAR; VAR test : BOOLEAN); 38 | 39 | (* ExpectedString compare two ARRAY OF CHAR, set test to FALSE 40 | if they don't match and display msg *) 41 | PROCEDURE ExpectedString(s1, s2, msg : ARRAY OF CHAR; VAR test : BOOLEAN); 42 | 43 | (* ExpectedChar compare two CHAR, set test to FALSE if they don't 44 | match and display msg *) 45 | PROCEDURE ExpectedChar(expected, got : CHAR; msg : ARRAY OF CHAR; VAR test : BOOLEAN); 46 | 47 | (* ExpectedBool compare to BOOLEAN values, set test to FALSE if they 48 | don't match and display message *) 49 | PROCEDURE ExpectedBool(expected, got : BOOLEAN; msg : ARRAY OF CHAR; VAR test : BOOLEAN); 50 | 51 | (* ExpectedBytes compares the first N values to two array of byte *) 52 | PROCEDURE ExpectedBytes(expected, got : ARRAY OF BYTE; n : INTEGER; msg : ARRAY OF CHAR; VAR test: BOOLEAN); 53 | 54 | (*ExpectedSet compares two sets, display message if they don't match and 55 | set the value of test to FALSE *) 56 | PROCEDURE ExpectedSet(expected, got : SET; msg : ARRAY OF CHAR; VAR test : BOOLEAN); 57 | 58 | (* ShowTitle displays the title in standard out and underlined with '=' *) 59 | PROCEDURE ShowTitle(s : ARRAY OF CHAR); 60 | 61 | (* Test -- run the test method and update the success and error variables 62 | provided. *) 63 | PROCEDURE Test(fn : TestProc; VAR success : INTEGER; VAR errors : INTEGER); 64 | 65 | (* Summarize -- sumarize the results using the test title, success 66 | and error counts. *) 67 | PROCEDURE Summarize(title : ARRAY OF CHAR; successes, errors : INTEGER); 68 | 69 | (* New initializes a new TestSet with a title *) 70 | PROCEDURE Init(VAR ts: TestSet; title : ARRAY OF CHAR); 71 | 72 | PROCEDURE Add(VAR ts : TestSet; fn : TestProc); 73 | 74 | PROCEDURE Run(ts : TestSet) : BOOLEAN; 75 | 76 | END Tests. 77 | -------------------------------------------------------------------------------- /obncdoc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Index of Artemis 7 | 8 | 9 | 10 |

Index

11 | 12 |
13 | DEFINITION Chars
14 | DEFINITION CharsTest
15 | DEFINITION DStrings
16 | DEFINITION DStringsTest
17 | DEFINITION JSON
18 | DEFINITION Obn2
19 | DEFINITION Obn2Test
20 | DEFINITION Path
21 | DEFINITION PathLists
22 | DEFINITION Scanner
23 | DEFINITION Tests
24 | 		
25 | 26 | 27 | -------------------------------------------------------------------------------- /obncdoc/style.css: -------------------------------------------------------------------------------- 1 | /* @import 'https://fonts.googleapis.com/css?family=Concert+One|Dosis'; */ 2 | 3 | body { 4 | font-family: 'Atkinson-Hyperlegible', 'Open Sans', sans-serif; 5 | font-size: calc(1em+1vw); 6 | padding: 0; 7 | margin: 0; 8 | width: 100%; 9 | height: auto; 10 | color: black; 11 | background-color: white; 12 | } 13 | 14 | a, a:link, a:visited { 15 | color: forestgreen; 16 | text-decoration: none; 17 | } 18 | 19 | a:active, a:focus, a:hover { 20 | color: maroon; 21 | text-decoration: underline; 22 | } 23 | 24 | 25 | 26 | ul { 27 | padding: 0; 28 | margin-left: 1.24em; 29 | /* list-style-type: disc;*/ 30 | } 31 | 32 | nav { 33 | position:fixed; 34 | top:0; 35 | display: block; 36 | width: 100%; 37 | height: auto; 38 | padding: 0; 39 | padding: 0.20em; 40 | /* caltech orange, white and black 41 | color: white; 42 | background-color: #FF6E1E; 43 | */ 44 | /* white on deep red */ 45 | color: white; 46 | background-color: #5f0202; 47 | } 48 | 49 | nav a, nav a:link, nav a:visited { 50 | font-weight: lighter; 51 | color: white; 52 | text-decoration: none; 53 | } 54 | 55 | nav a:active, nav a:focus, nav a:hover { 56 | font-weight: lighter; 57 | color: orange; 58 | text-decoration: none; 59 | text-transform: uppercase; 60 | } 61 | 62 | 63 | nav ul { 64 | display: block; 65 | width: 100%; 66 | height: auto; 67 | list-style: none; 68 | list-style-type: none; 69 | padding: 0; 70 | margin: 0; 71 | } 72 | 73 | nav ul li { 74 | display: inline-block; 75 | text-align: left; 76 | padding-top: 0em; 77 | padding-left: 0.82em; 78 | padding-right: 0.24em; 79 | padding-bottom: 0em; 80 | margin: 0; 81 | } 82 | 83 | section, article { 84 | display: block; 85 | max-width: 90%; 86 | height: auto; 87 | padding: 1.24em; 88 | margin-top: 1.24em; 89 | margin-bottom: 0.24em; 90 | } 91 | 92 | 93 | img.rss-valid { 94 | display: inline; 95 | width: auto; 96 | height: 0.82em; 97 | } 98 | 99 | h1 { 100 | font-size: 200%; 101 | } 102 | 103 | h2 { 104 | font-weight: lighter; 105 | font-size: 170%; 106 | } 107 | 108 | h3 { 109 | font-weight: lighter; 110 | font-size: 120%; 111 | text-transform: uppercase; 112 | } 113 | 114 | h4 { 115 | font-weight: lighter; 116 | font-size: 100%; 117 | text-transform: lowercase; 118 | } 119 | 120 | h1 code, h2 code, h3 code, h4 code { 121 | text-transform:none; 122 | } 123 | 124 | 125 | footer { 126 | position: fixed; 127 | bottom: 0; 128 | font-size: 0.82em; 129 | font-weight: lighter; 130 | padding: 0; 131 | margin: 0; 132 | width: 100%; 133 | height: auto; 134 | color: white; 135 | background-color: black; 136 | } 137 | 138 | /* NOTE: Ingnore a P tag inserted by Markdown when rendering headers */ 139 | footer p { 140 | display: block; 141 | width: 100%; 142 | height: auto; 143 | padding: 0; 144 | margin: 0; 145 | font-family: 'Dosis', sans-serif; 146 | font-size: 0.82em; 147 | font-weight: lighter; 148 | margin-top: 0.32em; 149 | margin-left: 0; 150 | margin-right: 0; 151 | margin-bottom: 0; 152 | } 153 | 154 | footer img { 155 | display: block; 156 | float: left; 157 | vertical-align: top; 158 | border: 1px solid black; 159 | border-top-left-radius: 1.2em; 160 | border-top-right-radius: 1.2em; 161 | box-shadow: inset 0.12em 0.12em black; 162 | width: 3.2em; 163 | height: auto; 164 | margin: 0.24em; 165 | } 166 | 167 | footer a, footer a:link, footer a:visited { 168 | font-weight: lighter; 169 | /* caltech orange */ 170 | color: #FF6E1E; 171 | } 172 | 173 | footer a:active, footer a:focus, footer a:hover { 174 | font-weight: lighter; 175 | color: lightgreen; 176 | } 177 | 178 | /* color injections for AndOr */ 179 | .red { 180 | color: red; 181 | } 182 | 183 | /* Google prittyprint customizaions CSS */ 184 | li.L0, li.L1, li.L2, li.L3, li.L4, li.L5, li.L6, li.L7, li.L8, li.L9 185 | { 186 | color: #555; 187 | list-style-type: decimal; 188 | } 189 | 190 | 191 | /* Mmark css */ 192 | #footnote-section { 193 | font-size: 80%; 194 | display: none; 195 | } 196 | 197 | .footnotes { 198 | font-size: 80%; 199 | } 200 | 201 | /* 202 | * Project Customizations 203 | */ 204 | div.project-name { 205 | display: block; 206 | width: 100%; 207 | height: auto; 208 | padding-top: 1.24em; 209 | padding-left: 1.24em; 210 | margin-top: 1.24em; 211 | } 212 | 213 | header blockquote { 214 | display: block; 215 | width: 100%; 216 | height: auto; 217 | padding: 0em; 218 | margin-left: 2.48em; 219 | } 220 | 221 | -------------------------------------------------------------------------------- /ofrontplus/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ofront+ modules 3 | --- 4 | 5 | Ofront+ - Not portable 6 | ====================== 7 | 8 | In this directory are Artemis modules for Ofront+. This is 9 | currently a placeholder but will become populated as the 10 | non-portable Artemis modules are completed. The non-portable 11 | modules use C code integration. It is a counter part 12 | to the obnc and oxford directories. 13 | 14 | Modules naming 15 | -------------- 16 | 17 | Where modules are not canonical to Artemis the modules names have 18 | a prefix of "art" (e.g. the Clock module is named artClock.Mod). Where 19 | they are canonical to Artemis (e.g. Chars.Mod in the project root) 20 | they do not have a prefix. 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /ofrontplus/TODO.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | … 12 |
13 |
14 |

15 | To do 16 |

17 |

18 | Next 19 |

20 |
    21 |
  • 22 | Learn Ofront+ command line options and how to handle pathing 23 |
      24 |
    • 25 | See “OBERON” environment variable 26 |
    • 27 |
    28 |
  • 29 |
  • 30 | Create a general purpose Makefile for compiling Artemis/Ofront+ projects 31 |
  • 32 |
33 |
34 | 65 |
66 | copyright (c) 2021 all rights reserved. 67 | Released under the BSD 3-Clause license 68 | See: http://opensource.org/licenses/BSD-3-Clause 69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /ofrontplus/TODO.md: -------------------------------------------------------------------------------- 1 | To do 2 | ===== 3 | 4 | Next 5 | ---- 6 | 7 | - [ ] Learn Ofront+ command line options and how to handle pathing 8 | - See "OBERON" environment variable 9 | - [ ] Create a general purpose Makefile for compiling Artemis/Ofront+ projects 10 | 11 | -------------------------------------------------------------------------------- /ofrontplus/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | Ofront+ modules 12 |
13 |
14 |

15 | Ofront+ - Not portable 16 |

17 |

18 | In this directory are Artemis modules for Ofront+. This is currently a placeholder but will become populated as the non-portable Artemis modules are completed. The non-portable modules use C code integration. It is a counter part to the obnc and oxford directories. 19 |

20 |

21 | Modules naming 22 |

23 |

24 | Where modules are not canonical to Artemis the modules names have a prefix of “art” (e.g. the Clock module is named artClock.Mod). Where they are canonical to Artemis (e.g. Chars.Mod in the project root) they do not have a prefix. 25 |

26 |
27 | 58 |
59 | copyright (c) 2021 all rights reserved. 60 | Released under the BSD 3-Clause license 61 | See: http://opensource.org/licenses/BSD-3-Clause 62 |
63 | 64 | 65 | -------------------------------------------------------------------------------- /ofrontplus/nav.md: -------------------------------------------------------------------------------- 1 | 2 | + [Home](/) 3 | + [README](../) 4 | + [LICENSE](../license.html) 5 | + [INSTALL](../install.html) 6 | + [OBNC Modules](../obnc/) 7 | + [Obc-3 Modules](../oxford/) 8 | + [Ofront+ Modules](./) 9 | + [development notes](../development-notes.html) 10 | + [Github](https://github.com/rsdoiel/Artemis) 11 | 12 | -------------------------------------------------------------------------------- /oxford/ArgsTest.m: -------------------------------------------------------------------------------- 1 | (** ArgsTest.m modules provides test coverage for artArgs.m 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE ArgsTest; 10 | 11 | IMPORT T := Tests, Args := artArgs, Out; 12 | 13 | VAR ts : T.TestSet; 14 | 15 | PROCEDURE TestOneTwoThree() : BOOLEAN; 16 | VAR test : BOOLEAN; one, two, three : ARRAY 12 OF CHAR; 17 | res : INTEGER; 18 | BEGIN test := TRUE; 19 | T.ExpectedInt(3, Args.count, "Args.count for 'argtest one two three'", test); 20 | IF Args.count = 3 THEN 21 | Args.Get(0, one, res); 22 | Args.Get(1, two, res); 23 | Args.Get(2, three, res); 24 | 25 | T.ExpectedString("one", one, "Args.Get(0, one, res) for 'argtest one two three'", test); 26 | T.ExpectedString("two", two, "Args.Get(1, two, res) for 'argtest one two three'", test); 27 | T.ExpectedString("three", three, "Args.Get(2, three, res) for 'argtest one two three'", test); 28 | END; 29 | RETURN test 30 | END TestOneTwoThree; 31 | 32 | BEGIN 33 | Out.String("NOTE: run `argtest one two three`"); Out.Ln; 34 | T.Init(ts, "ArgsTest"); 35 | T.Add(ts, TestOneTwoThree); 36 | ASSERT(T.Run(ts)); 37 | END ArgsTest. 38 | 39 | -------------------------------------------------------------------------------- /oxford/ClockTest.m: -------------------------------------------------------------------------------- 1 | (** ClockTest.m provide module Tests for Clock.mo. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE ClockTest; 10 | 11 | IMPORT T := Tests, Clock := artClock, Env := artEnv, Out, Strings; 12 | 13 | VAR ts : T.TestSet; 14 | 15 | PROCEDURE DisplayClock(ct : Clock.Clock); 16 | VAR i, hours, minutes : INTEGER; 17 | BEGIN 18 | Out.Int(ct.year, 4); 19 | Out.String("-"); 20 | IF ct.month < 10 THEN 21 | Out.String("0"); Out.Int(ct.month, 1); 22 | ELSE 23 | Out.Int(ct.month, 2); 24 | END; 25 | Out.String("-"); 26 | IF ct.day < 10 THEN 27 | Out.String("0"); Out.Int(ct.month, 1); 28 | ELSE 29 | Out.Int(ct.day, 2); 30 | END; 31 | Out.String(" "); 32 | IF ct.hour < 10 THEN 33 | Out.String("0"); Out.Int(ct.hour, 1); 34 | ELSE 35 | Out.Int(ct.hour, 2); 36 | END; 37 | Out.String(":"); 38 | IF ct.minute < 10 THEN 39 | Out.String("0"); Out.Int(ct.minute, 1); 40 | ELSE 41 | Out.Int(ct.minute, 2); 42 | END; 43 | Out.String(":"); 44 | IF ct.second < 10 THEN 45 | Out.String("0"); Out.Int(ct.second, 1); 46 | ELSE 47 | Out.Int(ct.second, 2); 48 | END; 49 | IF ct.isDST < 0 THEN 50 | Out.String(" "); (* DST info not available *) 51 | ELSIF ct.isDST = 0 THEN 52 | Out.String(" (ST)"); 53 | ELSIF ct.isDST = 1 THEN 54 | Out.String(" (DST)"); 55 | END; 56 | i := ABS(ct.utcOffset); 57 | IF (i >= 0) & (i <= 86400) THEN 58 | hours := (i DIV 3600) MOD 60; 59 | minutes := (i MOD 3600); 60 | Out.String(" UTC"); 61 | IF (ct.utcOffset >= 0) THEN 62 | Out.String("+"); 63 | IF hours < 10 THEN 64 | Out.String("0"); 65 | END; 66 | Out.Int(hours, 1); 67 | ELSE 68 | Out.String("-"); 69 | IF (ABS(hours) < 10) THEN 70 | Out.String("0"); 71 | END; 72 | Out.Int(ABS(hours), 1); 73 | END; 74 | IF minutes < 10 THEN 75 | Out.String("0"); Out.Int(minutes, 1); 76 | ELSE 77 | Out.Int(minutes, 2); 78 | END; 79 | END; 80 | Out.Ln(); 81 | END DisplayClock; 82 | 83 | PROCEDURE TestClockAndTime*() : BOOLEAN; 84 | VAR test : BOOLEAN; t1 : Clock.Clock; 85 | BEGIN test := TRUE; 86 | NEW(t1); 87 | Clock.Get(t1); 88 | T.ExpectedBool(TRUE, (t1.year > 2020), "Expected t1.year > 2020", test); 89 | T.ExpectedBool(TRUE, ((t1.month >= 1) & (t1.month <= 12)), "Expected (t1.month >= 1) & (t1.mongth <= 12)", test); 90 | T.ExpectedBool(TRUE, (t1.day > 0), "Expected t1.day > 0", test); 91 | T.ExpectedBool(TRUE, (t1.hour > -1), "Expected t1.hour > 0", test); 92 | T.ExpectedBool(TRUE, (t1.minute > -1), "Expected t1.minute > 0", test); 93 | T.ExpectedBool(TRUE, (t1.second > -1), "Expected t1.second > 0", test); 94 | 95 | RETURN test 96 | END TestClockAndTime; 97 | 98 | PROCEDURE TestClockSet*() : BOOLEAN; 99 | VAR test : BOOLEAN; ct, tt, sc : Clock.Clock; ok : BOOLEAN; 100 | uname, os : ARRAY 256 OF CHAR; res : INTEGER; 101 | BEGIN test := TRUE; 102 | res := 0; 103 | Env.Get("OS", os, res); 104 | Env.Get("SUDO_USER", uname, res); 105 | IF os = "Linux" THEN 106 | Out.String("Skipping TestClockSet(), Clock.Set() is not permitted under Linux"); Out.Ln(); 107 | ELSIF (Strings.Length(uname) = 0) & (os = "Darwin") THEN 108 | Out.String(" Skipping TestSet(), Clock.Set() requires admin privilleges for Darwin (macOS)");Out.Ln(); 109 | Out.String(" You can try rerunning tests with");Out.Ln(); 110 | Out.Ln(); Out.String(" sudo make test");Out.Ln();Out.Ln(); 111 | ELSE 112 | NEW(ct); NEW(tt); NEW(sc); 113 | Clock.Get(ct); 114 | Out.String(" Current clock: ");DisplayClock(ct); 115 | tt.year := ct.year + 1; 116 | tt.month := ct.month + 1; 117 | IF tt.month > 12 THEN 118 | INC(tt.year); 119 | ct.month := 1; 120 | END; 121 | tt.day := ct.day; 122 | tt.hour := ct.hour; 123 | tt.minute := ct.minute; 124 | tt.second := ct.second; 125 | tt.isDST := ct.isDST; 126 | tt.utcOffset := ct.utcOffset; 127 | Clock.Get(sc); (* Save the time to reset later *) 128 | Clock.Set(tt, ok); 129 | T.ExpectedBool(TRUE, ok, "Clock.Set(tt, ok) failed", test); 130 | IF ok THEN 131 | Out.String(" New clock: ");DisplayClock(tt); 132 | 133 | T.ExpectedBool(TRUE, ok, "Clock.Set(tt, ok) ", test); 134 | 135 | T.ExpectedBool(TRUE, (Clock.clock.year = tt.year), "new time year", test); 136 | T.ExpectedBool(TRUE, (Clock.clock.month = tt.month), "new time month", test); 137 | T.ExpectedBool(TRUE, (Clock.clock.day = tt.day), "new time day", test); 138 | T.ExpectedBool(TRUE, (Clock.clock.hour = tt.hour), "new time hour", test); 139 | T.ExpectedBool(TRUE, (Clock.clock.minute = tt.minute), "new time minute", test); 140 | T.ExpectedBool(TRUE, (Clock.clock.second = tt.second), "new time second", test); 141 | (* Reset the clock *) 142 | Clock.Set(sc, ok); 143 | Clock.Get(ct); 144 | Out.String(" Reset clock: "); DisplayClock(ct); 145 | END; 146 | END; 147 | 148 | RETURN test 149 | END TestClockSet; 150 | 151 | BEGIN 152 | T.Init(ts, "Test Clock"); 153 | T.Add(ts, TestClockAndTime); 154 | T.Add(ts, TestClockSet); 155 | ASSERT(T.Run(ts)); 156 | END ClockTest. 157 | 158 | 159 | -------------------------------------------------------------------------------- /oxford/ConvertTest.m: -------------------------------------------------------------------------------- 1 | (** ConvertTest.m provides module tests for Convert.m. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE ConvertTest; 10 | 11 | IMPORT T := Tests, Convert := artConvert; 12 | 13 | VAR ts : T.TestSet; 14 | 15 | PROCEDURE TestIntConvs() : BOOLEAN; 16 | VAR test, ok : BOOLEAN; 17 | expectI, gotI : INTEGER; 18 | expectS, gotS : ARRAY 128 OF CHAR; 19 | BEGIN test := TRUE; 20 | gotS[0] := 0X; gotI := 0; 21 | expectI := 101; 22 | expectS := "101"; 23 | 24 | Convert.StringToInt(expectS, gotI, ok); 25 | T.ExpectedBool(TRUE, ok, "StringToInt('101', gotI, ok) true", test); 26 | T.ExpectedInt(expectI, gotI, "StringToInt('101', gotI, ok)", test); 27 | 28 | Convert.IntToString(expectI, gotS, ok); 29 | T.ExpectedBool(TRUE, ok, "IntToString(101, gotS, ok) true", test); 30 | T.ExpectedString(expectS, gotS, "IntToString(101, gotS, ok)", test); 31 | 32 | RETURN test 33 | END TestIntConvs; 34 | 35 | PROCEDURE TestRealConvs() : BOOLEAN; 36 | VAR test, ok : BOOLEAN; 37 | expectR, gotR : REAL; 38 | expectS, gotS : ARRAY 128 OF CHAR; 39 | BEGIN test := TRUE; 40 | gotR := 0.0; gotS[0] := 0X; 41 | expectR := 3.1459; 42 | expectS := "3.145900"; 43 | 44 | Convert.StringToReal(expectS, gotR, ok); 45 | T.ExpectedBool(TRUE, ok, "StringToReal('3.1459', gotR, ok) true", test); 46 | T.ExpectedReal(expectR, gotR, "StringToReal('3.1459', gotR, ok)", test); 47 | 48 | Convert.RealToString(expectR, gotS, ok); 49 | T.ExpectedBool(TRUE, ok, "RealToString(3.1459, gotS; ok) true", test); 50 | T.ExpectedString(expectS, gotS, "RealToString(3.1459, gotS, ok)", test); 51 | 52 | RETURN test 53 | END TestRealConvs; 54 | 55 | BEGIN 56 | T.Init(ts, "artConvert"); 57 | T.Add(ts, TestIntConvs); 58 | T.Add(ts, TestRealConvs); 59 | ASSERT(T.Run(ts)); 60 | END ConvertTest. 61 | -------------------------------------------------------------------------------- /oxford/EnvTest.m: -------------------------------------------------------------------------------- 1 | (** EvnTest.m provide module tests for Env.m 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE EnvTest; 10 | 11 | IMPORT T := Tests, Env := artEnv, Out; 12 | 13 | VAR ts : T.TestSet; 14 | 15 | PROCEDURE TestEnv() : BOOLEAN; 16 | VAR test : BOOLEAN; value : ARRAY 256 OF CHAR; 17 | res : INTEGER; 18 | BEGIN test := TRUE; 19 | Env.Get("GOOD_NIGHT", value, res); 20 | T.ExpectedString("Irine", value, "Env.Get('GOOD_NIGHT', value, res') for 'env GOOD_NIGHT=Irine envtest'", test); 21 | RETURN test 22 | END TestEnv; 23 | 24 | BEGIN 25 | Out.String("NOTE: run `env GOOD_NIGHT=Irine envtest`"); Out.Ln; 26 | T.Init(ts, "EnvTest"); 27 | T.Add(ts, TestEnv); 28 | ASSERT(T.Run(ts)); 29 | END EnvTest. 30 | 31 | -------------------------------------------------------------------------------- /oxford/Makefile: -------------------------------------------------------------------------------- 1 | 2 | OS = $(shell uname) 3 | 4 | SUDO_USER = $$SUDO_USER 5 | 6 | SHARE_LIBS = 7 | 8 | #FIXME: Compiling under macOS is failing right now. This is true for 9 | # both static and dynamic compilations. 10 | # 11 | # Per https://spivey.oriel.ox.ac.uk/corner/How_to_add_primitives_to_OBC 12 | #GCC_SO_OPT = -m32 -fPIC -shared -I /usr/local/lib/obc 13 | #ifeq ($(OS),Darwin) 14 | # GCC_SO_OPT = -m32 -fPIC -bundle -undefined dynamic_lookup -I /usr/local/lib/obc 15 | #endif 16 | 17 | PROGRAMS = helloworld clocktest converttest argstest envtest 18 | 19 | build: $(SHARE_LIBS) $(PROGRAMS) ../Tests.m 20 | 21 | #../Tests.m: ../Tests.Mod 22 | # echo '(** Copied from ../Tests.Mod, DO NOT edit *)' >../Tests.m 23 | # #cat ../Tests.Mod >>../Tests.m 24 | 25 | clocktest: ../Tests.m artEnv.m artClock.m ClockTest.m 26 | obc -07 -c ../Tests.m 27 | obc -07 -c artClock.m 28 | obc -07 -c artClock.c 29 | obc -07 -c artEnv.m 30 | obc -07 -c ClockTest.m 31 | obc -07 -C -o clocktest ../Tests.m artClock.m artClock.o artEnv.m ClockTest.m 32 | 33 | converttest: ../Tests.m ConvertTest.m artConvert.m 34 | obc -07 -c ../Tests.m 35 | obc -07 -c artConvert.m 36 | obc -07 -c artConvert.c 37 | obc -07 -c ConvertTest.m 38 | obc -07 -C -o converttest artConvert.m artConvert.o ../Tests.m ConvertTest.m 39 | 40 | argstest: ../Tests.m artArgs.m ArgsTest.m 41 | obc -07 -o argstest artArgs.m ../Tests.m ArgsTest.m 42 | 43 | envtest: ../Tests.m artEnv.m EnvTest.m 44 | obc -07 -o envtest artEnv.m ../Tests.m EnvTest.m 45 | 46 | helloworld: helloworld.m 47 | obc -07 -o helloworld helloworld.m 48 | 49 | 50 | test: $(PROGRAMS) 51 | ./helloworld 52 | env OS=$(OS) SUDO_USER=$(SUDO_USER) ./clocktest 53 | ./argstest one two three 54 | env GOOD_NIGHT=Irine ./envtest 55 | ./converttest 56 | 57 | clean: .FORCE 58 | @for FNAME in $(shell ls -1 *.bak *~ *.o a.out 2>/dev/null); do rm $$FNAME; done 59 | @for FNAME in $(PROGRAMS); do if [ -f $$FNAME ]; then rm $$FNAME; fi; done 60 | @for FNAME in $(SHARED_LIBS); do if [ -f $$FNAME ]; then rm $$FNAME; fi; done 61 | @for FNAME in $(shell ls -1 *.k 2>/dev/null); do rm $$FNAME; done 62 | @for FNAME in $(shell ls -1 *.so 2>/dev/null); do rm $$FNAME; done 63 | 64 | full_test: clean test 65 | 66 | 67 | .FORCE: 68 | -------------------------------------------------------------------------------- /oxford/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Obc-3 modules 3 | --- 4 | 5 | Oxford - Not portable 6 | ===================== 7 | 8 | DRAFT: sketch of untested code. 9 | 10 | FIXME: I have not gotten the current Obc-3 to compile under Darwin (macOS). 11 | 12 | Modules in this directory are being ported to the Obc-3 compiler 13 | and should be compiled with the `-07` option. 14 | 15 | - [Obc-3 compiler](https://spivey.oriel.ox.ac.uk/corner/Oxford_Oberon-2_compiler) 16 | - [How to add primitives to Obc-3](https://spivey.oriel.ox.ac.uk/corner/How_to_add_primitives_to_OBC) 17 | 18 | Pre-requisites 19 | -------------- 20 | 21 | **Debian systems** 22 | 23 | ~~~bash 24 | sudo apt install build-essential autotools automake autoconf git 25 | sudo apt install ocaml 26 | sudo apt install libgtksourceview2.0-dev 27 | git clone git@github.com:Spivoxity/obc-3 28 | ~~~ 29 | 30 | NOTE: Unresolved issues on macOS 31 | -------------------------------- 32 | 33 | I am currently running into issues compiling these modules on macOS. 34 | Not sure if this is specific to my Mac (it is rather vintage) or due 35 | to problems with compiler flags. I suspect my Makefile is not calling 36 | the right options for macOS compilation. 37 | 38 | -------------------------------------------------------------------------------- /oxford/UnixTest.m: -------------------------------------------------------------------------------- 1 | (** UnixTest.m provide module tests for Unix.m 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE UnixTest; 10 | 11 | IMPORT T := Tests, Unix, Out, Env := artEnv; 12 | 13 | VAR 14 | ts : T.TestSet; 15 | successes, errors : INTEGER; 16 | 17 | PROCEDURE TestKernelName() : BOOLEAN; 18 | VAR test: BOOLEAN; expected, got : ARRAY 256 OF CHAR; res : INTEGER; 19 | BEGIN test := TRUE; 20 | Env.Get("OS", expected, res); 21 | IF expected[0] = 0X THEN 22 | Out.String("Skipping TestKernelName(), missing environment"); Out.Ln(); 23 | Out.String("variable OS (aka kernel name) needed to verify Unix.Kernel()"); Out.Ln(); 24 | ELSE 25 | Unix.KernelName(got); 26 | T.ExpectedString(expected, got, "Unix.KernelName(s) should match env. OS", test); 27 | END; 28 | RETURN test 29 | END TestKernelName; 30 | 31 | PROCEDURE TestArchitectureName() : BOOLEAN; 32 | VAR test: BOOLEAN; expected, got : ARRAY 24 OF CHAR; res : INTEGER; 33 | BEGIN test := TRUE; 34 | Env.Get("ARCH", expected, res); 35 | IF expected[0] = 0X THEN 36 | Out.String("Skipping TestArchitectureName(), missing environment"); Out.Ln(); 37 | Out.String("variable ARCH needed to verify Unix.Architecture()"); Out.Ln(); 38 | ELSE 39 | Unix.Architecture(got); 40 | T.ExpectedString(expected, got, "Unix.Architecture(s) should match env. OS", test); 41 | END; 42 | RETURN test 43 | END TestArchitectureName; 44 | 45 | PROCEDURE TestExit() : BOOLEAN; 46 | BEGIN 47 | Unix.Exit(0); 48 | RETURN FALSE 49 | END TestExit; 50 | 51 | BEGIN 52 | T.Init(ts, "Test Unix"); 53 | T.Add(ts, TestKernelName); 54 | T.Add(ts, TestArchitectureName); 55 | ASSERT(T.Run(ts)); 56 | (* Testing Unix.Exit(1) is tricky *) 57 | successes := 0; errors := 0; 58 | IF ~ TestExit() THEN 59 | Out.String("Test of Unix.Exit(), failed"); Out.Ln(); 60 | ASSERT(FALSE); 61 | END; 62 | END UnixTest. 63 | -------------------------------------------------------------------------------- /oxford/artArgs.m: -------------------------------------------------------------------------------- 1 | (** artArgs.m provides access to POSIX system arguments. It is based 2 | on the definition found in OBNC's extended library extArgs.Mod. 3 | 4 | Copyright (C) 2021 R. S. Doiel 5 | 6 | Released under The 3-Clause BSD License. 7 | See https://opensource.org/licenses/BSD-3-Clause 8 | 9 | *) 10 | MODULE artArgs; 11 | 12 | IMPORT Args; 13 | 14 | VAR 15 | count*: INTEGER; (*number of arguments*) 16 | 17 | (** Get provides access to the parameters passed one the command line. 18 | The parameters are n:th command line argument (0 <= n < count). 19 | 20 | The parameter res is provided for compatibilty with OBNC 21 | artArgs. It is ignored. *) 22 | PROCEDURE Get*(n: INTEGER; VAR arg: ARRAY OF CHAR; VAR res: INTEGER); 23 | BEGIN 24 | (* The zero's arg need to be the first parameter from the command line *) 25 | Args.GetArg(n + 1, arg); res := 0; 26 | END Get; 27 | 28 | BEGIN 29 | count := Args.argc - 1; 30 | END artArgs. 31 | 32 | -------------------------------------------------------------------------------- /oxford/artClock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * artClock.c provides an interface to C libraries used to implement artClock.m. 3 | * 4 | * Copyright (C) 2021 R. S. Doiel 5 | * 6 | * Released under The 3-Clause BSD License. 7 | * See https://opensource.org/licenses/BSD-3-Clause 8 | * 9 | */ 10 | #include 11 | #include 12 | 13 | void get_rtc_time(int *second_, int *minute_, int *hour_, int *day_, int *month_, int *year_, int *wDay_, int *yDay_, int *isDST_, int *utcOffset_, int *seconds_, int *nanoSeconds_, int *ok_) 14 | { 15 | struct timespec now; 16 | struct tm *dt; 17 | 18 | *ok_ = 1; /* Assume clock_gettime() successful */ 19 | if (clock_gettime(CLOCK_REALTIME, &now) == -1) { 20 | perror("clock_gettime(CLOCK_REALTIME, &now) failed"); 21 | *ok_ = 0; /* clock_gettime() failed for some reason */ 22 | } else { 23 | *seconds_ = now.tv_sec; 24 | *nanoSeconds_ = now.tv_nsec; 25 | dt = localtime(&now.tv_sec); 26 | *second_ = dt->tm_sec; 27 | *minute_ = dt->tm_min; 28 | *hour_ = dt->tm_hour; 29 | *day_ = dt->tm_mday; 30 | *month_ = dt->tm_mon + 1; /* We want 1 to 12 rather than 0 to 11 */ 31 | *year_ = dt->tm_year + 1900; /* Normalize to current year */ 32 | *wDay_ = dt->tm_wday; 33 | *yDay_ = dt->tm_yday; 34 | *isDST_ = dt->tm_isdst; 35 | *utcOffset_ = dt->tm_gmtoff; 36 | } 37 | } 38 | 39 | 40 | 41 | void set_rtc_time(int second_, int minute_, int hour_, int day_, int month_, int year_, int wDay_, int yDay_, int isDST_, int utcOffset_, int *ok_) 42 | { 43 | struct timespec nt; 44 | struct tm dt; 45 | 46 | dt.tm_sec = second_; 47 | dt.tm_min = minute_; 48 | dt.tm_hour = hour_; 49 | dt.tm_mday = day_; 50 | dt.tm_mon = (month_ - 1); /* de-normalize to 0 to 11 from 1 to 12 */ 51 | dt.tm_year = (year_ - 1900); /* adjust year to reflect POSIX value */ 52 | dt.tm_wday = wDay_; 53 | dt.tm_yday = yDay_; 54 | /* NOTE: tm_idst and tm_gmtoff are not ISO C or POSIX, they come from 55 | BSD and GNU systems. They appear to be available on macOS */ 56 | dt.tm_isdst = isDST_; 57 | dt.tm_gmtoff = utcOffset_; 58 | /* NOTE: You must have root permissions for clock_settime() to work */ 59 | nt.tv_sec = mktime(&dt); 60 | if (clock_settime(CLOCK_REALTIME, &nt) == -1) { 61 | perror("clock_settime(CLOCK_REALTIME, &nt) failed"); 62 | *ok_ = 0; 63 | } else { 64 | *ok_ = 1; 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /oxford/artConvert.c: -------------------------------------------------------------------------------- 1 | /** 2 | * extConvert.c provides the C implementation used in extConvert.m 3 | * 4 | * Copyright (C) 2021 R. S. Doiel 5 | * 6 | * Released under The 3-Clause BSD License. 7 | * See https://opensource.org/licenses/BSD-3-Clause 8 | * 9 | */ 10 | #include 11 | #include 12 | 13 | void conv_int_to_string(int i, char *s, int l) { 14 | snprintf(s, l, "%d", i); 15 | } 16 | 17 | void conv_real_to_string(float r, char *s, int l) { 18 | snprintf(s, l, "%f", r); 19 | } 20 | 21 | void conv_real_to_exp_string(float r, char *s, int l) { 22 | snprintf(s, l, "%e", r); 23 | } 24 | 25 | void conv_string_to_int(char *s, int *i) { 26 | *i = atoi(s); 27 | } 28 | 29 | void conv_string_to_real(char *s, float *r) { 30 | *r = atof(s); 31 | } 32 | -------------------------------------------------------------------------------- /oxford/artConvert.m: -------------------------------------------------------------------------------- 1 | (** artConvert.m provides procedures to convert between numbers and 2 | strings. It is based on the definition found in OBNC's 3 | extended library extConvert.Mod. 4 | 5 | Copyright (C) 2021 R. S. Doiel 6 | 7 | Released under The 3-Clause BSD License. 8 | See https://opensource.org/licenses/BSD-3-Clause 9 | 10 | *) 11 | MODULE artConvert; 12 | 13 | (* IMPORT SYSTEM; *) 14 | 15 | (** Conversions between numbers and strings 16 | 17 | All conversions from a string skips over preceeding whitespace. *) 18 | 19 | (** IntToString(i, s, d) returns in s the decimal representation of i. 20 | The done parameters is for compatibility, it is alwasy TRUE. *) 21 | PROCEDURE IntToString*(i: INTEGER; VAR s: ARRAY OF CHAR; VAR done: BOOLEAN); 22 | VAR l : INTEGER; 23 | BEGIN 24 | l := LEN(s); done := TRUE; 25 | IntToString0(i, s, l); 26 | END IntToString; 27 | 28 | PROCEDURE IntToString0(i : INTEGER; VAR s : ARRAY OF CHAR; l : INTEGER) IS "conv_int_to_string"; 29 | 30 | (** RealToString(x, s, d) returns in s a string representation of x. If s is large enough to hold the result, d is set to TRUE. Otherwise d is set to FALSE.*) 31 | PROCEDURE RealToString*(x: REAL; VAR s: ARRAY OF CHAR; VAR done: BOOLEAN); 32 | VAR l : INTEGER; 33 | BEGIN 34 | l := LEN(s); 35 | RealToString0(x, s, l); 36 | END RealToString; 37 | 38 | PROCEDURE RealToString0(x: REAL; VAR s: ARRAY OF CHAR; l : INTEGER) IS "conv_real_to_string"; 39 | 40 | 41 | (** StringToInt(s, i, d) returns in i the integer constant in s according to the format 42 | 43 | integer = digit {digit} | digit {hexDigit} "H". 44 | hexDigit = digit | "A" | "B" | "C" | "D" | "E" | "F". 45 | 46 | d indicates the success of the operation.*) 47 | PROCEDURE StringToInt*(s: ARRAY OF CHAR; VAR i: INTEGER; VAR done: BOOLEAN); 48 | BEGIN 49 | done := TRUE; 50 | StringToInt0(s, i); 51 | END StringToInt; 52 | 53 | PROCEDURE StringToInt0(s : ARRAY OF CHAR; VAR i : INTEGER) IS "conv_string_to_int"; 54 | 55 | (** StringToReal(s, x, d) returns in x the real number in s according to the format 56 | 57 | real = digit {digit} "." {digit} [ScaleFactor]. 58 | ScaleFactor = "E" ["+" | "-"] digit {digit}. 59 | 60 | d indicates the success of the operation. *) 61 | PROCEDURE StringToReal*(s: ARRAY OF CHAR; VAR x: REAL; VAR done: BOOLEAN); 62 | BEGIN 63 | done := TRUE; 64 | StringToReal0(s, x); 65 | END StringToReal; 66 | 67 | PROCEDURE StringToReal0(s: ARRAY OF CHAR; VAR x : REAL) IS "conv_string_to_real"; 68 | 69 | BEGIN 70 | (* SYSTEM.LOADLIB("./artConvert.so"); *) 71 | END artConvert. 72 | 73 | -------------------------------------------------------------------------------- /oxford/artEnv.m: -------------------------------------------------------------------------------- 1 | (**artEnv.m is a compatible module for code written for OBNC but compiler with Obc-3 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE artEnv; 10 | 11 | IMPORT Args, Strings; 12 | 13 | PROCEDURE Get*(name : ARRAY OF CHAR; VAR value : ARRAY OF CHAR; VAR res : INTEGER); 14 | VAR i, l1, l2 : INTEGER; val : ARRAY 512 OF CHAR; 15 | BEGIN 16 | l1 := LEN(value) - 1; (* Allow for trailing 0X *) 17 | Args.GetEnv(name, val); 18 | l2 := Strings.Length(val); 19 | IF l2 <= l1 THEN 20 | res := 0; 21 | ELSE 22 | res := l2 - l1; 23 | END; 24 | i := 0; 25 | WHILE (i < l2) & (val[i] # 0X) DO 26 | value[i] := val[i]; 27 | INC(i); 28 | END; 29 | value[i] := 0X; 30 | END Get; 31 | 32 | END artEnv. 33 | -------------------------------------------------------------------------------- /oxford/artUnix.m: -------------------------------------------------------------------------------- 1 | (** artUnix.m provides an interface to some POSIX services. 2 | 3 | Copyright (C) 2021 R. S. Doiel 4 | 5 | Released under The 3-Clause BSD License. 6 | See https://opensource.org/licenses/BSD-3-Clause 7 | 8 | *) 9 | MODULE artUnix; 10 | 11 | VAR 12 | kernel, architecture : ARRAY 24 OF CHAR; 13 | 14 | 15 | (* 16 | * C implemented procedures 17 | * ------------------------ 18 | *) 19 | 20 | (* uname does a popen call to `uname` *) 21 | PROCEDURE uname(opt : CHAR; VAR dest : ARRAY OF CHAR); 22 | BEGIN 23 | END uname; 24 | 25 | (** Exit performs a system exit with error number *) 26 | PROCEDURE Exit*(exitCode : INTEGER); 27 | BEGIN 28 | END Exit; 29 | 30 | (* 31 | * Oberon-7 implemented procedures 32 | * ------------------------------- 33 | *) 34 | 35 | (* mininum returns the lesser of two integer *) 36 | PROCEDURE minimum(a, b : INTEGER) : INTEGER; 37 | VAR res : INTEGER; 38 | BEGIN 39 | IF a < b THEN res := a; ELSE res := b; END; 40 | RETURN res 41 | END minimum; 42 | 43 | (* copy an array of chars, truncate dest if needed *) 44 | PROCEDURE copyChars(source : ARRAY OF CHAR; VAR dest : ARRAY OF CHAR); 45 | VAR i, l : INTEGER; 46 | BEGIN 47 | l := minimum(LEN(source), LEN(dest)) - 2; (* leave room of 0X *) 48 | IF l < 1 THEN l := 0 END; 49 | i := 0; dest[i] := 0X; 50 | WHILE (i < l) & (source[i] # 0X) DO 51 | dest[i] := source[i]; 52 | INC(i); 53 | END; 54 | dest[i] := 0X; DEC(i); 55 | IF (dest[i] = 10X) OR (dest[i] = 13X) THEN 56 | dest[i] := 0X; 57 | END; 58 | END copyChars; 59 | 60 | 61 | (** KernelName attempts a system exec call to `uname -s` to determine the 62 | Kernel name, e.g. Linux, Darwin, Windows *) 63 | PROCEDURE KernelName*(VAR dest : ARRAY OF CHAR); 64 | BEGIN 65 | IF kernel[0] = 0X THEN 66 | uname("s", kernel); 67 | END; 68 | copyChars(kernel, dest); 69 | END KernelName; 70 | 71 | (** Architecture attempts a system exec call to `uname -m` to determine 72 | the machine archtecture, e.g. i386, x86_64 *) 73 | PROCEDURE Architecture*(VAR dest : ARRAY OF CHAR); 74 | BEGIN 75 | IF architecture[0] = 0X THEN 76 | uname("m", architecture); 77 | END; 78 | copyChars(architecture, dest); 79 | END Architecture; 80 | 81 | 82 | BEGIN kernel[0] := 0X; architecture[0] := 0X; 83 | END artUnix. 84 | -------------------------------------------------------------------------------- /oxford/helloworld.m: -------------------------------------------------------------------------------- 1 | (** helloworld.m is intended to test the Obc-3 compiler installation. *) 2 | MODULE helloworld; 3 | 4 | IMPORT Args, Strings, Out; 5 | (* NOTE: Args provide GetEnv() for obc-3 *) 6 | VAR 7 | name : ARRAY 256 OF CHAR; 8 | 9 | BEGIN 10 | Args.GetEnv("USER", name); 11 | IF Strings.Length(name) > 0 THEN 12 | Out.String("Hello ");Out.String(name); Out.Ln; 13 | ELSE 14 | Out.String("Hello World!"); Out.Ln; 15 | END; 16 | END helloworld. 17 | -------------------------------------------------------------------------------- /oxford/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | Obc-3 modules 12 |
13 |
14 |

15 | Oxford - Not portable 16 |

17 |

18 | DRAFT: sketch of untested code. 19 |

20 |

21 | FIXME: I have not gotten the current Obc-3 to compile under Darwin (macOS). 22 |

23 |

24 | Modules in this directory are being ported to the Obc-3 compiler and should be compiled with the -07 option. 25 |

26 | 34 |

35 | Pre-requisites 36 |

37 |

38 | Debian systems 39 |

40 |
41 |
  sudo apt install build-essential autotools automake autoconf git
42 |   sudo apt install ocaml
43 |   sudo apt install libgtksourceview2.0-dev
44 |   git clone git@github.com:Spivoxity/obc-3
45 |
46 |

47 | NOTE: Unresolved issues on macOS 48 |

49 |

50 | I am currently running into issues compiling these modules on macOS. Not sure if this is specific to my Mac (it is rather vintage) or due to problems with compiler flags. I suspect my Makefile is not calling the right options for macOS compilation. 51 |

52 |
53 | 84 |
85 | copyright (c) 2021 all rights reserved. 86 | Released under the BSD 3-Clause license 87 | See: http://opensource.org/licenses/BSD-3-Clause 88 |
89 | 90 | 91 | -------------------------------------------------------------------------------- /oxford/nav.md: -------------------------------------------------------------------------------- 1 | 2 | + [Home](/) 3 | + [README](../) 4 | + [LICENSE](../license.html) 5 | + [INSTALL](../install.html) 6 | + [OBNC Modules](../obnc/) 7 | + [Obc-3 Modules](./) 8 | + [Ofront+ Modules](../ofrontplus/) 9 | + [development notes](../development-notes.html) 10 | + [Github](https://github.com/rsdoiel/Artemis) 11 | 12 | -------------------------------------------------------------------------------- /oxford/ocat.m: -------------------------------------------------------------------------------- 1 | (** ocat.Mod is inspired by ocat command found in Joseph Templ's in Ofront. 2 | 3 | Copyright (C) 2021 R. S. Doiel This Source Code Form is subject to the terms of the Mozilla PublicLicense, v. 2.0. If a copy of the MPL was not distributed with thisfile, You can obtain one at http://mozilla.org/MPL/2.0/. *) 4 | MODULE ocat; 5 | 6 | (** NOTE: OCat is a POSIX command line program. *) 7 | 8 | IMPORT Args := extArgs, Out, Files, Texts := TextsCmdLn, Chars, Convert := extConvert, Err := extErr; 9 | 10 | CONST 11 | TAB = 9X; 12 | LF = 10X; 13 | CR = 13X; 14 | SPACE = 20X; 15 | TILDE = "~"; 16 | 17 | VAR 18 | tabs : ARRAY 128 OF CHAR; 19 | 20 | (* Usage displays a help screen *) 21 | PROCEDURE Usage(); 22 | BEGIN 23 | Out.String("USAGE OCat [OPTION] FILENAME [[OPTION] FILENAME ...]"); Out.Ln(); 24 | Out.Ln(); 25 | Out.String("Read Oberon Texts and write them to standard out");Out.Ln(); 26 | Out.Ln(); 27 | Out.String("OPTIONS"); Out.Ln(); 28 | Out.Ln(); 29 | Out.String(" -h, --help"); Out.Char(Chars.TAB); Out.String("this help document"); Out.Ln();Out.Ln(); 30 | Out.String(" -t, --tabs"); Out.Char(Chars.TAB); Out.String("Allow tab characters"); Out.Ln(); 31 | Out.String(" --spaces"); Out.Char(Chars.TAB); Out.String("Convert tab characters to four spaces"); Out.Ln(); 32 | Out.String(" --spaces=X"); Out.Char(Chars.TAB); Out.String("Convert tab characters to X number of spaces"); Out.Ln(); 33 | Out.Ln(); 34 | END Usage; 35 | 36 | (* Convert Oberon texts to POSIX friendly standard out *) 37 | PROCEDURE Cat(filename : ARRAY OF CHAR); 38 | VAR T : Texts.Text; R : Texts.Reader; ch : CHAR; skipLF : BOOLEAN; 39 | BEGIN 40 | IF Files.Old(filename) # NIL THEN 41 | Texts.Open(T, filename); 42 | Texts.OpenReader(R, T, 0); 43 | (* FIXME: Need to handle case where this is an Oberon file 44 | and skip beyond the font settings to start of Text *) 45 | Texts.Read(R, ch); 46 | WHILE ~ R.eot DO 47 | IF (ch >= SPACE) & (ch <= TILDE) THEN 48 | Out.Char(ch); 49 | skipLF := FALSE; 50 | ELSIF ch = TAB THEN 51 | Out.String(tabs); 52 | skipLF := FALSE; 53 | ELSIF ch = LF THEN 54 | IF skipLF = TRUE THEN 55 | skipLF := FALSE; 56 | ELSE 57 | Out.Ln(); 58 | END; 59 | ELSIF ch = CR THEN 60 | Out.Ln(); 61 | skipLF := TRUE; 62 | END; 63 | Texts.Read(R, ch); 64 | END; 65 | Out.Ln(); 66 | ELSE 67 | Err.String("Can't open ");Err.String(filename);Err.Ln(); 68 | END; 69 | END Cat; 70 | 71 | (* Apply process POSIX command line parameters and envoke Cat.*) 72 | PROCEDURE Apply(); 73 | VAR i, j, k, res : INTEGER; arg : ARRAY 1024 OF CHAR; ok : BOOLEAN; 74 | BEGIN 75 | IF Args.count = 0 THEN 76 | Out.String("Try OCat --help for explanation of how this works"); Out.Ln(); 77 | ELSE 78 | i := 0; 79 | WHILE i < Args.count DO 80 | Args.Get(i, arg, res); 81 | IF Chars.Equal("-h", arg) OR Chars.Equal("--help", arg) THEN 82 | Usage(); 83 | ELSIF Chars.Equal("-t", arg) OR Chars.StartsWith("--tab", arg) THEN 84 | tabs[0] := Chars.TAB; tabs[1] := 0X; 85 | ELSIF Chars.StartsWith("--spaces=", arg) THEN 86 | Chars.TrimPrefix("--spaces=", arg); 87 | Convert.StringToInt(arg, k, ok); 88 | Chars.Clear(tabs); 89 | j := 0; 90 | WHILE j < k DO tabs[j] := " "; INC(j) END; 91 | tabs[j] := 0X; (* Terminate the tabs array of char *) 92 | ELSIF Chars.Equal("--spaces", arg) THEN 93 | Chars.Clear(tabs); 94 | tabs := " "; 95 | ELSE 96 | Cat(arg); 97 | END; 98 | INC(i); 99 | END; 100 | END; 101 | END Apply; 102 | 103 | BEGIN tabs[0] := Chars.TAB; tabs[1] := 0X; Apply(); 104 | END ocat. 105 | 106 | The POSIX command line version is built with 107 | 108 | obnc -o ocat ocat.Mod 109 | 110 | -------------------------------------------------------------------------------- /page.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ${if(fontmatter)}${if(title)}${title}{else}Project Artemis${endif} 5 | ${else}Project Artemis${endif} 6 | 7 | 8 | 9 | 10 | 11 | ${if(front_matter)} 12 |
13 | ${title} 14 |
15 | ${endif} 16 |
17 | ${content} 18 |
19 | 22 |
23 | copyright (c) 2021 all rights reserved. 24 | Released under the BSD 3-Clause license 25 | See: http://opensource.org/licenses/BSD-3-Clause 26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /ports/Oberon-2_to_Oberon-07.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | Ports, from Oberon-2 to Oberon-07 12 |
13 |
14 |

15 | Oberon-2 to Oberon-07 16 |

17 |

18 | In approaching bringing the full range of historic Oberon-2 modules to Oberon-07 I found it useful to have a rather systematic approach. 19 |

20 |

21 | Steps 22 |

23 |
    24 |
  1. 25 | Review Oberon-2 code and flag (via comments) 26 |
      27 |
    1. 28 | LOOP/EXIT replaced with WHILE, WHILE/ELSE, REPEAT/UNTIL, FOR/DO 29 |
    2. 30 |
    3. 31 | Convert RETURN to a single RETURN at end of functional procedure 32 |
    4. 33 |
    5. 34 | Refactor CASE is not used as a type guard 35 |
    6. 36 |
    7. 37 | Refactor any forward references 38 |
    8. 39 |
    40 |
  2. 41 |
  3. 42 | Refactor LOOP 43 |
  4. 44 |
  5. 45 | Refactor CASE statement 46 |
  6. 47 |
  7. 48 | Refactor RETURN clauses 49 |
  8. 50 |
  9. 51 | Refactor any forward references 52 |
  10. 53 |
  11. 54 | Review and replace use of LONGINT, SHORTINT, LONGREAL 55 |
  12. 56 |
  13. 57 | Update IMPORT, replace missing built-in with Obn2 equivalent 58 |
  14. 59 |
60 |

61 | Review code and flag issues 62 |

63 |

64 | Refactor LOOPS 65 |

66 |

67 | Oberon-07 does away with LOOP while it does allow a WHILE with an ELSE. REPEAT/UNTIL and FOR are also available. 68 |

69 |

70 | Refactor CASE 71 |

72 |

73 | Refactor RETURN 74 |

75 |

76 | Refactor forward references 77 |

78 |

79 | Update IMPORT 80 |

81 |

82 | Add Obn2 to IMPORT line. Replace missing Oberon-2 built-ins with the Obn2 equivallent. 83 |

84 |

85 | Update SHORTINT, LONGINT, LONGREAL 86 |

87 |
88 | 119 |
120 | copyright (c) 2021 all rights reserved. 121 | Released under the BSD 3-Clause license 122 | See: http://opensource.org/licenses/BSD-3-Clause 123 |
124 | 125 | 126 | -------------------------------------------------------------------------------- /ports/Oberon-2_to_Oberon-07.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ports, from Oberon-2 to Oberon-07 3 | --- 4 | 5 | Oberon-2 to Oberon-07 6 | ===================== 7 | 8 | In approaching bringing the full range of historic Oberon-2 modules 9 | to Oberon-07 I found it useful to have a rather systematic approach. 10 | 11 | Steps 12 | ----- 13 | 14 | 1. Review Oberon-2 code and flag (via comments) 15 | a. LOOP/EXIT replaced with WHILE, WHILE/ELSE, REPEAT/UNTIL, FOR/DO 16 | b. Convert RETURN to a single RETURN at end of functional procedure 17 | c. Refactor CASE is not used as a type guard 18 | d. Refactor any forward references 19 | 2. Refactor LOOP 20 | 3. Refactor CASE statement 21 | 4. Refactor RETURN clauses 22 | 5. Refactor any forward references 23 | 6. Review and replace use of LONGINT, SHORTINT, LONGREAL 24 | 7. Update IMPORT, replace missing built-in with Obn2 equivalent 25 | 26 | 27 | Review code and flag issues 28 | --------------------------- 29 | 30 | Refactor LOOPS 31 | -------------- 32 | 33 | Oberon-07 does away with LOOP while it does allow a WHILE with 34 | an ELSE. REPEAT/UNTIL and FOR are also available. 35 | 36 | Refactor CASE 37 | ------------- 38 | 39 | Refactor RETURN 40 | --------------- 41 | 42 | Refactor forward references 43 | --------------------------- 44 | 45 | Update IMPORT 46 | ------------- 47 | 48 | Add `Obn2` to IMPORT line. Replace missing Oberon-2 built-ins with 49 | the `Obn2` equivallent. 50 | 51 | Update SHORTINT, LONGINT, LONGREAL 52 | ---------------------------------- 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /ports/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ports, from Oberon-2 to Oberon-07 3 | --- 4 | 5 | README Ports 6 | ============ 7 | 8 | 9 | The ports directory contains modules that were ported to a 10 | POSIX environment from previous Oberon Systems written in 11 | Oberon-2. The ported code is written in Oberon-7. Where necessary 12 | compatibility modules have been created to minimize the changes 13 | to the ported code. 14 | 15 | - [s3](s3/) contains ports from Native Oberon to Oberon-7 16 | - [v4](v4/) contains ports of Linz V4 code to Oberon-7 17 | 18 | NOTE: Authorship of the modules in this sub directory vary. 19 | They included "ported" code. The "ports" retain their original 20 | authorship, copyright, license, etc. 21 | 22 | Porting Strategy 23 | ---------------- 24 | 25 | 1. [Porting the Oberon Compiler from Oberon to Oberon-07](https://people.inf.ethz.ch/wirth/Oberon/PortingOberon.pdf), Niklaus Wirth, 2007-08-15. 26 | 2. [Differences between Revised Oberon and Oberon](https://people.inf.ethz.ch/wirth/Oberon/Oberon07.pdf), Niklaus Wirth, 2008-03-22 / 2011-07-05 27 | 3. [The Programming Language Oberon](https://people.inf.ethz.ch/wirth/Oberon/Oberon07.Report.pdf), Niklaus Wirth, Revision 2013-10-01 / 2016-05-03 28 | - aka "The Programming Language Oberon-07 (Revised Oberon)" 29 | - Karl Landström provides an [HTML version](http://miasap.se/obnc/oberon-report.html) 30 | 31 | What follows are my notes which might be helpful to others (YMMV). 32 | 33 | The basic data types in Oberon-7 are more limitted. In some cases the 34 | data types could simply be mapped to the newer version of the language. 35 | The built-in procedures and functions are different from Oberon-2 to 36 | Oberon-7. The [Obn2.Mod](Obn2.Mod) provides a small collection of 37 | formerly build-in Oberon-2 function for use in Oberon-7. 38 | 39 | 40 | | Oberon-2 | Oberon-7 | Compatibility | 41 | |:---------|:--------------|:---------------| 42 | | LONGINT | INTEGER | | 43 | | LONGREAL | REAL | | 44 | | SHORTINT | BYTE | | 45 | | ASH | | Obn2.ASH | 46 | | MAX | | Obn2.MAX | 47 | | MIN | | Obn2.MIN | 48 | | ENTIER | FLOOR | Obn2.ENTIER | 49 | | HALT | ASSERT(FALSE) | Obn2.HALT | 50 | | ROT | ROR | Obn2.ROT | 51 | 52 | 53 | POSIX compilers 54 | --------------- 55 | 56 | Artemis and these ports have been developed with two Oberon-7 57 | POSIX based compilers in mind 58 | 59 | - [OBNC](https://) 60 | - [Obc-3](https://github.com/Spivoxity/Obc-3 "aka Oxford Oberon Compiler") 61 | 62 | OBNC advantage is it is realatively easy to port between POSIX systems. 63 | It only requires a good C compiler and optionally SDL 1.2. Obc-3 has the 64 | advantage of also being able to compile both Oberon-2 and Oberon-7 65 | code selectable with a command line flag. This has been used to help 66 | compare behaviors in the language. 67 | 68 | 69 | OBNC 70 | ---- 71 | 72 | Standard compiler envocation, `obnc MODULE_NAME` 73 | 74 | Haven't noticed deviation from Oakwood except Out has some 75 | additional output formats. 76 | 77 | 78 | Oxford Oberon Compiler (obc-3) 79 | ------------------------------ 80 | 81 | Standard compiler envocation, `obc -07 DEP_MODULE_LIST PROG_MODULE -m` 82 | 83 | The latest version on GitHub includes a more Oakwood-ish 84 | implementation of Out and Math modules. 85 | 86 | 87 | -------------------------------------------------------------------------------- /ports/nav.md: -------------------------------------------------------------------------------- 1 | 2 | + [Home](/) 3 | + [README](../) 4 | + [LICENSE](../license.html) 5 | + [INSTALL](../install.html) 6 | + [OBNC Modules](../obnc/) 7 | + [Obc-3 Modules](../oxford/) 8 | + [Ofront+ Modules](../ofrontplus/) 9 | + [development notes](../development-notes.html) 10 | + [Github](https://github.com/rsdoiel/Artemis) 11 | 12 | -------------------------------------------------------------------------------- /ports/s3/Conversions.Mod: -------------------------------------------------------------------------------- 1 | (* ETH Oberon, Copyright 1990-2003 Computer Systems Institute, ETH Zurich, CH-8092 Zurich. 2 | Refer to the license.txt file provided with this distribution. *) 3 | (* Port to Oberon-7 started RSD / 2021.06.04 *) 4 | MODULE Conversions; (** portable *) (** PRK / 20.01.97**) 5 | 6 | (* 7 | This module performs useful conversions between the different formats 8 | 9 | History 10 | 11 | 1.0 / 20.01.96 12 | o IntToStr, StrToInt, RealToStr 13 | o leading zeros removed in base2 conversion to Str 14 | 15 | *) 16 | 17 | IMPORT 18 | Reals, Strings, BIT; 19 | 20 | TYPE 21 | String = ARRAY 34 OF CHAR; 22 | 23 | VAR 24 | Min: ARRAY 16 OF String; 25 | Digit: ARRAY 17 OF CHAR; 26 | 27 | 28 | PROCEDURE BitPatternToStr (val: INTEGER; VAR str: ARRAY OF CHAR; base: INTEGER); 29 | VAR i, j, shift, size: BYTE; 30 | BEGIN 31 | ASSERT ((base=2) OR (base=8) OR (base=16)); 32 | IF base = 2 THEN shift := 1; size := 32 33 | ELSIF base = 8 THEN shift := 3; size := 11 34 | ELSIF base = 16 THEN shift := 4; size := 8 35 | END; 36 | IF LEN(str) < size+1 THEN COPY ("str to short", str); RETURN END; 37 | i := 0; j := 0; 38 | WHILE i < size DO 39 | str[j] := Digit[BIT.LAND(BIT.LLSH(val, (i+1)*shift - 32), base-1)]; 40 | INC (i); 41 | IF (j#0) OR (base#2) OR (str[0]#"0") THEN INC (j) END (* ejz proposal *) 42 | END; 43 | IF j=0 THEN str[0] := "0"; INC (j) END; (* ejz proposal *) 44 | str[j] := 0X; 45 | END BitPatternToStr; 46 | 47 | (** IntToStr -- convert a longint to a representation in a given base (2..16) *) 48 | PROCEDURE IntToStr* (val: LONGINT; VAR str: ARRAY OF CHAR; base: LONGINT); 49 | VAR i, j: LONGINT; digits: ARRAY 32 OF LONGINT; 50 | BEGIN 51 | IF (base <= 1) OR (base > 16) THEN COPY("???", str); RETURN END; 52 | IF (base = 2) OR (base = 16) THEN BitPatternToStr (val, str, base); RETURN END; 53 | IF val = MIN(LONGINT) THEN 54 | COPY (Min[base-1], str); RETURN 55 | END; 56 | IF val < 0 THEN val := -val; str[0] := "-"; j := 1 ELSE j := 0 END; 57 | i := 0; 58 | REPEAT 59 | digits[i] := val MOD base; INC (i); val := val DIV base 60 | UNTIL val = 0; 61 | DEC(i); 62 | WHILE i >= 0 DO 63 | str[j] := Digit[digits[i]]; INC (j); DEC (i) 64 | END; 65 | str[j] := 0X 66 | END IntToStr; 67 | 68 | 69 | (** RealToStr -- convert a longreal to a representation in a given base (2..16) *) 70 | PROCEDURE RealToStr*(x: LONGREAL; VAR s: ARRAY OF CHAR; base: LONGINT); 71 | VAR h, l: LONGINT; d: ARRAY 16 OF CHAR; 72 | 73 | BEGIN 74 | IF (base # 2) & (base # 10) & (base # 16) THEN COPY("???", s); RETURN END; 75 | IF base # 10 THEN 76 | Reals.IntL (x, h, l); 77 | IntToStr (h, s, base); IntToStr (l, d, base); 78 | Strings.Append (s, d); 79 | RETURN 80 | END; 81 | Strings.RealToStr (x, s) 82 | END RealToStr; 83 | 84 | (* ============================================================= *) 85 | PROCEDURE StrToInt* (s: ARRAY OF CHAR; VAR val: LONGINT; base: LONGINT); 86 | VAR j: LONGINT; neg: BOOLEAN; 87 | 88 | PROCEDURE IsOK (ch: CHAR; base: LONGINT): BOOLEAN; 89 | BEGIN 90 | IF Strings.UpperCh(ch) >= "A" THEN 91 | base := base - ORD(Strings.UpperCh(ch)) + ORD ("A") + 10 92 | ELSE 93 | base := base - ORD(ch) + ORD ("0") 94 | END; 95 | RETURN (ch >= "0") & (base > 0) 96 | END IsOK; 97 | 98 | BEGIN 99 | val := 0; j := 0; 100 | IF (base < 2) OR (base > 16) THEN RETURN END; 101 | IF s[j] = "-" THEN neg := TRUE; INC (j) END; 102 | WHILE IsOK(s[j], base) DO 103 | val := val * base; 104 | IF s[j] <= "9" THEN val := val+ ORD(s[j])-ORD("0") 105 | ELSE val := val + ORD(s[j])-ORD("7") 106 | END; 107 | INC (j) 108 | END; 109 | IF neg THEN val := -val END 110 | END StrToInt; 111 | 112 | 113 | BEGIN 114 | Min[0] := "???"; 115 | Min[1] := "10000000000000000000000000000000"; 116 | Min[2] := "???"; 117 | Min[3] := "???"; 118 | Min[4] := "???"; 119 | Min[5] := "???"; 120 | Min[6] := "???"; 121 | Min[7] := "???"; 122 | Min[8] := "???"; 123 | Min[9] := "-2147483648"; 124 | Min[10] := "???"; 125 | Min[11] := "???"; 126 | Min[12] := "???"; 127 | Min[13] := "???"; 128 | Min[14] := "???"; 129 | Min[15] := "80000000"; 130 | Digit := "0123456789ABCDEF"; 131 | END Conversions. 132 | 133 | 134 | -------------------------------------------------------------------------------- /ports/s3/README.md: -------------------------------------------------------------------------------- 1 | S3, Native Oberon ports 2 | ======================= 3 | 4 | This directory is for modules ported (or being ported) from 5 | Native Oberon 2.3.7. The original was Oberon-2 and is 6 | being ported to the Oberon-7. 7 | 8 | NOTE: Be mindful of information such as author, copyright and licenses 9 | maintained in the comments at the start of each module. 10 | 11 | -------------------------------------------------------------------------------- /ports/s3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | … 12 |
13 |
14 |

15 | S3, Native Oberon ports 16 |

17 |

18 | This directory is for modules ported (or being ported) from Native Oberon 2.3.7. The original was Oberon-2 and is being ported to the Oberon-7. 19 |

20 |

21 | NOTE: Be mindful of information such as author, copyright and licenses maintained in the comments at the start of each module. 22 |

23 |
24 | 27 |
28 | copyright (c) 2021 all rights reserved. 29 | Released under the BSD 3-Clause license 30 | See: http://opensource.org/licenses/BSD-3-Clause 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /ports/v4/README.md: -------------------------------------------------------------------------------- 1 | 2 | V4, Linz Oberon 3 | =============== 4 | 5 | This directory is for modules ported (or being ported) from 6 | Linz Oberon also known as V4. The original was Oberon-2 and is 7 | being ported to the Oberon-7. 8 | 9 | NOTE: Be mindful of information such as author, copyright and licenses 10 | maintained in the comments at the start of each module. 11 | 12 | -------------------------------------------------------------------------------- /ports/v4/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Project Artemis 5 | 6 | 7 | 8 | 9 | 10 |
11 | … 12 |
13 |
14 |

15 | V4, Linz Oberon 16 |

17 |

18 | This directory is for modules ported (or being ported) from Linz Oberon also known as V4. The original was Oberon-2 and is being ported to the Oberon-7. 19 |

20 |

21 | NOTE: Be mindful of information such as author, copyright and licenses maintained in the comments at the start of each module. 22 |

23 |
24 | 27 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /posix/Display.Mod: -------------------------------------------------------------------------------- 1 | (** Display.Mod impements a minimal set of procedures and 2 | exported variables to support porting the Native Oberon 2.3.6 3 | codebase envolved with Texts.Mod *) 4 | MODULE Display; 5 | 6 | END Display. 7 | -------------------------------------------------------------------------------- /posix/Kernel.Mod: -------------------------------------------------------------------------------- 1 | (** Kernel.Mod this is a compatibility module to 2 | allow us to port modules requiring specific Kernel 3 | functionality in a POSIX environment *) 4 | MODULE Kernel 5 | 6 | (*------------------- Miscellaneous Procedures from PO 2013 ------------*) 7 | 8 | (** Time exposes the Unix time value *) 9 | PROCEDURE Time*() : INTEGER; 10 | BEGIN 11 | END Time; 12 | 13 | (** Exposes returns the Unix time (epoch) *) 14 | PROCEDURE Clock*() : INTEGER; 15 | BEGIN 16 | END Clock; 17 | 18 | (** SetClock sets the clock given an INTEGER prepresentation 19 | of the date and time. NOTE: Most Linux will not allow you 20 | to set the clock from regular userspace. *) 21 | PROCEDURE SetClock*(dt: INTEGER); 22 | BEGIN 23 | END SetClock; 24 | 25 | (** Initialize the Kernel space *) 26 | PROCEDURE Init*; 27 | BEGIN 28 | END Init; 29 | 30 | END Kernel. 31 | -------------------------------------------------------------------------------- /publish.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | 4 | WORKING_BRANCH=$(git branch | grep '* ' | cut -d \ -f 2) 5 | if [ "$WORKING_BRANCH" = "gh-pages" ]; then 6 | git commit -am "publishing to gh-pages branch" 7 | git push origin gh-pages 8 | else 9 | echo "You're in $WORKING_BANCH branch" 10 | echo "You need to pull in changes to the gh-pages branch to publish" 11 | read -p "Pull into gh-pages and publish? Y/N " YES_NO 12 | if [ "$YES_NO" = "Y" ] || [ "$YES_NO" = "y" ]; then 13 | echo "Committing and pushing to $WORKING_BRANCH" 14 | git commit -am "commiting to $WORKING_BANCH"; 15 | git push origin "$WORKING_BRANCH"; 16 | echo "Changing branchs from $WORKING_BRANCH to gh-pages"; 17 | git checkout gh-pages 18 | echo "Merging changes from origin gh-pages" 19 | git pull origin gh-pages 20 | git commit -am "merging origin gh-pages" 21 | echo "Pulling changes from $WORKING_BRANCH info gh-pages" 22 | git pull origin "$WORKING_BRANCH" 23 | echo "Merging changes from $WORKING_BRANCH" 24 | git commit -am "merging $WORKING_BRANCH with gh-pages" 25 | echo "Pushing changes up and publishing" 26 | git push origin gh-pages 27 | echo "Changing back to your working branch $WORKING_BRANCH" 28 | git checkout "$WORKING_BRANCH" 29 | fi 30 | fi 31 | -------------------------------------------------------------------------------- /setup.bat: -------------------------------------------------------------------------------- 1 | SET PATH=%PATH%;C:\Program Files (x86)\OBNC 2 | --------------------------------------------------------------------------------