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.