/* do not edit automatically generated by mc from NameKey. */ /* NameKey.mod provides a dynamic binary tree name to key. Copyright (C) 2001-2023 Free Software Foundation, Inc. Contributed by Gaius Mulley . This file is part of GNU Modula-2. GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Modula-2; see the file COPYING3. If not see . */ # if !defined (PROC_D) # define PROC_D typedef void (*PROC_t) (void); typedef struct { PROC_t proc; } PROC; # endif # if !defined (TRUE) # define TRUE (1==1) # endif # if !defined (FALSE) # define FALSE (1==0) # endif #include #include #include # include "GStorage.h" # include "Gmcrts.h" #if defined(__cplusplus) # undef NULL # define NULL 0 #endif #define _NameKey_H #define _NameKey_C # include "GSYSTEM.h" # include "GStorage.h" # include "GIndexing.h" # include "GStrIO.h" # include "GStdIO.h" # include "GNumberIO.h" # include "GStrLib.h" # include "Glibc.h" # include "GASCII.h" # include "GM2RTS.h" # define NameKey_NulName 0 typedef unsigned int NameKey_Name; typedef struct NameKey_Node_r NameKey_Node; typedef char *NameKey_PtrToChar; typedef NameKey_Node *NameKey_NameNode; typedef enum {NameKey_less, NameKey_equal, NameKey_greater} NameKey_Comparison; struct NameKey_Node_r { NameKey_PtrToChar Data; NameKey_Name Key; NameKey_NameNode Left; NameKey_NameNode Right; }; static NameKey_NameNode BinaryTree; static Indexing_Index KeyIndex; static unsigned int LastIndice; /* MakeKey - returns the Key of the symbol, a. If a is not in the name table then it is added, otherwise the Key of a is returned directly. Note that the name table has no scope - it merely presents a more convienient way of expressing strings. By a Key. */ extern "C" NameKey_Name NameKey_MakeKey (const char *a_, unsigned int _a_high); /* makekey - returns the Key of the symbol, a. If a is not in the name table then it is added, otherwise the Key of a is returned directly. Note that the name table has no scope - it merely presents a more convienient way of expressing strings. By a Key. These keys last for the duration of compilation. */ extern "C" NameKey_Name NameKey_makekey (void * a); /* GetKey - returns the name, a, of the key, Key. */ extern "C" void NameKey_GetKey (NameKey_Name key, char *a, unsigned int _a_high); /* LengthKey - returns the StrLen of Key. */ extern "C" unsigned int NameKey_LengthKey (NameKey_Name Key); /* IsKey - returns TRUE if string, a, is currently a key. We dont use the Compare function, we inline it and avoid converting, a, into a String, for speed. */ extern "C" unsigned int NameKey_IsKey (const char *a_, unsigned int _a_high); /* KeyToCharStar - returns the C char * string equivalent for, key. */ extern "C" void NameKey_WriteKey (NameKey_Name key); /* IsSameExcludingCase - returns TRUE if key1 and key2 are the same. It is case insensitive. This function deliberately inlines CAP for speed. */ extern "C" unsigned int NameKey_IsSameExcludingCase (NameKey_Name key1, NameKey_Name key2); /* KeyToCharStar - returns the C char * string equivalent for, key. */ extern "C" void * NameKey_KeyToCharStar (NameKey_Name key); /* CharKey - returns the key[i] character. */ extern "C" char NameKey_CharKey (NameKey_Name key, unsigned int i); /* DoMakeKey - finds the name, n, in the tree or else create a name. If a name is found then the string, n, is deallocated. */ static NameKey_Name DoMakeKey (NameKey_PtrToChar n, unsigned int higha); /* Compare - return the result of Names[i] with Names[j] */ static NameKey_Comparison Compare (NameKey_PtrToChar pi, NameKey_Name j); /* FindNodeAndParentInTree - search BinaryTree for a name. If this name is found in the BinaryTree then child is set to this name and father is set to the node above. A comparison is returned to assist adding entries into this tree. */ static NameKey_Comparison FindNodeAndParentInTree (NameKey_PtrToChar n, NameKey_NameNode *child, NameKey_NameNode *father); /* DoMakeKey - finds the name, n, in the tree or else create a name. If a name is found then the string, n, is deallocated. */ static NameKey_Name DoMakeKey (NameKey_PtrToChar n, unsigned int higha) { NameKey_Comparison result; NameKey_NameNode father; NameKey_NameNode child; NameKey_Name k; result = FindNodeAndParentInTree (n, &child, &father); if (child == NULL) { if (result == NameKey_less) { Storage_ALLOCATE ((void **) &child, sizeof (NameKey_Node)); father->Left = child; } else if (result == NameKey_greater) { /* avoid dangling else. */ Storage_ALLOCATE ((void **) &child, sizeof (NameKey_Node)); father->Right = child; } child->Right = NULL; child->Left = NULL; LastIndice += 1; child->Key = LastIndice; child->Data = n; Indexing_PutIndice (KeyIndex, child->Key, reinterpret_cast (n)); k = LastIndice; } else { Storage_DEALLOCATE (reinterpret_cast (&n), higha+1); k = child->Key; } return k; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* Compare - return the result of Names[i] with Names[j] */ static NameKey_Comparison Compare (NameKey_PtrToChar pi, NameKey_Name j) { NameKey_PtrToChar pj; char c1; char c2; pj = static_cast (NameKey_KeyToCharStar (j)); c1 = (*pi); c2 = (*pj); while ((c1 != ASCII_nul) || (c2 != ASCII_nul)) { if (c1 < c2) { return NameKey_less; } else if (c1 > c2) { /* avoid dangling else. */ return NameKey_greater; } else { /* avoid dangling else. */ pi += 1; pj += 1; c1 = (*pi); c2 = (*pj); } } return NameKey_equal; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* FindNodeAndParentInTree - search BinaryTree for a name. If this name is found in the BinaryTree then child is set to this name and father is set to the node above. A comparison is returned to assist adding entries into this tree. */ static NameKey_Comparison FindNodeAndParentInTree (NameKey_PtrToChar n, NameKey_NameNode *child, NameKey_NameNode *father) { NameKey_Comparison result; /* firstly set up the initial values of child and father, using sentinal node */ (*father) = BinaryTree; (*child) = BinaryTree->Left; if ((*child) == NULL) { return NameKey_less; } else { do { result = Compare (n, (*child)->Key); if (result == NameKey_less) { (*father) = (*child); (*child) = (*child)->Left; } else if (result == NameKey_greater) { /* avoid dangling else. */ (*father) = (*child); (*child) = (*child)->Right; } } while (! (((*child) == NULL) || (result == NameKey_equal))); return result; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* MakeKey - returns the Key of the symbol, a. If a is not in the name table then it is added, otherwise the Key of a is returned directly. Note that the name table has no scope - it merely presents a more convienient way of expressing strings. By a Key. */ extern "C" NameKey_Name NameKey_MakeKey (const char *a_, unsigned int _a_high) { NameKey_PtrToChar n; NameKey_PtrToChar p; unsigned int i; unsigned int higha; char a[_a_high+1]; /* make a local copy of each unbounded array. */ memcpy (a, a_, _a_high+1); higha = StrLib_StrLen ((const char *) a, _a_high); Storage_ALLOCATE (reinterpret_cast (&p), higha+1); if (p == NULL) { M2RTS_HALT (-1); /* out of memory error */ __builtin_unreachable (); } else { n = p; i = 0; while (i < higha) { (*p) = a[i]; i += 1; p += 1; } (*p) = ASCII_nul; return DoMakeKey (n, higha); } ReturnException ("../../gcc-read-write/gcc/m2/gm2-compiler/NameKey.def", 20, 1); __builtin_unreachable (); } /* makekey - returns the Key of the symbol, a. If a is not in the name table then it is added, otherwise the Key of a is returned directly. Note that the name table has no scope - it merely presents a more convienient way of expressing strings. By a Key. These keys last for the duration of compilation. */ extern "C" NameKey_Name NameKey_makekey (void * a) { NameKey_PtrToChar n; NameKey_PtrToChar p; NameKey_PtrToChar pa; unsigned int i; unsigned int higha; if (a == NULL) { return NameKey_NulName; } else { higha = static_cast (libc_strlen (a)); Storage_ALLOCATE (reinterpret_cast (&p), higha+1); if (p == NULL) { M2RTS_HALT (-1); /* out of memory error */ __builtin_unreachable (); } else { n = p; pa = static_cast (a); i = 0; while (i < higha) { (*p) = (*pa); i += 1; p += 1; pa += 1; } (*p) = ASCII_nul; return DoMakeKey (n, higha); } } ReturnException ("../../gcc-read-write/gcc/m2/gm2-compiler/NameKey.def", 20, 1); __builtin_unreachable (); } /* GetKey - returns the name, a, of the key, Key. */ extern "C" void NameKey_GetKey (NameKey_Name key, char *a, unsigned int _a_high) { NameKey_PtrToChar p; unsigned int i; unsigned int higha; p = static_cast (NameKey_KeyToCharStar (key)); i = 0; higha = _a_high; while (((p != NULL) && (i <= higha)) && ((*p) != ASCII_nul)) { a[i] = (*p); p += 1; i += 1; } if (i <= higha) { a[i] = ASCII_nul; } } /* LengthKey - returns the StrLen of Key. */ extern "C" unsigned int NameKey_LengthKey (NameKey_Name Key) { unsigned int i; NameKey_PtrToChar p; p = static_cast (NameKey_KeyToCharStar (Key)); i = 0; while ((*p) != ASCII_nul) { i += 1; p += 1; } return i; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* IsKey - returns TRUE if string, a, is currently a key. We dont use the Compare function, we inline it and avoid converting, a, into a String, for speed. */ extern "C" unsigned int NameKey_IsKey (const char *a_, unsigned int _a_high) { NameKey_NameNode child; NameKey_PtrToChar p; unsigned int i; unsigned int higha; char a[_a_high+1]; /* make a local copy of each unbounded array. */ memcpy (a, a_, _a_high+1); /* firstly set up the initial values of child, using sentinal node */ child = BinaryTree->Left; if (child != NULL) { do { i = 0; higha = _a_high; p = static_cast (NameKey_KeyToCharStar (child->Key)); while ((i <= higha) && (a[i] != ASCII_nul)) { if (a[i] < (*p)) { child = child->Left; i = higha; } else if (a[i] > (*p)) { /* avoid dangling else. */ child = child->Right; i = higha; } else { /* avoid dangling else. */ if ((a[i] == ASCII_nul) || (i == higha)) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if ((*p) == ASCII_nul) { return TRUE; } else { child = child->Left; } } p += 1; } i += 1; } } while (! (child == NULL)); } return FALSE; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* KeyToCharStar - returns the C char * string equivalent for, key. */ extern "C" void NameKey_WriteKey (NameKey_Name key) { NameKey_PtrToChar s; s = static_cast (NameKey_KeyToCharStar (key)); while ((s != NULL) && ((*s) != ASCII_nul)) { StdIO_Write ((*s)); s += 1; } } /* IsSameExcludingCase - returns TRUE if key1 and key2 are the same. It is case insensitive. This function deliberately inlines CAP for speed. */ extern "C" unsigned int NameKey_IsSameExcludingCase (NameKey_Name key1, NameKey_Name key2) { NameKey_PtrToChar pi; NameKey_PtrToChar pj; char c1; char c2; if (key1 == key2) { return TRUE; } else { pi = static_cast (NameKey_KeyToCharStar (key1)); pj = static_cast (NameKey_KeyToCharStar (key2)); c1 = (*pi); c2 = (*pj); while ((c1 != ASCII_nul) && (c2 != ASCII_nul)) { 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'))))))) { pi += 1; pj += 1; c1 = (*pi); c2 = (*pj); } else { /* difference found */ return FALSE; } } return c1 == c2; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* KeyToCharStar - returns the C char * string equivalent for, key. */ extern "C" void * NameKey_KeyToCharStar (NameKey_Name key) { if ((key == NameKey_NulName) || (! (Indexing_InBounds (KeyIndex, key)))) { return NULL; } else { return Indexing_GetIndice (KeyIndex, key); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* CharKey - returns the key[i] character. */ extern "C" char NameKey_CharKey (NameKey_Name key, unsigned int i) { NameKey_PtrToChar p; if (i >= (NameKey_LengthKey (key))) { M2RTS_HALT (-1); __builtin_unreachable (); } p = static_cast (NameKey_KeyToCharStar (key)); p += i; return (*p); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } extern "C" void _M2_NameKey_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { LastIndice = 0; KeyIndex = Indexing_InitIndex (1); Storage_ALLOCATE ((void **) &BinaryTree, sizeof (NameKey_Node)); BinaryTree->Left = NULL; } extern "C" void _M2_NameKey_finish (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { }