From 9423fb1b376c2dfdef5f7c3076722c0a43f89783 Mon Sep 17 00:00:00 2001 From: mane Date: Thu, 2 Apr 2020 23:20:19 +0400 Subject: [PATCH] Module renaming --- vpkCharacterStack.Mod | 121 +++++++++++++++ vpkDependencyResolver.Mod | 116 +++++++++++++++ vpkFileManager.Mod | 81 ++++++++++ vpkHttp.Mod | 144 ++++++++++++++++++ vpkInternet.Mod | 102 +++++++++++++ vpkJsonParser.Mod | 304 ++++++++++++++++++++++++++++++++++++++ vpkLogger.Mod | 82 ++++++++++ vpkNetdb.Mod | 79 ++++++++++ vpkPackageFileParser.Mod | 34 +++++ vpkPackageResolver.Mod | 50 +++++++ vpkRemoteClient.Mod | 6 + vpkSettings.Mod | 8 + vpkSockets.Mod | 157 ++++++++++++++++++++ vpkStringHelpers.Mod | 243 ++++++++++++++++++++++++++++++ vpkTest.Mod | 15 ++ vpkTime.Mod | 30 ++++ vpkTypes.Mod | 41 +++++ vpkUserDetails.Mod | 16 ++ 18 files changed, 1629 insertions(+) create mode 100644 vpkCharacterStack.Mod create mode 100644 vpkDependencyResolver.Mod create mode 100644 vpkFileManager.Mod create mode 100644 vpkHttp.Mod create mode 100644 vpkInternet.Mod create mode 100644 vpkJsonParser.Mod create mode 100644 vpkLogger.Mod create mode 100644 vpkNetdb.Mod create mode 100644 vpkPackageFileParser.Mod create mode 100644 vpkPackageResolver.Mod create mode 100644 vpkRemoteClient.Mod create mode 100644 vpkSettings.Mod create mode 100644 vpkSockets.Mod create mode 100644 vpkStringHelpers.Mod create mode 100644 vpkTest.Mod create mode 100644 vpkTime.Mod create mode 100644 vpkTypes.Mod create mode 100644 vpkUserDetails.Mod diff --git a/vpkCharacterStack.Mod b/vpkCharacterStack.Mod new file mode 100644 index 0000000..b79c2ae --- /dev/null +++ b/vpkCharacterStack.Mod @@ -0,0 +1,121 @@ +MODULE vpkCharacterStack; +IMPORT List, Out, Sys; + +TYPE + integer* = Sys.integer; + TObject* = Sys.TObject; + + Node* = POINTER TO NodeDesc; + NodeDesc* = List.NodeDesc; + + TChar* = POINTER TO TCharDesc; + + TCharDesc = RECORD (Sys.TObjectDesc) + char* : CHAR + END; + + string = Sys.string; + + CharacterStackType* = POINTER TO CharacterStackTypeDesc; + + CharacterStackTypeDesc* = RECORD (List.TListDesc) + pop*: PROCEDURE(self: CharacterStackType): CHAR; + push*: PROCEDURE(self: CharacterStackType; char: CHAR); + top*: PROCEDURE(self: CharacterStackType) : CHAR; + END; + +VAR + characterStack: CharacterStackType; + +PROCEDURE push(self: CharacterStackType; char: CHAR); +VAR + ch: TChar; + int: integer; +BEGIN + NEW(ch); + ch.char := char; + int := self.Add(self, ch); +END push; + +PROCEDURE pop(self: CharacterStackType): CHAR; +VAR + n: Node; +BEGIN + NEW(n); + + IF self.Count = 0 THEN RETURN 0X END; + + n := self.Get(self, self.Count - 1); + self.Delete(self, self.Count - 1); + RETURN n.obj(TChar).char; +END pop; + +PROCEDURE top(self: CharacterStackType): CHAR; +VAR + n: Node; +BEGIN + NEW(n); + + IF self.Count = 0 THEN RETURN 0X END; + + n := self.Get(self, self.Count - 1); + RETURN n.obj(TChar).char; +END top; + +PROCEDURE Create* () : CharacterStackType; +VAR + l : CharacterStackType; +BEGIN + NEW(l); + l.First := NIL; + l.Last := NIL; + l.Count := 0; + l.Add := List.Add; + l.Append := List.Append; + l.AppendList := List.AppendList; + l.Clear := List.Clear; + l.Free := List.Free; + l.Insert := List.Insert; + l.Delete := List.Delete; + l.Empty := List.Empty; + l.Get := List.Get; + l.res := TRUE; + + l.pop := pop; + l.push:= push; + l.top := top; + RETURN(l); +END Create; + +BEGIN + (* NEW(characterStack); + characterStack := Create(); + characterStack.push(characterStack, 'a'); + characterStack.push(characterStack, 'b'); + characterStack.push(characterStack, 'c'); + + Out.Char(characterStack.top(characterStack)); + Out.Ln(); + Out.Char(characterStack.pop(characterStack)); + Out.Ln(); + Out.Char(characterStack.top(characterStack)); + Out.Ln(); + Out.Char(characterStack.pop(characterStack)); + Out.Ln(); + Out.Char(characterStack.top(characterStack)); + Out.Ln(); + Out.Char(characterStack.pop(characterStack)); + Out.Ln(); + Out.Char(characterStack.top(characterStack)); + Out.Ln(); + Out.Char(characterStack.pop(characterStack)); + Out.Ln(); + Out.Char(characterStack.top(characterStack)); + Out.Ln(); + Out.Char(characterStack.pop(characterStack)); + Out.Ln(); + Out.Char(characterStack.top(characterStack)); + Out.Ln(); + Out.Char(characterStack.pop(characterStack)); + Out.Ln(); *) +END vpkCharacterStack. diff --git a/vpkDependencyResolver.Mod b/vpkDependencyResolver.Mod new file mode 100644 index 0000000..6fa9939 --- /dev/null +++ b/vpkDependencyResolver.Mod @@ -0,0 +1,116 @@ +MODULE vpkDependencyResolver; +IMPORT vpkJsonParser, vpkSettings, vpkPackageResolver, Strings, vpkLogger; + +CONST ArrayMaxNumber = 30; + +VAR + moduleNames: ARRAY ArrayMaxNumber OF vpkJsonParser.TString; + moduleJson: ARRAY ArrayMaxNumber OF vpkJsonParser.TString; + moduleVersions: ARRAY ArrayMaxNumber OF vpkJsonParser.TString; + + j : LONGINT; + +PROCEDURE ResolveVersionFiles *(jsonString: ARRAY OF CHAR); +VAR + jsonRecord, dependencies: vpkJsonParser.JsonTypePointer; + keyFound: BOOLEAN; + packageName, version, filePath: ARRAY 32 OF CHAR; + returnedJSON: vpkJsonParser.TString; + keys: ARRAY ArrayMaxNumber OF vpkJsonParser.TString; + i, k : LONGINT; +BEGIN + jsonRecord := vpkJsonParser.Create(jsonString); + keyFound := jsonRecord.GetTerminal(jsonRecord, "Package", packageName); + IF keyFound THEN + vpkLogger.Log("Parsing package by name"); + vpkLogger.Log(packageName); + vpkLogger.Log("------------------------"); + ELSE vpkLogger.Log("Value for the Key is not found"); RETURN; END; + + dependencies := jsonRecord.GetNonTerminal(jsonRecord, "Dependencies"); + + IF dependencies = NIL THEN + vpkLogger.Log("Parsing package by name"); + vpkLogger.Log(packageName); + vpkLogger.Log("Error"); + vpkLogger.Log("No dependency"); + vpkLogger.Log("------------------------"); + END; + + dependencies.GetTerminalKeys(dependencies, keys); + + FOR i := 0 TO dependencies.TerminalNumber - 1 DO (* TODO: rewrite with working getter everywhere*) + keyFound := dependencies.GetTerminal(dependencies, keys[i], version); + + IF ~keyFound THEN vpkLogger.Log('ERROR while searching key'); vpkLogger.Log(keys[i]); END; + ASSERT(keyFound); + + COPY("", filePath); + Strings.Append("/", filePath); + Strings.Append(keys[i], filePath); + Strings.Append("/", filePath); + Strings.Append(version, filePath); + Strings.Append("/", filePath); + Strings.Append(vpkSettings.packageFileName, filePath); + + vpkJsonParser.Empty(returnedJSON); + + vpkPackageResolver.ResolveFile( + vpkSettings.host, + vpkSettings.port, + filePath, + keys[i], + vpkSettings.packageFileName, + returnedJSON + ); + + keyFound := FALSE; + IF j >= LEN(moduleNames) THEN + vpkLogger.Log("Out of range in ResolveVersionFiles function in ..."); + END; + ASSERT(j < LEN(moduleNames)); + + FOR k := 0 TO j - 1 DO + IF Strings.Match(moduleNames[k], keys[i]) THEN + keyFound := TRUE; + END; + END; + + + IF ~keyFound THEN + COPY(keys[i], moduleNames[j]); + COPY(version, moduleVersions[j]); + COPY(returnedJSON, moduleJson[j]); + INC(j); + ResolveVersionFiles(returnedJSON); + END; + END; +END ResolveVersionFiles; + +PROCEDURE ResolvePackages*(); +VAR + i: LONGINT; + keyFound: BOOLEAN; + jsonRecord, filesRecord: vpkJsonParser.JsonTypePointer; + values: ARRAY 10 OF vpkJsonParser.TString; + host, port, path, packageName, version: ARRAY 50 OF CHAR; +BEGIN + FOR i := 0 TO j - 1 DO + jsonRecord := vpkJsonParser.Create(moduleJson[i]); + filesRecord := jsonRecord.GetNonTerminal(jsonRecord, "Files"); + + IF filesRecord = NIL THEN + vpkLogger.Log("Error: no files section found"); + END; + + ASSERT(filesRecord # NIL); + keyFound := jsonRecord.GetTerminal(jsonRecord, "Remote", host); + keyFound := jsonRecord.GetTerminal(jsonRecord, "Port", port); + keyFound := jsonRecord.GetTerminal(jsonRecord, "Path", path); + keyFound := jsonRecord.GetTerminal(jsonRecord, "Package", packageName); + keyFound := jsonRecord.GetTerminal(jsonRecord, "Version", version); + vpkPackageResolver.Resolve(host, port, path, packageName, version, filesRecord.TerminalValues); (* TODO: filesRecord.TerminalValues create working getter for this*) + END; +END ResolvePackages; + +END vpkDependencyResolver. diff --git a/vpkFileManager.Mod b/vpkFileManager.Mod new file mode 100644 index 0000000..6db0ee2 --- /dev/null +++ b/vpkFileManager.Mod @@ -0,0 +1,81 @@ +MODULE vpkFileManager; +IMPORT Files, Out, vpkLogger, Strings, Platform; + +PROCEDURE WriteString(VAR r : Files.Rider; str : ARRAY OF CHAR); +BEGIN + Files.WriteBytes(r, str, Strings.Length(str)); +END WriteString; + +PROCEDURE Read*(fileName: ARRAY OF CHAR; VAR returnString: ARRAY OF CHAR): BOOLEAN; +VAR + f: Files.File; + r: Files.Rider; + i: LONGINT; +BEGIN + f := Files.Old(fileName); + + IF f = NIL THEN + vpkLogger.Log("-------------------"); + vpkLogger.Log("File Name"); + vpkLogger.Log(fileName); + vpkLogger.Log("File not found"); + vpkLogger.Log("-------------------"); + RETURN FALSE + END; + + Files.Set(r, f, 0); + + i := 0; + REPEAT + Files.Read(r, returnString[i]); + INC(i); + UNTIL r.eof OR (i>=LEN(returnString)); + + RETURN TRUE; +END Read; + +PROCEDURE Write*(fileName, content: ARRAY OF CHAR): BOOLEAN; +VAR + f: Files.File; + r: Files.Rider; + i: LONGINT; +BEGIN + f := Files.New(fileName); + + IF f = NIL THEN + vpkLogger.Log("-------------------"); + vpkLogger.Log("File Name"); + vpkLogger.Log(fileName); + vpkLogger.Log("File not found"); + vpkLogger.Log("-------------------"); + RETURN FALSE + END; + + Files.Set(r, f, 0); + vpkLogger.Log("Writing to file"); + vpkLogger.Log(fileName); + vpkLogger.Log("-------------------"); + WriteString(r, content); + + Files.Register(f); + + RETURN TRUE; +END Write; + +PROCEDURE CreateDirectory*(name, path: ARRAY OF CHAR): BOOLEAN; +VAR + command, path0: ARRAY 100 OF CHAR; + errorCode: LONGINT; +BEGIN + COPY(path, path0); + COPY("mkdir -p ", command); + Strings.Append("/", path0); + Strings.Append(name, path0); + Strings.Append(path0, command); + errorCode := Platform.System(command); + + IF errorCode = 0 THEN RETURN TRUE + ELSE RETURN FALSE END; +END CreateDirectory; + +END vpkFileManager. diff --git a/vpkHttp.Mod b/vpkHttp.Mod new file mode 100644 index 0000000..94a85c5 --- /dev/null +++ b/vpkHttp.Mod @@ -0,0 +1,144 @@ +MODULE vpkHttp; +IMPORT Strings, vpkInternet, vpkLogger, Out; +CONST + MAXARRAYNUMBER = 10000; + MAXARRAYNUMBEREXTENDED = 100000; + +TYPE + PSTRING = POINTER TO ARRAY OF CHAR; + +VAR + buff, buff2: ARRAY MAXARRAYNUMBEREXTENDED OF CHAR; + +PROCEDURE Empty *(VAR string: ARRAY OF CHAR); +VAR + i : LONGINT; +BEGIN + FOR i := 0 TO LEN(string) - 1 DO string[i] := 0X END; + COPY("", string); +END Empty; + +PROCEDURE getClean *(buff: ARRAY OF CHAR; VAR clean: ARRAY OF CHAR); +VAR + i: INTEGER; + newLine: ARRAY 2 OF CHAR; + lineIsHeader, EOL, notFirstLine: BOOLEAN; +BEGIN + i := 0; + notFirstLine := FALSE; + lineIsHeader := FALSE; + EOL := FALSE; + + REPEAT + IF EOL THEN + lineIsHeader := FALSE; + EOL := FALSE; + notFirstLine := TRUE + END; + + IF buff[i] = ":" THEN lineIsHeader := TRUE END; + + IF ((buff[i - 1] = 0DX) & (buff[i] = 0AX)) THEN EOL := TRUE END; + + INC(i); + UNTIL (i + 2 > Strings.Length(buff)) OR (~lineIsHeader & EOL & notFirstLine); + + Strings.Extract(buff, i, Strings.Length(buff), clean); +END getClean; + +PROCEDURE AppendEOLAndClean(buff: ARRAY OF CHAR; VAR buffClean: PSTRING); +VAR i: LONGINT; +BEGIN + i := Strings.Length(buff); + + NEW(buffClean, i + 3); + + COPY(buff, buffClean^); + + buffClean[i] := 0DX; + buffClean[i + 1] := 0AX; + buffClean[i + 2] := " "; +END AppendEOLAndClean; + +PROCEDURE addHeader(key, val: ARRAY OF CHAR; VAR buff: PSTRING); +VAR + header: ARRAY MAXARRAYNUMBER OF CHAR; +BEGIN + Empty(header); + Strings.Append(key, header); + Strings.Append(": ", header); + Strings.Append(val, header); + AppendEOLAndClean(header, buff); +END addHeader; + +PROCEDURE getHeader(buff, key: ARRAY OF CHAR; VAR val: ARRAY OF CHAR); +VAR + positionStart, valPositionStart, i: LONGINT; +BEGIN + positionStart := Strings.Pos(key, buff, 0); + valPositionStart := positionStart + Strings.Length(key) + 1; + i := 0; + REPEAT + val[i] := buff[valPositionStart + i]; + INC(i); + UNTIL (ORD(val[i]) = 10) (* 0DX number(newline)*) OR + (i > Strings.Length(buff)); +END getHeader; + +PROCEDURE get *(host, port, path: ARRAY OF CHAR; VAR buff: ARRAY OF CHAR); +VAR + socket : vpkInternet.Socket; + connectionFlag: BOOLEAN; + valueContentLength: REAL; + send, valueContentLengthString: ARRAY MAXARRAYNUMBER OF CHAR; + sendClean: PSTRING; + httpTail: ARRAY 16 OF CHAR; + endOfLine: ARRAY 3 OF CHAR; + tmpBuff: ARRAY MAXARRAYNUMBER OF CHAR; +BEGIN + Empty( buff); + httpTail := " HTTP/1.1"; + + connectionFlag := vpkInternet.Connect(host, port, socket); + + send := "GET "; + + Strings.Append(path, send); + Strings.Append(httpTail, send); + + + AppendEOLAndClean(send, sendClean); + connectionFlag := vpkInternet.Write(socket, sendClean^); + + addHeader("HOST", host, sendClean); + connectionFlag := vpkInternet.Write(socket, sendClean^); + + addHeader("User-Agent", "oberon-http-client/1.0", sendClean); + connectionFlag := vpkInternet.Write(socket, sendClean^); + + addHeader("Accept", "*/*", sendClean); + connectionFlag := vpkInternet.Write(socket, sendClean^); + + AppendEOLAndClean("", sendClean); + connectionFlag := vpkInternet.Write(socket, sendClean^); + REPEAT + Empty( tmpBuff); + + connectionFlag := vpkInternet.Read(socket, tmpBuff); + Strings.Append(tmpBuff, buff); + getHeader(buff, "Content-Length", valueContentLengthString); + Strings.StrToReal(valueContentLengthString, valueContentLength); + (* Out.Real(valueContentLength, 6); + Out.Ln; + vpkLogger.LogIntLn(Strings.Length(buff)); + *) + (* vpkLogger.Log(buff); *) + UNTIL ~connectionFlag OR (Strings.Length(buff) > valueContentLength); + vpkInternet.Disconnect(socket); +END get; + +BEGIN + (* get("norayr.am", "/tmp/", "80", buff); + getClean(buff, buff2); + vpkLogger.Log(buff2); *) +END vpkHttp. diff --git a/vpkInternet.Mod b/vpkInternet.Mod new file mode 100644 index 0000000..820f8bc --- /dev/null +++ b/vpkInternet.Mod @@ -0,0 +1,102 @@ +MODULE vpkInternet; (*noch 14.4.2017 / 14.4.2017*) +IMPORT vpkSockets, vpkNetdb, vpkTypes, Strings, Out, Platform, SYSTEM; + +TYPE + + Socket* = LONGINT; (* INT32 *) + + Int16 = vpkTypes.Int16; + Int32 = vpkTypes.Int32; + Int64 = vpkTypes.Int64; + +PROCEDURE Write*(fd: Socket; buf: ARRAY OF CHAR): BOOLEAN; +VAR + l: SYSTEM.ADDRESS; + r: INTEGER; + len: LONGINT; +BEGIN + l := SYSTEM.ADR(buf[0]); + len := Strings.Length(buf)-1; + r := Platform.Write(fd, l, len); + IF r = -1 THEN + (*Out.String("write() failed."); Out.Ln;*) + RETURN FALSE + ELSE + (*Out.String("write() success."); Out.Ln;*) + RETURN TRUE + END; +END Write; + +PROCEDURE Read*(fd: Socket; VAR buf: ARRAY OF CHAR): BOOLEAN; +VAR + p: SYSTEM.ADDRESS; + l, f: LONGINT; + r: INTEGER; +BEGIN + p := SYSTEM.ADR(buf[0]); + l := LEN(buf)-1; + f := 0; + r := Platform.Read(fd, p, l, f); + IF r >= 0 THEN RETURN TRUE ELSE RETURN FALSE END +END Read; + +PROCEDURE Connect*(host, port: ARRAY OF CHAR; VAR conn: Socket): BOOLEAN; +VAR + hints, res : vpkNetdb.addrInfo; + pres, pres2, phints: vpkNetdb.PaddrInfo; + tmpaddr : SYSTEM.ADDRESS; + tmp32 : vpkNetdb.Int32; + (*conn : vpkNetdb.Int32;*) +BEGIN + hints.aiFamily := vpkSockets.AfUnspec; + hints.aiSockType := vpkSockets.SockStream; + hints.aiFlags := 0; + hints.aiProtocol := vpkNetdb.ipprotoTCP; + hints.aiAddrLen := 0; + hints.aiAddr := 0; hints.aiCanonName := 0; hints.aiNext := 0; + + phints := SYSTEM.VAL(vpkNetdb.PaddrInfo, SYSTEM.ADR(hints)); + pres := SYSTEM.VAL(vpkNetdb.PaddrInfo, SYSTEM.ADR(res)); + pres2 := SYSTEM.VAL(vpkNetdb.PaddrInfo, SYSTEM.ADR(pres)); + + tmp32 := vpkNetdb.getAddrInfo(host, port, phints, pres2); + + IF tmp32 # 0 THEN + Out.String("getaddrinfo() failed"); Out.Ln; + HALT(1); + ELSE + Out.String("getaddrinfo() returned 0, success"); Out.Ln; + END; + + conn := vpkSockets.Socket(pres^.aiFamily, pres^.aiSockType, pres^.aiProtocol); + + IF conn = -1 THEN + Out.String("socket() returned -1, error"); Out.Ln; + HALT(1); + ELSE + Out.String("socket() succeeded."); Out.Ln; + END; + + tmpaddr := SYSTEM.ADR(pres^.aiAddr); + + tmp32 := vpkSockets.Connect(conn, pres^.aiAddr, pres^.aiAddrLen); + vpkNetdb.freeAddrInfo(pres); + IF tmp32 = 0 THEN + Out.String("connect() succeeded."); Out.Ln; + RETURN TRUE + ELSE + Out.String("connect() failed."); Out.Ln; + RETURN FALSE + END; + + +END Connect; + +PROCEDURE Disconnect*(VAR fd: Socket); +VAR + i : INTEGER; +BEGIN +i := Platform.Close(fd); +END Disconnect; + +END vpkInternet. diff --git a/vpkJsonParser.Mod b/vpkJsonParser.Mod new file mode 100644 index 0000000..93af9d6 --- /dev/null +++ b/vpkJsonParser.Mod @@ -0,0 +1,304 @@ +MODULE vpkJsonParser; +IMPORT vpkLogger, vpkCharacterStack, Strings, Out, strutils, vpkSettings; +CONST + ArrayMaxNumber = 30; + ArrayMaxNumberChar = 2000; + (* Const *) + symbolBracketStart = "{"; + symbolBracketEnd = "}"; + (* TODO: Reverse " and ' *) + quote = vpkSettings.quote; + coma = ","; +TYPE + TString* = ARRAY ArrayMaxNumberChar OF CHAR; + + JsonTypePointer* = POINTER TO JsonType; + + JsonType* = RECORD + GetTerminal* : PROCEDURE(self : JsonTypePointer; string : ARRAY OF CHAR; VAR returnValue : ARRAY OF CHAR): BOOLEAN; + GetNonTerminal* : PROCEDURE(self : JsonTypePointer; key : ARRAY OF CHAR): JsonTypePointer; + HasKey* : PROCEDURE(self : JsonTypePointer; key : ARRAY OF CHAR): BOOLEAN; + TypeOfTheKey* : PROCEDURE(self : JsonTypePointer; key : ARRAY OF CHAR; VAR returnValue : ARRAY OF CHAR); + GetTerminalKeys* : PROCEDURE(self : JsonTypePointer; VAR destination : ARRAY OF TString); + GetTerminalValues* : PROCEDURE(self : JsonTypePointer; VAR destination : ARRAY OF TString); + GetNoneTerminalKeys* : PROCEDURE(self : JsonTypePointer; VAR destination : ARRAY OF TString); + GetTerminalNumber* : PROCEDURE(self : JsonTypePointer): LONGINT; + GetNonTerminalNumber* : PROCEDURE(self : JsonTypePointer): LONGINT; + + TerminalKeys : ARRAY ArrayMaxNumber OF TString; + TerminalValues* : ARRAY ArrayMaxNumber OF TString; + TerminalNumber* : LONGINT; + + NonTerminalKeys : ARRAY ArrayMaxNumber OF TString; + NonTerminalValues : POINTER TO ARRAY OF JsonTypePointer; + NonTerminalNumber* : LONGINT; + END; + +VAR + jsonRecord: JsonTypePointer; + testValue: ARRAY ArrayMaxNumber OF CHAR; + keyFound: BOOLEAN; + +PROCEDURE GetTerminalNumber*(self : JsonTypePointer): LONGINT; +BEGIN RETURN self.TerminalNumber END GetTerminalNumber; + +PROCEDURE GetNonTerminalNumber*(self : JsonTypePointer): LONGINT; +BEGIN RETURN self.NonTerminalNumber END GetNonTerminalNumber; + +PROCEDURE GetNonTerminal(self : JsonTypePointer; key : ARRAY OF CHAR): JsonTypePointer; +VAR + i: LONGINT; +BEGIN + FOR i := 0 TO self.NonTerminalNumber - 1 DO + IF Strings.Match(key, self.NonTerminalKeys[i]) THEN RETURN self.NonTerminalValues[i] END; + END; + + RETURN NIL; +END GetNonTerminal; + +PROCEDURE Empty *(VAR string: ARRAY OF CHAR); +VAR + i : LONGINT; +BEGIN + FOR i := 0 TO LEN(string) - 1 DO string[i] := 0X END; + COPY("", string); +END Empty; + +PROCEDURE GetTerminal *(self: JsonTypePointer; key: ARRAY OF CHAR; VAR returnValue: ARRAY OF CHAR): BOOLEAN; +VAR + i: LONGINT; + noneTerminal: JsonTypePointer; + strings: strutils.strings; + parent, children: ARRAY ArrayMaxNumber OF CHAR; +BEGIN + + FOR i := 0 TO self.TerminalNumber DO + IF Strings.Match(key, self.TerminalKeys[i]) THEN COPY(self.TerminalValues[i], returnValue); RETURN TRUE END; + END; + + strings := strutils.tokenize(key, '.'); + + IF LEN(strings^) < 1 THEN RETURN FALSE END; + + COPY(strings^[0], parent); + + IF Strings.Length(parent) < 1 THEN RETURN FALSE END; + + noneTerminal := self.GetNonTerminal(self, parent); + + IF noneTerminal = NIL THEN RETURN FALSE END; + + FOR i := 1 TO LEN(strings^) - 1 DO + Strings.Append(strings[i], children); + IF i < LEN(strings^) - 1 THEN + Strings.Append(".", children); + END; + END; + + RETURN noneTerminal.GetTerminal(noneTerminal, children, returnValue); + + RETURN FALSE; +END GetTerminal; + +PROCEDURE GetTerminalKeys(self : JsonTypePointer; VAR destination : ARRAY OF TString); +VAR + i: LONGINT; +BEGIN + FOR i := 0 TO self.TerminalNumber DO + COPY(self.TerminalKeys[i], destination[i]); + END; +END GetTerminalKeys; + +PROCEDURE GetTerminalValues(self : JsonTypePointer; VAR destination : ARRAY OF TString); +VAR + i: LONGINT; +BEGIN + FOR i := 0 TO self.TerminalNumber - 1 DO + Empty(destination[i]); + COPY(self.TerminalValues[i], destination[i]); + END; +END GetTerminalValues; + +PROCEDURE GetNoneTerminalKeys(self : JsonTypePointer; VAR destination : ARRAY OF TString); +VAR + i: LONGINT; +BEGIN + FOR i := 0 TO LEN(self.NonTerminalKeys) - 1 DO + destination[i] := self.NonTerminalKeys[i]; + END; +END GetNoneTerminalKeys; +(* + TODO: + Create a good validation for comas + Create a good validation for name repetition +*) + +PROCEDURE PushDownString( + string: ARRAY OF CHAR; + startCharacter: CHAR; + endCharacter: CHAR; + i: LONGINT; + VAR returnString: ARRAY OF CHAR): LONGINT; +VAR + characterStack: vpkCharacterStack.CharacterStackType; + j , k: LONGINT; +BEGIN + NEW(characterStack); + j := i; + characterStack := vpkCharacterStack.Create(); + Empty(returnString); + REPEAT + IF (characterStack.Count > 1) & (string[j] = endCharacter) THEN + REPEAT UNTIL characterStack.pop(characterStack) = startCharacter; + ELSE + characterStack.push(characterStack, string[j]); + INC(j); + END; + UNTIL characterStack.Count = 0; (* do not trust top it btings OAX on EOL*) + + IF j >= LEN(returnString) THEN + vpkLogger.Log('ERROR string out of range in JSON parser'); + END; + ASSERT(j < LEN(returnString)); + + FOR k := i TO j DO + returnString[k - i] := string[k]; + END; + + RETURN j; (* returning next symbol of quote *) +END PushDownString; + +PROCEDURE deQuote(text: ARRAY OF CHAR; VAR result: ARRAY OF CHAR); +VAR + i, j: LONGINT; +BEGIN + j := 0; + FOR i := 0 TO Strings.Length(text) DO + IF text[i] # quote THEN + result[j] := text[i]; + INC(j); + END; + END; +END deQuote; + +PROCEDURE Create*(text: ARRAY OF CHAR): JsonTypePointer; +VAR + self: JsonTypePointer; + i, j, terminalIterator, noneTerminalIterator: LONGINT; + characterStack: vpkCharacterStack.CharacterStackType; + key, val, nonTerminalVal, string: ARRAY ArrayMaxNumberChar OF CHAR; + symbol: CHAR; + symbolStart: CHAR; + quoteStart: BOOLEAN; +BEGIN + NEW(self); + NEW(self.NonTerminalValues, ArrayMaxNumber); + self.GetTerminal := GetTerminal; + self.GetNonTerminal := GetNonTerminal; + self.GetTerminalKeys := GetTerminalKeys; + self.GetNoneTerminalKeys := GetNoneTerminalKeys; + NEW(characterStack); + characterStack := vpkCharacterStack.Create(); + + i := 0; + j := 0; + terminalIterator := 0; + noneTerminalIterator := 0; + + Empty(key); + Empty(val); + Empty(nonTerminalVal); + Empty(string); + + quoteStart := FALSE; + + REPEAT + IF (text[i] = symbolBracketStart) & (i = 0) THEN + INC(i); + (* vpkLogger.Log("Starting Parse Json"); *) + END; + + IF symbol = symbolBracketStart THEN + (* vpkLogger.Log("End Parsing Json"); *) + END; + symbol := text[i]; + + (* vpkLogger.LogIntLn(i); *) + (* IF i > 508 THEN + vpkLogger.Log(text); + END; *) + (* terminals *) + IF symbol = quote THEN + i := PushDownString(text, quote, quote, i, string); + END; + + IF (Strings.Length(string) > 0) & (symbol = quote) THEN + IF Strings.Length(key) > 0 THEN + COPY(string, val); + ELSE + COPY(string, key); + END; + + Empty(string); + END; + + IF (Strings.Length(key) > 0) & (Strings.Length(val) > 0) THEN + deQuote(key, self.TerminalKeys[terminalIterator]); + deQuote(val, self.TerminalValues[terminalIterator]); + + INC(terminalIterator); + + Empty(key); + Empty(val); + END; + + (* none terminals *) + IF symbol = symbolBracketStart THEN + i := PushDownString(text, symbolBracketStart, symbolBracketEnd, i, string); + END; + + IF (Strings.Length(string) > 0) & (symbol = symbolBracketStart) THEN + IF Strings.Length(key) > 0 THEN + COPY(string, nonTerminalVal); + END; + + Empty(string); + END; + + IF (Strings.Length(key) > 0) & (Strings.Length(nonTerminalVal) > 0) THEN + deQuote(key, self.NonTerminalKeys[noneTerminalIterator]); + self.NonTerminalValues[noneTerminalIterator] := Create(nonTerminalVal); + + INC(noneTerminalIterator); + + Empty(key); + Empty(nonTerminalVal); + END; + + INC(i); + UNTIL (i >= LEN(text) - 1) OR (text[i] = 0X); + + self.NonTerminalNumber := noneTerminalIterator; + self.TerminalNumber := terminalIterator; + + RETURN self; +END Create; + +BEGIN + (* NEW(jsonRecord); + jsonRecord := Create("{'foo': 'bar', 'test': 'test1', 'test2': {'sub': 'dub'}}"); + + keyFound := jsonRecord.GetTerminal(jsonRecord, "foo", testValue); + + IF keyFound THEN + vpkLogger.Log('found KEY'); + vpkLogger.Log(testValue); + ELSE vpkLogger.Log('Value for the Key is not found') END; + + keyFound := jsonRecord.GetTerminal(jsonRecord, "test2.sub", testValue); + + IF keyFound THEN + vpkLogger.Log('found KEY'); + vpkLogger.Log(testValue); + ELSE vpkLogger.Log('Value for the Key is not found') END; *) +END vpkJsonParser. diff --git a/vpkLogger.Mod b/vpkLogger.Mod new file mode 100644 index 0000000..3c493ab --- /dev/null +++ b/vpkLogger.Mod @@ -0,0 +1,82 @@ +MODULE vpkLogger; +IMPORT vpkTime, Out, Strings; + +CONST + deca = 10; + +PROCEDURE GetDecas(number: LONGINT): LONGINT; +VAR + i: LONGINT; +BEGIN + i := 1; + + WHILE number > deca DO + number := number DIV deca; + INC(i); + END; + + RETURN i; +END GetDecas; + +PROCEDURE LogInt*(number: LONGINT); +BEGIN + Out.Int(number, GetDecas(number)); +END LogInt; + +PROCEDURE LogIntLn*(number: LONGINT); +BEGIN + LogInt(number); + Out.Ln(); +END LogIntLn; + +PROCEDURE LogNormalized*(number, normal: LONGINT); +VAR + decimals, i: LONGINT; +BEGIN + i:=0; + decimals := GetDecas(number); + WHILE decimals + i < normal DO + INC(i); + Out.Int(0, 1) + END; + + LogInt(number); +END LogNormalized; + +PROCEDURE Log*(buff: ARRAY OF CHAR); +VAR + year, month, day, hour, min, sec, i: LONGINT; +BEGIN + vpkTime.Now(year, month, day, hour, min, sec); + + LogNormalized(year, 4); + Out.String("/"); + LogNormalized(month, 2); + Out.String("/"); + LogNormalized(day, 2); + Out.String(" "); + LogNormalized(hour, 2); + Out.String("-"); + LogNormalized(min, 2); + Out.String("-"); + LogNormalized(sec, 2); + Out.String(" :- "); + FOR i := 0 TO Strings.Length(buff) - 1 DO + (* Out.Char(" "); + Out.Int(ORD(buff[i]), 4); + Out.Char("-"); *) + Out.Char(buff[i]); + (* Out.Char(" ");Out.Char(" ");Out.Char(" "); *) + END; + Out.Ln; +END Log; + +PROCEDURE Char*(char: CHAR); +VAR + string :ARRAY 1 OF CHAR; +BEGIN + string[0] :=char; + Log(string); +END Char; + +END vpkLogger. diff --git a/vpkNetdb.Mod b/vpkNetdb.Mod new file mode 100644 index 0000000..e669ce1 --- /dev/null +++ b/vpkNetdb.Mod @@ -0,0 +1,79 @@ +MODULE vpkNetdb; (*noch 23.2.2017 / 14.4.2017*) + +IMPORT SYSTEM; + +CONST + ipprotoIP* = 0; + + ipprotoICMP* = 1; + + ipprotoIGMP* = 2; + + ipprotoIPIP* = 4; + + ipprotoTCP* = 6; + + ipprotoEGP* = 8; + + ipprotoPUP* = 12; + + ipprotoUDP* = 17; + + ipprotoIDP* = 22; + + ipprotoTP* = 29; + + ipprotoDCCP* = 33; + + ipprotoIPV6* = 41; + + ipprotoRSVP* = 46; + + ipprotoGRE* = 47; + + ipprotoESP* = 50; + + ipprotoAH* = 51; + + ipprotoMTP* = 92; + + ipprotoBEETPH* = 94; + + ipprotoENCAP* = 98; + + ipprotoPIM* = 103; + + ipprotoCOMP* = 108; + + ipprotoSCTP* = 132; + + ipprotoUDPLITE* = 136; + + ipprotoMPLS* = 137; + + ipprotoRAW* = 255; + +TYPE + Int32* = LONGINT; + Int64* = HUGEINT; + +TYPE + PaddrInfo* = POINTER [1] TO addrInfo; + + addrInfo* = RECORD + aiFlags*: Int32; + aiFamily*:Int32; + aiSockType*: Int32; + aiProtocol*: Int32; + aiAddrLen*: Int32; + aiAddr*, aiCanonName*, aiNext*: SYSTEM.ADDRESS; (* pointers *) + END; + + +PROCEDURE -getAddrInfo*(VAR node, service: ARRAY OF CHAR; hints: PaddrInfo; res: PaddrInfo): Int32 +"getaddrinfo (node, service, hints, res)"; + +PROCEDURE -freeAddrInfo*( res: PaddrInfo) +"freeaddrinfo(res)"; + +END vpkNetdb. diff --git a/vpkPackageFileParser.Mod b/vpkPackageFileParser.Mod new file mode 100644 index 0000000..238c89c --- /dev/null +++ b/vpkPackageFileParser.Mod @@ -0,0 +1,34 @@ +MODULE vpkPackageFileParser; +IMPORT + vpkJsonParser, + vpkFileManager, + vpkHttp, + vpkLogger, + vpkDependencyResolver, + vpkSettings; +CONST + MAXARRAYNUMBER = 1000; +PROCEDURE install*; +VAR + jsonData: ARRAY MAXARRAYNUMBER OF CHAR; + success: BOOLEAN; +BEGIN + vpkLogger.Log("Starting install process"); + success := vpkFileManager.Read(vpkSettings.packageFileName, jsonData); + + IF ~success THEN vpkLogger.Log("Some ERROR occured while reading VERSIONFILE") END; + ASSERT(success); + + vpkLogger.Log("Starting resolving dependencies"); + + vpkDependencyResolver.ResolveVersionFiles(jsonData); + vpkDependencyResolver.ResolvePackages(); + vpkLogger.Log("======================"); + vpkLogger.Log("======================"); + vpkLogger.Log("Installation complete"); + vpkLogger.Log("Thanks for using OPIUM!"); +END install; + +BEGIN + +END vpkPackageFileParser. diff --git a/vpkPackageResolver.Mod b/vpkPackageResolver.Mod new file mode 100644 index 0000000..111eb03 --- /dev/null +++ b/vpkPackageResolver.Mod @@ -0,0 +1,50 @@ +MODULE vpkPackageResolver; +IMPORT vpkFileManager, vpkHttp, Strings, vpkLogger, vpkSettings, vpkJsonParser; + +CONST ArrayMaxNumber = 1000; + +PROCEDURE ResolveFile *(host, port, path, packageName, fileName : ARRAY OF CHAR; VAR returnValue : ARRAY OF CHAR); +VAR + localPath: ARRAY ArrayMaxNumber OF CHAR; + isSuccessfull: BOOLEAN; +BEGIN + vpkLogger.Log('path'); + vpkLogger.Log(path); + vpkHttp.get(host, port, path, returnValue); + vpkHttp.getClean(returnValue, returnValue); + isSuccessfull := vpkFileManager.CreateDirectory(packageName, vpkSettings.installPath); + + IF ~isSuccessfull THEN vpkLogger.Log("Something went wrong, while downloading files") END; + ASSERT(isSuccessfull); + vpkLogger.Log(path); + + vpkLogger.Log(packageName); + COPY(vpkSettings.installPath, localPath); + + Strings.Append("/", localPath); + Strings.Append(packageName, localPath); + Strings.Append("/", localPath); + Strings.Append(fileName, localPath); + + isSuccessfull := vpkFileManager.Write(localPath, returnValue); + +END ResolveFile; + +PROCEDURE Resolve *(host, port, path, packageName, version: ARRAY OF CHAR; files: ARRAY OF vpkJsonParser.TString); +VAR + i : LONGINT; + helperString: ARRAY 10000 OF CHAR; +BEGIN + Strings.Append("/", path); + FOR i := 0 TO LEN(files) - 1 DO + IF ~Strings.Match(files[i], "") THEN + vpkJsonParser.Empty(helperString); + COPY(path, helperString); + Strings.Append(files[i], helperString); + + ResolveFile(host, port, helperString, packageName, files[i], helperString); + END; + END; +END Resolve; + +END vpkPackageResolver. diff --git a/vpkRemoteClient.Mod b/vpkRemoteClient.Mod new file mode 100644 index 0000000..9641a10 --- /dev/null +++ b/vpkRemoteClient.Mod @@ -0,0 +1,6 @@ +MODULE vpkRemoteClient; +IMPORT + httpClient +BEGIN + +END vpkRemoteClient. diff --git a/vpkSettings.Mod b/vpkSettings.Mod new file mode 100644 index 0000000..ea332e0 --- /dev/null +++ b/vpkSettings.Mod @@ -0,0 +1,8 @@ +MODULE vpkSettings; +CONST + packageFileName* = "VersionFile.json"; + host* = "localhost"; + port* = "80"; + installPath* = "dependencies"; + quote* = '"'; +END vpkSettings. diff --git a/vpkSockets.Mod b/vpkSockets.Mod new file mode 100644 index 0000000..862b9fe --- /dev/null +++ b/vpkSockets.Mod @@ -0,0 +1,157 @@ +MODULE vpkSockets; (*noch 23.2.2017 / 14.4.2017*) +IMPORT vpkTypes, SYS := SYSTEM; + +TYPE + Int16* = vpkTypes.Int16; (* INTEGER on 32 bit platform *) + Int32* = vpkTypes.Int32; + Int64* = vpkTypes.Int64; + +CONST + SockStream* = 1; + SockDgram* = 2; + SockRaw* = 3; + SockRdm* = 4; + SockSeqpacket* = 5; + SockDccp* = 6; + SockPacket* = 10; + + AfUnspec* = 0; (* Unspecified. *) + AfLocal* = 1; (* Local to host (pipes and file-domain). *) + AfUnix* = 1; (* POSIX name for PF_LOCAL. *) + AfFile* = 1; (* Another non-standard name for PF_LOCAL. *) + AfInet* = 2; (* IP protocol family. *) + AfAx25* = 3; (* Amateur Radio AX.25. *) + AfIpx* = 4; (* Novell Internet Protocol. *) + AfAppletalk* = 5; (* Appletalk DDP. *) + AfNetrom* = 6; (* Amateur radio NetROM. *) + AfBridge* = 7; (* Multiprotocol bridge. *) + AfAtmpvc* = 8; (* ATM PVCs. *) + AfX25* = 9; (* Reserved for X.25 project. *) + AfInet6* = 10; (* IP version 6. *) + AfRose* = 11; (* Amateur Radio X.25 PLP. *) + AfDecnet* = 12; (* Reserved for DECnet project. *) + AfNetbeui*= 13; (* Reserved for 802.2LLC project. *) + AfSecurity*=14; (* Security callback pseudo AF. *) + AfKey* = 15; (* PF_KEY key management API. *) + AfNetlink*= 16; + AfRoute* = 16; (* Alias to emulate 4.4BSD. *) + AfPacket = 17; (* Packet family. *) + AfAsh = 18; (* Ash. *) + AfEconet* = 19; (* Acorn Econet. *) + AfAtmsvc* = 20; (* ATM SVCs. *) + AfRds* = 21; (* RDS sockets. *) + AfSna = 22; (* Linux SNA Project *) + AfIrda* = 23; (* IRDA sockets. *) + AfPppox = 24; (* PPPoX sockets. *) + AfWanpipe*= 25; (* Wanpipe API sockets. *) + AfLlc* = 26; (* Linux LLC. *) + AfCan* = 29; (* Controller Area Network. *) + AfTipc* = 30; (* TIPC sockets. *) + AfBluetooth* = 31; (* Bluetooth sockets. *) + AfIucv* = 32; (* IUCV sockets. *) + AfRxrpc* = 33; (* RxRPC sockets. *) + AfIsdn* = 34; (* mISDN sockets. *) + AfPhonet* = 35; (* Phonet sockets. *) + AfIeee802154* = 36; (* IEEE 802.15.4 sockets. *) + AfCaif* = 37; (* CAIF sockets. *) + AfAlg* = 38; (* Algorithm sockets. *) + AfNfc* = 39; (* NFC sockets. *) + AfVsock* = 40; (* vSockets. *) + AfMax* = 41; (* For now.. *) + + InAddrAny* = 0; + +TYPE +(* + (* /usr/include/netinet/in.h *) + InAddr* = RECORD + SAddr* : Int32; + END; + + SockAddrIn* = RECORD + SinFamily* : Int16; + SinPort* : Int16; + SinAddr* : InAddr; + SinZero* : ARRAY 8 OF CHAR; + END; +*) + (* /usr/include/sys/socket.h *) + + SockAddr* = RECORD + SaFamily* : Int16; + SaData* : ARRAY 14 OF CHAR + END; +(* + PROCEDURE -includeSockets + "#include "; +*) + PROCEDURE -socket(domain, type, protocol: Int32): Int32 + "(int)socket(domain, type, protocol)"; + + PROCEDURE Socket*(domain, type, protocol: Int32): Int32; + BEGIN + RETURN socket(domain, type, protocol) + END Socket; + + PROCEDURE -bind(sockfd: Int32; VAR addr: SockAddr; addrlen: Int32): Int32 + "(int)bind(sockfd, addr, addrlen)"; + + PROCEDURE Bind*(sockfd: Int32; VAR addr: SockAddr; addrlen: Int32): Int32; + BEGIN + RETURN bind(sockfd, addr, addrlen) + END Bind; + + PROCEDURE -listen(sockfd, backlog: Int32): Int32 + "(int)listen(sockfd, backlog)"; + + PROCEDURE Listen*(sockfd, backlog: Int32): Int32; + BEGIN + RETURN listen(sockfd, backlog) + END Listen; + + PROCEDURE -accept(sockfd: Int32; VAR addr: SockAddr; VAR addrlen: Int32): Int32 + "(int)accept(sockfd, addr, addrlen)"; + + PROCEDURE Accept*(sockfd: Int32; VAR addr: SockAddr; VAR addrlen: Int32): Int32; + BEGIN + RETURN accept(sockfd, addr, addrlen) + END Accept; + (* int connect(int sockfd, const struct sockaddr *addr, + socklen_t addrlen); *) + PROCEDURE -connect(sockfd: Int32; addr: SYS.ADDRESS; addrlen: Int32): Int32 + "(INTEGER)(connect(sockfd, addr, addrlen))"; + + + PROCEDURE Connect*(sockfd: Int32; sockaddr: SYS.ADDRESS; addrlen: Int32): Int32; + BEGIN + RETURN connect(sockfd, sockaddr, addrlen) + END Connect; + + (* ssize_t recv(int sockfd, void *buf, size_t len, int flags); *) + + PROCEDURE -recv(sockfd: Int32; buf: SYS.ADDRESS; len: Int64; flags: Int32):Int64 + "(HUGEINT)recv(sockfd, buf, len, flags)"; + +(* + PROCEDURE -SizeofSockaddr(): INTEGER + "sizeof(sockaddr)"; + + PROCEDURE -Error(msg: ARRAY OF CHAR; len: INTEGER) + "write(1/*stdout*/, msg, len); char ch = 0xa; write(1, &ch, 1)"; + + PROCEDURE sockaddrCheck; (* check for inconsistent usage of sigjmp_buf; better avoid Unix_JmpBuf *) + VAR x, y: LONGINT; + BEGIN + x := SizeofSockaddr(); + y := SIZE(SockAddr); + IF x # y THEN + Error("sockets.sockaddrCheck: inconsistent usage of sockaddr", 52); + HALT(1); + END +END sockaddrCheck; +*) +BEGIN + + +END vpkSockets. + diff --git a/vpkStringHelpers.Mod b/vpkStringHelpers.Mod new file mode 100644 index 0000000..7ff5580 --- /dev/null +++ b/vpkStringHelpers.Mod @@ -0,0 +1,243 @@ +MODULE vpkStringHelpers; (*noch 18.5.2017 / 19.5.2017*) +IMPORT Strings := ooc2Strings, Out; + +CONST + CR* = 0DX; + LF* = 0AX; + +TYPE + pstring* = POINTER TO ARRAY OF CHAR; + pstrings* = POINTER TO ARRAY OF pstring; + +(** fills whole array with zeroes, useful when one needs to get several strings which contain characters < ' ' and not necessarily end with 0X *) +PROCEDURE zeroStr*(VAR str: ARRAY OF CHAR); +VAR + i, j : LONGINT; +BEGIN + i := LEN(str); + j := 0; + REPEAT + str[j] := 0X; + INC(j) + UNTIL j = i; +END zeroStr; + +PROCEDURE appendLFCR*(VAR str: ARRAY OF CHAR); +VAR + l : INTEGER; +BEGIN + l := Strings.Length(str); + str[l] := LF; + str[l+1] := CR; + str[l+2] := 0X; +END appendLFCR; + +PROCEDURE findChar*(ch: CHAR; VAR line: ARRAY OF CHAR; VAR b: BOOLEAN; VAR pos: INTEGER); +VAR + i : INTEGER; +BEGIN + i := -1; pos := -1; + b := FALSE; + REPEAT + INC(i); + IF line[i] = ch THEN b := TRUE; pos := i END; + UNTIL b OR (i = LEN(line) - 1); +END findChar; + +(* cuts line, takes the part till the eol *) +PROCEDURE cutLine*(VAR src, dst: ARRAY OF CHAR); +VAR + found: BOOLEAN; + pos : INTEGER; + i : INTEGER; +BEGIN + COPY("", dst); + findChar(LF, src, found, pos); + IF found THEN + i := 0; + REPEAT + dst[i] := src[i]; + INC(i); + UNTIL (i = pos) OR (i = LEN(dst)-2); + dst[i] := src[i]; + dst[i+1] := 0X + END; +END cutLine; + +(* put 0X after eol in the string *) +PROCEDURE terminateLine*(VAR str: ARRAY OF CHAR); +VAR + found: BOOLEAN; + pos : INTEGER; +BEGIN + findChar(LF, str, found, pos); + IF found THEN + IF (pos + 1) < LEN(str) THEN + str[pos + 1] := 0X + END + END; +END terminateLine; + +PROCEDURE getTillEOL*(VAR src: ARRAY OF CHAR; spos: INTEGER; VAR dst: ARRAY OF CHAR); (* actually get till any character < ' ' *) +VAR + i, j: INTEGER; +BEGIN + zeroStr(dst); + i := 0; + j := spos+1; + REPEAT + dst[i] := src[i+j]; + INC(i); + UNTIL (i+j = Strings.Length(src)) OR (src[i+j] < ' '); +END getTillEOL; + +(* get next word starting from spos till the ' ' *) +PROCEDURE getNextWord*(VAR src: ARRAY OF CHAR; spos: INTEGER; VAR dst: ARRAY OF CHAR); +VAR + i, j: INTEGER; +BEGIN + zeroStr(dst); + i := 0; + j := spos+1; + REPEAT + dst[i] := src[i+j]; + INC(i); + UNTIL (i+j = Strings.Length(src)) OR (src[i+j] <= ' '); +END getNextWord; + +PROCEDURE contains* (VAR line : ARRAY OF CHAR; pattern: ARRAY OF CHAR): BOOLEAN; +VAR + found: BOOLEAN; + pos : INTEGER; + i : INTEGER; + patternLength: INTEGER; + tmpline: POINTER TO ARRAY OF CHAR; +BEGIN + i := 0; + patternLength := Strings.Length(pattern); + NEW(tmpline, patternLength+1); + found := FALSE; + REPEAT + Strings.Extract(line, i, patternLength, tmpline^); + found := Strings.Equal(pattern, tmpline^); + INC(i); +UNTIL found OR (i = LEN(line) - patternLength - 1); + IF found THEN RETURN TRUE ELSE RETURN FALSE END +END contains; + +PROCEDURE contains1*(VAR line: ARRAY OF CHAR; pat : ARRAY OF CHAR): BOOLEAN; +VAR + found: BOOLEAN; + pos : INTEGER; +BEGIN + Strings.FindNext(pat, line, 0, found, pos); + IF found THEN RETURN TRUE ELSE RETURN FALSE END +END contains1; + +PROCEDURE dumpText*(VAR text: ARRAY OF CHAR); +VAR + i : INTEGER; +BEGIN + i := 0; + REPEAT + Out.Int(i, 3); Out.String(" | ord: "); Out.Int(ORD(text[i]), 15); Out.String(", char: '"); Out.Char(text[i]); Out.Char("'"); Out.Ln; + INC(i) + UNTIL i = LEN(text); +END dumpText; + +PROCEDURE dumpTextTill0*(VAR text: ARRAY OF CHAR); +VAR + i : INTEGER; +BEGIN + i := 0; + REPEAT + Out.Int(i, 3); Out.String(" | ord: "); Out.Int(ORD(text[i]), 15); Out.String(", char: '"); Out.Char(text[i]); Out.Char("'"); Out.Ln; + INC(i) + UNTIL (text[i] = 0X) OR (i = LEN(text)); +END dumpTextTill0; + + +PROCEDURE textToPstrings*(VAR text: ARRAY OF CHAR): pstrings; +VAR + i, j, lineNum, start, number: INTEGER; + pstrs: pstrings; + pstr: pstring; +BEGIN + i := 0; + j := 0; + REPEAT + IF text[i] = 0AX THEN INC(j) END; + INC(i); + UNTIL (i = LEN(text)) OR (text[i] = 0X); (* now in j we have count of lines *) + (* and in i we have position of the end of the text *) + NEW(pstrs, j); (*creating ptsrs array with that count *) + lineNum := 0; (* current line number, will inc until j*) + number := 0; (* character index in the text *) + REPEAT (* now we have to fill it line by line *) + WHILE (text[number] = 0AX) OR (text[number] = 0DX) DO INC(number) END; + start := number; + REPEAT + INC(number) + UNTIL (number = LEN(text) - 1) OR (text[number] = 0AX) OR (text[number] = 0DX) OR (text[number] = 0X); (* reached eol *) + NEW(pstr, number - start + 1); + Strings.Extract(text, start, number - start, pstr^); + pstrs^[lineNum] := pstr; + INC(lineNum); + UNTIL (lineNum = j) OR (number = i); + RETURN pstrs +END textToPstrings; + + (* IntToStr routine taken from + https://github.com/romiras/Oberon-F-components/blob/master/Ott/Mod/IntStr.cp + and modified to work on 64bit system by dcwbrown, + in order to avoid using oocIntStr, which has many dependencies *) + PROCEDURE Reverse0 (VAR str : ARRAY OF CHAR; start, end : INTEGER); + (* Reverses order of characters in the interval [start..end]. *) + VAR + h : CHAR; + BEGIN + WHILE start < end DO + h := str[start]; str[start] := str[end]; str[end] := h; + INC(start); DEC(end) + END + END Reverse0; + + PROCEDURE IntToStr*(int: LONGINT; VAR str: ARRAY OF CHAR); + (* Converts the value of `int' to string form and copies the possibly truncated + result to `str'. *) + VAR + b : ARRAY 21 OF CHAR; + s, e: INTEGER; + maxLength : SHORTINT; (* maximum number of digits representing a LONGINT value *) + BEGIN + IF SIZE(LONGINT) = 4 THEN maxLength := 11 END; + IF SIZE(LONGINT) = 8 THEN maxLength := 20 END; + (* build representation in string 'b' *) + IF int = MIN(LONGINT) THEN (* smallest LONGINT, -int is an overflow *) + IF SIZE(LONGINT) = 4 THEN + b := "-2147483648"; + e := 11 + ELSE (* SIZE(LONGINT) = 8 *) + b := "-9223372036854775808"; + e := 20 + END + ELSE + IF int < 0 THEN (* negative sign *) + b[0] := "-"; int := -int; s := 1 + ELSE (* no sign *) + s := 0 + END; + e := s; (* 's' holds starting position of string *) + REPEAT + b[e] := CHR(int MOD 10+ORD("0")); + int := int DIV 10; + INC(e) + UNTIL int = 0; + b[e] := 0X; + Reverse0(b, s, e-1); + END; + COPY(b, str) (* truncate output if necessary *) + END IntToStr; + + +END vpkStringHelpers. diff --git a/vpkTest.Mod b/vpkTest.Mod new file mode 100644 index 0000000..327b006 --- /dev/null +++ b/vpkTest.Mod @@ -0,0 +1,15 @@ +MODULE vpkTest; +IMPORT Out; +VAR + string: POINTER TO ARRAY OF CHAR; +BEGIN + NEW(string, 42); + string[1] := "a"; + Out.Char(string[1]); + Out.Ln(); + Out.Int(ORD(string[1]), 10); + Out.Ln(); + Out.Int(ORD(string[2]), 10); + Out.Ln(); + COPY("Gago", string); +END vpkTest. diff --git a/vpkTime.Mod b/vpkTime.Mod new file mode 100644 index 0000000..fcdce37 --- /dev/null +++ b/vpkTime.Mod @@ -0,0 +1,30 @@ +MODULE vpkTime; +IMPORT SYSTEM; + +PROCEDURE -Aincludesystime '#include '; (* for gettimeofday *) +PROCEDURE -Aincludetime '#include '; (* for localtime *) +PROCEDURE -Aincludesystypes '#include '; + +PROCEDURE -gettimeval "struct timeval tv; gettimeofday(&tv,0)"; +PROCEDURE -tvsec(): LONGINT "tv.tv_sec"; +PROCEDURE -tvusec(): LONGINT "tv.tv_usec"; +PROCEDURE -sectotm(s: LONGINT) "struct tm *time = localtime((time_t*)&s)"; +PROCEDURE -tmsec(): LONGINT "(LONGINT)time->tm_sec"; +PROCEDURE -tmmin(): LONGINT "(LONGINT)time->tm_min"; +PROCEDURE -tmhour(): LONGINT "(LONGINT)time->tm_hour"; +PROCEDURE -tmmday(): LONGINT "(LONGINT)time->tm_mday"; +PROCEDURE -tmmon(): LONGINT "(LONGINT)time->tm_mon"; +PROCEDURE -tmyear(): LONGINT "(LONGINT)time->tm_year"; + +PROCEDURE Now*(VAR year, month, day, hour, min, sec: LONGINT); +BEGIN + gettimeval; sectotm(tvsec()); + year := tmyear() + 1900; + month := tmmon(); + day := tmmday(); + hour := tmhour(); + min := tmmin(); + sec := tmsec(); +END Now; + +END vpkTime. diff --git a/vpkTypes.Mod b/vpkTypes.Mod new file mode 100644 index 0000000..e3fffe5 --- /dev/null +++ b/vpkTypes.Mod @@ -0,0 +1,41 @@ +MODULE vpkTypes; (*noch 23.2.2017 / 13.4.2017*) +IMPORT SYS := SYSTEM; + + +TYPE + intarr64 = ARRAY 8 OF SYS.BYTE; (* to emulate int16 on x86_64; -- noch *) + intarr32 = ARRAY 4 OF SYS.BYTE; + intarr16 = ARRAY 2 OF SYS.BYTE; + Int16* = INTEGER; (* INTEGER on 32 bit platform *) + Int32* = LONGINT; + Int64* = HUGEINT; + String* = ARRAY 256 OF CHAR; + + PROCEDURE HugeintToInt16*(in: HUGEINT; VAR out: Int16); + VAR + int64 : intarr64; + int16 : intarr16; + BEGIN + int64 := SYS.VAL(intarr64, in); + int16[0] := int64[0]; + int16[1] := int64[1]; + out := SYS.VAL(Int16, int16) + END HugeintToInt16; + + PROCEDURE LongintToInt16*(int: LONGINT; VAR int16: Int16); + BEGIN + int16 := SYS.VAL(Int16, int) + END LongintToInt16; + + PROCEDURE htons*(in: Int16; VAR out : Int16); + VAR + tmpin, tmpout : intarr16; + BEGIN + tmpin := SYS.VAL(intarr16, in); + tmpout := SYS.VAL(intarr16, out); + tmpout[0] := tmpin[1]; + tmpout[1] := tmpin[0]; + out := SYS.VAL(Int16, tmpout) + END htons; + +END vpkTypes. diff --git a/vpkUserDetails.Mod b/vpkUserDetails.Mod new file mode 100644 index 0000000..0c39f9b --- /dev/null +++ b/vpkUserDetails.Mod @@ -0,0 +1,16 @@ +MODULE UserDetails; +IMPORT Platform; + +PROCEDURE GetUsername*(VAR str : ARRAY OF CHAR):BOOLEAN; +BEGIN + RETURN Platform.getEnv("USER", str); +END GetUsername; + + + + + + + + +END vpkUserDetails.