1 /********************************************************************/
2 /*                                                                  */
3 /*  s7   Seed7 interpreter                                          */
4 /*  Copyright (C) 1990 - 2000, 2012, 2013, 2015  Thomas Mertes      */
5 /*                2021  Thomas Mertes                               */
6 /*                                                                  */
7 /*  This program is free software; you can redistribute it and/or   */
8 /*  modify it under the terms of the GNU General Public License as  */
9 /*  published by the Free Software Foundation; either version 2 of  */
10 /*  the License, or (at your option) any later version.             */
11 /*                                                                  */
12 /*  This program is distributed in the hope that it will be useful, */
13 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of  */
14 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   */
15 /*  GNU General Public License for more details.                    */
16 /*                                                                  */
17 /*  You should have received a copy of the GNU General Public       */
18 /*  License along with this program; if not, write to the           */
19 /*  Free Software Foundation, Inc., 51 Franklin Street,             */
20 /*  Fifth Floor, Boston, MA  02110-1301, USA.                       */
21 /*                                                                  */
22 /*  Module: General                                                 */
23 /*  File: seed7/src/identutl.c                                      */
24 /*  Changes: 1991 - 1994, 2012, 2013, 2015, 2021  Thomas Mertes     */
25 /*  Content: Procedures to maintain objects of type identType.      */
26 /*                                                                  */
27 /********************************************************************/
28 
29 #define LOG_FUNCTIONS 0
30 #define VERBOSE_EXCEPTIONS 0
31 
32 #include "version.h"
33 
34 #include "stdlib.h"
35 #include "stdio.h"
36 #include "string.h"
37 
38 #include "common.h"
39 #include "data.h"
40 #include "heaputl.h"
41 #include "flistutl.h"
42 #include "chclsutl.h"
43 #include "entutl.h"
44 
45 #undef EXTERN
46 #define EXTERN
47 #include "identutl.h"
48 
49 
50 
new_ident(const_ustriType name,sySizeType length)51 identType new_ident (const_ustriType name, sySizeType length)
52 
53   {
54     register identType created_ident;
55 
56   /* new_ident */
57     logFunction(printf("new_ident\n"););
58     if (ALLOC_RECORD(created_ident, identRecord, count.ident)) {
59       if (!ALLOC_ID_NAME(created_ident->name, length)) {
60         FREE_RECORD(created_ident, identRecord, count.ident);
61         created_ident = NULL;
62       } else {
63         COUNT_ID_NAME(length);
64         memcpy(created_ident->name, name, (size_t) length);
65         created_ident->name[length] = '\0';
66         created_ident->next1 = NULL;
67         created_ident->next2 = NULL;
68         created_ident->prefix_priority = 0;
69         created_ident->infix_priority = 0;
70         created_ident->left_token_priority = -1;
71         created_ident->prefix_token = NULL;
72         created_ident->infix_token = NULL;
73         created_ident->entity = NULL;
74       } /* if */
75     } /* if */
76     logFunction(printf("new_ident -->\n"););
77     return created_ident;
78   } /* new_ident */
79 
80 
81 
free_ident(const_progType currentProg,identType old_ident)82 static void free_ident (const_progType currentProg, identType old_ident)
83 
84   {
85     sySizeType length;
86 
87   /* free_ident */
88     logFunction(printf("free_ident\n"););
89     if (old_ident != NULL) {
90       length = strlen((cstriType) old_ident->name);
91       FREE_ID_NAME(old_ident->name, length);
92       free_ident(currentProg, old_ident->next1);
93       free_ident(currentProg, old_ident->next2);
94       free_entity(currentProg, old_ident->entity);
95       FREE_RECORD(old_ident, identRecord, count.ident);
96     } /* if */
97     logFunction(printf("free_ident ->\n"););
98   } /* free_ident */
99 
100 
101 
get_ident(progType currentProg,const_ustriType name)102 identType get_ident (progType currentProg, const_ustriType name)
103 
104   {
105     register identType ident_found;
106     register int comparison;
107     register boolType searching;
108     sySizeType length;
109 
110   /* get_ident */
111     logFunction(printf("get_ident\n"););
112     length = strlen((const_cstriType) name);
113     if (length == 1 && (op_character(name[0]) ||
114         char_class(name[0]) == LEFTPARENCHAR ||
115         char_class(name[0]) == PARENCHAR)) {
116       ident_found = currentProg->ident.table1[(int) name[0]];
117     } else {
118       if (IDENT_TABLE(currentProg, name, length) == NULL) {
119         ident_found = new_ident(name, length);
120         IDENT_TABLE(currentProg, name, length) = ident_found;
121       } else {
122         ident_found = IDENT_TABLE(currentProg, name, length);
123         searching = TRUE;
124         do {
125           if ((comparison = strncmp((const_cstriType) name,
126               (cstriType) ident_found->name, length)) == 0) {
127             if (ident_found->name[length] == '\0') {
128               searching = FALSE;
129             } else {
130               if (ident_found->next1 == NULL) {
131                 ident_found->next1 = new_ident(name, length);
132                 searching = FALSE;
133               } /* if */
134               ident_found = ident_found->next1;
135             } /* if */
136           } else if (comparison < 0) {
137             if (ident_found->next1 == NULL) {
138               ident_found->next1 = new_ident(name, length);
139               searching = FALSE;
140             } /* if */
141             ident_found = ident_found->next1;
142           } else {
143             if (ident_found->next2 == NULL) {
144               ident_found->next2 = new_ident(name, length);
145               searching = FALSE;
146             } /* if */
147             ident_found = ident_found->next2;
148           } /* if */
149         } while (searching);
150       } /* if */
151     } /* if */
152     logFunction(printf("get_ident -->\n"););
153     return ident_found;
154   } /* get_ident */
155 
156 
157 
close_idents(const_progType currentProg)158 void close_idents (const_progType currentProg)
159 
160   {
161     int position;
162     int character;
163 
164   /* close_idents */
165     logFunction(printf("close_idents\n"););
166     for (position = 0; position < ID_TABLE_SIZE; position++) {
167       free_ident(currentProg, currentProg->ident.table[position]);
168     } /* for */
169     for (character = '!'; character <= '~'; character++) {
170       if (op_character(character) ||
171           char_class(character) == LEFTPARENCHAR ||
172           char_class(character) == PARENCHAR) {
173         free_ident(currentProg, currentProg->ident.table1[character]);
174       } /* if */
175     } /* for */
176     free_ident(currentProg, currentProg->ident.literal);
177     free_ident(currentProg, currentProg->ident.end_of_file);
178     logFunction(printf("close_idents -->\n"););
179   } /* close_idents */
180 
181 
182 
init_idents(progType currentProg,errInfoType * err_info)183 void init_idents (progType currentProg, errInfoType *err_info)
184 
185   {
186     int position;
187     ucharType character;
188 
189   /* init_idents */
190     logFunction(printf("init_ident\n"););
191     for (position = 0; position < ID_TABLE_SIZE; position++) {
192       currentProg->ident.table[position] = NULL;
193     } /* for */
194     for (character = '!'; character <= '~'; character++) {
195       if (op_character(character) ||
196           char_class(character) == LEFTPARENCHAR ||
197           char_class(character) == PARENCHAR) {
198         if ((currentProg->ident.table1[(int) character] =
199              new_ident(&character, (sySizeType) 1)) == NULL) {
200           *err_info = MEMORY_ERROR;
201         } /* if */
202       } /* if */
203     } /* for */
204     if ((currentProg->ident.literal =
205          new_ident((const_ustriType) " *SIMPLE_IDENT* ", (sySizeType) 16)) == NULL) {
206       *err_info = MEMORY_ERROR;
207     } /* if */
208     if ((currentProg->ident.end_of_file =
209          new_ident((const_ustriType) "END OF FILE", (sySizeType) 11)) == NULL) {
210       *err_info = MEMORY_ERROR;
211     } /* if */
212     logFunction(printf("init_ident -->\n"););
213   } /* init_idents */
214