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-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 <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 390592229 : static NameKey_Name DoMakeKey (NameKey_PtrToChar n, unsigned int higha)
176 : {
177 390592229 : NameKey_Comparison result;
178 390592229 : NameKey_NameNode father;
179 390592229 : NameKey_NameNode child;
180 390592229 : NameKey_Name k;
181 :
182 390592229 : result = FindNodeAndParentInTree (n, &child, &father);
183 390592229 : if (child == NULL)
184 : {
185 16267750 : if (result == NameKey_less)
186 : {
187 6848906 : Storage_ALLOCATE ((void **) &child, sizeof (NameKey_Node));
188 6848906 : father->Left = child;
189 : }
190 : /*
191 : MemIncr (NameKeyTreeMemDiag, 1, 1) ;
192 : MemIncr (NameKeyTreeMemDiag, 2, SIZE (child^))
193 : */
194 9418844 : else if (result == NameKey_greater)
195 : {
196 : /* avoid dangling else. */
197 9418844 : Storage_ALLOCATE ((void **) &child, sizeof (NameKey_Node));
198 9418844 : father->Right = child;
199 : }
200 : /*
201 : MemIncr (NameKeyTreeMemDiag, 1, 1) ;
202 : MemIncr (NameKeyTreeMemDiag, 2, SIZE (child^))
203 : */
204 16267750 : child->Right = NULL;
205 16267750 : child->Left = NULL;
206 16267750 : LastIndice += 1;
207 16267750 : child->Key = LastIndice;
208 16267750 : child->Data = n;
209 16267750 : Indexing_PutIndice (KeyIndex, child->Key, reinterpret_cast <void *> (n));
210 16267750 : k = LastIndice;
211 : }
212 : else
213 : {
214 374324479 : Storage_DEALLOCATE (reinterpret_cast <void **> (&n), higha+1);
215 374324479 : k = child->Key;
216 : }
217 : /*
218 : MemDecr (NameKeyWordMemDiag, 1, 1) ;
219 : MemDecr (NameKeyWordMemDiag, 2, higha + 1)
220 : */
221 390592229 : return k;
222 : /* static analysis guarentees a RETURN statement will be used before here. */
223 : __builtin_unreachable ();
224 : }
225 :
226 :
227 : /*
228 : Compare - return the result of Names[i] with Names[j]
229 : */
230 :
231 6702979788 : static NameKey_Comparison Compare (NameKey_PtrToChar pi, NameKey_Name j)
232 : {
233 6702979788 : NameKey_PtrToChar pj;
234 6702979788 : char c1;
235 6702979788 : char c2;
236 :
237 6702979788 : pj = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (j));
238 6702979788 : c1 = (*pi);
239 6702979788 : c2 = (*pj);
240 13106408179 : while ((c1 != ASCII_nul) || (c2 != ASCII_nul))
241 : {
242 12732083700 : if (c1 < c2)
243 : {
244 : return NameKey_less;
245 : }
246 10380195277 : else if (c1 > c2)
247 : {
248 : /* avoid dangling else. */
249 : return NameKey_greater;
250 : }
251 : else
252 : {
253 : /* avoid dangling else. */
254 6403428391 : pi += 1;
255 6403428391 : pj += 1;
256 6403428391 : c1 = (*pi);
257 6403428391 : c2 = (*pj);
258 : }
259 : }
260 : return NameKey_equal;
261 : /* static analysis guarentees a RETURN statement will be used before here. */
262 : __builtin_unreachable ();
263 : }
264 :
265 :
266 : /*
267 : FindNodeAndParentInTree - search BinaryTree for a name.
268 : If this name is found in the BinaryTree then
269 : child is set to this name and father is set to the node above.
270 : A comparison is returned to assist adding entries into this tree.
271 : */
272 :
273 390592229 : static NameKey_Comparison FindNodeAndParentInTree (NameKey_PtrToChar n, NameKey_NameNode *child, NameKey_NameNode *father)
274 : {
275 390592229 : NameKey_Comparison result;
276 :
277 : /* firstly set up the initial values of child and father, using sentinal node */
278 390592229 : (*father) = BinaryTree;
279 390592229 : (*child) = BinaryTree->Left;
280 390592229 : if ((*child) == NULL)
281 : {
282 : return NameKey_less;
283 : }
284 : else
285 : {
286 6702979788 : do {
287 6702979788 : result = Compare (n, (*child)->Key);
288 6702979788 : if (result == NameKey_less)
289 : {
290 2351888423 : (*father) = (*child);
291 2351888423 : (*child) = (*child)->Left;
292 : }
293 4351091365 : else if (result == NameKey_greater)
294 : {
295 : /* avoid dangling else. */
296 3976766886 : (*father) = (*child);
297 3976766886 : (*child) = (*child)->Right;
298 : }
299 6702979788 : } while (! (((*child) == NULL) || (result == NameKey_equal)));
300 390577277 : return result;
301 : }
302 : /* static analysis guarentees a RETURN statement will be used before here. */
303 : __builtin_unreachable ();
304 : }
305 :
306 :
307 : /*
308 : MakeKey - returns the Key of the symbol, a. If a is not in the
309 : name table then it is added, otherwise the Key of a is returned
310 : directly. Note that the name table has no scope - it merely
311 : presents a more convienient way of expressing strings. By a Key.
312 : */
313 :
314 64352213 : extern "C" NameKey_Name NameKey_MakeKey (const char *a_, unsigned int _a_high)
315 : {
316 64352213 : NameKey_PtrToChar n;
317 64352213 : NameKey_PtrToChar p;
318 64352213 : unsigned int i;
319 64352213 : unsigned int higha;
320 64352213 : char a[_a_high+1];
321 :
322 : /* make a local copy of each unbounded array. */
323 64352213 : memcpy (a, a_, _a_high+1);
324 :
325 128704426 : higha = StrLib_StrLen ((const char *) a, _a_high);
326 64352213 : Storage_ALLOCATE (reinterpret_cast <void **> (&p), higha+1);
327 : /*
328 : MemIncr (NameKeyWordMemDiag, 1, 1) ;
329 : MemIncr (NameKeyWordMemDiag, 2, higha + 1) ;
330 : */
331 64352213 : if (p == NULL)
332 : {
333 0 : M2RTS_HALT (-1); /* Out of memory error. */
334 : __builtin_unreachable ();
335 : }
336 : else
337 : {
338 : n = p;
339 : i = 0;
340 556416876 : while (i < higha)
341 : {
342 492064663 : (*p) = a[i];
343 492064663 : i += 1;
344 492064663 : p += 1;
345 : }
346 64352213 : (*p) = ASCII_nul;
347 64352213 : return DoMakeKey (n, higha);
348 : }
349 : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/NameKey.def", 20, 1);
350 : __builtin_unreachable ();
351 64352213 : }
352 :
353 :
354 : /*
355 : makekey - returns the Key of the symbol, a. If a is not in the
356 : name table then it is added, otherwise the Key of a is returned
357 : directly. Note that the name table has no scope - it merely
358 : presents a more convienient way of expressing strings. By a Key.
359 : These keys last for the duration of compilation.
360 : */
361 :
362 326240058 : extern "C" NameKey_Name NameKey_makekey (void * a)
363 : {
364 326240058 : NameKey_PtrToChar n;
365 326240058 : NameKey_PtrToChar p;
366 326240058 : NameKey_PtrToChar pa;
367 326240058 : unsigned int i;
368 326240058 : unsigned int higha;
369 :
370 326240058 : if (a == NULL)
371 : {
372 : return NameKey_NulName;
373 : }
374 : else
375 : {
376 326240016 : higha = static_cast<unsigned int> (libc_strlen (a));
377 326240016 : Storage_ALLOCATE (reinterpret_cast <void **> (&p), higha+1);
378 326240016 : if (p == NULL)
379 : {
380 0 : M2RTS_HALT (-1); /* Out of memory error. */
381 : __builtin_unreachable ();
382 : }
383 : else
384 : {
385 : n = p;
386 : pa = static_cast<NameKey_PtrToChar> (a);
387 : i = 0;
388 2492203276 : while (i < higha)
389 : {
390 2165963260 : (*p) = (*pa);
391 2165963260 : i += 1;
392 2165963260 : p += 1;
393 2165963260 : pa += 1;
394 : }
395 326240016 : (*p) = ASCII_nul;
396 326240016 : return DoMakeKey (n, higha);
397 : }
398 : }
399 : ReturnException ("/home/worker/buildworker/tiber-lcov/build/gcc/m2/gm2-compiler/NameKey.def", 20, 1);
400 : __builtin_unreachable ();
401 : }
402 :
403 :
404 : /*
405 : GetKey - returns the name, a, of the key, Key.
406 : */
407 :
408 87992 : extern "C" void NameKey_GetKey (NameKey_Name key, char *a, unsigned int _a_high)
409 : {
410 87992 : NameKey_PtrToChar p;
411 87992 : unsigned int i;
412 87992 : unsigned int higha;
413 :
414 87992 : p = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (key));
415 87992 : i = 0;
416 87992 : higha = _a_high;
417 376748 : while (((p != NULL) && (i <= higha)) && ((*p) != ASCII_nul))
418 : {
419 200764 : const_cast<char *>(a)[i] = (*p);
420 200764 : p += 1;
421 200764 : i += 1;
422 : }
423 87992 : if (i <= higha)
424 : {
425 69354 : const_cast<char *>(a)[i] = ASCII_nul;
426 : }
427 87992 : }
428 :
429 :
430 : /*
431 : LengthKey - returns the StrLen of Key.
432 : */
433 :
434 380387 : extern "C" unsigned int NameKey_LengthKey (NameKey_Name Key)
435 : {
436 380387 : unsigned int i;
437 380387 : NameKey_PtrToChar p;
438 :
439 380387 : i = 0;
440 380387 : if (Key != NameKey_NulName)
441 : {
442 379895 : p = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (Key));
443 4497873 : while ((*p) != ASCII_nul)
444 : {
445 3738083 : i += 1;
446 3738083 : p += 1;
447 : }
448 : }
449 380387 : return i;
450 : /* static analysis guarentees a RETURN statement will be used before here. */
451 : __builtin_unreachable ();
452 : }
453 :
454 :
455 : /*
456 : IsKey - returns TRUE if string, a, is currently a key.
457 : We dont use the Compare function, we inline it and avoid
458 : converting, a, into a String, for speed.
459 : */
460 :
461 0 : extern "C" bool NameKey_IsKey (const char *a_, unsigned int _a_high)
462 : {
463 0 : NameKey_NameNode child;
464 0 : NameKey_PtrToChar p;
465 0 : unsigned int i;
466 0 : unsigned int higha;
467 0 : char a[_a_high+1];
468 :
469 : /* make a local copy of each unbounded array. */
470 0 : memcpy (a, a_, _a_high+1);
471 :
472 : /* firstly set up the initial values of child, using sentinal node */
473 0 : child = BinaryTree->Left;
474 0 : if (child != NULL)
475 : {
476 0 : do {
477 0 : i = 0;
478 0 : higha = _a_high;
479 0 : p = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (child->Key));
480 0 : while ((i <= higha) && (a[i] != ASCII_nul))
481 : {
482 0 : if (a[i] < (*p))
483 : {
484 0 : child = child->Left;
485 0 : i = higha;
486 : }
487 0 : else if (a[i] > (*p))
488 : {
489 : /* avoid dangling else. */
490 0 : child = child->Right;
491 0 : i = higha;
492 : }
493 : else
494 : {
495 : /* avoid dangling else. */
496 0 : if ((a[i] == ASCII_nul) || (i == higha))
497 : {
498 : /* avoid gcc warning by using compound statement even if not strictly necessary. */
499 0 : if ((*p) == ASCII_nul)
500 : {
501 : return true;
502 : }
503 : else
504 : {
505 0 : child = child->Left;
506 : }
507 : }
508 0 : p += 1;
509 : }
510 0 : i += 1;
511 : }
512 0 : } while (! (child == NULL));
513 : }
514 : return false;
515 : /* static analysis guarentees a RETURN statement will be used before here. */
516 : __builtin_unreachable ();
517 0 : }
518 :
519 :
520 : /*
521 : KeyToCharStar - returns the C char * string equivalent for, key.
522 : */
523 :
524 0 : extern "C" void NameKey_WriteKey (NameKey_Name key)
525 : {
526 0 : NameKey_PtrToChar s;
527 :
528 0 : s = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (key));
529 0 : while ((s != NULL) && ((*s) != ASCII_nul))
530 : {
531 0 : StdIO_Write ((*s));
532 0 : s += 1;
533 : }
534 0 : }
535 :
536 :
537 : /*
538 : IsSameExcludingCase - returns TRUE if key1 and key2 are
539 : the same. It is case insensitive.
540 : This function deliberately inlines CAP for speed.
541 : */
542 :
543 288960 : extern "C" bool NameKey_IsSameExcludingCase (NameKey_Name key1, NameKey_Name key2)
544 : {
545 288960 : NameKey_PtrToChar pi;
546 288960 : NameKey_PtrToChar pj;
547 288960 : char c1;
548 288960 : char c2;
549 :
550 288960 : if (key1 == key2)
551 : {
552 : return true;
553 : }
554 : else
555 : {
556 288960 : pi = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (key1));
557 288960 : pj = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (key2));
558 288960 : c1 = (*pi);
559 288960 : c2 = (*pj);
560 349452 : while ((c1 != ASCII_nul) && (c2 != ASCII_nul))
561 : {
562 347012 : 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')))))))
563 : {
564 60492 : pi += 1;
565 60492 : pj += 1;
566 60492 : c1 = (*pi);
567 60492 : c2 = (*pj);
568 : }
569 : else
570 : {
571 : /* difference found */
572 : return false;
573 : }
574 : }
575 2440 : return c1 == c2;
576 : }
577 : /* static analysis guarentees a RETURN statement will be used before here. */
578 : __builtin_unreachable ();
579 : }
580 :
581 :
582 : /*
583 : KeyToCharStar - returns the C char * string equivalent for, key.
584 : */
585 :
586 7690945161 : extern "C" void * NameKey_KeyToCharStar (NameKey_Name key)
587 : {
588 7690945161 : if ((key == NameKey_NulName) || (! (Indexing_InBounds (KeyIndex, key))))
589 : {
590 585087954 : return NULL;
591 : }
592 : else
593 : {
594 7105857207 : return Indexing_GetIndice (KeyIndex, key);
595 : }
596 : /* static analysis guarentees a RETURN statement will be used before here. */
597 : __builtin_unreachable ();
598 : }
599 :
600 :
601 : /*
602 : CharKey - returns the key[i] character.
603 : */
604 :
605 4320 : extern "C" char NameKey_CharKey (NameKey_Name key, unsigned int i)
606 : {
607 4320 : NameKey_PtrToChar p;
608 :
609 4320 : if (i >= (NameKey_LengthKey (key)))
610 : {
611 0 : M2RTS_HALT (-1);
612 : __builtin_unreachable ();
613 : }
614 4320 : p = static_cast<NameKey_PtrToChar> (NameKey_KeyToCharStar (key));
615 4320 : p += i;
616 4320 : return (*p);
617 : /* static analysis guarentees a RETURN statement will be used before here. */
618 : __builtin_unreachable ();
619 : }
620 :
621 14952 : extern "C" void _M2_NameKey_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
622 : {
623 : /*
624 : NameKeyWordMemDiag
625 : := InitMemDiagnostic
626 : ('NameKey:Words',
627 : '{0N} total words {1d} consuming {2M} ({2P})') ;
628 : NameKeyTreeMemDiag
629 : := InitMemDiagnostic
630 : ('NameKey:Tree',
631 : '{0N} total tree nodes {1d} consuming {2M} ({2P})') ;
632 : */
633 14952 : LastIndice = 0;
634 14952 : KeyIndex = Indexing_InitIndex (1);
635 14952 : Storage_ALLOCATE ((void **) &BinaryTree, sizeof (NameKey_Node));
636 14952 : BinaryTree->Left = NULL;
637 14952 : }
638 :
639 0 : extern "C" void _M2_NameKey_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
640 : {
641 0 : }
|