|
@@ -16,12 +16,9 @@ GNU General Public License for more details.
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
along with Free Oberon. If not, see <http://www.gnu.org/licenses/>.
|
|
|
*)
|
|
|
-IMPORT T := TermBox, Files, Args, Utf8,
|
|
|
+IMPORT T := TermBox, Files, Args, Utf8, Builder,
|
|
|
OV, Editor, Term, FoStrings, Config, Strings, Int, Out, Kernel;
|
|
|
CONST
|
|
|
- version* = '1.1.0-alpha.5';
|
|
|
- year = 2022;
|
|
|
-
|
|
|
(* Direction of Selection *)
|
|
|
dirLeft = 0;
|
|
|
dirRight = 1;
|
|
@@ -53,12 +50,6 @@ CONST
|
|
|
defLang = 'en';
|
|
|
|
|
|
TYPE
|
|
|
- StrList = POINTER TO StrListDesc;
|
|
|
- StrListDesc = RECORD
|
|
|
- s: ARRAY 256 OF CHAR; (* Module name *)
|
|
|
- fname: ARRAY 256 OF CHAR; (* Filename of module source *)
|
|
|
- next: StrList
|
|
|
- END;
|
|
|
Fnames = ARRAY 32, 256 OF CHAR;
|
|
|
|
|
|
VAR
|
|
@@ -66,10 +57,6 @@ VAR
|
|
|
inputBuf: ARRAY 16300 OF CHAR; (* Saves entered chars before Enter pressed *)
|
|
|
inputBufLen: INTEGER;
|
|
|
programFinished: BOOLEAN;
|
|
|
- tempWindowed: BOOLEAN; (* TRUE if editor windowed while program is running *)
|
|
|
- needWindowed: BOOLEAN;
|
|
|
- sysModules: StrList;
|
|
|
- workDir: ARRAY 256 OF CHAR; (* Directory of main file of compiled program *)
|
|
|
app: OV.App;
|
|
|
|
|
|
curX, curY: INTEGER; (* Cursor position *)
|
|
@@ -97,33 +84,6 @@ PROCEDURE ShowError(s: ARRAY OF CHAR);
|
|
|
BEGIN Editor.SetMsg(app.windows(Editor.Editor), s)
|
|
|
END ShowError;
|
|
|
|
|
|
-(* !TODO move out, rewrite *)
|
|
|
-PROCEDURE StringsFindNext*(what, where: ARRAY OF CHAR;
|
|
|
- begin: INTEGER; VAR found: BOOLEAN; VAR resultPos: INTEGER);
|
|
|
-VAR i: INTEGER;
|
|
|
-BEGIN
|
|
|
- IF begin < Strings.Length(where) THEN i := 0;
|
|
|
- LOOP
|
|
|
- IF what[i] = 0X THEN
|
|
|
- (* reached end of what *)
|
|
|
- found := TRUE; resultPos := begin - i;
|
|
|
- EXIT
|
|
|
- ELSIF where[begin] = 0X THEN
|
|
|
- (* end of string (but not of what) *)
|
|
|
- found := FALSE;
|
|
|
- EXIT
|
|
|
- ELSIF where[begin] = what[i] THEN
|
|
|
- (* characters identic, compare next one *)
|
|
|
- INC(begin); INC(i)
|
|
|
- ELSE
|
|
|
- (* difference found: reset indices and restart *)
|
|
|
- DEC(begin, i - 1); i := 0
|
|
|
- END
|
|
|
- END
|
|
|
- ELSE found := FALSE
|
|
|
- END
|
|
|
-END StringsFindNext;
|
|
|
-
|
|
|
PROCEDURE FileNew(c: OV.Control);
|
|
|
VAR e: Editor.Editor;
|
|
|
p, br: OV.Control;
|
|
@@ -152,8 +112,8 @@ END FileNew;
|
|
|
|
|
|
PROCEDURE FnameToCaption(IN fname: ARRAY OF CHAR; VAR caption: ARRAY OF CHAR);
|
|
|
BEGIN
|
|
|
- IF Strings.Pos(Editor.stdPath, fname, 0) = 0 THEN
|
|
|
- Strings.Extract(fname, Strings.Length(Editor.stdPath),
|
|
|
+ IF Strings.Pos(Config.stdPath, fname, 0) = 0 THEN
|
|
|
+ Strings.Extract(fname, Strings.Length(Config.stdPath),
|
|
|
LEN(caption), caption)
|
|
|
ELSE caption := fname$
|
|
|
END
|
|
@@ -183,20 +143,10 @@ BEGIN
|
|
|
WHILE (e # NIL) & (e.fname # fname) DO
|
|
|
IF e.next = f THEN e := NIL ELSE e := e.next(Editor.Editor) END
|
|
|
END;
|
|
|
- IF e = NIL THEN DoOpenFile(fname)
|
|
|
- ELSE app.windows := e; OV.SetFocus(e)
|
|
|
- END;
|
|
|
+ IF e = NIL THEN DoOpenFile(fname) ELSE app.windows := e; OV.SetFocus(e) END;
|
|
|
OV.DrawApp(app)
|
|
|
END FocusOrOpenFile;
|
|
|
|
|
|
-PROCEDURE ReadInt(IN s: ARRAY OF CHAR; VAR i, res: INTEGER);
|
|
|
-BEGIN res := 0;
|
|
|
- WHILE ('0' <= s[i]) & (s[i] <= '9') DO
|
|
|
- res := res * 10 + ORD(s[i]) - ORD('0');
|
|
|
- INC(i)
|
|
|
- END
|
|
|
-END ReadInt;
|
|
|
-
|
|
|
PROCEDURE ScrollScreen;
|
|
|
VAR x, y, tW, tH: INTEGER;
|
|
|
ch: CHAR;
|
|
@@ -258,41 +208,6 @@ BEGIN
|
|
|
terminalNeedRedraw := TRUE
|
|
|
END Backspace;
|
|
|
|
|
|
-PROCEDURE ParseErrors(VAR s: ARRAY OF CHAR; fname: ARRAY OF CHAR;
|
|
|
- VAR line, col, error: INTEGER);
|
|
|
-VAR i, j, st, len, skip: INTEGER; found: BOOLEAN;
|
|
|
-BEGIN fname[0] := 0X; line := 1; col := 1;
|
|
|
- StringsFindNext(' translating ', s, 0, found, i);
|
|
|
- IF found THEN INC(i, 13); j := 0; (* Read module name *)
|
|
|
- WHILE (j < LEN(fname) - 1) & (s[i] > ' ') DO
|
|
|
- fname[j] := s[i]; INC(i); INC(j)
|
|
|
- END;
|
|
|
- fname[j] := 0X;
|
|
|
- (* Remove everything up to the following line *)
|
|
|
- WHILE (s[i] # 0X) & (s[i] # 0AX) DO INC(i) END;
|
|
|
- Strings.Delete(s, 0, i + 1); i := 0;
|
|
|
- (* Read line and column numbers, i.e. '10:23' *)
|
|
|
- WHILE (s[i] # 0X) & (s[i] <= ' ') DO INC(i) END;
|
|
|
- IF ('0' <= s[i]) & (s[i] <= '9') THEN
|
|
|
- ReadInt(s, i, line);
|
|
|
- IF s[i] = ':' THEN INC(i) END;
|
|
|
- IF ('0' <= s[i]) & (s[i] <= '9') THEN
|
|
|
- ReadInt(s, i, col)
|
|
|
- END;
|
|
|
- WHILE (s[i] # 0X) & (s[i] # 'e') DO INC(i) END;
|
|
|
- IF (s[i + 1] = 'r') & (s[i + 2] = 'r') & (s[i + 3] = ' ') THEN
|
|
|
- INC(i, 4); ReadInt(s, i, error)
|
|
|
- ELSE error := 0
|
|
|
- END;
|
|
|
- FoStrings.MakeErrorStr(error, s)
|
|
|
- END
|
|
|
- ELSE StringsFindNext('): ', s, 0, found, i); (* In case of gcc error *)
|
|
|
- IF found THEN Strings.Delete(s, 0, i + 3) END;
|
|
|
- i := 0; WHILE (s[i] # 0X) & (s[i] # 0AX) & (s[i] # 0DX) DO INC(i) END;
|
|
|
- s[i] := 0X
|
|
|
- END
|
|
|
-END ParseErrors;
|
|
|
-
|
|
|
PROCEDURE PollProgram;
|
|
|
VAR len, i: INTEGER;
|
|
|
err: INTEGER;
|
|
@@ -329,7 +244,6 @@ BEGIN
|
|
|
IF Term.ProcessFinished(err) THEN
|
|
|
Read(TRUE); (* Read everything until pipe is empty *)
|
|
|
programFinished := TRUE;
|
|
|
- IF tempWindowed THEN T.SwitchToFS END;
|
|
|
IF err = 0 THEN s := ' '; FoStrings.Append('pressAnyKeyToReturnToIde', s)
|
|
|
ELSE s := ' '; FoStrings.Append('runtimeError', s);
|
|
|
Strings.Append(' ', s); Int.Append(err, s)
|
|
@@ -415,193 +329,6 @@ BEGIN quit := FALSE;
|
|
|
IF ~terminalMouseShown THEN T.ShowMouse END
|
|
|
END RunTerminal;
|
|
|
|
|
|
-PROCEDURE IsSysModule(IN name: ARRAY OF CHAR): BOOLEAN;
|
|
|
-VAR p: StrList;
|
|
|
-BEGIN p := sysModules;
|
|
|
- WHILE (p # NIL) & (p.s # name) DO p := p.next END ;
|
|
|
-RETURN p # NIL END IsSysModule;
|
|
|
-
|
|
|
-PROCEDURE ModuleExists(IN fname: ARRAY OF CHAR): BOOLEAN;
|
|
|
-VAR F: Files.File;
|
|
|
- exists: BOOLEAN;
|
|
|
-BEGIN F := Files.Old(fname); exists := F # NIL;
|
|
|
- IF F # NIL THEN Files.Close(F) END ;
|
|
|
-RETURN exists END ModuleExists;
|
|
|
-
|
|
|
-PROCEDURE SetWorkDir(IN fname: ARRAY OF CHAR);
|
|
|
-VAR i: INTEGER;
|
|
|
-BEGIN i := Strings.Length(fname);
|
|
|
- WHILE (i # -1) & (fname[i] # '/') & (fname[i] # '\') DO DEC(i) END;
|
|
|
- IF i # -1 THEN Strings.Extract(fname, 0, i + 1, workDir)
|
|
|
- ELSE workDir[0] := 0X
|
|
|
- END
|
|
|
-END SetWorkDir;
|
|
|
-
|
|
|
-PROCEDURE SplitModName(IN s: ARRAY OF CHAR;
|
|
|
- VAR m1, m2: ARRAY OF CHAR): BOOLEAN;
|
|
|
-VAR i: INTEGER;
|
|
|
-BEGIN i := 1;
|
|
|
- WHILE (s[i] # 0X) & ~(('A' <= s[i]) & (s[i] <= 'Z') &
|
|
|
- ~(('A' <= s[i - 1]) & (s[i - 1] <= 'Z')))
|
|
|
- DO INC(i)
|
|
|
- END;
|
|
|
- IF s[i] # 0X THEN
|
|
|
- Strings.Extract(s, 0, i, m1);
|
|
|
- Strings.Extract(s, i, LEN(m2), m2)
|
|
|
- END ;
|
|
|
-RETURN s[i] # 0X END SplitModName;
|
|
|
-
|
|
|
-PROCEDURE FindModule(IN mod: ARRAY OF CHAR; VAR fname: ARRAY OF CHAR): BOOLEAN;
|
|
|
-VAR ok: BOOLEAN;
|
|
|
- s, m1, m2: ARRAY 256 OF CHAR;
|
|
|
-BEGIN ok := FALSE; (* Try 'Programs/A/GuiButtons.Mod' *)
|
|
|
- s := workDir$; Strings.Append(mod, s); Strings.Append('.Mod', s);
|
|
|
- IF ModuleExists(s) THEN fname := s$; ok := TRUE
|
|
|
- ELSIF SplitModName(mod, m1, m2) THEN (* Try 'Programs/A/Gui/Buttons.Mod' *)
|
|
|
- s := workDir$; Strings.Append(m1, s); Strings.Append('/', s);
|
|
|
- Strings.Append(m2, s); Strings.Append('.Mod', s);
|
|
|
- IF ModuleExists(s) THEN fname := s$; ok := TRUE END
|
|
|
- END ;
|
|
|
-RETURN ok END FindModule;
|
|
|
-
|
|
|
-PROCEDURE RunCommand(IN fname, mod: ARRAY OF CHAR;
|
|
|
- link, graph, main: BOOLEAN; list: StrList): BOOLEAN;
|
|
|
-CONST bufLen = 20480;
|
|
|
-VAR buf: ARRAY bufLen OF SHORTCHAR;
|
|
|
- e: Editor.Editor;
|
|
|
- p: StrList;
|
|
|
- len, err, line, col, error: INTEGER;
|
|
|
- command: ARRAY 32 OF CHAR;
|
|
|
- q: ARRAY 1024 OF SHORTCHAR;
|
|
|
- z: ARRAY 1024 OF CHAR;
|
|
|
- cmd: ARRAY 1024 OF CHAR;
|
|
|
- s, sN: ARRAY 80 OF CHAR;
|
|
|
- tW, tH: INTEGER;
|
|
|
- success: BOOLEAN;
|
|
|
-BEGIN
|
|
|
- T.Size(tW, tH);
|
|
|
- IF ~link THEN command := 'compile'
|
|
|
- ELSIF graph THEN command := 'link_graph'
|
|
|
- ELSE command := 'link_console'
|
|
|
- END;
|
|
|
- IF Config.isWindows THEN
|
|
|
- IF Term.SearchPath('cmd.exe', q) # 0 THEN
|
|
|
- Utf8.Decode(q, cmd);
|
|
|
- Strings.Insert('"', 0, cmd);
|
|
|
- Strings.Append('" /C Data\bin\', cmd);
|
|
|
- Strings.Append(command, cmd);
|
|
|
- Strings.Append('.bat ', cmd)
|
|
|
- ELSE T.Print(0, tH - 1, -1, 'Could not find cmd.exe', 15, 4) (*!FIXME*)
|
|
|
- END
|
|
|
- ELSE (* Linux *)
|
|
|
- cmd := 'Data/bin/'; Strings.Append(command, cmd);
|
|
|
- Strings.Append('.sh ', cmd)
|
|
|
- END;
|
|
|
-
|
|
|
- IF Strings.Pos(Editor.stdPath, fname, 0) = 0 THEN
|
|
|
- Strings.Extract(fname, Strings.Length(Editor.stdPath), LEN(s), s)
|
|
|
- ELSE s := fname$
|
|
|
- END;
|
|
|
- Strings.Append(s, cmd);
|
|
|
-
|
|
|
- IF main THEN Strings.Append(' -m', cmd)
|
|
|
- ELSIF link & (list # NIL) THEN
|
|
|
- p := list;
|
|
|
- WHILE p.next # NIL DO
|
|
|
- IF ModuleExists(p.fname) THEN
|
|
|
- Strings.Append(' ', cmd); Strings.Append(p.s, cmd);
|
|
|
- Strings.Append('.c', cmd)
|
|
|
- END;
|
|
|
- p := p.next
|
|
|
- END
|
|
|
- END;
|
|
|
- Utf8.Encode(cmd, q);
|
|
|
- success := (Term.RunProcess(q, buf, bufLen, len, err) # 0) &
|
|
|
- (err = 0);
|
|
|
- IF ~success THEN
|
|
|
- s := ' Command returned '; Int.Append(err, s);
|
|
|
- Strings.Append(' exit status ', s);
|
|
|
- IF (len > 0) & (len < bufLen) THEN
|
|
|
- IF buf[len - 1] = 0AX THEN buf[len - 1] := 0X
|
|
|
- ELSE buf[len] := 0X
|
|
|
- END;
|
|
|
- Utf8.Decode(buf, z);
|
|
|
- ParseErrors(z, fname, line, col, error);
|
|
|
- FocusOrOpenFile(fname);
|
|
|
- e := app.windows(Editor.Editor);
|
|
|
- IF (col = 1) & (line # 1) THEN
|
|
|
- e.text.MoveToLineCol(line - 1, 256, e.h - 2)
|
|
|
- ELSE e.text.MoveToLineCol(line, col, e.h - 2)
|
|
|
- END;
|
|
|
- Editor.PrintText(app.windows(Editor.Editor))
|
|
|
- ELSIF link THEN FoStrings.GetErrorStr(422, z)
|
|
|
- ELSE FoStrings.GetErrorStr(421, z)
|
|
|
- END;
|
|
|
- IF z[0] = 0X THEN ShowError(s) ELSE ShowError(z) END
|
|
|
- END ;
|
|
|
-RETURN success END RunCommand;
|
|
|
-
|
|
|
-PROCEDURE Compile(IN fname, mod: ARRAY OF CHAR; main: BOOLEAN): BOOLEAN;
|
|
|
-BEGIN RETURN RunCommand(fname, mod, FALSE, FALSE, main, NIL)
|
|
|
-END Compile;
|
|
|
-
|
|
|
-PROCEDURE Link(IN fname, mod: ARRAY OF CHAR;
|
|
|
- graph: BOOLEAN; list: StrList; VAR exename: ARRAY OF CHAR): BOOLEAN;
|
|
|
-VAR ok: BOOLEAN;
|
|
|
- s: ARRAY 2048 OF CHAR;
|
|
|
- res: INTEGER;
|
|
|
-BEGIN ok := RunCommand(fname, mod, TRUE, graph, FALSE, list);
|
|
|
- IF ok THEN (* Move executable file if workDir is non-standard *)
|
|
|
- s := mod$; IF Config.isWindows THEN Strings.Append('.exe', s) END;
|
|
|
- exename := 'bin/'; Strings.Append(s, exename);
|
|
|
- IF workDir # Editor.stdPath THEN
|
|
|
- Strings.Insert(workDir, 0, s);
|
|
|
- Files.Rename(exename, s, res);
|
|
|
- IF res = 0 THEN exename := s$ END
|
|
|
- END
|
|
|
- END ;
|
|
|
-RETURN ok END Link;
|
|
|
-
|
|
|
-PROCEDURE ResetSysModules;
|
|
|
-
|
|
|
- PROCEDURE Add(s: ARRAY OF CHAR);
|
|
|
- VAR p: StrList;
|
|
|
- BEGIN NEW(p); p.s := s$; p.fname[0] := 0X;
|
|
|
- p.next := sysModules; sysModules := p
|
|
|
- END Add;
|
|
|
-
|
|
|
-BEGIN sysModules := NIL;
|
|
|
- Add('SYSTEM'); Add('Texts'); Add('Files'); Add('Strings');
|
|
|
- Add('In'); Add('Out'); Add('Math'); Add('MathL');
|
|
|
- Add('Modules'); Add('Platform'); Add('Oberon'); Add('Reals');
|
|
|
- Add('VT100'); Add('Graph'); Add('TermBox'); Add('Term');
|
|
|
- Add('Allegro5'); Add('Dir'); Add('Int'); Add('Random')
|
|
|
-END ResetSysModules;
|
|
|
-
|
|
|
-PROCEDURE CompileAll(modules: StrList; graph: BOOLEAN;
|
|
|
- VAR exename: ARRAY OF CHAR): BOOLEAN;
|
|
|
-VAR p, last: StrList;
|
|
|
- ok: BOOLEAN;
|
|
|
-BEGIN exename[0] := 0X;
|
|
|
- IF modules # NIL THEN
|
|
|
- ok := TRUE; p := modules;
|
|
|
- WHILE ok & (p.next # NIL) DO
|
|
|
- IF ModuleExists(p.fname) THEN
|
|
|
- IF ~Compile(p.fname, '', FALSE) THEN ok := FALSE END
|
|
|
- ELSIF ~IsSysModule(p.s) THEN ok := FALSE
|
|
|
- END;
|
|
|
- p := p.next
|
|
|
- END;
|
|
|
- IF ok THEN
|
|
|
- IF ModuleExists(p.fname) THEN
|
|
|
- IF ~Compile(p.fname, '', TRUE) THEN ok := FALSE END
|
|
|
- END;
|
|
|
- ok := ok & Link(p.fname, p.s, graph, modules, exename);
|
|
|
- END
|
|
|
- ELSE ok := FALSE
|
|
|
- END ;
|
|
|
-RETURN ok END CompileAll;
|
|
|
-
|
|
|
PROCEDURE RunProgram(IN prg: ARRAY OF CHAR);
|
|
|
VAR dir, err: ARRAY 256 OF CHAR;
|
|
|
s, d: ARRAY 2048 OF SHORTCHAR;
|
|
@@ -697,179 +424,43 @@ VAR w: OV.Window;
|
|
|
BEGIN
|
|
|
END OptionsLanguage;
|
|
|
|
|
|
-PROCEDURE SkipComment(VAR R: Files.Rider; VAR ch: CHAR; VAR s: ARRAY OF CHAR);
|
|
|
-VAR last: CHAR;
|
|
|
-BEGIN last := ch; Files.ReadChar(R, ch);
|
|
|
- WHILE ~R.eof & ((last # '*') OR (ch # ')')) DO
|
|
|
- IF (last = '(') & (ch = '*') THEN SkipComment(R, ch, s) END;
|
|
|
- last := ch; Files.ReadChar(R, ch)
|
|
|
- END;
|
|
|
- IF ~R.eof THEN Files.ReadChar(R, ch) END;
|
|
|
- WHILE ~R.eof & (ch <= ' ') DO Files.ReadChar(R, ch) END
|
|
|
-END SkipComment;
|
|
|
-
|
|
|
-PROCEDURE ReadCh(VAR R: Files.Rider; VAR ch: CHAR; VAR line, col: INTEGER);
|
|
|
-BEGIN Files.ReadChar(R, ch);
|
|
|
- IF ch = 0AX THEN INC(line); col := 1 ELSE INC(col) END
|
|
|
-END ReadCh;
|
|
|
-
|
|
|
-PROCEDURE GetSym(VAR R: Files.Rider; VAR ch: CHAR; VAR s: ARRAY OF CHAR;
|
|
|
- VAR line, col: INTEGER);
|
|
|
-VAR i: INTEGER;
|
|
|
+PROCEDURE BuildErrorCallback(IN fname: ARRAY OF CHAR;
|
|
|
+ col, line, error: INTEGER; IN msg: ARRAY OF CHAR);
|
|
|
+VAR e: Editor.Editor;
|
|
|
BEGIN
|
|
|
- WHILE ~R.eof & (ch <= ' ') DO ReadCh(R, ch, line, col) END;
|
|
|
- i := 0;
|
|
|
- IF ~R.eof THEN
|
|
|
- IF ch = '(' THEN
|
|
|
- ReadCh(R, ch, line, col);
|
|
|
- IF ch = '*' THEN ReadCh(R, ch, line, col); SkipComment(R, ch, s)
|
|
|
- ELSE s[i] := ch; INC(i)
|
|
|
+ IF fname[0] # 0X THEN
|
|
|
+ FocusOrOpenFile(fname);
|
|
|
+ e := app.windows(Editor.Editor);
|
|
|
+ IF (col >= 1) & (line >= 1) THEN
|
|
|
+ IF (col = 1) & (line # 1) THEN
|
|
|
+ e.text.MoveToLineCol(line - 1, 256, e.h - 2)
|
|
|
+ ELSE e.text.MoveToLineCol(line, col, e.h - 2)
|
|
|
END
|
|
|
END;
|
|
|
- IF ('A' <= CAP(ch)) & (CAP(ch) <= 'Z') OR (ch = '_') THEN
|
|
|
- WHILE ~R.eof &
|
|
|
- (('A' <= CAP(ch)) & (CAP(ch) <= 'Z') OR
|
|
|
- ('0' <= ch) & (ch <= '9') OR (ch = '_')) DO
|
|
|
- IF i < LEN(s) - 1 THEN s[i] := ch; INC(i) END;
|
|
|
- ReadCh(R, ch, line, col)
|
|
|
- END
|
|
|
- ELSE
|
|
|
- WHILE ~R.eof & (ch > ' ') &
|
|
|
- ~(('A' <= CAP(ch)) & (CAP(ch) <= 'Z') OR
|
|
|
- ('0' <= ch) & (ch <= '9') OR (ch = '_')) DO
|
|
|
- IF i < LEN(s) - 1 THEN s[i] := ch; INC(i) END;
|
|
|
- ReadCh(R, ch, line, col)
|
|
|
- END
|
|
|
- END
|
|
|
- END;
|
|
|
- s[i] := 0X
|
|
|
-END GetSym;
|
|
|
-
|
|
|
-(** Returns true if the two module names are equal.
|
|
|
- modname is the identifier that comes after the keyword MODULE.
|
|
|
- filebase is the file name without the extension; on Windows it
|
|
|
- is allowed to be written in different case. *)
|
|
|
-PROCEDURE EqualModuleNames(modname, filebase: ARRAY OF CHAR): BOOLEAN;
|
|
|
-BEGIN IF Config.isWindows THEN Strings.Cap(modname); Strings.Cap(filebase) END;
|
|
|
-RETURN modname = filebase END EqualModuleNames;
|
|
|
-
|
|
|
-PROCEDURE GetImportedModules(IN fname, modname: ARRAY OF CHAR;
|
|
|
- VAR ok: BOOLEAN; VAR line, col: INTEGER): StrList;
|
|
|
-VAR F: Files.File;
|
|
|
- R: Files.Rider;
|
|
|
- top, p: StrList;
|
|
|
- ch: CHAR;
|
|
|
- mod, s, fname2: ARRAY 256 OF CHAR;
|
|
|
- exit: BOOLEAN;
|
|
|
-BEGIN ok := FALSE; NEW(top); top.next := NIL; p := top;
|
|
|
- F := Files.Old(fname);
|
|
|
- IF F # NIL THEN
|
|
|
- Files.Set(R, F, 0); Files.ReadChar(R, ch);
|
|
|
- line := 1; col := 1; GetSym(R, ch, s, line, col);
|
|
|
- IF s = 'MODULE' THEN GetSym(R, ch, s, line, col);
|
|
|
- IF EqualModuleNames(modname, s) THEN
|
|
|
- GetSym(R, ch, s, line, col);
|
|
|
- IF s = ';' THEN GetSym(R, ch, s, line, col); ok := TRUE;
|
|
|
- IF s = 'IMPORT' THEN GetSym(R, ch, s, line, col); exit := FALSE;
|
|
|
- WHILE ~exit & ('A' <= CAP(s[0])) & (CAP(s[0]) <= 'Z') DO
|
|
|
- mod := s; GetSym(R, ch, s, line, col); fname2[0] := 0X;
|
|
|
- IF s = ':=' THEN GetSym(R, ch, s, line, col);
|
|
|
- mod := s; GetSym(R, ch, s, line, col)
|
|
|
- END;
|
|
|
- IF IsSysModule(mod) OR FindModule(mod, fname2) THEN
|
|
|
- NEW(p.next); p := p.next; p.next := NIL;
|
|
|
- p.s := mod$; p.fname := fname2$
|
|
|
- END;
|
|
|
- IF s = ',' THEN GetSym(R, ch, s, line, col)
|
|
|
- ELSE exit := FALSE
|
|
|
- END
|
|
|
- END
|
|
|
- END
|
|
|
- END
|
|
|
- END
|
|
|
- END
|
|
|
- END ;
|
|
|
-RETURN top.next END GetImportedModules;
|
|
|
-
|
|
|
-PROCEDURE AddUniqueToList(what: StrList; VAR where: StrList);
|
|
|
-VAR p, q, nextP: StrList;
|
|
|
-BEGIN
|
|
|
- IF where = NIL THEN where := what
|
|
|
- ELSE
|
|
|
- p := what;
|
|
|
- WHILE p # NIL DO
|
|
|
- nextP := p.next;
|
|
|
- IF where.s # p.s THEN
|
|
|
- q := where;
|
|
|
- WHILE (q.next # NIL) & (q.next.s # p.s) DO q := q.next END;
|
|
|
- IF q.next = NIL THEN q.next := p; p.next := NIL END
|
|
|
- END;
|
|
|
- p := nextP
|
|
|
- END
|
|
|
- END
|
|
|
-END AddUniqueToList;
|
|
|
-
|
|
|
-PROCEDURE UsedModuleList(IN modname, fname: ARRAY OF CHAR;
|
|
|
- VAR ok: BOOLEAN; VAR errFname: ARRAY OF CHAR;
|
|
|
- VAR errLine, errCol: INTEGER): StrList;
|
|
|
-VAR res, list, list2, p: StrList;
|
|
|
-BEGIN res := NIL; ok := TRUE;
|
|
|
- IF ~IsSysModule(modname) THEN
|
|
|
- list := GetImportedModules(fname, modname, ok, errLine, errCol); p := list;
|
|
|
- IF ok THEN
|
|
|
- WHILE ok & (p # NIL) DO
|
|
|
- list2 := UsedModuleList(p.s, p.fname, ok, errFname, errLine, errCol);
|
|
|
- AddUniqueToList(list2, res);
|
|
|
- p := p.next
|
|
|
- END
|
|
|
- ELSE Strings.Copy(fname, errFname)
|
|
|
- END
|
|
|
- END;
|
|
|
- IF ok THEN
|
|
|
- NEW(p); p.s := modname$; p.fname := fname$; p.next := NIL;
|
|
|
- AddUniqueToList(p, res)
|
|
|
- END ;
|
|
|
-RETURN res END UsedModuleList;
|
|
|
-
|
|
|
-PROCEDURE ImportsGraph(p: StrList): BOOLEAN;
|
|
|
-BEGIN WHILE (p # NIL) & (p.s # 'Graph') DO p := p.next END ;
|
|
|
-RETURN p # NIL END ImportsGraph;
|
|
|
-
|
|
|
-(* "Module.Mod" -> "Module" *)
|
|
|
-PROCEDURE GetModuleName(IN fname: ARRAY OF CHAR; VAR modname: ARRAY OF CHAR);
|
|
|
-VAR i, j: INTEGER;
|
|
|
-BEGIN i := 0; j := 0;
|
|
|
- WHILE fname[i] # 0X DO INC(i) END; DEC(i);
|
|
|
- WHILE (i # -1) & (fname[i] # '/') DO DEC(i) END; INC(i);
|
|
|
- WHILE (fname[i] # 0X) & (fname[i] # '.') DO
|
|
|
- modname[j] := fname[i]; INC(i); INC(j)
|
|
|
+ Editor.PrintText(app.windows(Editor.Editor))
|
|
|
END;
|
|
|
- modname[j] := 0X
|
|
|
-END GetModuleName;
|
|
|
+ ShowError(msg)
|
|
|
+END BuildErrorCallback;
|
|
|
|
|
|
PROCEDURE OnBuild(c: OV.Control);
|
|
|
VAR w: OV.Window;
|
|
|
- graph, ok: BOOLEAN;
|
|
|
+ graph: BOOLEAN;
|
|
|
mainFname, modname, exename, errFname, s: ARRAY 256 OF CHAR;
|
|
|
- errLine, errCol: INTEGER;
|
|
|
- modules: StrList;
|
|
|
+ errLine, errCol, res: INTEGER;
|
|
|
+ modules: Builder.StrList;
|
|
|
e: Editor.Editor;
|
|
|
BEGIN w := c.app.windows;
|
|
|
IF (w # NIL) & (w IS Editor.Editor) THEN
|
|
|
IF Editor.TextChanged(w(Editor.Editor)) THEN FileSave(c) END;
|
|
|
IF w(Editor.Editor).fname[0] # 0X THEN
|
|
|
mainFname := w(Editor.Editor).fname$;
|
|
|
- SetWorkDir(mainFname);
|
|
|
- GetModuleName(mainFname, modname);
|
|
|
- modules := UsedModuleList(modname, mainFname, ok,
|
|
|
- errFname, errLine, errCol);
|
|
|
- IF ok THEN
|
|
|
- graph := ImportsGraph(modules);
|
|
|
- needWindowed := graph;
|
|
|
- IF CompileAll(modules, graph, exename) THEN
|
|
|
- tempWindowed := needWindowed & T.IsFS();
|
|
|
- tempWindowed := FALSE; (*!FIXME Test on Linux and then remove tempWindowed alltogeter*)
|
|
|
- IF tempWindowed THEN T.SwitchToWindow END;
|
|
|
+ Builder.SetWorkDir(mainFname);
|
|
|
+ Builder.GetModuleName(mainFname, modname);
|
|
|
+ modules := Builder.UsedModuleList(modname, mainFname,
|
|
|
+ errFname, errLine, errCol, res);
|
|
|
+ IF res = 0 THEN
|
|
|
+ graph := Builder.ImportsGraph(modules);
|
|
|
+ IF Builder.CompileAll(modules, graph, exename, BuildErrorCallback) THEN
|
|
|
RunProgram(exename)
|
|
|
END
|
|
|
ELSE
|
|
@@ -900,12 +491,12 @@ BEGIN w := OV.NewWindow(); w.modal := TRUE;
|
|
|
L.do.resize(L, 1, Y, W - 2, 1); OV.Add(w, L); INC(Y, 2);
|
|
|
|
|
|
FoStrings.Get('version', s); Strings.Append(' ', s);
|
|
|
- Strings.Append(version, s);
|
|
|
+ Strings.Append(Config.version, s);
|
|
|
L := OV.NewLabel(s); L.align := OV.center;
|
|
|
L.do.resize(L, 1, Y, W - 2, 1); OV.Add(w, L); INC(Y, 2);
|
|
|
|
|
|
FoStrings.Get('copyright', s); Strings.Append(' 2017-', s);
|
|
|
- Int.Append(year, s); Strings.Append(' ', s);
|
|
|
+ Int.Append(Config.year, s); Strings.Append(' ', s);
|
|
|
FoStrings.Append('copyrightBy', s);
|
|
|
|
|
|
L := OV.NewLabel(s); L.align := OV.center;
|
|
@@ -1243,7 +834,7 @@ BEGIN
|
|
|
IF (L < 4) OR (Strings.Pos('.Mod', s, L - 4) = -1) THEN
|
|
|
Strings.Append('.Mod', s)
|
|
|
END;
|
|
|
- Strings.Insert(Editor.stdPath, 0, s);
|
|
|
+ Strings.Insert(Config.stdPath, 0, s);
|
|
|
END
|
|
|
END ParseFileNameArg;
|
|
|
|
|
@@ -1308,8 +899,6 @@ BEGIN
|
|
|
T.Init;
|
|
|
IF T.Done THEN
|
|
|
InitIDE;
|
|
|
- needWindowed := TRUE;
|
|
|
- ResetSysModules;
|
|
|
OpenFiles(fnames);
|
|
|
success := TRUE
|
|
|
ELSE Out.String('Terminal init failed.'); Out.Ln
|