]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/mc-boot/GnameKey.c
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / mc-boot / GnameKey.c
CommitLineData
1eee94d3
GM
1/* do not edit automatically generated by mc from nameKey. */
2/* nameKey.mod provides a dynamic binary tree name to key.
3
83ffe9cd 4Copyright (C) 2015-2023 Free Software Foundation, Inc.
1eee94d3
GM
5Contributed by Gaius Mulley <gaius@glam.ac.uk>.
6
7This file is part of GNU Modula-2.
8
9GNU Modula-2 is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 3, or (at your option)
12any later version.
13
14GNU Modula-2 is distributed in the hope that it will be useful, but
15WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along 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# if !defined (PROC_D)
26# define PROC_D
27 typedef void (*PROC_t) (void);
28 typedef struct { PROC_t proc; } PROC;
29# endif
30
31# if !defined (TRUE)
32# define TRUE (1==1)
33# endif
34
35# if !defined (FALSE)
36# define FALSE (1==0)
37# endif
38
39# include "GStorage.h"
40# include "Gmcrts.h"
41#if defined(__cplusplus)
42# undef NULL
43# define NULL 0
44#endif
45#define _nameKey_H
46#define _nameKey_C
47
48# include "GSYSTEM.h"
49# include "GStorage.h"
50# include "GIndexing.h"
51# include "GStrIO.h"
52# include "GStdIO.h"
53# include "GNumberIO.h"
54# include "GStrLib.h"
55# include "Glibc.h"
56# include "GASCII.h"
57# include "GM2RTS.h"
58
59# define nameKey_NulName 0
60typedef unsigned int nameKey_Name;
61
62typedef struct nameKey__T1_r nameKey__T1;
63
64typedef char *nameKey_ptrToChar;
65
66typedef nameKey__T1 *nameKey_nameNode;
67
68typedef enum {nameKey_less, nameKey_equal, nameKey_greater} nameKey_comparison;
69
70struct nameKey__T1_r {
71 nameKey_ptrToChar data;
72 nameKey_Name key;
73 nameKey_nameNode left;
74 nameKey_nameNode right;
75 };
76
77static nameKey_nameNode binaryTree;
78static Indexing_Index keyIndex;
79static unsigned int lastIndice;
80
81/*
82 makeKey - returns the Key of the symbol, a. If a is not in the
83 name table then it is added, otherwise the Key of a is returned
84 directly. Note that the name table has no scope - it merely
85 presents a more convienient way of expressing strings. By a Key.
86*/
87
88extern "C" nameKey_Name nameKey_makeKey (const char *a_, unsigned int _a_high);
89
90/*
91 makekey - returns the Key of the symbol, a. If a is not in the
92 name table then it is added, otherwise the Key of a is returned
93 directly. Note that the name table has no scope - it merely
94 presents a more convienient way of expressing strings. By a Key.
95 These keys last for the duration of compilation.
96*/
97
98extern "C" nameKey_Name nameKey_makekey (void * a);
99
100/*
101 getKey - returns the name, a, of the key, Key.
102*/
103
104extern "C" void nameKey_getKey (nameKey_Name key, char *a, unsigned int _a_high);
105
106/*
107 lengthKey - returns the StrLen of Key.
108*/
109
110extern "C" unsigned int nameKey_lengthKey (nameKey_Name key);
111
112/*
113 isKey - returns TRUE if string, a, is currently a key.
114 We dont use the Compare function, we inline it and avoid
115 converting, a, into a String, for speed.
116*/
117
118extern "C" unsigned int nameKey_isKey (const char *a_, unsigned int _a_high);
119
120/*
121 keyToCharStar - returns the C char * string equivalent for, key.
122*/
123
124extern "C" void nameKey_writeKey (nameKey_Name key);
125
126/*
127 isSameExcludingCase - returns TRUE if key1 and key2 are
128 the same. It is case insensitive.
129 This function deliberately inlines CAP for speed.
130*/
131
132extern "C" unsigned int nameKey_isSameExcludingCase (nameKey_Name key1, nameKey_Name key2);
133
134/*
135 keyToCharStar - returns the C char * string equivalent for, key.
136*/
137
138extern "C" void * nameKey_keyToCharStar (nameKey_Name key);
139
140/*
141 doMakeKey - finds the name, n, in the tree or else create a name.
142 If a name is found then the string, n, is deallocated.
143*/
144
145static nameKey_Name doMakeKey (nameKey_ptrToChar n, unsigned int higha);
146
147/*
148 compare - return the result of Names[i] with Names[j]
149*/
150
151static nameKey_comparison compare (nameKey_ptrToChar pi, nameKey_Name j);
152
153/*
154 findNodeAndParentInTree - search BinaryTree for a name.
155 If this name is found in the BinaryTree then
156 child is set to this name and father is set to the node above.
157 A comparison is returned to assist adding entries into this tree.
158*/
159
160static nameKey_comparison findNodeAndParentInTree (nameKey_ptrToChar n, nameKey_nameNode *child, nameKey_nameNode *father);
161
162
163/*
164 doMakeKey - finds the name, n, in the tree or else create a name.
165 If a name is found then the string, n, is deallocated.
166*/
167
168static nameKey_Name doMakeKey (nameKey_ptrToChar n, unsigned int higha)
169{
170 nameKey_comparison result;
171 nameKey_nameNode father;
172 nameKey_nameNode child;
173 nameKey_Name k;
174
175 result = findNodeAndParentInTree (n, &child, &father);
176 if (child == NULL)
177 {
178 if (result == nameKey_less)
179 {
180 Storage_ALLOCATE ((void **) &child, sizeof (nameKey__T1));
181 father->left = child;
182 }
183 else if (result == nameKey_greater)
184 {
185 /* avoid dangling else. */
186 Storage_ALLOCATE ((void **) &child, sizeof (nameKey__T1));
187 father->right = child;
188 }
189 child->right = NULL;
190 child->left = NULL;
191 lastIndice += 1;
192 child->key = lastIndice;
193 child->data = n;
194 Indexing_PutIndice (keyIndex, child->key, reinterpret_cast<void *> (n));
195 k = lastIndice;
196 }
197 else
198 {
199 Storage_DEALLOCATE (reinterpret_cast<void **> (&n), higha+1);
200 k = child->key;
201 }
202 return k;
203 /* static analysis guarentees a RETURN statement will be used before here. */
204 __builtin_unreachable ();
205}
206
207
208/*
209 compare - return the result of Names[i] with Names[j]
210*/
211
212static nameKey_comparison compare (nameKey_ptrToChar pi, nameKey_Name j)
213{
214 nameKey_ptrToChar pj;
215 char c1;
216 char c2;
217
218 pj = static_cast<nameKey_ptrToChar> (nameKey_keyToCharStar (j));
219 c1 = (*pi);
220 c2 = (*pj);
221 while ((c1 != ASCII_nul) || (c2 != ASCII_nul))
222 {
223 if (c1 < c2)
224 {
225 return nameKey_less;
226 }
227 else if (c1 > c2)
228 {
229 /* avoid dangling else. */
230 return nameKey_greater;
231 }
232 else
233 {
234 /* avoid dangling else. */
235 pi += 1;
236 pj += 1;
237 c1 = (*pi);
238 c2 = (*pj);
239 }
240 }
241 return nameKey_equal;
242 /* static analysis guarentees a RETURN statement will be used before here. */
243 __builtin_unreachable ();
244}
245
246
247/*
248 findNodeAndParentInTree - search BinaryTree for a name.
249 If this name is found in the BinaryTree then
250 child is set to this name and father is set to the node above.
251 A comparison is returned to assist adding entries into this tree.
252*/
253
254static nameKey_comparison findNodeAndParentInTree (nameKey_ptrToChar n, nameKey_nameNode *child, nameKey_nameNode *father)
255{
256 nameKey_comparison result;
257
258 /* firstly set up the initial values of child and father, using sentinal node */
259 (*father) = binaryTree;
260 (*child) = binaryTree->left;
261 if ((*child) == NULL)
262 {
263 return nameKey_less;
264 }
265 else
266 {
267 do {
268 result = compare (n, (*child)->key);
269 if (result == nameKey_less)
270 {
271 (*father) = (*child);
272 (*child) = (*child)->left;
273 }
274 else if (result == nameKey_greater)
275 {
276 /* avoid dangling else. */
277 (*father) = (*child);
278 (*child) = (*child)->right;
279 }
280 } while (! (((*child) == NULL) || (result == nameKey_equal)));
281 return result;
282 }
283 /* static analysis guarentees a RETURN statement will be used before here. */
284 __builtin_unreachable ();
285}
286
287
288/*
289 makeKey - returns the Key of the symbol, a. If a is not in the
290 name table then it is added, otherwise the Key of a is returned
291 directly. Note that the name table has no scope - it merely
292 presents a more convienient way of expressing strings. By a Key.
293*/
294
295extern "C" nameKey_Name nameKey_makeKey (const char *a_, unsigned int _a_high)
296{
297 nameKey_ptrToChar n;
298 nameKey_ptrToChar p;
299 unsigned int i;
300 unsigned int higha;
301 char a[_a_high+1];
302
303 /* make a local copy of each unbounded array. */
304 memcpy (a, a_, _a_high+1);
305
306 higha = StrLib_StrLen ((const char *) a, _a_high);
307 Storage_ALLOCATE (reinterpret_cast<void **> (&p), higha+1);
308 if (p == NULL)
309 {
310 M2RTS_HALT (-1); /* out of memory error */
311 __builtin_unreachable ();
312 }
313 else
314 {
315 n = p;
316 i = 0;
317 while (i < higha)
318 {
319 (*p) = a[i];
320 i += 1;
321 p += 1;
322 }
323 (*p) = ASCII_nul;
324 return doMakeKey (n, higha);
325 }
326 ReturnException ("../../gcc-git-devel-modula2/gcc/m2/mc/nameKey.def", 20, 1);
327 __builtin_unreachable ();
328}
329
330
331/*
332 makekey - returns the Key of the symbol, a. If a is not in the
333 name table then it is added, otherwise the Key of a is returned
334 directly. Note that the name table has no scope - it merely
335 presents a more convienient way of expressing strings. By a Key.
336 These keys last for the duration of compilation.
337*/
338
339extern "C" nameKey_Name nameKey_makekey (void * a)
340{
341 nameKey_ptrToChar n;
342 nameKey_ptrToChar p;
343 nameKey_ptrToChar pa;
344 unsigned int i;
345 unsigned int higha;
346
347 if (a == NULL)
348 {
349 return nameKey_NulName;
350 }
351 else
352 {
353 higha = static_cast<unsigned int> (libc_strlen (a));
354 Storage_ALLOCATE (reinterpret_cast<void **> (&p), higha+1);
355 if (p == NULL)
356 {
357 M2RTS_HALT (-1); /* out of memory error */
358 __builtin_unreachable ();
359 }
360 else
361 {
362 n = p;
363 pa = static_cast<nameKey_ptrToChar> (a);
364 i = 0;
365 while (i < higha)
366 {
367 (*p) = (*pa);
368 i += 1;
369 p += 1;
370 pa += 1;
371 }
372 (*p) = ASCII_nul;
373 return doMakeKey (n, higha);
374 }
375 }
376 ReturnException ("../../gcc-git-devel-modula2/gcc/m2/mc/nameKey.def", 20, 1);
377 __builtin_unreachable ();
378}
379
380
381/*
382 getKey - returns the name, a, of the key, Key.
383*/
384
385extern "C" void nameKey_getKey (nameKey_Name key, char *a, unsigned int _a_high)
386{
387 nameKey_ptrToChar p;
388 unsigned int i;
389 unsigned int higha;
390
391 p = static_cast<nameKey_ptrToChar> (nameKey_keyToCharStar (key));
392 i = 0;
393 higha = _a_high;
394 while (((p != NULL) && (i <= higha)) && ((*p) != ASCII_nul))
395 {
396 a[i] = (*p);
397 p += 1;
398 i += 1;
399 }
400 if (i <= higha)
401 {
402 a[i] = ASCII_nul;
403 }
404}
405
406
407/*
408 lengthKey - returns the StrLen of Key.
409*/
410
411extern "C" unsigned int nameKey_lengthKey (nameKey_Name key)
412{
413 unsigned int i;
414 nameKey_ptrToChar p;
415
416 p = static_cast<nameKey_ptrToChar> (nameKey_keyToCharStar (key));
417 i = 0;
418 while ((*p) != ASCII_nul)
419 {
420 i += 1;
421 p += 1;
422 }
423 return i;
424 /* static analysis guarentees a RETURN statement will be used before here. */
425 __builtin_unreachable ();
426}
427
428
429/*
430 isKey - returns TRUE if string, a, is currently a key.
431 We dont use the Compare function, we inline it and avoid
432 converting, a, into a String, for speed.
433*/
434
435extern "C" unsigned int nameKey_isKey (const char *a_, unsigned int _a_high)
436{
437 nameKey_nameNode child;
438 nameKey_ptrToChar p;
439 unsigned int i;
440 unsigned int higha;
441 char a[_a_high+1];
442
443 /* make a local copy of each unbounded array. */
444 memcpy (a, a_, _a_high+1);
445
446 /* firstly set up the initial values of child, using sentinal node */
447 child = binaryTree->left;
448 if (child != NULL)
449 {
450 do {
451 i = 0;
452 higha = _a_high;
453 p = static_cast<nameKey_ptrToChar> (nameKey_keyToCharStar (child->key));
454 while ((i <= higha) && (a[i] != ASCII_nul))
455 {
456 if (a[i] < (*p))
457 {
458 child = child->left;
459 i = higha;
460 }
461 else if (a[i] > (*p))
462 {
463 /* avoid dangling else. */
464 child = child->right;
465 i = higha;
466 }
467 else
468 {
469 /* avoid dangling else. */
470 if ((a[i] == ASCII_nul) || (i == higha))
471 {
472 /* avoid gcc warning by using compound statement even if not strictly necessary. */
473 if ((*p) == ASCII_nul)
474 {
475 return TRUE;
476 }
477 else
478 {
479 child = child->left;
480 }
481 }
482 p += 1;
483 }
484 i += 1;
485 }
486 } while (! (child == NULL));
487 }
488 return FALSE;
489 /* static analysis guarentees a RETURN statement will be used before here. */
490 __builtin_unreachable ();
491}
492
493
494/*
495 keyToCharStar - returns the C char * string equivalent for, key.
496*/
497
498extern "C" void nameKey_writeKey (nameKey_Name key)
499{
500 nameKey_ptrToChar s;
501
502 s = static_cast<nameKey_ptrToChar> (nameKey_keyToCharStar (key));
503 while ((s != NULL) && ((*s) != ASCII_nul))
504 {
505 StdIO_Write ((*s));
506 s += 1;
507 }
508}
509
510
511/*
512 isSameExcludingCase - returns TRUE if key1 and key2 are
513 the same. It is case insensitive.
514 This function deliberately inlines CAP for speed.
515*/
516
517extern "C" unsigned int nameKey_isSameExcludingCase (nameKey_Name key1, nameKey_Name key2)
518{
519 nameKey_ptrToChar pi;
520 nameKey_ptrToChar pj;
521 char c1;
522 char c2;
523
524 if (key1 == key2)
525 {
526 return TRUE;
527 }
528 else
529 {
530 pi = static_cast<nameKey_ptrToChar> (nameKey_keyToCharStar (key1));
531 pj = static_cast<nameKey_ptrToChar> (nameKey_keyToCharStar (key2));
532 c1 = (*pi);
533 c2 = (*pj);
534 while ((c1 != ASCII_nul) && (c2 != ASCII_nul))
535 {
536 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')))))))
537 {
538 pi += 1;
539 pj += 1;
540 c1 = (*pi);
541 c2 = (*pj);
542 }
543 else
544 {
545 /* difference found */
546 return FALSE;
547 }
548 }
549 return c1 == c2;
550 }
551 /* static analysis guarentees a RETURN statement will be used before here. */
552 __builtin_unreachable ();
553}
554
555
556/*
557 keyToCharStar - returns the C char * string equivalent for, key.
558*/
559
560extern "C" void * nameKey_keyToCharStar (nameKey_Name key)
561{
562 if ((key == nameKey_NulName) || (! (Indexing_InBounds (keyIndex, key))))
563 {
564 return NULL;
565 }
566 else
567 {
568 return Indexing_GetIndice (keyIndex, key);
569 }
570 /* static analysis guarentees a RETURN statement will be used before here. */
571 __builtin_unreachable ();
572}
573
574extern "C" void _M2_nameKey_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
575{
576 lastIndice = 0;
577 keyIndex = Indexing_InitIndex (1);
578 Storage_ALLOCATE ((void **) &binaryTree, sizeof (nameKey__T1));
579 binaryTree->left = NULL;
580}
581
582extern "C" void _M2_nameKey_finish (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
583{
584}