1 /* Pawn compiler - maintenance of various lists
3 * o Name list (aliases)
5 * o Macro definitions (text substitutions)
6 * o Documentation tags and automatic listings
9 * Copyright (c) ITB CompuPhase, 2001-2006
11 * This software is provided "as-is", without any express or implied warranty.
12 * In no event will the authors be held liable for any damages arising from
13 * the use of this software.
15 * Permission is granted to anyone to use this software for any purpose,
16 * including commercial applications, and to alter it and redistribute it
17 * freely, subject to the following restrictions:
19 * 1. The origin of this software must not be misrepresented; you must not
20 * claim that you wrote the original software. If you use this software in
21 * a product, an acknowledgment in the product documentation would be
22 * appreciated but is not required.
23 * 2. Altered source versions must be plainly marked as such, and must not be
24 * misrepresented as being the original software.
25 * 3. This notice may not be removed or altered from any source distribution.
36 #include <alloc/fortify.h>
39 /* a "private" implementation of strdup(), so that porting
40 * to other memory allocators becomes easier.
43 SC_FUNC char* duplicatestring(const char* sourcestring)
45 char* result=(char*)malloc(strlen(sourcestring)+1);
46 strcpy(result,sourcestring);
51 static stringpair *insert_stringpair(stringpair *root,char *first,char *second,int matchlength)
53 stringpair *cur,*pred;
58 /* create a new node, and check whether all is okay */
59 if ((cur=(stringpair*)malloc(sizeof(stringpair)))==NULL)
61 cur->first=duplicatestring(first);
62 cur->second=duplicatestring(second);
63 cur->matchlength=matchlength;
64 if (cur->first==NULL || cur->second==NULL) {
67 if (cur->second!=NULL)
72 /* link the node to the tree, find the position */
73 for (pred=root; pred->next!=NULL && strcmp(pred->next->first,first)<0; pred=pred->next)
80 static void delete_stringpairtable(stringpair *root)
82 stringpair *cur, *next;
88 assert(cur->first!=NULL);
89 assert(cur->second!=NULL);
95 memset(root,0,sizeof(stringpair));
98 static stringpair *find_stringpair(stringpair *cur,char *first,int matchlength)
102 assert(matchlength>0); /* the function cannot handle zero-length comparison */
104 while (cur!=NULL && result<=0) {
105 result=(int)*cur->first - (int)*first;
106 if (result==0 && matchlength==cur->matchlength) {
107 result=strncmp(cur->first,first,matchlength);
116 static int delete_stringpair(stringpair *root,stringpair *item)
122 while (cur->next!=NULL) {
123 if (cur->next==item) {
124 cur->next=item->next; /* unlink from list */
125 assert(item->first!=NULL);
126 assert(item->second!=NULL);
137 /* ----- string list functions ----------------------------------- */
138 static stringlist *insert_string(stringlist *root,char *string)
142 assert(string!=NULL);
143 if ((cur=(stringlist*)malloc(sizeof(stringlist)))==NULL)
144 error(103); /* insufficient memory (fatal error) */
145 if ((cur->line=duplicatestring(string))==NULL)
146 error(103); /* insufficient memory (fatal error) */
147 /* insert as "last" */
149 while (root->next!=NULL)
151 cur->next=root->next;
156 static char *get_string(stringlist *root,int index)
162 while (cur!=NULL && index-->0)
165 assert(cur->line!=NULL);
171 static int delete_string(stringlist *root,int index)
173 stringlist *cur,*item;
176 for (cur=root; cur->next!=NULL && index>0; cur=cur->next,index--)
178 if (cur->next!=NULL) {
180 cur->next=item->next; /* unlink from list */
181 assert(item->line!=NULL);
189 SC_FUNC void delete_stringtable(stringlist *root)
191 stringlist *cur,*next;
197 assert(cur->line!=NULL);
202 memset(root,0,sizeof(stringlist));
206 /* ----- alias table --------------------------------------------- */
207 static stringpair alias_tab = {NULL, NULL, NULL}; /* alias table */
209 SC_FUNC stringpair *insert_alias(char *name,char *alias)
214 assert(strlen(name)<=sNAMEMAX);
216 assert(strlen(alias)<=sNAMEMAX);
217 if ((cur=insert_stringpair(&alias_tab,name,alias,strlen(name)))==NULL)
218 error(103); /* insufficient memory (fatal error) */
222 SC_FUNC int lookup_alias(char *target,char *name)
224 stringpair *cur=find_stringpair(alias_tab.next,name,strlen(name));
226 assert(strlen(cur->second)<=sNAMEMAX);
227 strcpy(target,cur->second);
232 SC_FUNC void delete_aliastable(void)
234 delete_stringpairtable(&alias_tab);
237 /* ----- include paths list -------------------------------------- */
238 static stringlist includepaths = {NULL, NULL}; /* directory list for include files */
240 SC_FUNC stringlist *insert_path(char *path)
242 return insert_string(&includepaths,path);
245 SC_FUNC char *get_path(int index)
247 return get_string(&includepaths,index);
250 SC_FUNC void delete_pathtable(void)
252 delete_stringtable(&includepaths);
253 assert(includepaths.next==NULL);
257 /* ----- text substitution patterns ------------------------------ */
258 #if !defined NO_DEFINE
260 static stringpair substpair = { NULL, NULL, NULL}; /* list of substitution pairs */
262 static stringpair *substindex['z'-PUBLIC_CHAR+1]; /* quick index to first character */
263 static void adjustindex(char c)
266 assert(c>='A' && c<='Z' || c>='a' && c<='z' || c=='_' || c==PUBLIC_CHAR);
267 assert(PUBLIC_CHAR<'A' && 'A'<'_' && '_'<'z');
269 for (cur=substpair.next; cur!=NULL && cur->first[0]!=c; cur=cur->next)
271 substindex[(int)c-PUBLIC_CHAR]=cur;
274 SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen)
278 assert(pattern!=NULL);
279 assert(substitution!=NULL);
280 if ((cur=insert_stringpair(&substpair,pattern,substitution,prefixlen))==NULL)
281 error(103); /* insufficient memory (fatal error) */
282 adjustindex(*pattern);
286 SC_FUNC stringpair *find_subst(char *name,int length)
291 assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
292 item=substindex[(int)*name-PUBLIC_CHAR];
294 item=find_stringpair(item,name,length);
298 SC_FUNC int delete_subst(char *name,int length)
303 assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
304 item=substindex[(int)*name-PUBLIC_CHAR];
306 item=find_stringpair(item,name,length);
309 delete_stringpair(&substpair,item);
314 SC_FUNC void delete_substtable(void)
317 delete_stringpairtable(&substpair);
318 for (i=0; i<sizeof substindex/sizeof substindex[0]; i++)
322 #endif /* !defined NO_SUBST */
325 /* ----- input file list ----------------------------------------- */
326 static stringlist sourcefiles = {NULL, NULL};
328 SC_FUNC stringlist *insert_sourcefile(char *string)
330 return insert_string(&sourcefiles,string);
333 SC_FUNC char *get_sourcefile(int index)
335 return get_string(&sourcefiles,index);
338 SC_FUNC void delete_sourcefiletable(void)
340 delete_stringtable(&sourcefiles);
341 assert(sourcefiles.next==NULL);
345 /* ----- documentation tags -------------------------------------- */
346 #if !defined SC_LIGHT
347 static stringlist docstrings = {NULL, NULL};
349 SC_FUNC stringlist *insert_docstring(char *string)
351 return insert_string(&docstrings,string);
354 SC_FUNC char *get_docstring(int index)
356 return get_string(&docstrings,index);
359 SC_FUNC void delete_docstring(int index)
361 delete_string(&docstrings,index);
364 SC_FUNC void delete_docstringtable(void)
366 delete_stringtable(&docstrings);
367 assert(docstrings.next==NULL);
369 #endif /* !defined SC_LIGHT */
372 /* ----- autolisting --------------------------------------------- */
373 static stringlist autolist = {NULL, NULL};
375 SC_FUNC stringlist *insert_autolist(char *string)
377 return insert_string(&autolist,string);
380 SC_FUNC char *get_autolist(int index)
382 return get_string(&autolist,index);
385 SC_FUNC void delete_autolisttable(void)
387 delete_stringtable(&autolist);
388 assert(autolist.next==NULL);
392 /* ----- debug information --------------------------------------- */
394 /* These macros are adapted from LibDGG libdgg-int64.h, see
395 * http://www.dennougedougakkai-ndd.org/pub/libdgg/
397 #if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
398 #define __STDC_FORMAT_MACROS
399 #define __STDC_CONSTANT_MACROS
400 #include <inttypes.h> /* automatically includes stdint.h */
401 #elif (defined _MSC_VER || defined __BORLANDC__) && (defined _I64_MAX || defined HAVE_I64)
402 #define PRId64 "I64d"
403 #define PRIx64 "I64x"
408 #if PAWN_CELL_SIZE==64
411 #elif PAWN_CELL_SIZE==32
419 static stringlist dbgstrings = {NULL, NULL};
421 SC_FUNC stringlist *insert_dbgfile(const char *filename)
424 if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
425 char string[_MAX_PATH+40];
426 assert(filename!=NULL);
427 assert(strlen(filename)+40<sizeof string);
428 sprintf(string,"F:%" PRIxC " %s",code_idx,filename);
429 return insert_string(&dbgstrings,string);
434 SC_FUNC stringlist *insert_dbgline(int linenr)
436 if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
439 linenr--; /* line numbers are zero-based in the debug information */
440 sprintf(string,"L:%" PRIxC " %x",code_idx,linenr);
441 return insert_string(&dbgstrings,string);
446 SC_FUNC stringlist *insert_dbgsymbol(symbol *sym)
448 if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
449 char string[2*sNAMEMAX+128];
450 char symname[2*sNAMEMAX+16];
452 funcdisplayname(symname,sym->name);
453 /* address tag:name codestart codeend ident vclass [tag:dim ...] */
454 if (sym->ident==iFUNCTN) {
455 sprintf(string,"S:%" PRIxC " %x:%s %" PRIxC " %" PRIxC " %x %x",
456 sym->addr,sym->tag,symname,sym->addr,sym->codeaddr,sym->ident,sym->vclass);
458 sprintf(string,"S:%" PRIxC " %x:%s %" PRIxC " %" PRIxC " %x %x",
459 sym->addr,sym->tag,symname,sym->codeaddr,code_idx,sym->ident,sym->vclass);
461 if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
463 int count=sym->dim.array.level;
466 strcat(string," [ ");
467 for (sub=sym; sub!=NULL; sub=finddepend(sub)) {
468 assert(sub->dim.array.level==count--);
469 sprintf(string+strlen(string),"%x:%x ",sub->x.tags.index,sub->dim.array.length);
474 return insert_string(&dbgstrings,string);
479 SC_FUNC char *get_dbgstring(int index)
481 return get_string(&dbgstrings,index);
484 SC_FUNC void delete_dbgstringtable(void)
486 delete_stringtable(&dbgstrings);
487 assert(dbgstrings.next==NULL);