Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from M2Preprocess. */
2 : : /* M2Preprocess.mod provides a mechanism to invoke the C preprocessor.
3 : :
4 : : Copyright (C) 2001-2024 Free Software Foundation, Inc.
5 : : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 : :
7 : : This file is part of GNU Modula-2.
8 : :
9 : : GNU Modula-2 is free software; you can redistribute it and/or modify
10 : : it under the terms of the GNU General Public License as published by
11 : : the Free Software Foundation; either version 3, or (at your option)
12 : : any later version.
13 : :
14 : : GNU Modula-2 is distributed in the hope that it will be useful, but
15 : : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU General Public License
20 : : along with GNU Modula-2; see the file COPYING3. If not see
21 : : <http://www.gnu.org/licenses/>. */
22 : :
23 : : #include "config.h"
24 : : #include "system.h"
25 : : #include <stdbool.h>
26 : : # if !defined (PROC_D)
27 : : # define PROC_D
28 : : typedef void (*PROC_t) (void);
29 : : typedef struct { PROC_t proc; } PROC;
30 : : # endif
31 : :
32 : : # if !defined (FALSE)
33 : : # define FALSE (1==0)
34 : : # endif
35 : :
36 : : #if defined(__cplusplus)
37 : : # undef NULL
38 : : # define NULL 0
39 : : #endif
40 : : #define _M2Preprocess_H
41 : : #define _M2Preprocess_C
42 : :
43 : : # include "GSYSTEM.h"
44 : : # include "GDynamicStrings.h"
45 : : # include "Gchoosetemp.h"
46 : : # include "Gpexecute.h"
47 : : # include "Glibc.h"
48 : : # include "GLists.h"
49 : : # include "GFIO.h"
50 : : # include "GM2Printf.h"
51 : : # include "GM2Options.h"
52 : : # include "GNameKey.h"
53 : : # include "GM2RTS.h"
54 : :
55 : : # define Debugging false
56 : : static Lists_List ListOfFiles;
57 : :
58 : : /*
59 : : PreprocessModule - preprocess a file, filename, returning the new filename
60 : : of the preprocessed file.
61 : : Preprocessing will only occur if requested by the user.
62 : : If no preprocessing was requested then filename is returned.
63 : : If preprocessing occurs then a temporary file is created
64 : : and its name is returned.
65 : : All temporary files will be deleted when the compiler exits.
66 : : outputdep is the filename which will contain the dependency
67 : : info if -M, -MM is provided. outputdep can be NIL in which case
68 : : it is ignored.
69 : : */
70 : :
71 : : extern "C" DynamicStrings_String M2Preprocess_PreprocessModule (DynamicStrings_String filename, bool topSource, bool deleteDep, DynamicStrings_String outputDep);
72 : :
73 : : /*
74 : : MakeSaveTempsFileNameExt - creates and return the temporary filename.ext.
75 : : in the current working directory unless
76 : : SaveTempsDir = obj, when we put it in the dumpdir
77 : : if that is specified (or fallback to '.' if not).
78 : : */
79 : :
80 : : extern "C" DynamicStrings_String M2Preprocess_MakeSaveTempsFileNameExt (DynamicStrings_String filename, DynamicStrings_String ext);
81 : :
82 : : /*
83 : : OnExitDelete - when the application finishes delete filename.
84 : : */
85 : :
86 : : extern "C" DynamicStrings_String M2Preprocess_OnExitDelete (DynamicStrings_String filename);
87 : :
88 : : /*
89 : : RemoveFile - removes a single file, s.
90 : : */
91 : :
92 : : static void RemoveFile (unsigned int w);
93 : :
94 : : /*
95 : : RemoveFiles -
96 : : */
97 : :
98 : : static int RemoveFiles (void);
99 : : static DynamicStrings_String GetFileName (DynamicStrings_String Path);
100 : :
101 : : /*
102 : : MakeSaveTempsFileName - return a temporary file like
103 : : "./filename.{def,mod}.m2i" in the current working directory unless
104 : : SaveTempsDir = obj, when we put it in the dumpdir if that is specified
105 : : (or fallback to '.' if not).
106 : : We have to keep the original extension because that disambiguates .def
107 : : and .mod files (otherwise, we'd need two 'preprocessed' extensions).
108 : : */
109 : :
110 : : static DynamicStrings_String MakeSaveTempsFileName (DynamicStrings_String filename);
111 : :
112 : : /*
113 : : BuildCommandLineExecute - build the cpp command line and execute the command and return
114 : : the tempfile containing the preprocessed source.
115 : : */
116 : :
117 : : static DynamicStrings_String BuildCommandLineExecute (DynamicStrings_String filename, bool topSource, bool deleteDep, DynamicStrings_String command, DynamicStrings_String outputdep);
118 : :
119 : :
120 : : /*
121 : : RemoveFile - removes a single file, s.
122 : : */
123 : :
124 : 15003 : static void RemoveFile (unsigned int w)
125 : : {
126 : 15003 : NameKey_Name n;
127 : :
128 : 15003 : n = static_cast<NameKey_Name> (w);
129 : 15003 : if (Debugging)
130 : : {
131 : : libc_printf ((const char *) "removing: %s\\n", 14, NameKey_KeyToCharStar (n));
132 : : }
133 : 15003 : if ((libc_unlink (NameKey_KeyToCharStar (n))) != 0)
134 : : {} /* empty. */
135 : 15003 : }
136 : :
137 : :
138 : : /*
139 : : RemoveFiles -
140 : : */
141 : :
142 : 12963 : static int RemoveFiles (void)
143 : : {
144 : 12963 : Lists_ForeachItemInListDo (ListOfFiles, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) RemoveFile});
145 : 12963 : return 0;
146 : : /* static analysis guarentees a RETURN statement will be used before here. */
147 : : __builtin_unreachable ();
148 : : }
149 : :
150 : 166878 : static DynamicStrings_String GetFileName (DynamicStrings_String Path)
151 : : {
152 : 166878 : int fstart;
153 : :
154 : : /*
155 : : Return the filename with no path.
156 : : */
157 : 166878 : fstart = DynamicStrings_RIndex (Path, '/', 0);
158 : 166878 : if (fstart == -1)
159 : : {
160 : : fstart = 0;
161 : : }
162 : : else
163 : : {
164 : 12963 : fstart = fstart+1;
165 : : }
166 : 166878 : return DynamicStrings_Dup (DynamicStrings_Slice (Path, fstart, static_cast<int> (DynamicStrings_Length (Path))));
167 : : /* static analysis guarentees a RETURN statement will be used before here. */
168 : : __builtin_unreachable ();
169 : : }
170 : :
171 : :
172 : : /*
173 : : MakeSaveTempsFileName - return a temporary file like
174 : : "./filename.{def,mod}.m2i" in the current working directory unless
175 : : SaveTempsDir = obj, when we put it in the dumpdir if that is specified
176 : : (or fallback to '.' if not).
177 : : We have to keep the original extension because that disambiguates .def
178 : : and .mod files (otherwise, we'd need two 'preprocessed' extensions).
179 : : */
180 : :
181 : 0 : static DynamicStrings_String MakeSaveTempsFileName (DynamicStrings_String filename)
182 : : {
183 : 0 : return M2Preprocess_MakeSaveTempsFileNameExt (filename, DynamicStrings_InitString ((const char *) ".m2i", 4));
184 : : /* static analysis guarentees a RETURN statement will be used before here. */
185 : : __builtin_unreachable ();
186 : : }
187 : :
188 : :
189 : : /*
190 : : BuildCommandLineExecute - build the cpp command line and execute the command and return
191 : : the tempfile containing the preprocessed source.
192 : : */
193 : :
194 : 2040 : static DynamicStrings_String BuildCommandLineExecute (DynamicStrings_String filename, bool topSource, bool deleteDep, DynamicStrings_String command, DynamicStrings_String outputdep)
195 : : {
196 : 2040 : DynamicStrings_String tempfile;
197 : 2040 : DynamicStrings_String commandLine;
198 : :
199 : 2040 : commandLine = DynamicStrings_Dup (command);
200 : 2040 : tempfile = static_cast<DynamicStrings_String> (NULL);
201 : : /* We support MD and MMD for the main file only, at present. */
202 : 2040 : if (topSource || M2Options_PPonly)
203 : : {
204 : 456 : if (M2Options_GetMD ())
205 : : {
206 : 0 : tempfile = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) " -MD ", 5), outputdep);
207 : : }
208 : 456 : else if (M2Options_GetMMD ())
209 : : {
210 : : /* avoid dangling else. */
211 : 0 : tempfile = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) " -MMD ", 6), outputdep);
212 : : }
213 : 0 : if (tempfile != NULL)
214 : : {
215 : 0 : commandLine = DynamicStrings_ConCat (DynamicStrings_Dup (commandLine), DynamicStrings_Dup (tempfile));
216 : : /* We can only add MQ if we already have an MD/MMD. */
217 : 0 : if ((M2Options_GetMQ ()) != NULL)
218 : : {
219 : 0 : tempfile = DynamicStrings_InitStringCharStar (M2Options_GetMQ ());
220 : 0 : commandLine = DynamicStrings_ConCat (DynamicStrings_Dup (commandLine), DynamicStrings_Dup (tempfile));
221 : : }
222 : : }
223 : : }
224 : : /* The output file depends on whether we are in stand-alone PP mode, and
225 : : if an output file is specified. */
226 : 2040 : tempfile = static_cast<DynamicStrings_String> (NULL);
227 : 2040 : if (M2Options_PPonly)
228 : : {
229 : : /* avoid dangling else. */
230 : 0 : if ((M2Options_GetObj ()) != NULL)
231 : : {
232 : 0 : tempfile = DynamicStrings_InitStringCharStar (M2Options_GetObj ());
233 : : }
234 : : }
235 : 2040 : else if (M2Options_SaveTemps)
236 : : {
237 : : /* avoid dangling else. */
238 : 0 : tempfile = MakeSaveTempsFileName (filename);
239 : : }
240 : : else
241 : : {
242 : : /* avoid dangling else. */
243 : 2040 : tempfile = DynamicStrings_InitStringCharStar (choosetemp_make_temp_file (NameKey_KeyToCharStar (NameKey_MakeKey ((const char *) ".m2i", 4))));
244 : : }
245 : 2040 : commandLine = DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_Dup (commandLine), ' '), filename);
246 : 2040 : if (tempfile != NULL)
247 : : {
248 : 2040 : commandLine = DynamicStrings_ConCat (DynamicStrings_ConCat (DynamicStrings_Dup (commandLine), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " -o ", 4))), tempfile);
249 : : }
250 : 2040 : if (((outputdep != NULL) && ((DynamicStrings_Length (outputdep)) > 0)) && ((M2Options_GetM ()) || (M2Options_GetMM ())))
251 : : {
252 : 0 : commandLine = DynamicStrings_ConCat (commandLine, DynamicStrings_ConCat (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " -MF ", 5)), outputdep));
253 : 0 : if (deleteDep && ! M2Options_SaveTemps)
254 : : {
255 : 0 : outputdep = M2Preprocess_OnExitDelete (outputdep);
256 : : }
257 : : }
258 : : /* for now we'll use system */
259 : 2040 : if (M2Options_Verbose)
260 : : {
261 : 0 : M2Printf_fprintf1 (FIO_StdOut, (const char *) "preprocess: %s\\n", 16, (const unsigned char *) &commandLine, (sizeof (commandLine)-1));
262 : : }
263 : 2040 : if ((libc_system (DynamicStrings_string (commandLine))) != 0)
264 : : {
265 : 0 : M2Printf_fprintf1 (FIO_StdErr, (const char *) "C preprocessor failed when preprocessing %s\\n", 45, (const unsigned char *) &filename, (sizeof (filename)-1));
266 : 0 : libc_exit (1);
267 : : }
268 : 2040 : commandLine = DynamicStrings_KillString (commandLine);
269 : 2040 : if (M2Options_SaveTemps)
270 : : {
271 : : return tempfile;
272 : : }
273 : : else
274 : : {
275 : 2040 : return M2Preprocess_OnExitDelete (tempfile);
276 : : }
277 : : /* static analysis guarentees a RETURN statement will be used before here. */
278 : : __builtin_unreachable ();
279 : : }
280 : :
281 : :
282 : : /*
283 : : PreprocessModule - preprocess a file, filename, returning the new filename
284 : : of the preprocessed file.
285 : : Preprocessing will only occur if requested by the user.
286 : : If no preprocessing was requested then filename is returned.
287 : : If preprocessing occurs then a temporary file is created
288 : : and its name is returned.
289 : : All temporary files will be deleted when the compiler exits.
290 : : outputdep is the filename which will contain the dependency
291 : : info if -M, -MM is provided. outputdep can be NIL in which case
292 : : it is ignored.
293 : : */
294 : :
295 : 166878 : extern "C" DynamicStrings_String M2Preprocess_PreprocessModule (DynamicStrings_String filename, bool topSource, bool deleteDep, DynamicStrings_String outputDep)
296 : : {
297 : 166878 : DynamicStrings_String command;
298 : :
299 : 166878 : if (M2Options_GetCpp ())
300 : : {
301 : 2040 : command = M2Options_CppCommandLine ();
302 : 2040 : if ((command == NULL) || (DynamicStrings_EqualArray (command, (const char *) "", 0)))
303 : : {
304 : 0 : return DynamicStrings_Dup (filename);
305 : : }
306 : 2040 : command = BuildCommandLineExecute (filename, topSource, deleteDep, command, outputDep);
307 : 2040 : if (command == NULL)
308 : : {
309 : : return filename;
310 : : }
311 : : else
312 : : {
313 : 2040 : return command;
314 : : }
315 : : }
316 : : else
317 : : {
318 : 164838 : return DynamicStrings_Dup (filename);
319 : : }
320 : : /* static analysis guarentees a RETURN statement will be used before here. */
321 : : __builtin_unreachable ();
322 : : }
323 : :
324 : :
325 : : /*
326 : : MakeSaveTempsFileNameExt - creates and return the temporary filename.ext.
327 : : in the current working directory unless
328 : : SaveTempsDir = obj, when we put it in the dumpdir
329 : : if that is specified (or fallback to '.' if not).
330 : : */
331 : :
332 : 166878 : extern "C" DynamicStrings_String M2Preprocess_MakeSaveTempsFileNameExt (DynamicStrings_String filename, DynamicStrings_String ext)
333 : : {
334 : 166878 : DynamicStrings_String NewName;
335 : 166878 : DynamicStrings_String DumpDir;
336 : 166878 : DynamicStrings_String NewDir;
337 : :
338 : 166878 : NewName = DynamicStrings_ConCat (DynamicStrings_Dup (GetFileName (filename)), ext);
339 : 166878 : NewDir = DynamicStrings_Dup (M2Options_GetSaveTempsDir ());
340 : 166878 : DumpDir = DynamicStrings_Dup (M2Options_GetDumpDir ());
341 : 166878 : if (Debugging)
342 : : {
343 : : M2Printf_fprintf1 (FIO_StdOut, (const char *) "newname: %s", 11, (const unsigned char *) &NewName, (sizeof (NewName)-1));
344 : : M2Printf_fprintf1 (FIO_StdOut, (const char *) " NewDir: %s", 11, (const unsigned char *) &NewDir, (sizeof (NewDir)-1));
345 : : M2Printf_fprintf1 (FIO_StdOut, (const char *) " DumpDir: %s\\n", 14, (const unsigned char *) &DumpDir, (sizeof (DumpDir)-1));
346 : : }
347 : 166878 : if (((NewDir != NULL) && (DynamicStrings_EqualArray (NewDir, (const char *) "obj", 3))) && (DumpDir != NULL))
348 : : {
349 : 0 : return DynamicStrings_ConCat (DumpDir, NewName);
350 : : }
351 : : else
352 : : {
353 : 166878 : return DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "./", 2), NewName);
354 : : }
355 : : /* static analysis guarentees a RETURN statement will be used before here. */
356 : : __builtin_unreachable ();
357 : : }
358 : :
359 : :
360 : : /*
361 : : OnExitDelete - when the application finishes delete filename.
362 : : */
363 : :
364 : 15003 : extern "C" DynamicStrings_String M2Preprocess_OnExitDelete (DynamicStrings_String filename)
365 : : {
366 : 15003 : if (filename != NULL)
367 : : {
368 : 15003 : if (Debugging)
369 : : {
370 : : libc_printf ((const char *) "scheduling removal: %s\\n", 24, DynamicStrings_string (filename));
371 : : }
372 : 15003 : Lists_IncludeItemIntoList (ListOfFiles, NameKey_makekey (DynamicStrings_string (filename)));
373 : : }
374 : 15003 : return filename;
375 : : /* static analysis guarentees a RETURN statement will be used before here. */
376 : : __builtin_unreachable ();
377 : : }
378 : :
379 : 12963 : extern "C" void _M2_M2Preprocess_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
380 : : {
381 : 12963 : Lists_InitList (&ListOfFiles);
382 : 12963 : if ((libc_atexit ((libc_exitP_C) RemoveFiles)) != 0)
383 : : {
384 : 0 : M2RTS_HALT (-1);
385 : : __builtin_unreachable ();
386 : : }
387 : 12963 : }
388 : :
389 : 0 : extern "C" void _M2_M2Preprocess_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
390 : : {
391 : 0 : }
|