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