1 (* gm2lgen.mod generates the main C function from a list of module names.
3 Copyright (C) 2001-2022 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 This file is part of GNU Modula-2.
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Modula-2; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. *)
27 Date : Fri Sep 15 14:42:17 BST 1989
28 Description: Generates the main C function, from a list of module names.
31 FROM libc IMPORT exit ;
32 FROM ASCII IMPORT eof ;
33 FROM SArgs IMPORT GetArg ;
35 FROM Indexing IMPORT Index, InitIndex, KillIndex, HighIndice, LowIndice,
36 IncludeIndiceIntoIndex, GetIndice ;
38 FROM FIO IMPORT File, StdIn, StdOut, StdErr, WriteChar,
39 ReadString, WriteString, EOF, IsNoError, WriteLine, Close ;
41 FROM DynamicStrings IMPORT String, InitString, KillString, ConCat, RemoveWhitePrefix,
42 EqualArray, Mark, Assign, Fin, InitStringChar, Length, Slice, Equal,
45 FROM M2Printf IMPORT fprintf0, fprintf1, fprintf2 ;
46 FROM SFIO IMPORT OpenToWrite, WriteS, ReadS, OpenToRead ;
47 FROM FormatStrings IMPORT Sprintf0, Sprintf1 ;
51 Comment = '#' ; (* Comment leader *)
58 ExitNeeded : BOOLEAN ;
60 FunctionList : Index ;
65 OpenOutputFile - attempts to open an output file.
68 PROCEDURE OpenOutputFile (s: String) ;
70 fo := OpenToWrite(s) ;
73 fprintf1(StdErr, 'cannot write to: %s\n', s) ;
80 OpenInputFile - attempts to open an input file.
83 PROCEDURE OpenInputFile (s: String) ;
88 fprintf1 (StdErr, 'cannot open: %s\n', s) ;
95 DisplayHelp - display brief help and exit.
98 PROCEDURE DisplayHelp ;
100 fprintf0 (StdErr, 'gm2lgen [--exit] [-fcpp] [-fshared] [-h] [--help] [--main function]\n');
101 fprintf0 (StdErr, ' [-o outputfile] [--terminate] [inputfile]\n');
117 NeedTerminate := TRUE ;
118 NeedInitial := TRUE ;
120 SharedLibrary := FALSE ;
121 MainName := InitString('main') ;
124 WHILE GetArg(s, i) DO
125 IF EqualArray(s, '--exit')
128 ELSIF EqualArray(s, '--terminate')
130 NeedTerminate := FALSE
131 ELSIF EqualArray(s, '--initial')
134 ELSIF EqualArray(s, '-h') OR EqualArray(s, '--help')
137 ELSIF EqualArray(s, '-fshared')
139 SharedLibrary := TRUE
140 ELSIF EqualArray(s, '-fcpp')
143 ELSIF EqualArray(s, '-o')
150 fprintf0(StdErr, 'missing filename option after -o\n') ;
153 ELSIF EqualArray(s, '--main')
158 MainName := Assign(MainName, s)
160 fprintf0(StdErr, 'missing functionname after option -main\n') ;
179 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('\nvoid __attribute__ ((constructor)) init (void);\n')))))) ;
180 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('\nvoid __attribute__ ((constructor)) init (void)\n'))))))
182 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('\nstatic void init (int argc, char *argv[])\n')))))) ;
184 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('{\n'))))));
185 GenInitializationCalls ;
186 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('}\n'))))));
194 PROCEDURE GenFinish ;
198 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('\nvoid __attribute__ ((destructor)) finish (void);\n')))))) ;
199 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('\nvoid __attribute__ ((destructor)) finish (void)\n'))))))
201 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('\nstatic void finish (void)\n'))))))
203 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('{\n')))))) ;
204 GenFinalizationCalls ;
205 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('}\n'))))))
210 GenMain - writes out the main() function together with module initialization
216 FunctionList := InitIndex(1) ;
224 Fin(WriteS(fo, Mark(Sprintf1(Mark(InitString('\nint %s (int argc, char *argv[])\n')), MainName)))) ;
225 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('{\n')))))) ;
226 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' init (argc, argv);\n')))))) ;
227 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' finish ();\n')))))) ;
228 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' return (0);\n')))))) ;
229 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('}\n'))))))
236 GenExternals - writes out the external prototypes for each module initializer.
239 PROCEDURE GenExternals ;
246 Fin(WriteS(fo, Mark(InitString('extern ')))) ;
249 Fin(WriteS(fo, Mark(InitString('"C"'))))
251 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' void exit(int);\n\n')))))) ;
255 Fin(WriteS(fo, Mark(InitString('extern "C"')))) ;
256 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' void RTExceptions_DefaultErrorCatch(void);\n'))))))
258 n := HighIndice(FunctionList) ;
261 funcname := GetIndice(FunctionList, i) ;
262 Fin(WriteS(fo, Mark(InitString('extern ')))) ;
265 Fin(WriteS(fo, Mark(InitString('"C"'))))
267 Fin(WriteS(fo, Mark(Sprintf1(Mark(InitString(' void _M2_%s_init (int argc, char *argv[]);\n')), funcname)))) ;
268 Fin(WriteS(fo, Mark(InitString('extern ')))) ;
271 Fin(WriteS(fo, Mark(InitString('"C"'))))
273 Fin(WriteS(fo, Mark(Sprintf1(Mark(InitString(' void _M2_%s_finish (void);\n')), funcname)))) ;
278 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('\nextern ')))))) ;
281 Fin(WriteS(fo, Mark(InitString('"C"'))))
283 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' void M2RTS_ExecuteTerminationProcedures(void);\n'))))))
287 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString('\nextern ')))))) ;
290 Fin(WriteS(fo, Mark(InitString('"C"'))))
292 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' void M2RTS_ExecuteInitialProcedures(void);\n'))))))
298 GenInitializationCalls - writes out the initialization calls for the modules
299 in the application suit.
302 PROCEDURE GenInitializationCalls ;
307 n := HighIndice(FunctionList) ;
308 i := LowIndice(FunctionList) ;
311 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' try {\n'))))))
320 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' '))))))
322 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' M2RTS_ExecuteInitialProcedures ();\n'))))))
325 funcname := GetIndice(FunctionList, i) ;
328 Fin(WriteS(fo, Mark(InitString(' '))))
332 Fin(WriteS(fo, Mark(Sprintf1(Mark(InitString(' _M2_%s_init (0, (char **)0);\n')),
335 Fin(WriteS(fo, Mark(Sprintf1(Mark(InitString(' _M2_%s_init (argc, argv);\n')),
342 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' }\n')))))) ;
343 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' catch (...) {\n')))))) ;
344 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' RTExceptions_DefaultErrorCatch();\n')))))) ;
345 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' }\n'))))))
347 END GenInitializationCalls ;
351 GenFinalizationCalls - writes out the finalization calls for the modules
352 in the application suit.
355 PROCEDURE GenFinalizationCalls ;
362 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' try {\n'))))))
368 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' '))))))
370 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' M2RTS_ExecuteTerminationProcedures ();\n'))))))
372 n := HighIndice(FunctionList) ;
373 i := LowIndice(FunctionList) ;
375 funcname := GetIndice(FunctionList, n) ;
378 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' '))))))
380 Fin(WriteS(fo, Mark(Sprintf1(Mark(InitString(' _M2_%s_finish ();\n')),
388 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' '))))))
390 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' exit (0);\n'))))))
394 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' }\n')))))) ;
395 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' catch (...) {\n')))))) ;
396 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' RTExceptions_DefaultErrorCatch();\n')))))) ;
397 Fin(WriteS(fo, Mark(Sprintf0(Mark(InitString(' }\n'))))))
399 END GenFinalizationCalls ;
403 BuildFunctionList - reads in the list of functions and stores them.
406 PROCEDURE BuildFunctionList ;
411 s := RemoveComment(RemoveWhitePrefix(ReadS(fi)), Comment) ;
412 IF (NOT Equal(Mark(InitStringChar(Comment)),
413 Mark(Slice(s, 0, Length(Mark(InitStringChar(Comment)))-1)))) AND
414 (NOT EqualArray(s, ''))
416 IncludeIndiceIntoIndex(FunctionList, s)
419 END BuildFunctionList ;