|
dvander@27
|
1 |
/* Pawn compiler - maintenance of various lists |
|
dvander@27
|
2 |
* |
|
dvander@27
|
3 |
* o Name list (aliases) |
|
dvander@27
|
4 |
* o Include path list |
|
faluco@62
|
5 |
* o Macro definitions (text substitutions) |
|
faluco@62
|
6 |
* o Documentation tags and automatic listings |
|
faluco@62
|
7 |
* o Debug strings |
|
dvander@27
|
8 |
* |
|
dvander@27
|
9 |
* Copyright (c) ITB CompuPhase, 2001-2006 |
|
dvander@27
|
10 |
* |
|
dvander@27
|
11 |
* This software is provided "as-is", without any express or implied warranty. |
|
dvander@27
|
12 |
* In no event will the authors be held liable for any damages arising from |
|
dvander@27
|
13 |
* the use of this software. |
|
dvander@27
|
14 |
* |
|
dvander@27
|
15 |
* Permission is granted to anyone to use this software for any purpose, |
|
dvander@27
|
16 |
* including commercial applications, and to alter it and redistribute it |
|
dvander@27
|
17 |
* freely, subject to the following restrictions: |
|
dvander@27
|
18 |
* |
|
dvander@27
|
19 |
* 1. The origin of this software must not be misrepresented; you must not |
|
dvander@27
|
20 |
* claim that you wrote the original software. If you use this software in |
|
dvander@27
|
21 |
* a product, an acknowledgment in the product documentation would be |
|
dvander@27
|
22 |
* appreciated but is not required. |
|
dvander@27
|
23 |
* 2. Altered source versions must be plainly marked as such, and must not be |
|
dvander@27
|
24 |
* misrepresented as being the original software. |
|
dvander@27
|
25 |
* 3. This notice may not be removed or altered from any source distribution. |
|
dvander@27
|
26 |
* |
|
dvander@365
|
27 |
* Version: $Id$ |
|
dvander@27
|
28 |
*/ |
|
dvander@27
|
29 |
#include <assert.h> |
|
dvander@27
|
30 |
#include <limits.h> |
|
dvander@27
|
31 |
#include <stdlib.h> |
|
dvander@27
|
32 |
#include <string.h> |
|
dvander@27
|
33 |
#include "sc.h" |
|
ds@1266
|
34 |
#include "lstring.h" |
|
dvander@27
|
35 |
|
|
dvander@27
|
36 |
#if defined FORTIFY |
|
dvander@27
|
37 |
#include <alloc/fortify.h> |
|
dvander@27
|
38 |
#endif |
|
dvander@27
|
39 |
|
|
dvander@27
|
40 |
/* a "private" implementation of strdup(), so that porting |
|
dvander@27
|
41 |
* to other memory allocators becomes easier. |
|
dvander@27
|
42 |
* By S�ren Hannibal. |
|
dvander@27
|
43 |
*/ |
|
dvander@27
|
44 |
SC_FUNC char* duplicatestring(const char* sourcestring) |
|
dvander@27
|
45 |
{ |
|
dvander@27
|
46 |
char* result=(char*)malloc(strlen(sourcestring)+1); |
|
dvander@27
|
47 |
strcpy(result,sourcestring); |
|
dvander@27
|
48 |
return result; |
|
dvander@27
|
49 |
} |
|
dvander@27
|
50 |
|
|
dvander@27
|
51 |
|
|
dvander@27
|
52 |
static stringpair *insert_stringpair(stringpair *root,char *first,char *second,int matchlength) |
|
dvander@27
|
53 |
{ |
|
dvander@27
|
54 |
stringpair *cur,*pred; |
|
dvander@27
|
55 |
|
|
dvander@27
|
56 |
assert(root!=NULL); |
|
dvander@27
|
57 |
assert(first!=NULL); |
|
dvander@27
|
58 |
assert(second!=NULL); |
|
dvander@27
|
59 |
/* create a new node, and check whether all is okay */ |
|
dvander@27
|
60 |
if ((cur=(stringpair*)malloc(sizeof(stringpair)))==NULL) |
|
dvander@27
|
61 |
return NULL; |
|
dvander@27
|
62 |
cur->first=duplicatestring(first); |
|
dvander@27
|
63 |
cur->second=duplicatestring(second); |
|
dvander@27
|
64 |
cur->matchlength=matchlength; |
|
ds@1267
|
65 |
cur->documentation=NULL; |
|
dvander@27
|
66 |
if (cur->first==NULL || cur->second==NULL) { |
|
dvander@27
|
67 |
if (cur->first!=NULL) |
|
dvander@27
|
68 |
free(cur->first); |
|
dvander@27
|
69 |
if (cur->second!=NULL) |
|
dvander@27
|
70 |
free(cur->second); |
|
dvander@27
|
71 |
free(cur); |
|
dvander@27
|
72 |
return NULL; |
|
dvander@27
|
73 |
} /* if */ |
|
dvander@27
|
74 |
/* link the node to the tree, find the position */ |
|
dvander@27
|
75 |
for (pred=root; pred->next!=NULL && strcmp(pred->next->first,first)<0; pred=pred->next) |
|
dvander@27
|
76 |
/* nothing */; |
|
dvander@27
|
77 |
cur->next=pred->next; |
|
dvander@27
|
78 |
pred->next=cur; |
|
dvander@27
|
79 |
return cur; |
|
dvander@27
|
80 |
} |
|
dvander@27
|
81 |
|
|
dvander@27
|
82 |
static void delete_stringpairtable(stringpair *root) |
|
dvander@27
|
83 |
{ |
|
dvander@27
|
84 |
stringpair *cur, *next; |
|
dvander@27
|
85 |
|
|
dvander@27
|
86 |
assert(root!=NULL); |
|
dvander@27
|
87 |
cur=root->next; |
|
dvander@27
|
88 |
while (cur!=NULL) { |
|
dvander@27
|
89 |
next=cur->next; |
|
dvander@27
|
90 |
assert(cur->first!=NULL); |
|
dvander@27
|
91 |
assert(cur->second!=NULL); |
|
dvander@27
|
92 |
free(cur->first); |
|
dvander@27
|
93 |
free(cur->second); |
|
dvander@27
|
94 |
free(cur); |
|
dvander@27
|
95 |
cur=next; |
|
dvander@27
|
96 |
} /* while */ |
|
dvander@27
|
97 |
memset(root,0,sizeof(stringpair)); |
|
dvander@27
|
98 |
} |
|
dvander@27
|
99 |
|
|
dvander@27
|
100 |
static stringpair *find_stringpair(stringpair *cur,char *first,int matchlength) |
|
dvander@27
|
101 |
{ |
|
dvander@27
|
102 |
int result=0; |
|
dvander@27
|
103 |
|
|
dvander@27
|
104 |
assert(matchlength>0); /* the function cannot handle zero-length comparison */ |
|
dvander@27
|
105 |
assert(first!=NULL); |
|
dvander@27
|
106 |
while (cur!=NULL && result<=0) { |
|
dvander@27
|
107 |
result=(int)*cur->first - (int)*first; |
|
dvander@27
|
108 |
if (result==0 && matchlength==cur->matchlength) { |
|
dvander@27
|
109 |
result=strncmp(cur->first,first,matchlength); |
|
dvander@27
|
110 |
if (result==0) |
|
dvander@27
|
111 |
return cur; |
|
dvander@27
|
112 |
} /* if */ |
|
dvander@27
|
113 |
cur=cur->next; |
|
dvander@27
|
114 |
} /* while */ |
|
dvander@27
|
115 |
return NULL; |
|
dvander@27
|
116 |
} |
|
dvander@27
|
117 |
|
|
dvander@27
|
118 |
static int delete_stringpair(stringpair *root,stringpair *item) |
|
dvander@27
|
119 |
{ |
|
dvander@27
|
120 |
stringpair *cur; |
|
dvander@27
|
121 |
|
|
dvander@27
|
122 |
assert(root!=NULL); |
|
dvander@27
|
123 |
cur=root; |
|
dvander@27
|
124 |
while (cur->next!=NULL) { |
|
dvander@27
|
125 |
if (cur->next==item) { |
|
dvander@27
|
126 |
cur->next=item->next; /* unlink from list */ |
|
dvander@27
|
127 |
assert(item->first!=NULL); |
|
dvander@27
|
128 |
assert(item->second!=NULL); |
|
dvander@27
|
129 |
free(item->first); |
|
dvander@27
|
130 |
free(item->second); |
|
dvander@27
|
131 |
free(item); |
|
dvander@27
|
132 |
return TRUE; |
|
dvander@27
|
133 |
} /* if */ |
|
dvander@27
|
134 |
cur=cur->next; |
|
dvander@27
|
135 |
} /* while */ |
|
dvander@27
|
136 |
return FALSE; |
|
dvander@27
|
137 |
} |
|
dvander@27
|
138 |
|
|
dvander@27
|
139 |
/* ----- string list functions ----------------------------------- */ |
|
dvander@27
|
140 |
static stringlist *insert_string(stringlist *root,char *string) |
|
dvander@27
|
141 |
{ |
|
dvander@27
|
142 |
stringlist *cur; |
|
dvander@27
|
143 |
|
|
dvander@27
|
144 |
assert(string!=NULL); |
|
dvander@27
|
145 |
if ((cur=(stringlist*)malloc(sizeof(stringlist)))==NULL) |
|
dvander@27
|
146 |
error(103); /* insufficient memory (fatal error) */ |
|
dvander@27
|
147 |
if ((cur->line=duplicatestring(string))==NULL) |
|
dvander@27
|
148 |
error(103); /* insufficient memory (fatal error) */ |
|
dvander@27
|
149 |
/* insert as "last" */ |
|
dvander@27
|
150 |
assert(root!=NULL); |
|
dvander@27
|
151 |
while (root->next!=NULL) |
|
dvander@27
|
152 |
root=root->next; |
|
dvander@27
|
153 |
cur->next=root->next; |
|
dvander@27
|
154 |
root->next=cur; |
|
dvander@27
|
155 |
return cur; |
|
dvander@27
|
156 |
} |
|
dvander@27
|
157 |
|
|
dvander@27
|
158 |
static char *get_string(stringlist *root,int index) |
|
dvander@27
|
159 |
{ |
|
dvander@27
|
160 |
stringlist *cur; |
|
dvander@27
|
161 |
|
|
dvander@27
|
162 |
assert(root!=NULL); |
|
dvander@27
|
163 |
cur=root->next; |
|
dvander@27
|
164 |
while (cur!=NULL && index-->0) |
|
dvander@27
|
165 |
cur=cur->next; |
|
dvander@27
|
166 |
if (cur!=NULL) { |
|
dvander@27
|
167 |
assert(cur->line!=NULL); |
|
dvander@27
|
168 |
return cur->line; |
|
dvander@27
|
169 |
} /* if */ |
|
dvander@27
|
170 |
return NULL; |
|
dvander@27
|
171 |
} |
|
dvander@27
|
172 |
|
|
dvander@27
|
173 |
static int delete_string(stringlist *root,int index) |
|
dvander@27
|
174 |
{ |
|
dvander@27
|
175 |
stringlist *cur,*item; |
|
dvander@27
|
176 |
|
|
dvander@27
|
177 |
assert(root!=NULL); |
|
dvander@27
|
178 |
for (cur=root; cur->next!=NULL && index>0; cur=cur->next,index--) |
|
dvander@27
|
179 |
/* nothing */; |
|
dvander@27
|
180 |
if (cur->next!=NULL) { |
|
dvander@27
|
181 |
item=cur->next; |
|
dvander@27
|
182 |
cur->next=item->next; /* unlink from list */ |
|
dvander@27
|
183 |
assert(item->line!=NULL); |
|
dvander@27
|
184 |
free(item->line); |
|
dvander@27
|
185 |
free(item); |
|
dvander@27
|
186 |
return TRUE; |
|
dvander@27
|
187 |
} /* if */ |
|
dvander@27
|
188 |
return FALSE; |
|
dvander@27
|
189 |
} |
|
dvander@27
|
190 |
|
|
dvander@27
|
191 |
SC_FUNC void delete_stringtable(stringlist *root) |
|
dvander@27
|
192 |
{ |
|
dvander@27
|
193 |
stringlist *cur,*next; |
|
dvander@27
|
194 |
|
|
dvander@27
|
195 |
assert(root!=NULL); |
|
dvander@27
|
196 |
cur=root->next; |
|
dvander@27
|
197 |
while (cur!=NULL) { |
|
dvander@27
|
198 |
next=cur->next; |
|
dvander@27
|
199 |
assert(cur->line!=NULL); |
|
dvander@27
|
200 |
free(cur->line); |
|
dvander@27
|
201 |
free(cur); |
|
dvander@27
|
202 |
cur=next; |
|
dvander@27
|
203 |
} /* while */ |
|
dvander@27
|
204 |
memset(root,0,sizeof(stringlist)); |
|
dvander@27
|
205 |
} |
|
dvander@27
|
206 |
|
|
dvander@27
|
207 |
|
|
dvander@27
|
208 |
/* ----- alias table --------------------------------------------- */ |
|
dvander@27
|
209 |
static stringpair alias_tab = {NULL, NULL, NULL}; /* alias table */ |
|
dvander@27
|
210 |
|
|
dvander@27
|
211 |
SC_FUNC stringpair *insert_alias(char *name,char *alias) |
|
dvander@27
|
212 |
{ |
|
dvander@27
|
213 |
stringpair *cur; |
|
dvander@27
|
214 |
|
|
dvander@27
|
215 |
assert(name!=NULL); |
|
dvander@27
|
216 |
assert(strlen(name)<=sNAMEMAX); |
|
dvander@27
|
217 |
assert(alias!=NULL); |
|
dvander@27
|
218 |
assert(strlen(alias)<=sNAMEMAX); |
|
dvander@27
|
219 |
if ((cur=insert_stringpair(&alias_tab,name,alias,strlen(name)))==NULL) |
|
dvander@27
|
220 |
error(103); /* insufficient memory (fatal error) */ |
|
dvander@27
|
221 |
return cur; |
|
dvander@27
|
222 |
} |
|
dvander@27
|
223 |
|
|
dvander@27
|
224 |
SC_FUNC int lookup_alias(char *target,char *name) |
|
dvander@27
|
225 |
{ |
|
dvander@27
|
226 |
stringpair *cur=find_stringpair(alias_tab.next,name,strlen(name)); |
|
dvander@27
|
227 |
if (cur!=NULL) { |
|
dvander@27
|
228 |
assert(strlen(cur->second)<=sNAMEMAX); |
|
dvander@27
|
229 |
strcpy(target,cur->second); |
|
dvander@27
|
230 |
} /* if */ |
|
dvander@27
|
231 |
return cur!=NULL; |
|
dvander@27
|
232 |
} |
|
dvander@27
|
233 |
|
|
dvander@27
|
234 |
SC_FUNC void delete_aliastable(void) |
|
dvander@27
|
235 |
{ |
|
dvander@27
|
236 |
delete_stringpairtable(&alias_tab); |
|
dvander@27
|
237 |
} |
|
dvander@27
|
238 |
|
|
dvander@27
|
239 |
/* ----- include paths list -------------------------------------- */ |
|
dvander@27
|
240 |
static stringlist includepaths = {NULL, NULL}; /* directory list for include files */ |
|
dvander@27
|
241 |
|
|
dvander@27
|
242 |
SC_FUNC stringlist *insert_path(char *path) |
|
dvander@27
|
243 |
{ |
|
dvander@27
|
244 |
return insert_string(&includepaths,path); |
|
dvander@27
|
245 |
} |
|
dvander@27
|
246 |
|
|
dvander@27
|
247 |
SC_FUNC char *get_path(int index) |
|
dvander@27
|
248 |
{ |
|
dvander@27
|
249 |
return get_string(&includepaths,index); |
|
dvander@27
|
250 |
} |
|
dvander@27
|
251 |
|
|
dvander@27
|
252 |
SC_FUNC void delete_pathtable(void) |
|
dvander@27
|
253 |
{ |
|
dvander@27
|
254 |
delete_stringtable(&includepaths); |
|
dvander@27
|
255 |
assert(includepaths.next==NULL); |
|
dvander@27
|
256 |
} |
|
dvander@27
|
257 |
|
|
dvander@27
|
258 |
|
|
dvander@27
|
259 |
/* ----- text substitution patterns ------------------------------ */ |
|
dvander@27
|
260 |
#if !defined NO_DEFINE |
|
dvander@27
|
261 |
|
|
dvander@27
|
262 |
static stringpair substpair = { NULL, NULL, NULL}; /* list of substitution pairs */ |
|
dvander@27
|
263 |
|
|
dvander@27
|
264 |
static stringpair *substindex['z'-PUBLIC_CHAR+1]; /* quick index to first character */ |
|
dvander@27
|
265 |
static void adjustindex(char c) |
|
dvander@27
|
266 |
{ |
|
dvander@27
|
267 |
stringpair *cur; |
|
dvander@27
|
268 |
assert(c>='A' && c<='Z' || c>='a' && c<='z' || c=='_' || c==PUBLIC_CHAR); |
|
dvander@27
|
269 |
assert(PUBLIC_CHAR<'A' && 'A'<'_' && '_'<'z'); |
|
dvander@27
|
270 |
|
|
dvander@27
|
271 |
for (cur=substpair.next; cur!=NULL && cur->first[0]!=c; cur=cur->next) |
|
dvander@27
|
272 |
/* nothing */; |
|
dvander@27
|
273 |
substindex[(int)c-PUBLIC_CHAR]=cur; |
|
dvander@27
|
274 |
} |
|
dvander@27
|
275 |
|
|
dvander@27
|
276 |
SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen) |
|
dvander@27
|
277 |
{ |
|
dvander@27
|
278 |
stringpair *cur; |
|
dvander@27
|
279 |
|
|
dvander@27
|
280 |
assert(pattern!=NULL); |
|
dvander@27
|
281 |
assert(substitution!=NULL); |
|
dvander@27
|
282 |
if ((cur=insert_stringpair(&substpair,pattern,substitution,prefixlen))==NULL) |
|
dvander@27
|
283 |
error(103); /* insufficient memory (fatal error) */ |
|
dvander@27
|
284 |
adjustindex(*pattern); |
|
ds@1266
|
285 |
|
|
ds@1266
|
286 |
if (pc_deprecate!=NULL) { |
|
ds@1266
|
287 |
assert(cur!=NULL); |
|
ds@1266
|
288 |
cur->flags|=flgDEPRECATED; |
|
ds@1266
|
289 |
if (sc_status==statWRITE) { |
|
ds@1266
|
290 |
if (cur->documentation!=NULL) { |
|
ds@1266
|
291 |
free(cur->documentation); |
|
ds@1266
|
292 |
cur->documentation=NULL; |
|
ds@1266
|
293 |
} /* if */ |
|
ds@1266
|
294 |
cur->documentation=pc_deprecate; |
|
ds@1266
|
295 |
} else { |
|
ds@1266
|
296 |
free(pc_deprecate); |
|
ds@1266
|
297 |
} /* if */ |
|
ds@1266
|
298 |
pc_deprecate=NULL; |
|
ds@1266
|
299 |
} else { |
|
ds@1266
|
300 |
cur->flags = 0; |
|
ds@1266
|
301 |
cur->documentation = NULL; |
|
ds@1266
|
302 |
} /* if */ |
|
ds@1266
|
303 |
|
|
dvander@27
|
304 |
return cur; |
|
dvander@27
|
305 |
} |
|
dvander@27
|
306 |
|
|
dvander@27
|
307 |
SC_FUNC stringpair *find_subst(char *name,int length) |
|
dvander@27
|
308 |
{ |
|
dvander@27
|
309 |
stringpair *item; |
|
dvander@27
|
310 |
assert(name!=NULL); |
|
dvander@27
|
311 |
assert(length>0); |
|
dvander@27
|
312 |
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR); |
|
dvander@27
|
313 |
item=substindex[(int)*name-PUBLIC_CHAR]; |
|
dvander@27
|
314 |
if (item!=NULL) |
|
dvander@27
|
315 |
item=find_stringpair(item,name,length); |
|
ds@1266
|
316 |
|
|
ds@1266
|
317 |
if (item && (item->flags & flgDEPRECATED) != 0) |
|
ds@1266
|
318 |
{ |
|
ds@1266
|
319 |
static char macro[128]; |
|
ds@1266
|
320 |
char *rem, *msg = (item->documentation != NULL) ? item->documentation : ""; |
|
ds@1266
|
321 |
strlcpy(macro, item->first, sizeof(macro)); |
|
ds@1266
|
322 |
|
|
ds@1266
|
323 |
/* If macro contains an opening parentheses and a percent sign, then assume that |
|
ds@1266
|
324 |
* it takes arguments and remove them from the warning message. |
|
ds@1266
|
325 |
*/ |
|
ds@1266
|
326 |
if ((rem = strchr(macro, '(')) != NULL && strchr(macro, '%') > rem) |
|
ds@1266
|
327 |
{ |
|
ds@1266
|
328 |
*rem = '\0'; |
|
ds@1266
|
329 |
} |
|
ds@1266
|
330 |
|
|
ds@1266
|
331 |
error(234, macro, msg); /* deprecated (macro/constant) */ |
|
ds@1266
|
332 |
} |
|
dvander@27
|
333 |
return item; |
|
dvander@27
|
334 |
} |
|
dvander@27
|
335 |
|
|
dvander@27
|
336 |
SC_FUNC int delete_subst(char *name,int length) |
|
dvander@27
|
337 |
{ |
|
dvander@27
|
338 |
stringpair *item; |
|
dvander@27
|
339 |
assert(name!=NULL); |
|
dvander@27
|
340 |
assert(length>0); |
|
dvander@27
|
341 |
assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR); |
|
dvander@27
|
342 |
item=substindex[(int)*name-PUBLIC_CHAR]; |
|
dvander@27
|
343 |
if (item!=NULL) |
|
dvander@27
|
344 |
item=find_stringpair(item,name,length); |
|
dvander@27
|
345 |
if (item==NULL) |
|
dvander@27
|
346 |
return FALSE; |
|
ds@1267
|
347 |
if (item->documentation) |
|
ds@1267
|
348 |
{ |
|
ds@1267
|
349 |
free(item->documentation); |
|
ds@1267
|
350 |
item->documentation=NULL; |
|
ds@1267
|
351 |
} |
|
dvander@27
|
352 |
delete_stringpair(&substpair,item); |
|
dvander@27
|
353 |
adjustindex(*name); |
|
dvander@27
|
354 |
return TRUE; |
|
dvander@27
|
355 |
} |
|
dvander@27
|
356 |
|
|
dvander@27
|
357 |
SC_FUNC void delete_substtable(void) |
|
dvander@27
|
358 |
{ |
|
dvander@27
|
359 |
int i; |
|
dvander@27
|
360 |
delete_stringpairtable(&substpair); |
|
dvander@27
|
361 |
for (i=0; i<sizeof substindex/sizeof substindex[0]; i++) |
|
dvander@27
|
362 |
substindex[i]=NULL; |
|
dvander@27
|
363 |
} |
|
dvander@27
|
364 |
|
|
dvander@27
|
365 |
#endif /* !defined NO_SUBST */ |
|
dvander@27
|
366 |
|
|
dvander@27
|
367 |
|
|
dvander@27
|
368 |
/* ----- input file list ----------------------------------------- */ |
|
dvander@27
|
369 |
static stringlist sourcefiles = {NULL, NULL}; |
|
dvander@27
|
370 |
|
|
dvander@27
|
371 |
SC_FUNC stringlist *insert_sourcefile(char *string) |
|
dvander@27
|
372 |
{ |
|
dvander@27
|
373 |
return insert_string(&sourcefiles,string); |
|
dvander@27
|
374 |
} |
|
dvander@27
|
375 |
|
|
dvander@27
|
376 |
SC_FUNC char *get_sourcefile(int index) |
|
dvander@27
|
377 |
{ |
|
dvander@27
|
378 |
return get_string(&sourcefiles,index); |
|
dvander@27
|
379 |
} |
|
dvander@27
|
380 |
|
|
dvander@27
|
381 |
SC_FUNC void delete_sourcefiletable(void) |
|
dvander@27
|
382 |
{ |
|
dvander@27
|
383 |
delete_stringtable(&sourcefiles); |
|
dvander@27
|
384 |
assert(sourcefiles.next==NULL); |
|
dvander@27
|
385 |
} |
|
dvander@27
|
386 |
|
|
dvander@27
|
387 |
|
|
dvander@27
|
388 |
/* ----- documentation tags -------------------------------------- */ |
|
dvander@27
|
389 |
#if !defined SC_LIGHT |
|
dvander@27
|
390 |
static stringlist docstrings = {NULL, NULL}; |
|
dvander@27
|
391 |
|
|
dvander@27
|
392 |
SC_FUNC stringlist *insert_docstring(char *string) |
|
dvander@27
|
393 |
{ |
|
dvander@27
|
394 |
return insert_string(&docstrings,string); |
|
dvander@27
|
395 |
} |
|
dvander@27
|
396 |
|
|
dvander@27
|
397 |
SC_FUNC char *get_docstring(int index) |
|
dvander@27
|
398 |
{ |
|
dvander@27
|
399 |
return get_string(&docstrings,index); |
|
dvander@27
|
400 |
} |
|
dvander@27
|
401 |
|
|
dvander@27
|
402 |
SC_FUNC void delete_docstring(int index) |
|
dvander@27
|
403 |
{ |
|
dvander@27
|
404 |
delete_string(&docstrings,index); |
|
dvander@27
|
405 |
} |
|
dvander@27
|
406 |
|
|
dvander@27
|
407 |
SC_FUNC void delete_docstringtable(void) |
|
dvander@27
|
408 |
{ |
|
dvander@27
|
409 |
delete_stringtable(&docstrings); |
|
dvander@27
|
410 |
assert(docstrings.next==NULL); |
|
dvander@27
|
411 |
} |
|
dvander@27
|
412 |
#endif /* !defined SC_LIGHT */ |
|
dvander@27
|
413 |
|
|
dvander@27
|
414 |
|
|
dvander@27
|
415 |
/* ----- autolisting --------------------------------------------- */ |
|
dvander@27
|
416 |
static stringlist autolist = {NULL, NULL}; |
|
dvander@27
|
417 |
|
|
dvander@27
|
418 |
SC_FUNC stringlist *insert_autolist(char *string) |
|
dvander@27
|
419 |
{ |
|
dvander@27
|
420 |
return insert_string(&autolist,string); |
|
dvander@27
|
421 |
} |
|
dvander@27
|
422 |
|
|
dvander@27
|
423 |
SC_FUNC char *get_autolist(int index) |
|
dvander@27
|
424 |
{ |
|
dvander@27
|
425 |
return get_string(&autolist,index); |
|
dvander@27
|
426 |
} |
|
dvander@27
|
427 |
|
|
dvander@27
|
428 |
SC_FUNC void delete_autolisttable(void) |
|
dvander@27
|
429 |
{ |
|
dvander@27
|
430 |
delete_stringtable(&autolist); |
|
dvander@27
|
431 |
assert(autolist.next==NULL); |
|
dvander@27
|
432 |
} |
|
dvander@27
|
433 |
|
|
dvander@27
|
434 |
|
|
dvander@27
|
435 |
/* ----- debug information --------------------------------------- */ |
|
dvander@27
|
436 |
|
|
dvander@27
|
437 |
/* These macros are adapted from LibDGG libdgg-int64.h, see |
|
dvander@27
|
438 |
* http://www.dennougedougakkai-ndd.org/pub/libdgg/ |
|
dvander@27
|
439 |
*/ |
|
dvander@27
|
440 |
#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L |
|
dvander@27
|
441 |
#define __STDC_FORMAT_MACROS |
|
dvander@27
|
442 |
#define __STDC_CONSTANT_MACROS |
|
dvander@27
|
443 |
#include <inttypes.h> /* automatically includes stdint.h */ |
|
dvander@27
|
444 |
#elif (defined _MSC_VER || defined __BORLANDC__) && (defined _I64_MAX || defined HAVE_I64) |
|
dvander@27
|
445 |
#define PRId64 "I64d" |
|
dvander@27
|
446 |
#define PRIx64 "I64x" |
|
dvander@27
|
447 |
#else |
|
dvander@27
|
448 |
#define PRId64 "lld" |
|
dvander@27
|
449 |
#define PRIx64 "llx" |
|
dvander@27
|
450 |
#endif |
|
dvander@27
|
451 |
#if PAWN_CELL_SIZE==64 |
|
dvander@27
|
452 |
#define PRIdC PRId64 |
|
dvander@27
|
453 |
#define PRIxC PRIx64 |
|
dvander@27
|
454 |
#elif PAWN_CELL_SIZE==32 |
|
dvander@27
|
455 |
#define PRIdC "ld" |
|
dvander@27
|
456 |
#define PRIxC "lx" |
|
dvander@27
|
457 |
#else |
|
dvander@27
|
458 |
#define PRIdC "d" |
|
dvander@27
|
459 |
#define PRIxC "x" |
|
dvander@27
|
460 |
#endif |
|
dvander@27
|
461 |
|
|
dvander@27
|
462 |
static stringlist dbgstrings = {NULL, NULL}; |
|
dvander@27
|
463 |
|
|
dvander@27
|
464 |
SC_FUNC stringlist *insert_dbgfile(const char *filename) |
|
dvander@27
|
465 |
{ |
|
dvander@27
|
466 |
|
|
dvander@27
|
467 |
if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) { |
|
dvander@27
|
468 |
char string[_MAX_PATH+40]; |
|
dvander@27
|
469 |
assert(filename!=NULL); |
|
dvander@27
|
470 |
assert(strlen(filename)+40<sizeof string); |
|
dvander@27
|
471 |
sprintf(string,"F:%" PRIxC " %s",code_idx,filename); |
|
dvander@27
|
472 |
return insert_string(&dbgstrings,string); |
|
dvander@27
|
473 |
} /* if */ |
|
dvander@27
|
474 |
return NULL; |
|
dvander@27
|
475 |
} |
|
dvander@27
|
476 |
|
|
dvander@27
|
477 |
SC_FUNC stringlist *insert_dbgline(int linenr) |
|
dvander@27
|
478 |
{ |
|
dvander@27
|
479 |
if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) { |
|
dvander@27
|
480 |
char string[40]; |
|
dvander@27
|
481 |
if (linenr>0) |
|
dvander@27
|
482 |
linenr--; /* line numbers are zero-based in the debug information */ |
|
dvander@27
|
483 |
sprintf(string,"L:%" PRIxC " %x",code_idx,linenr); |
|
dvander@27
|
484 |
return insert_string(&dbgstrings,string); |
|
dvander@27
|
485 |
} /* if */ |
|
dvander@27
|
486 |
return NULL; |
|
dvander@27
|
487 |
} |
|
dvander@27
|
488 |
|
|
dvander@27
|
489 |
SC_FUNC stringlist *insert_dbgsymbol(symbol *sym) |
|
dvander@27
|
490 |
{ |
|
dvander@27
|
491 |
if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) { |
|
dvander@27
|
492 |
char string[2*sNAMEMAX+128]; |
|
dvander@27
|
493 |
char symname[2*sNAMEMAX+16]; |
|
dvander@27
|
494 |
|
|
dvander@27
|
495 |
funcdisplayname(symname,sym->name); |
|
dvander@27
|
496 |
/* address tag:name codestart codeend ident vclass [tag:dim ...] */ |
|
dvander@27
|
497 |
if (sym->ident==iFUNCTN) { |
|
dvander@27
|
498 |
sprintf(string,"S:%" PRIxC " %x:%s %" PRIxC " %" PRIxC " %x %x", |
|
dvander@27
|
499 |
sym->addr,sym->tag,symname,sym->addr,sym->codeaddr,sym->ident,sym->vclass); |
|
dvander@27
|
500 |
} else { |
|
dvander@27
|
501 |
sprintf(string,"S:%" PRIxC " %x:%s %" PRIxC " %" PRIxC " %x %x", |
|
dvander@27
|
502 |
sym->addr,sym->tag,symname,sym->codeaddr,code_idx,sym->ident,sym->vclass); |
|
dvander@27
|
503 |
} /* if */ |
|
dvander@27
|
504 |
if (sym->ident==iARRAY || sym->ident==iREFARRAY) { |
|
dvander@27
|
505 |
#if !defined NDEBUG |
|
dvander@27
|
506 |
int count=sym->dim.array.level; |
|
dvander@27
|
507 |
#endif |
|
dvander@27
|
508 |
symbol *sub; |
|
dvander@27
|
509 |
strcat(string," [ "); |
|
dvander@27
|
510 |
for (sub=sym; sub!=NULL; sub=finddepend(sub)) { |
|
dvander@27
|
511 |
assert(sub->dim.array.level==count--); |
|
dvander@27
|
512 |
sprintf(string+strlen(string),"%x:%x ",sub->x.tags.index,sub->dim.array.length); |
|
dvander@27
|
513 |
} /* for */ |
|
dvander@27
|
514 |
strcat(string,"]"); |
|
dvander@27
|
515 |
} /* if */ |
|
dvander@27
|
516 |
|
|
dvander@27
|
517 |
return insert_string(&dbgstrings,string); |
|
dvander@27
|
518 |
} /* if */ |
|
dvander@27
|
519 |
return NULL; |
|
dvander@27
|
520 |
} |
|
dvander@27
|
521 |
|
|
dvander@27
|
522 |
SC_FUNC char *get_dbgstring(int index) |
|
dvander@27
|
523 |
{ |
|
dvander@27
|
524 |
return get_string(&dbgstrings,index); |
|
dvander@27
|
525 |
} |
|
dvander@27
|
526 |
|
|
dvander@27
|
527 |
SC_FUNC void delete_dbgstringtable(void) |
|
dvander@27
|
528 |
{ |
|
dvander@27
|
529 |
delete_stringtable(&dbgstrings); |
|
dvander@27
|
530 |
assert(dbgstrings.next==NULL); |
|
dvander@27
|
531 |
} |