Line data Source code
1 : /* do not edit automatically generated by mc from M2Graph. */
2 : /* M2Graph.mod maintains the dependancy graph depth.
3 :
4 : Copyright (C) 2022-2026 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 : # include "GStorage.h"
39 : #if defined(__cplusplus)
40 : # undef NULL
41 : # define NULL 0
42 : #endif
43 : #define _M2Graph_C
44 :
45 : #include "GM2Graph.h"
46 : # include "GStorage.h"
47 : # include "GStrLib.h"
48 : # include "GNumberIO.h"
49 : # include "GStrIO.h"
50 : # include "GNameKey.h"
51 : # include "GLists.h"
52 : # include "GIndexing.h"
53 : # include "GM2Printf.h"
54 : # include "GSymbolTable.h"
55 :
56 : # define Debugging false
57 : typedef struct M2Graph__T1_r M2Graph__T1;
58 :
59 : typedef struct M2Graph__T2_r M2Graph__T2;
60 :
61 : typedef M2Graph__T2 *M2Graph_node;
62 :
63 : typedef enum {M2Graph_initial, M2Graph_started, M2Graph_ordered} M2Graph_state;
64 :
65 : typedef M2Graph__T1 *M2Graph_Graph__opaque;
66 :
67 : struct M2Graph__T1_r {
68 : Indexing_Index nodes;
69 : };
70 :
71 : struct M2Graph__T2_r {
72 : unsigned int moduleSym;
73 : Indexing_Index deps;
74 : M2Graph_state nstate;
75 : };
76 :
77 :
78 : /*
79 : InitGraph - creates and returns an empty graph.
80 : */
81 :
82 : extern "C" M2Graph_Graph M2Graph_InitGraph (void);
83 :
84 : /*
85 : KillGraph - deletes graph and all nodes.
86 : */
87 :
88 : extern "C" void M2Graph_KillGraph (M2Graph_Graph *g);
89 :
90 : /*
91 : AddDependent - adds moduleSym <- dependSym into the graph.
92 : */
93 :
94 : extern "C" void M2Graph_AddDependent (M2Graph_Graph graph, unsigned int moduleSym, unsigned int dependSym);
95 :
96 : /*
97 : SortGraph - returns a List containing the sorted graph.
98 : */
99 :
100 : extern "C" Lists_List M2Graph_SortGraph (M2Graph_Graph g, unsigned int topModule);
101 :
102 : /*
103 : KillNode - deletes the dynamic storage associated with nptr.
104 : */
105 :
106 : static void KillNode (M2Graph_node nptr);
107 :
108 : /*
109 : initNode - create a new node in graph and return the node.
110 : */
111 :
112 : static M2Graph_node initNode (M2Graph_Graph__opaque graph, unsigned int moduleSym);
113 :
114 : /*
115 : getNode - returns a node from graph representing moduleSym.
116 : If the node does not exist it is created.
117 : */
118 :
119 : static M2Graph_node getNode (M2Graph_Graph__opaque graph, unsigned int moduleSym);
120 :
121 : /*
122 : createDependent - mptr imports from dptr.
123 : */
124 :
125 : static void createDependent (M2Graph_node mptr, M2Graph_node dptr);
126 :
127 : /*
128 : resolveImports - recursively resolve imports using ISO Modula-2
129 : rules for the order of module initialization.
130 : */
131 :
132 : static void resolveImports (Lists_List sorted, M2Graph_node nptr);
133 :
134 : /*
135 : setNodesInitial - changes the state of all nodes in graph to initial.
136 : */
137 :
138 : static void setNodesInitial (M2Graph_Graph__opaque g);
139 :
140 :
141 : /*
142 : KillNode - deletes the dynamic storage associated with nptr.
143 : */
144 :
145 0 : static void KillNode (M2Graph_node nptr)
146 : {
147 0 : nptr->deps = Indexing_KillIndex (nptr->deps);
148 0 : }
149 :
150 :
151 : /*
152 : initNode - create a new node in graph and return the node.
153 : */
154 :
155 87306 : static M2Graph_node initNode (M2Graph_Graph__opaque graph, unsigned int moduleSym)
156 : {
157 87306 : M2Graph_node nptr;
158 :
159 87306 : Storage_ALLOCATE ((void **) &nptr, sizeof (M2Graph__T2));
160 87306 : nptr->moduleSym = moduleSym;
161 87306 : nptr->deps = Indexing_InitIndex (1);
162 87306 : nptr->nstate = M2Graph_initial;
163 87306 : Indexing_IncludeIndiceIntoIndex (graph->nodes, reinterpret_cast <void *> (nptr));
164 87306 : return nptr;
165 : /* static analysis guarentees a RETURN statement will be used before here. */
166 : __builtin_unreachable ();
167 : }
168 :
169 :
170 : /*
171 : getNode - returns a node from graph representing moduleSym.
172 : If the node does not exist it is created.
173 : */
174 :
175 584444 : static M2Graph_node getNode (M2Graph_Graph__opaque graph, unsigned int moduleSym)
176 : {
177 584444 : unsigned int i;
178 584444 : unsigned int n;
179 584444 : M2Graph_node nptr;
180 :
181 584444 : i = 1;
182 584444 : n = Indexing_HighIndice (graph->nodes);
183 9356598 : while (i <= n)
184 : {
185 8684848 : nptr = static_cast<M2Graph_node> (Indexing_GetIndice (graph->nodes, i));
186 8684848 : if (nptr->moduleSym == moduleSym)
187 : {
188 : return nptr;
189 : }
190 8187710 : i += 1;
191 : }
192 87306 : return initNode (graph, moduleSym);
193 : /* static analysis guarentees a RETURN statement will be used before here. */
194 : __builtin_unreachable ();
195 : }
196 :
197 :
198 : /*
199 : createDependent - mptr imports from dptr.
200 : */
201 :
202 290880 : static void createDependent (M2Graph_node mptr, M2Graph_node dptr)
203 : {
204 0 : Indexing_IncludeIndiceIntoIndex (mptr->deps, reinterpret_cast <void *> (dptr));
205 290880 : }
206 :
207 :
208 : /*
209 : resolveImports - recursively resolve imports using ISO Modula-2
210 : rules for the order of module initialization.
211 : */
212 :
213 94334 : static void resolveImports (Lists_List sorted, M2Graph_node nptr)
214 : {
215 94334 : unsigned int i;
216 94334 : unsigned int n;
217 94334 : NameKey_Name libname;
218 94334 : NameKey_Name name;
219 :
220 94334 : if (nptr->nstate == M2Graph_initial)
221 : {
222 31460 : nptr->nstate = M2Graph_started;
223 31460 : name = SymbolTable_GetSymName (nptr->moduleSym);
224 31460 : libname = SymbolTable_GetLibName (nptr->moduleSym);
225 31460 : i = 1;
226 31460 : n = Indexing_HighIndice (nptr->deps);
227 31460 : if (Debugging)
228 : {
229 : M2Printf_printf3 ((const char *) "resolving %a [%a] %d dependents\\n", 33, (const unsigned char *) &name, (sizeof (name)-1), (const unsigned char *) &libname, (sizeof (libname)-1), (const unsigned char *) &n, (sizeof (n)-1));
230 : }
231 154570 : while (i <= n)
232 : {
233 91650 : resolveImports (sorted, reinterpret_cast <M2Graph_node> (Indexing_GetIndice (nptr->deps, i)));
234 91650 : i += 1;
235 : }
236 31460 : nptr->nstate = M2Graph_ordered;
237 31460 : Lists_IncludeItemIntoList (sorted, nptr->moduleSym);
238 : }
239 94334 : }
240 :
241 :
242 : /*
243 : setNodesInitial - changes the state of all nodes in graph to initial.
244 : */
245 :
246 2684 : static void setNodesInitial (M2Graph_Graph__opaque g)
247 : {
248 2684 : unsigned int i;
249 2684 : unsigned int n;
250 2684 : M2Graph_node nptr;
251 :
252 2684 : i = 1;
253 2684 : n = Indexing_HighIndice (g->nodes);
254 91754 : while (i <= n)
255 : {
256 86386 : nptr = static_cast<M2Graph_node> (Indexing_GetIndice (g->nodes, i));
257 86386 : nptr->nstate = M2Graph_initial;
258 86386 : i += 1;
259 : }
260 2684 : }
261 :
262 :
263 : /*
264 : InitGraph - creates and returns an empty graph.
265 : */
266 :
267 2684 : extern "C" M2Graph_Graph M2Graph_InitGraph (void)
268 : {
269 2684 : M2Graph_Graph__opaque g;
270 :
271 2684 : Storage_ALLOCATE ((void **) &g, sizeof (M2Graph__T1));
272 2684 : g->nodes = Indexing_InitIndex (1);
273 2684 : return static_cast<M2Graph_Graph> (g);
274 : /* static analysis guarentees a RETURN statement will be used before here. */
275 : __builtin_unreachable ();
276 : }
277 :
278 :
279 : /*
280 : KillGraph - deletes graph and all nodes.
281 : */
282 :
283 0 : extern "C" void M2Graph_KillGraph (M2Graph_Graph *g)
284 : {
285 0 : unsigned int i;
286 0 : unsigned int n;
287 0 : M2Graph_node nptr;
288 :
289 0 : n = Indexing_HighIndice (static_cast<M2Graph_Graph__opaque> ((*g))->nodes);
290 0 : i = 1;
291 0 : while (i <= n)
292 : {
293 0 : nptr = static_cast<M2Graph_node> (Indexing_GetIndice (static_cast<M2Graph_Graph__opaque> ((*g))->nodes, i));
294 0 : KillNode (nptr);
295 0 : i += 1;
296 : }
297 0 : (*g) = static_cast<M2Graph_Graph> (NULL);
298 0 : }
299 :
300 :
301 : /*
302 : AddDependent - adds moduleSym <- dependSym into the graph.
303 : */
304 :
305 334710 : extern "C" void M2Graph_AddDependent (M2Graph_Graph graph, unsigned int moduleSym, unsigned int dependSym)
306 : {
307 334710 : M2Graph_node mptr;
308 334710 : M2Graph_node dptr;
309 :
310 334710 : if (((SymbolTable_IsModule (moduleSym)) || (! (SymbolTable_IsDefinitionForC (moduleSym)))) && ((SymbolTable_IsModule (dependSym)) || (! (SymbolTable_IsDefinitionForC (dependSym)))))
311 : {
312 290880 : mptr = getNode (static_cast<M2Graph_Graph__opaque> (graph), moduleSym);
313 290880 : dptr = getNode (static_cast<M2Graph_Graph__opaque> (graph), dependSym);
314 290880 : createDependent (mptr, dptr);
315 : }
316 334710 : }
317 :
318 :
319 : /*
320 : SortGraph - returns a List containing the sorted graph.
321 : */
322 :
323 2684 : extern "C" Lists_List M2Graph_SortGraph (M2Graph_Graph g, unsigned int topModule)
324 : {
325 2684 : Lists_List sorted;
326 2684 : M2Graph_node nptr;
327 :
328 2684 : Lists_InitList (&sorted);
329 2684 : setNodesInitial (static_cast<M2Graph_Graph__opaque> (g));
330 2684 : nptr = getNode (static_cast<M2Graph_Graph__opaque> (g), topModule);
331 2684 : resolveImports (sorted, nptr);
332 2684 : Lists_RemoveItemFromList (sorted, topModule);
333 2684 : Lists_IncludeItemIntoList (sorted, topModule); /* Ensure topModule is last. */
334 2684 : return sorted; /* Ensure topModule is last. */
335 : /* static analysis guarentees a RETURN statement will be used before here. */
336 : __builtin_unreachable ();
337 : }
338 :
339 0 : extern "C" void _M2_M2Graph_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
340 : {
341 0 : }
342 :
343 0 : extern "C" void _M2_M2Graph_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
344 : {
345 0 : }
|