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