Branch data Line data Source code
1 : : /* do not edit automatically generated by mc from NameKey. */
2 : : /* NameKey.mod provides a dynamic binary tree name to key.
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 (TRUE)
33 : : # define TRUE (1==1)
34 : : # endif
35 : :
36 : : # if !defined (FALSE)
37 : : # define FALSE (1==0)
38 : : # endif
39 : :
40 : : # include "GStorage.h"
41 : : # include "Gmcrts.h"
42 : : #if defined(__cplusplus)
43 : : # undef NULL
44 : : # define NULL 0
45 : : #endif
46 : : #define _NameKey_C
47 : :
48 : : #include "GNameKey.h"
49 : : # include "GSYSTEM.h"
50 : : # include "GStorage.h"
51 : : # include "GIndexing.h"
52 : : # include "GStrIO.h"
53 : : # include "GStdIO.h"
54 : : # include "GNumberIO.h"
55 : : # include "GStrLib.h"
56 : : # include "Glibc.h"
57 : : # include "GASCII.h"
58 : : # include "GM2RTS.h"
59 : :
60 : : # define NameKey_NulName 0
61 : : typedef unsigned int NameKey_Name;
62 : :
63 : : typedef struct NameKey_Node_r NameKey_Node;
64 : :
65 : : typedef char *NameKey_PtrToChar;
66 : :
67 : : typedef NameKey_Node *NameKey_NameNode;
68 : :
69 : : typedef enum {NameKey_less, NameKey_equal, NameKey_greater} NameKey_Comparison;
70 : :
71 : : struct NameKey_Node_r {
72 : : NameKey_PtrToChar Data;
73 : : NameKey_Name Key;
74 : : NameKey_NameNode Left;
75 : : NameKey_NameNode Right;
76 : : };
77 : :
78 : : static NameKey_NameNode BinaryTree;
79 : : static Indexing_Index KeyIndex;
80 : : static unsigned int LastIndice;
81 : :
82 : : /*
83 : : MakeKey - returns the Key of the symbol, a. If a is not in the
84 : : name table then it is added, otherwise the Key of a is returned
85 : : directly. Note that the name table has no scope - it merely
86 : : presents a more convienient way of expressing strings. By a Key.
87 : : */
88 : :
89 : : extern "C" NameKey_Name NameKey_MakeKey (const char *a_, unsigned int _a_high);
90 : :
91 : : /*
92 : : makekey - returns the Key of the symbol, a. If a is not in the
93 : : name table then it is added, otherwise the Key of a is returned
94 : : directly. Note that the name table has no scope - it merely
95 : : presents a more convienient way of expressing strings. By a Key.
96 : : These keys last for the duration of compilation.
97 : : */
98 : :
99 : : extern "C" NameKey_Name NameKey_makekey (void * a);
100 : :
101 : : /*
102 : : GetKey - returns the name, a, of the key, Key.
103 : : */
104 : :
105 : : extern "C" void NameKey_GetKey (NameKey_Name key, char *a, unsigned int _a_high);
106 : :
107 : : /*
108 : : LengthKey - returns the StrLen of Key.
109 : : */
110 : :
111 : : extern "C" unsigned int NameKey_LengthKey (NameKey_Name Key);
112 : :
113 : : /*
114 : : IsKey - returns TRUE if string, a, is currently a key.
115 : : We dont use the Compare function, we inline it and avoid
116 : : converting, a, into a String, for speed.
117 : : */
118 : :
119 : : extern "C" bool NameKey_IsKey (const char *a_, unsigned int _a_high);
120 : :
121 : : /*
122 : : KeyToCharStar - returns the C char * string equivalent for, key.
123 : : */
124 : :
125 : : extern "C" void NameKey_WriteKey (NameKey_Name key);
126 : :
127 : : /*
128 : : IsSameExcludingCase - returns TRUE if key1 and key2 are
129 : : the same. It is case insensitive.
130 : : This function deliberately inlines CAP for speed.
131 : : */
132 : :
133 : : extern "C" bool NameKey_IsSameExcludingCase (NameKey_Name key1, NameKey_Name key2);
134 : :
135 : : /*
136 : : KeyToCharStar - returns the C char * string equivalent for, key.
137 : : */
138 : :
139 : : extern "C" void * NameKey_KeyToCharStar (NameKey_Name key);
140 : :
141 : : /*
142 : : CharKey - returns the key[i] character.
143 : : */
144 : :
145 : : extern "C" char NameKey_CharKey (NameKey_Name key, unsigned int i);
146 : :
147 : : /*
148 : : DoMakeKey - finds the name, n, in the tree or else create a name.
149 : : If a name is found then the string, n, is deallocated.
150 : : */
151 : :
152 : : static NameKey_Name DoMakeKey (NameKey_PtrToChar n, unsigned int higha);
153 : :
154 : : /*
155 : : Compare - return the result of Names[i] with Names[j]
156 : : */
157 : :
158 : : static NameKey_Comparison Compare (NameKey_PtrToChar pi, NameKey_Name j);
159 : :
160 : : /*
161 : : FindNodeAndParentInTree - search BinaryTree for a name.
162 : : If this name is found in the BinaryTree then
163 : : child is set to this name and father is set to the node above.
164 : : A comparison is returned to assist adding entries into this tree.
165 : : */
166 : :
167 : : static NameKey_Comparison FindNodeAndParentInTree (NameKey_PtrToChar n, NameKey_NameNode *child, NameKey_NameNode *father);
168 : :
169 : :
170 : : /*
171 : : DoMakeKey - finds the name, n, in the tree or else create a name.
172 : : If a name is found then the string, n, is deallocated.
173 : : */
174 : :
175 : 239400174 : static NameKey_Name DoMakeKey (NameKey_PtrToChar n, unsigned int higha)
176 : : {
177 : 239400174 : NameKey_Comparison result;
178 : 239400174 : NameKey_NameNode father;
179 : 239400174 : NameKey_NameNode child;
180 : 239400174 : NameKey_Name k;
181 : :
182 : 239400174 : result = FindNodeAndParentInTree (n, &child, &father);
183 : 239400174 : if (child == NULL)
184 : : {
185 : 11973222 : if (result == NameKey_less)
186 : : {
187 : 5053149 : Storage_ALLOCATE ((void **) &child, sizeof (NameKey_Node));
188 : 5053149 : father->Left = child;
189 : : }
190 : 6920073 : else if (result == NameKey_greater)
191 : : {
192 : : /* avoid dangling else. */
193 : 6920073 : Storage_ALLOCATE ((void **) &child, sizeof (NameKey_Node));
194 : 6920073 : father->Right = child;
195 : : }
196 : 11973222 : child->Right = NULL;
197 : 11973222 : child->Left = NULL;
198 : 11973222 : LastIndice += 1;
199 : 11973222 : child->Key = LastIndice;
200 : 11973222 : child->Data = n;
201 : 11973222 : Indexing_PutIndice (KeyIndex, child->Key, reinterpret_cast <void *> (n));
202 : 11973222 : k = LastIndice;
203 : : }
204 : : else
205 : : {
206 : 227426952 : Storage_DEALLOCATE (reinterpret_cast <void **> (&n), higha+1);
207 : 227426952 : k = child->Key;
208 : : }
209 : 239400174 : return k;
210 : : /* static analysis guarentees a RETURN statement will be used before here. */
211 : : __builtin_unreachable ();
212 : : }
213 : :
214 : :
215 : : /*
216 : : Compare - return the result of Names[i] with Names[j]
217 : : */
218 : :
219 : 3920276255 : static NameKey_Comparison Compare (NameKey_PtrToChar pi, NameKey_Name j)
220 : : {
221 : 3920276255 : NameKey_PtrToChar pj;
222 : 3920276255 : char c1;
223 : 3920276255 : char c2;
224 : :
225 : 3920276255 : pj = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (j));
226 : 3920276255 : c1 = (*pi);
227 : 3920276255 : c2 = (*pj);
228 : 7558106516 : while ((c1 != ASCII_nul) || (c2 != ASCII_nul))
229 : : {
230 : 7330679564 : if (c1 < c2)
231 : : {
232 : : return NameKey_less;
233 : : }
234 : 5892126255 : else if (c1 > c2)
235 : : {
236 : : /* avoid dangling else. */
237 : : return NameKey_greater;
238 : : }
239 : : else
240 : : {
241 : : /* avoid dangling else. */
242 : 3637830261 : pi += 1;
243 : 3637830261 : pj += 1;
244 : 3637830261 : c1 = (*pi);
245 : 3637830261 : c2 = (*pj);
246 : : }
247 : : }
248 : : return NameKey_equal;
249 : : /* static analysis guarentees a RETURN statement will be used before here. */
250 : : __builtin_unreachable ();
251 : : }
252 : :
253 : :
254 : : /*
255 : : FindNodeAndParentInTree - search BinaryTree for a name.
256 : : If this name is found in the BinaryTree then
257 : : child is set to this name and father is set to the node above.
258 : : A comparison is returned to assist adding entries into this tree.
259 : : */
260 : :
261 : 239400174 : static NameKey_Comparison FindNodeAndParentInTree (NameKey_PtrToChar n, NameKey_NameNode *child, NameKey_NameNode *father)
262 : : {
263 : 239400174 : NameKey_Comparison result;
264 : :
265 : : /* firstly set up the initial values of child and father, using sentinal node */
266 : 239400174 : (*father) = BinaryTree;
267 : 239400174 : (*child) = BinaryTree->Left;
268 : 239400174 : if ((*child) == NULL)
269 : : {
270 : : return NameKey_less;
271 : : }
272 : : else
273 : : {
274 : 3920276255 : do {
275 : 3920276255 : result = Compare (n, (*child)->Key);
276 : 3920276255 : if (result == NameKey_less)
277 : : {
278 : 1438553309 : (*father) = (*child);
279 : 1438553309 : (*child) = (*child)->Left;
280 : : }
281 : 2481722946 : else if (result == NameKey_greater)
282 : : {
283 : : /* avoid dangling else. */
284 : 2254295994 : (*father) = (*child);
285 : 2254295994 : (*child) = (*child)->Right;
286 : : }
287 : 3920276255 : } while (! (((*child) == NULL) || (result == NameKey_equal)));
288 : 239385942 : return result;
289 : : }
290 : : /* static analysis guarentees a RETURN statement will be used before here. */
291 : : __builtin_unreachable ();
292 : : }
293 : :
294 : :
295 : : /*
296 : : MakeKey - returns the Key of the symbol, a. If a is not in the
297 : : name table then it is added, otherwise the Key of a is returned
298 : : directly. Note that the name table has no scope - it merely
299 : : presents a more convienient way of expressing strings. By a Key.
300 : : */
301 : :
302 : 52581085 : extern "C" NameKey_Name NameKey_MakeKey (const char *a_, unsigned int _a_high)
303 : : {
304 : 52581085 : NameKey_PtrToChar n;
305 : 52581085 : NameKey_PtrToChar p;
306 : 52581085 : unsigned int i;
307 : 52581085 : unsigned int higha;
308 : 52581085 : char a[_a_high+1];
309 : :
310 : : /* make a local copy of each unbounded array. */
311 : 52581085 : memcpy (a, a_, _a_high+1);
312 : :
313 : 105162170 : higha = StrLib_StrLen ((const char *) a, _a_high);
314 : 52581085 : Storage_ALLOCATE (reinterpret_cast <void **> (&p), higha+1);
315 : 52581085 : if (p == NULL)
316 : : {
317 : 0 : M2RTS_HALT (-1); /* out of memory error */
318 : : __builtin_unreachable ();
319 : : }
320 : : else
321 : : {
322 : : n = p;
323 : : i = 0;
324 : 433941855 : while (i < higha)
325 : : {
326 : 381360770 : (*p) = a[i];
327 : 381360770 : i += 1;
328 : 381360770 : p += 1;
329 : : }
330 : 52581085 : (*p) = ASCII_nul;
331 : 52581085 : return DoMakeKey (n, higha);
332 : : }
333 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/NameKey.def", 20, 1);
334 : : __builtin_unreachable ();
335 : 52581085 : }
336 : :
337 : :
338 : : /*
339 : : makekey - returns the Key of the symbol, a. If a is not in the
340 : : name table then it is added, otherwise the Key of a is returned
341 : : directly. Note that the name table has no scope - it merely
342 : : presents a more convienient way of expressing strings. By a Key.
343 : : These keys last for the duration of compilation.
344 : : */
345 : :
346 : 186819131 : extern "C" NameKey_Name NameKey_makekey (void * a)
347 : : {
348 : 186819131 : NameKey_PtrToChar n;
349 : 186819131 : NameKey_PtrToChar p;
350 : 186819131 : NameKey_PtrToChar pa;
351 : 186819131 : unsigned int i;
352 : 186819131 : unsigned int higha;
353 : :
354 : 186819131 : if (a == NULL)
355 : : {
356 : : return NameKey_NulName;
357 : : }
358 : : else
359 : : {
360 : 186819089 : higha = static_cast<unsigned int> (libc_strlen (a));
361 : 186819089 : Storage_ALLOCATE (reinterpret_cast <void **> (&p), higha+1);
362 : 186819089 : if (p == NULL)
363 : : {
364 : 0 : M2RTS_HALT (-1); /* out of memory error */
365 : : __builtin_unreachable ();
366 : : }
367 : : else
368 : : {
369 : : n = p;
370 : : pa = static_cast<NameKey_PtrToChar> (a);
371 : : i = 0;
372 : 1503515644 : while (i < higha)
373 : : {
374 : 1316696555 : (*p) = (*pa);
375 : 1316696555 : i += 1;
376 : 1316696555 : p += 1;
377 : 1316696555 : pa += 1;
378 : : }
379 : 186819089 : (*p) = ASCII_nul;
380 : 186819089 : return DoMakeKey (n, higha);
381 : : }
382 : : }
383 : : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/NameKey.def", 20, 1);
384 : : __builtin_unreachable ();
385 : : }
386 : :
387 : :
388 : : /*
389 : : GetKey - returns the name, a, of the key, Key.
390 : : */
391 : :
392 : 62969 : extern "C" void NameKey_GetKey (NameKey_Name key, char *a, unsigned int _a_high)
393 : : {
394 : 62969 : NameKey_PtrToChar p;
395 : 62969 : unsigned int i;
396 : 62969 : unsigned int higha;
397 : :
398 : 62969 : p = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (key));
399 : 62969 : i = 0;
400 : 62969 : higha = _a_high;
401 : 293824 : while (((p != NULL) && (i <= higha)) && ((*p) != ASCII_nul))
402 : : {
403 : 167886 : const_cast<char *>(a)[i] = (*p);
404 : 167886 : p += 1;
405 : 167886 : i += 1;
406 : : }
407 : 62969 : if (i <= higha)
408 : : {
409 : 45200 : const_cast<char *>(a)[i] = ASCII_nul;
410 : : }
411 : 62969 : }
412 : :
413 : :
414 : : /*
415 : : LengthKey - returns the StrLen of Key.
416 : : */
417 : :
418 : 292176 : extern "C" unsigned int NameKey_LengthKey (NameKey_Name Key)
419 : : {
420 : 292176 : unsigned int i;
421 : 292176 : NameKey_PtrToChar p;
422 : :
423 : 292176 : i = 0;
424 : 292176 : if (Key != NameKey_NulName)
425 : : {
426 : 291720 : p = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (Key));
427 : 3880576 : while ((*p) != ASCII_nul)
428 : : {
429 : 3297136 : i += 1;
430 : 3297136 : p += 1;
431 : : }
432 : : }
433 : 292176 : return i;
434 : : /* static analysis guarentees a RETURN statement will be used before here. */
435 : : __builtin_unreachable ();
436 : : }
437 : :
438 : :
439 : : /*
440 : : IsKey - returns TRUE if string, a, is currently a key.
441 : : We dont use the Compare function, we inline it and avoid
442 : : converting, a, into a String, for speed.
443 : : */
444 : :
445 : 0 : extern "C" bool NameKey_IsKey (const char *a_, unsigned int _a_high)
446 : : {
447 : 0 : NameKey_NameNode child;
448 : 0 : NameKey_PtrToChar p;
449 : 0 : unsigned int i;
450 : 0 : unsigned int higha;
451 : 0 : char a[_a_high+1];
452 : :
453 : : /* make a local copy of each unbounded array. */
454 : 0 : memcpy (a, a_, _a_high+1);
455 : :
456 : : /* firstly set up the initial values of child, using sentinal node */
457 : 0 : child = BinaryTree->Left;
458 : 0 : if (child != NULL)
459 : : {
460 : 0 : do {
461 : 0 : i = 0;
462 : 0 : higha = _a_high;
463 : 0 : p = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (child->Key));
464 : 0 : while ((i <= higha) && (a[i] != ASCII_nul))
465 : : {
466 : 0 : if (a[i] < (*p))
467 : : {
468 : 0 : child = child->Left;
469 : 0 : i = higha;
470 : : }
471 : 0 : else if (a[i] > (*p))
472 : : {
473 : : /* avoid dangling else. */
474 : 0 : child = child->Right;
475 : 0 : i = higha;
476 : : }
477 : : else
478 : : {
479 : : /* avoid dangling else. */
480 : 0 : if ((a[i] == ASCII_nul) || (i == higha))
481 : : {
482 : : /* avoid gcc warning by using compound statement even if not strictly necessary. */
483 : 0 : if ((*p) == ASCII_nul)
484 : : {
485 : : return true;
486 : : }
487 : : else
488 : : {
489 : 0 : child = child->Left;
490 : : }
491 : : }
492 : 0 : p += 1;
493 : : }
494 : 0 : i += 1;
495 : : }
496 : 0 : } while (! (child == NULL));
497 : : }
498 : : return false;
499 : : /* static analysis guarentees a RETURN statement will be used before here. */
500 : : __builtin_unreachable ();
501 : 0 : }
502 : :
503 : :
504 : : /*
505 : : KeyToCharStar - returns the C char * string equivalent for, key.
506 : : */
507 : :
508 : 0 : extern "C" void NameKey_WriteKey (NameKey_Name key)
509 : : {
510 : 0 : NameKey_PtrToChar s;
511 : :
512 : 0 : s = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (key));
513 : 0 : while ((s != NULL) && ((*s) != ASCII_nul))
514 : : {
515 : 0 : StdIO_Write ((*s));
516 : 0 : s += 1;
517 : : }
518 : 0 : }
519 : :
520 : :
521 : : /*
522 : : IsSameExcludingCase - returns TRUE if key1 and key2 are
523 : : the same. It is case insensitive.
524 : : This function deliberately inlines CAP for speed.
525 : : */
526 : :
527 : 0 : extern "C" bool NameKey_IsSameExcludingCase (NameKey_Name key1, NameKey_Name key2)
528 : : {
529 : 0 : NameKey_PtrToChar pi;
530 : 0 : NameKey_PtrToChar pj;
531 : 0 : char c1;
532 : 0 : char c2;
533 : :
534 : 0 : if (key1 == key2)
535 : : {
536 : : return true;
537 : : }
538 : : else
539 : : {
540 : 0 : pi = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (key1));
541 : 0 : pj = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (key2));
542 : 0 : c1 = (*pi);
543 : 0 : c2 = (*pj);
544 : 0 : while ((c1 != ASCII_nul) && (c2 != ASCII_nul))
545 : : {
546 : 0 : if (((c1 == c2) || (((c1 >= 'A') && (c1 <= 'Z')) && (c2 == ((char) (( ((unsigned int) (c1))- ((unsigned int) ('A')))+ ((unsigned int) ('a'))))))) || (((c2 >= 'A') && (c2 <= 'Z')) && (c1 == ((char) (( ((unsigned int) (c2))- ((unsigned int) ('A')))+ ((unsigned int) ('a')))))))
547 : : {
548 : 0 : pi += 1;
549 : 0 : pj += 1;
550 : 0 : c1 = (*pi);
551 : 0 : c2 = (*pj);
552 : : }
553 : : else
554 : : {
555 : : /* difference found */
556 : : return false;
557 : : }
558 : : }
559 : 0 : return c1 == c2;
560 : : }
561 : : /* static analysis guarentees a RETURN statement will be used before here. */
562 : : __builtin_unreachable ();
563 : : }
564 : :
565 : :
566 : : /*
567 : : KeyToCharStar - returns the C char * string equivalent for, key.
568 : : */
569 : :
570 : 4471998420 : extern "C" void * NameKey_KeyToCharStar (NameKey_Name key)
571 : : {
572 : 4471998420 : if ((key == NameKey_NulName) || (! (Indexing_InBounds (KeyIndex, key))))
573 : : {
574 : 322203663 : return NULL;
575 : : }
576 : : else
577 : : {
578 : 4149794757 : return Indexing_GetIndice (KeyIndex, key);
579 : : }
580 : : /* static analysis guarentees a RETURN statement will be used before here. */
581 : : __builtin_unreachable ();
582 : : }
583 : :
584 : :
585 : : /*
586 : : CharKey - returns the key[i] character.
587 : : */
588 : :
589 : 3864 : extern "C" char NameKey_CharKey (NameKey_Name key, unsigned int i)
590 : : {
591 : 3864 : NameKey_PtrToChar p;
592 : :
593 : 3864 : if (i >= (NameKey_LengthKey (key)))
594 : : {
595 : 0 : M2RTS_HALT (-1);
596 : : __builtin_unreachable ();
597 : : }
598 : 3864 : p = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (key));
599 : 3864 : p += i;
600 : 3864 : return (*p);
601 : : /* static analysis guarentees a RETURN statement will be used before here. */
602 : : __builtin_unreachable ();
603 : : }
604 : :
605 : 14232 : extern "C" void _M2_NameKey_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
606 : : {
607 : 14232 : LastIndice = 0;
608 : 14232 : KeyIndex = Indexing_InitIndex (1);
609 : 14232 : Storage_ALLOCATE ((void **) &BinaryTree, sizeof (NameKey_Node));
610 : 14232 : BinaryTree->Left = NULL;
611 : 14232 : }
612 : :
613 : 0 : extern "C" void _M2_NameKey_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
614 : : {
615 : 0 : }
|