Branch data 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-2025 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 : 63420 : static M2Graph_node initNode (M2Graph_Graph__opaque graph, unsigned int moduleSym)
156 : : {
157 : 63420 : M2Graph_node nptr;
158 : :
159 : 63420 : Storage_ALLOCATE ((void **) &nptr, sizeof (M2Graph__T2));
160 : 63420 : nptr->moduleSym = moduleSym;
161 : 63420 : nptr->deps = Indexing_InitIndex (1);
162 : 63420 : nptr->nstate = M2Graph_initial;
163 : 63420 : Indexing_IncludeIndiceIntoIndex (graph->nodes, reinterpret_cast <void *> (nptr));
164 : 63420 : 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 : 407252 : static M2Graph_node getNode (M2Graph_Graph__opaque graph, unsigned int moduleSym)
176 : : {
177 : 407252 : unsigned int i;
178 : 407252 : unsigned int n;
179 : 407252 : M2Graph_node nptr;
180 : :
181 : 407252 : i = 1;
182 : 407252 : n = Indexing_HighIndice (graph->nodes);
183 : 5267534 : while (i <= n)
184 : : {
185 : 4796862 : nptr = static_cast<M2Graph_node> (Indexing_GetIndice (graph->nodes, i));
186 : 4796862 : if (nptr->moduleSym == moduleSym)
187 : : {
188 : : return nptr;
189 : : }
190 : 4453030 : i += 1;
191 : : }
192 : 63420 : 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 : 202314 : static void createDependent (M2Graph_node mptr, M2Graph_node dptr)
203 : : {
204 : 0 : Indexing_IncludeIndiceIntoIndex (mptr->deps, reinterpret_cast <void *> (dptr));
205 : 202314 : }
206 : :
207 : :
208 : : /*
209 : : resolveImports - recursively resolve imports using ISO Modula-2
210 : : rules for the order of module initialization.
211 : : */
212 : :
213 : 77840 : static void resolveImports (Lists_List sorted, M2Graph_node nptr)
214 : : {
215 : 77840 : unsigned int i;
216 : 77840 : unsigned int n;
217 : 77840 : NameKey_Name libname;
218 : 77840 : NameKey_Name name;
219 : :
220 : 77840 : if (nptr->nstate == M2Graph_initial)
221 : : {
222 : 26600 : nptr->nstate = M2Graph_started;
223 : 26600 : name = SymbolTable_GetSymName (nptr->moduleSym);
224 : 26600 : libname = SymbolTable_GetLibName (nptr->moduleSym);
225 : 26600 : i = 1;
226 : 26600 : n = Indexing_HighIndice (nptr->deps);
227 : 26600 : 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 : 128416 : while (i <= n)
232 : : {
233 : 75216 : resolveImports (sorted, reinterpret_cast <M2Graph_node> (Indexing_GetIndice (nptr->deps, i)));
234 : 75216 : i += 1;
235 : : }
236 : 26600 : nptr->nstate = M2Graph_ordered;
237 : 26600 : Lists_IncludeItemIntoList (sorted, nptr->moduleSym);
238 : : }
239 : 77840 : }
240 : :
241 : :
242 : : /*
243 : : setNodesInitial - changes the state of all nodes in graph to initial.
244 : : */
245 : :
246 : 2624 : static void setNodesInitial (M2Graph_Graph__opaque g)
247 : : {
248 : 2624 : unsigned int i;
249 : 2624 : unsigned int n;
250 : 2624 : M2Graph_node nptr;
251 : :
252 : 2624 : i = 1;
253 : 2624 : n = Indexing_HighIndice (g->nodes);
254 : 67772 : while (i <= n)
255 : : {
256 : 62524 : nptr = static_cast<M2Graph_node> (Indexing_GetIndice (g->nodes, i));
257 : 62524 : nptr->nstate = M2Graph_initial;
258 : 62524 : i += 1;
259 : : }
260 : 2624 : }
261 : :
262 : :
263 : : /*
264 : : InitGraph - creates and returns an empty graph.
265 : : */
266 : :
267 : 2624 : extern "C" M2Graph_Graph M2Graph_InitGraph (void)
268 : : {
269 : 2624 : M2Graph_Graph__opaque g;
270 : :
271 : 2624 : Storage_ALLOCATE ((void **) &g, sizeof (M2Graph__T1));
272 : 2624 : g->nodes = Indexing_InitIndex (1);
273 : 2624 : 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 : 235714 : extern "C" void M2Graph_AddDependent (M2Graph_Graph graph, unsigned int moduleSym, unsigned int dependSym)
306 : : {
307 : 235714 : M2Graph_node mptr;
308 : 235714 : M2Graph_node dptr;
309 : :
310 : 235714 : if (((SymbolTable_IsModule (moduleSym)) || (! (SymbolTable_IsDefinitionForC (moduleSym)))) && ((SymbolTable_IsModule (dependSym)) || (! (SymbolTable_IsDefinitionForC (dependSym)))))
311 : : {
312 : 202314 : mptr = getNode (static_cast<M2Graph_Graph__opaque> (graph), moduleSym);
313 : 202314 : dptr = getNode (static_cast<M2Graph_Graph__opaque> (graph), dependSym);
314 : 202314 : createDependent (mptr, dptr);
315 : : }
316 : 235714 : }
317 : :
318 : :
319 : : /*
320 : : SortGraph - returns a List containing the sorted graph.
321 : : */
322 : :
323 : 2624 : extern "C" Lists_List M2Graph_SortGraph (M2Graph_Graph g, unsigned int topModule)
324 : : {
325 : 2624 : Lists_List sorted;
326 : 2624 : M2Graph_node nptr;
327 : :
328 : 2624 : Lists_InitList (&sorted);
329 : 2624 : setNodesInitial (static_cast<M2Graph_Graph__opaque> (g));
330 : 2624 : nptr = getNode (static_cast<M2Graph_Graph__opaque> (g), topModule);
331 : 2624 : resolveImports (sorted, nptr);
332 : 2624 : Lists_RemoveItemFromList (sorted, topModule);
333 : 2624 : Lists_IncludeItemIntoList (sorted, topModule); /* Ensure topModule is last. */
334 : 2624 : 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 : }
|