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