Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. (*
  2.     Copyright 2016 Anton Krotov
  3.  
  4.     This file is part of Compiler.
  5.  
  6.     Compiler is free software: you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation, either version 3 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     Compiler is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with Compiler. If not, see <http://www.gnu.org/licenses/>.
  18. *)
  19.  
  20. MODULE UTILS;
  21.  
  22. IMPORT sys := SYSTEM, H := HOST, ERRORS;
  23.  
  24. CONST
  25.  
  26.   OS* = H.OS;
  27.   Slash* = H.Slash;
  28.   Ext* = ".ob07";
  29.   MAX_PATH = 1024;
  30.   MAX_PARAM = 1024;
  31.   Date* = 1451606400; (* 2016-01-01 *)
  32.  
  33. TYPE
  34.  
  35.   STRING* = ARRAY MAX_PATH OF CHAR;
  36.  
  37.   ITEM* = POINTER TO rITEM;
  38.  
  39.   rITEM* = RECORD
  40.     Next*, Prev*: ITEM
  41.   END;
  42.  
  43.   LIST* = POINTER TO RECORD
  44.     First*, Last*: ITEM;
  45.     Count*: INTEGER
  46.   END;
  47.  
  48.   STRCONST* = POINTER TO RECORD (rITEM)
  49.     Str*: STRING;
  50.     Len*, Number*: INTEGER
  51.   END;
  52.  
  53. VAR
  54.  
  55.   Params: ARRAY MAX_PARAM, 2 OF INTEGER;
  56.   ParamCount*, Line*, Unit*: INTEGER;  
  57.   FileName: STRING;
  58.  
  59. PROCEDURE SetFile*(F: STRING);
  60. BEGIN
  61.   FileName := F
  62. END SetFile;
  63.  
  64. PROCEDURE IsInf*(x: LONGREAL): BOOLEAN;
  65.   RETURN ABS(x) = sys.INF(LONGREAL)
  66. END IsInf;
  67.  
  68. PROCEDURE GetChar(adr: INTEGER): CHAR;
  69. VAR res: CHAR;
  70. BEGIN
  71.   sys.GET(adr, res)
  72.   RETURN res
  73. END GetChar;
  74.  
  75. PROCEDURE ParamParse(count: INTEGER);
  76. VAR c: CHAR; cond, p: INTEGER;
  77.  
  78.   PROCEDURE ChangeCond(A, B, C: INTEGER);
  79.   BEGIN
  80.     cond := C;
  81.     CASE c OF
  82.     |0X: cond := 6
  83.     |1X..20X: cond := A
  84.     |22X: cond := B
  85.     ELSE
  86.     END
  87.   END ChangeCond;
  88.  
  89. BEGIN
  90.   p := H.GetCommandLine();
  91.   cond := 0;
  92.   WHILE (count < MAX_PARAM) & (cond # 6) DO
  93.     c := GetChar(p);
  94.     CASE cond OF
  95.     |0: ChangeCond(0, 4, 1); IF cond = 1 THEN Params[count, 0] := p END
  96.     |4: ChangeCond(5, 0, 5); IF cond = 5 THEN Params[count, 0] := p END
  97.     |1: ChangeCond(0, 3, 1); IF cond IN {0, 6} THEN Params[count, 1] := p - 1; INC(count) END
  98.     |3, 5: ChangeCond(cond, 1, cond); IF cond = 6 THEN Params[count, 1] := p - 1; INC(count) END
  99.     ELSE
  100.     END;
  101.     INC(p)
  102.   END;
  103.   ParamCount := count - 1
  104. END ParamParse;
  105.  
  106. PROCEDURE ParamStr*(VAR str: ARRAY OF CHAR; n: INTEGER);
  107. VAR i, j, len: INTEGER; c: CHAR;
  108. BEGIN
  109.   j := 0;
  110.   IF n <= ParamCount THEN
  111.     len := LEN(str) - 1;
  112.     i := Params[n, 0];
  113.     WHILE (j < len) & (i <= Params[n, 1]) DO
  114.       c := GetChar(i);
  115.       IF c # 22X THEN
  116.         str[j] := c;
  117.         INC(j)
  118.       END;
  119.       INC(i)
  120.     END
  121.   END;
  122.   str[j] := 0X
  123. END ParamStr;
  124.  
  125. PROCEDURE GetMem*(n: INTEGER): INTEGER;
  126.   RETURN H.malloc(n)
  127. END GetMem;
  128.  
  129. PROCEDURE CloseF*(F: INTEGER);
  130. BEGIN
  131.   H.CloseFile(F)
  132. END CloseF;
  133.  
  134. PROCEDURE Read*(F, Buffer, Count: INTEGER): INTEGER;
  135.   RETURN H.FileRW(F, Buffer, Count, FALSE)
  136. END Read;
  137.  
  138. PROCEDURE Write*(F, Buffer, Count: INTEGER): INTEGER;
  139.   RETURN H.FileRW(F, Buffer, Count, TRUE)
  140. END Write;
  141.  
  142. PROCEDURE FileSize*(F: INTEGER): INTEGER;
  143.   RETURN H.FileSize(F)
  144. END FileSize;
  145.  
  146. PROCEDURE CharC*(x: CHAR);
  147. VAR str: ARRAY 2 OF CHAR;
  148. BEGIN
  149.   str[0] := x;
  150.   str[1] := 0X;
  151.   H.OutString(str)
  152. END CharC;
  153.  
  154. PROCEDURE Int*(x: INTEGER);
  155. VAR i: INTEGER; buf: ARRAY 11 OF INTEGER;
  156. BEGIN
  157.   i := 0;
  158.   REPEAT
  159.     buf[i] := x MOD 10;
  160.     x := x DIV 10;
  161.     INC(i)
  162.   UNTIL x = 0;
  163.   REPEAT
  164.     DEC(i);
  165.     CharC(CHR(buf[i] + ORD("0")))
  166.   UNTIL i = 0
  167. END Int;
  168.  
  169. PROCEDURE Ln*;
  170. BEGIN
  171.   CharC(0DX);
  172.   CharC(0AX)
  173. END Ln;
  174.  
  175. PROCEDURE OutString*(str: ARRAY OF CHAR);
  176. BEGIN
  177.   H.OutString(str)
  178. END OutString;
  179.  
  180. PROCEDURE ErrMsg*(code: INTEGER);
  181. VAR str: ARRAY 1024 OF CHAR;
  182. BEGIN
  183.   ERRORS.ErrorMsg(code, str);
  184.   OutString("error: ("); Int(code); OutString(") "); OutString(str); Ln
  185. END ErrMsg;
  186.  
  187. PROCEDURE ErrMsgPos*(line, col, code: INTEGER);
  188. VAR s: STRING;
  189. BEGIN
  190.   ErrMsg(code);
  191.   OutString("file:  "); OutString(FileName); Ln;
  192.   OutString("line:  "); Int(line); Ln;
  193.   OutString("pos:   "); Int(col); Ln;
  194. END ErrMsgPos;
  195.  
  196. PROCEDURE UnitLine*(newUnit, newLine: INTEGER);
  197. BEGIN
  198.   Unit := newUnit;
  199.   Line := newLine
  200. END UnitLine;
  201.  
  202. PROCEDURE min*(a, b: INTEGER): INTEGER;
  203. BEGIN
  204.   IF a > b THEN
  205.     a := b
  206.   END
  207.   RETURN a
  208. END min;
  209.  
  210. PROCEDURE Align*(n: INTEGER): INTEGER;
  211.   RETURN (4 - n MOD 4) MOD 4
  212. END Align;
  213.  
  214. PROCEDURE CAP(x: CHAR): CHAR;
  215. BEGIN
  216.   IF (x >= "a") & (x <= "z") THEN
  217.     x := CHR(ORD(x) - 32)
  218.   END
  219.   RETURN x
  220. END CAP;
  221.  
  222. PROCEDURE streq*(a, b: ARRAY OF CHAR): BOOLEAN;
  223. VAR i: INTEGER;
  224. BEGIN
  225.   i := -1;
  226.   REPEAT
  227.     INC(i)
  228.   UNTIL (CAP(a[i]) # CAP(b[i])) OR (a[i] = 0X) OR (b[i] = 0X)
  229.   RETURN a[i] = b[i]
  230. END streq;
  231.  
  232. PROCEDURE concat*(VAR L: STRING; R: STRING);
  233. VAR i, n, pos: INTEGER;
  234. BEGIN
  235.   n := LENGTH(R);
  236.   i := 0;
  237.   pos := LENGTH(L);
  238.   WHILE (i <= n) & (pos < LEN(L)) DO
  239.     L[pos] := R[i];
  240.     INC(pos);
  241.     INC(i)
  242.   END
  243. END concat;
  244.  
  245. PROCEDURE GetStr*(this: LIST; str: STRING): STRCONST;
  246. VAR res: STRCONST;
  247. BEGIN
  248.   res := this.First(STRCONST);
  249.   WHILE (res # NIL) & (res.Str # str) DO
  250.     res := res.Next(STRCONST)
  251.   END
  252.   RETURN res
  253. END GetStr;
  254.  
  255. PROCEDURE Push*(this: LIST; item: ITEM);
  256. BEGIN
  257.   IF this.Count = 0 THEN
  258.     this.First := item;
  259.     item.Prev := NIL
  260.   ELSE
  261.     this.Last.Next := item;
  262.     item.Prev := this.Last
  263.   END;
  264.   INC(this.Count);
  265.   this.Last := item;
  266.   item.Next := NIL
  267. END Push;
  268.  
  269. PROCEDURE Insert*(this: LIST; item, prev: ITEM);
  270. BEGIN
  271.   IF prev # this.Last THEN
  272.     item.Next := prev.Next;
  273.     item.Prev := prev;
  274.     prev.Next := item;
  275.     item.Next.Prev := item;
  276.     INC(this.Count)
  277.   ELSE
  278.     Push(this, item)
  279.   END
  280. END Insert;
  281.  
  282. PROCEDURE Clear*(this: LIST);
  283. BEGIN
  284.   this.First := NIL;
  285.   this.Last := NIL;
  286.   this.Count := 0
  287. END Clear;
  288.  
  289. PROCEDURE Revers(VAR str: STRING);
  290. VAR a, b: INTEGER; c: CHAR;
  291. BEGIN
  292.   a := 0;
  293.   b := LENGTH(str) - 1;
  294.   WHILE a < b DO
  295.     c := str[a];
  296.     str[a] := str[b];
  297.     str[b] := c;
  298.     INC(a);
  299.     DEC(b)
  300.   END
  301. END Revers;
  302.  
  303. PROCEDURE Split*(FName: STRING; VAR Path, Name, Ext: STRING);
  304. VAR i, j, k: INTEGER;
  305. BEGIN
  306.   i := LENGTH(FName) - 1;
  307.   j := 0;
  308.   WHILE (i >= 0) & (FName[i] # Slash) DO
  309.     Name[j] := FName[i];
  310.     DEC(i);
  311.     INC(j)
  312.   END;
  313.   Name[j] := 0X;
  314.   Revers(Name);
  315.   j := 0;
  316.   k := LENGTH(Name) - 1;
  317.   WHILE (k >= 0) & (Name[k] # ".") DO
  318.     Ext[j] := Name[k];
  319.     DEC(k);
  320.     INC(j)
  321.   END;
  322.   IF k >= 0 THEN
  323.     Name[k] := 0X;
  324.     Ext[j] := ".";
  325.     INC(j)
  326.   ELSE
  327.     j := 0
  328.   END;
  329.   Ext[j] := 0X;
  330.   Revers(Ext);
  331.   FOR j := 0 TO i DO
  332.     Path[j] := FName[j]
  333.   END;
  334.   Path[i + 1] := 0X
  335. END Split;
  336.          
  337. PROCEDURE LinuxParam;
  338. VAR p, i, str: INTEGER; c: CHAR;
  339. BEGIN
  340.   p := H.GetCommandLine();
  341.   sys.GET(p, ParamCount);
  342.   sys.GET(p + 4, p);
  343.   FOR i := 0 TO ParamCount - 1 DO
  344.     sys.GET(p + i * 4, str);
  345.     Params[i, 0] := str;
  346.     REPEAT
  347.       sys.GET(str, c);
  348.       INC(str)
  349.     UNTIL c = 0X;
  350.     Params[i, 1] := str - 1
  351.   END;
  352.   DEC(ParamCount)
  353. END LinuxParam;    
  354.  
  355. PROCEDURE Time*;
  356. VAR sec, dsec: INTEGER;
  357. BEGIN
  358.   OutString("elapsed time ");
  359.   H.Time(sec, dsec);
  360.   sec := sec - H.sec;
  361.   dsec := dsec - H.dsec;
  362.   dsec := dsec + sec * 100;
  363.   Int(dsec DIV 100); CharC(".");
  364.   dsec := dsec MOD 100;
  365.   IF dsec < 10 THEN
  366.     Int(0)
  367.   END;
  368.   Int(dsec); OutString(" sec"); Ln
  369. END Time;
  370.  
  371. PROCEDURE HALT*(n: INTEGER);
  372. BEGIN
  373.   Time;
  374.   H.ExitProcess(n)
  375. END HALT;
  376.  
  377. PROCEDURE MemErr*(err: BOOLEAN);
  378. BEGIN
  379.   IF err THEN
  380.     ErrMsg(72);
  381.     HALT(1)
  382.   END
  383. END MemErr;
  384.  
  385. PROCEDURE CreateList*(): LIST;
  386. VAR nov: LIST;
  387. BEGIN
  388.   NEW(nov);
  389.   MemErr(nov = NIL)
  390.   RETURN nov
  391. END CreateList;
  392.  
  393. PROCEDURE CreateF*(FName: ARRAY OF CHAR): INTEGER;
  394.   RETURN H.CreateFile(FName)
  395. END CreateF;
  396.  
  397. PROCEDURE OpenF*(FName: ARRAY OF CHAR(*; Mode: INTEGER*)): INTEGER;
  398.   RETURN H.OpenFile(FName)
  399. END OpenF;
  400.  
  401. PROCEDURE Init;
  402. VAR p: INTEGER;
  403.  
  404.   PROCEDURE last(VAR p: INTEGER);
  405.   BEGIN
  406.     WHILE GetChar(p) # 0X DO INC(p) END;
  407.     DEC(p)
  408.   END last;
  409.  
  410. BEGIN
  411.   H.init;
  412.   IF OS = "WIN" THEN
  413.     ParamParse(0)
  414.   ELSIF OS = "KOS" THEN
  415.     ParamParse(1);
  416.     Params[0, 0] := H.GetName();
  417.     Params[0, 1] := Params[0, 0];
  418.     last(Params[0, 1])
  419.   ELSIF OS = "LNX" THEN
  420.     LinuxParam
  421.   END
  422. END Init;
  423.  
  424. BEGIN
  425.   Init
  426. END UTILS.