sourcepawn/compiler/sclist.c
author David Anderson <dvander@alliedmods.net>
Fri Mar 16 18:19:26 2007 +0000 (2007-03-16)
changeset 630 2b1aca886622
parent 365 d830b2b0414f
child 1266 ef8dd1cddc35
permissions -rw-r--r--
fixed debug section not being packed -- oops!
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"
dvander@27
    34
dvander@27
    35
#if defined FORTIFY
dvander@27
    36
  #include <alloc/fortify.h>
dvander@27
    37
#endif
dvander@27
    38
dvander@27
    39
/* a "private" implementation of strdup(), so that porting
dvander@27
    40
 * to other memory allocators becomes easier.
dvander@27
    41
 * By S�ren Hannibal.
dvander@27
    42
 */
dvander@27
    43
SC_FUNC char* duplicatestring(const char* sourcestring)
dvander@27
    44
{
dvander@27
    45
  char* result=(char*)malloc(strlen(sourcestring)+1);
dvander@27
    46
  strcpy(result,sourcestring);
dvander@27
    47
  return result;
dvander@27
    48
}
dvander@27
    49
dvander@27
    50
dvander@27
    51
static stringpair *insert_stringpair(stringpair *root,char *first,char *second,int matchlength)
dvander@27
    52
{
dvander@27
    53
  stringpair *cur,*pred;
dvander@27
    54
dvander@27
    55
  assert(root!=NULL);
dvander@27
    56
  assert(first!=NULL);
dvander@27
    57
  assert(second!=NULL);
dvander@27
    58
  /* create a new node, and check whether all is okay */
dvander@27
    59
  if ((cur=(stringpair*)malloc(sizeof(stringpair)))==NULL)
dvander@27
    60
    return NULL;
dvander@27
    61
  cur->first=duplicatestring(first);
dvander@27
    62
  cur->second=duplicatestring(second);
dvander@27
    63
  cur->matchlength=matchlength;
dvander@27
    64
  if (cur->first==NULL || cur->second==NULL) {
dvander@27
    65
    if (cur->first!=NULL)
dvander@27
    66
      free(cur->first);
dvander@27
    67
    if (cur->second!=NULL)
dvander@27
    68
      free(cur->second);
dvander@27
    69
    free(cur);
dvander@27
    70
    return NULL;
dvander@27
    71
  } /* if */
dvander@27
    72
  /* link the node to the tree, find the position */
dvander@27
    73
  for (pred=root; pred->next!=NULL && strcmp(pred->next->first,first)<0; pred=pred->next)
dvander@27
    74
    /* nothing */;
dvander@27
    75
  cur->next=pred->next;
dvander@27
    76
  pred->next=cur;
dvander@27
    77
  return cur;
dvander@27
    78
}
dvander@27
    79
dvander@27
    80
static void delete_stringpairtable(stringpair *root)
dvander@27
    81
{
dvander@27
    82
  stringpair *cur, *next;
dvander@27
    83
dvander@27
    84
  assert(root!=NULL);
dvander@27
    85
  cur=root->next;
dvander@27
    86
  while (cur!=NULL) {
dvander@27
    87
    next=cur->next;
dvander@27
    88
    assert(cur->first!=NULL);
dvander@27
    89
    assert(cur->second!=NULL);
dvander@27
    90
    free(cur->first);
dvander@27
    91
    free(cur->second);
dvander@27
    92
    free(cur);
dvander@27
    93
    cur=next;
dvander@27
    94
  } /* while */
dvander@27
    95
  memset(root,0,sizeof(stringpair));
dvander@27
    96
}
dvander@27
    97
dvander@27
    98
static stringpair *find_stringpair(stringpair *cur,char *first,int matchlength)
dvander@27
    99
{
dvander@27
   100
  int result=0;
dvander@27
   101
dvander@27
   102
  assert(matchlength>0);  /* the function cannot handle zero-length comparison */
dvander@27
   103
  assert(first!=NULL);
dvander@27
   104
  while (cur!=NULL && result<=0) {
dvander@27
   105
    result=(int)*cur->first - (int)*first;
dvander@27
   106
    if (result==0 && matchlength==cur->matchlength) {
dvander@27
   107
      result=strncmp(cur->first,first,matchlength);
dvander@27
   108
      if (result==0)
dvander@27
   109
        return cur;
dvander@27
   110
    } /* if */
dvander@27
   111
    cur=cur->next;
dvander@27
   112
  } /* while */
dvander@27
   113
  return NULL;
dvander@27
   114
}
dvander@27
   115
dvander@27
   116
static int delete_stringpair(stringpair *root,stringpair *item)
dvander@27
   117
{
dvander@27
   118
  stringpair *cur;
dvander@27
   119
dvander@27
   120
  assert(root!=NULL);
dvander@27
   121
  cur=root;
dvander@27
   122
  while (cur->next!=NULL) {
dvander@27
   123
    if (cur->next==item) {
dvander@27
   124
      cur->next=item->next;     /* unlink from list */
dvander@27
   125
      assert(item->first!=NULL);
dvander@27
   126
      assert(item->second!=NULL);
dvander@27
   127
      free(item->first);
dvander@27
   128
      free(item->second);
dvander@27
   129
      free(item);
dvander@27
   130
      return TRUE;
dvander@27
   131
    } /* if */
dvander@27
   132
    cur=cur->next;
dvander@27
   133
  } /* while */
dvander@27
   134
  return FALSE;
dvander@27
   135
}
dvander@27
   136
dvander@27
   137
/* ----- string list functions ----------------------------------- */
dvander@27
   138
static stringlist *insert_string(stringlist *root,char *string)
dvander@27
   139
{
dvander@27
   140
  stringlist *cur;
dvander@27
   141
dvander@27
   142
  assert(string!=NULL);
dvander@27
   143
  if ((cur=(stringlist*)malloc(sizeof(stringlist)))==NULL)
dvander@27
   144
    error(103);       /* insufficient memory (fatal error) */
dvander@27
   145
  if ((cur->line=duplicatestring(string))==NULL)
dvander@27
   146
    error(103);       /* insufficient memory (fatal error) */
dvander@27
   147
  /* insert as "last" */
dvander@27
   148
  assert(root!=NULL);
dvander@27
   149
  while (root->next!=NULL)
dvander@27
   150
    root=root->next;
dvander@27
   151
  cur->next=root->next;
dvander@27
   152
  root->next=cur;
dvander@27
   153
  return cur;
dvander@27
   154
}
dvander@27
   155
dvander@27
   156
static char *get_string(stringlist *root,int index)
dvander@27
   157
{
dvander@27
   158
  stringlist *cur;
dvander@27
   159
dvander@27
   160
  assert(root!=NULL);
dvander@27
   161
  cur=root->next;
dvander@27
   162
  while (cur!=NULL && index-->0)
dvander@27
   163
    cur=cur->next;
dvander@27
   164
  if (cur!=NULL) {
dvander@27
   165
    assert(cur->line!=NULL);
dvander@27
   166
    return cur->line;
dvander@27
   167
  } /* if */
dvander@27
   168
  return NULL;
dvander@27
   169
}
dvander@27
   170
dvander@27
   171
static int delete_string(stringlist *root,int index)
dvander@27
   172
{
dvander@27
   173
  stringlist *cur,*item;
dvander@27
   174
dvander@27
   175
  assert(root!=NULL);
dvander@27
   176
  for (cur=root; cur->next!=NULL && index>0; cur=cur->next,index--)
dvander@27
   177
    /* nothing */;
dvander@27
   178
  if (cur->next!=NULL) {
dvander@27
   179
    item=cur->next;
dvander@27
   180
    cur->next=item->next;       /* unlink from list */
dvander@27
   181
    assert(item->line!=NULL);
dvander@27
   182
    free(item->line);
dvander@27
   183
    free(item);
dvander@27
   184
    return TRUE;
dvander@27
   185
  } /* if */
dvander@27
   186
  return FALSE;
dvander@27
   187
}
dvander@27
   188
dvander@27
   189
SC_FUNC void delete_stringtable(stringlist *root)
dvander@27
   190
{
dvander@27
   191
  stringlist *cur,*next;
dvander@27
   192
dvander@27
   193
  assert(root!=NULL);
dvander@27
   194
  cur=root->next;
dvander@27
   195
  while (cur!=NULL) {
dvander@27
   196
    next=cur->next;
dvander@27
   197
    assert(cur->line!=NULL);
dvander@27
   198
    free(cur->line);
dvander@27
   199
    free(cur);
dvander@27
   200
    cur=next;
dvander@27
   201
  } /* while */
dvander@27
   202
  memset(root,0,sizeof(stringlist));
dvander@27
   203
}
dvander@27
   204
dvander@27
   205
dvander@27
   206
/* ----- alias table --------------------------------------------- */
dvander@27
   207
static stringpair alias_tab = {NULL, NULL, NULL};   /* alias table */
dvander@27
   208
dvander@27
   209
SC_FUNC stringpair *insert_alias(char *name,char *alias)
dvander@27
   210
{
dvander@27
   211
  stringpair *cur;
dvander@27
   212
dvander@27
   213
  assert(name!=NULL);
dvander@27
   214
  assert(strlen(name)<=sNAMEMAX);
dvander@27
   215
  assert(alias!=NULL);
dvander@27
   216
  assert(strlen(alias)<=sNAMEMAX);
dvander@27
   217
  if ((cur=insert_stringpair(&alias_tab,name,alias,strlen(name)))==NULL)
dvander@27
   218
    error(103);       /* insufficient memory (fatal error) */
dvander@27
   219
  return cur;
dvander@27
   220
}
dvander@27
   221
dvander@27
   222
SC_FUNC int lookup_alias(char *target,char *name)
dvander@27
   223
{
dvander@27
   224
  stringpair *cur=find_stringpair(alias_tab.next,name,strlen(name));
dvander@27
   225
  if (cur!=NULL) {
dvander@27
   226
    assert(strlen(cur->second)<=sNAMEMAX);
dvander@27
   227
    strcpy(target,cur->second);
dvander@27
   228
  } /* if */
dvander@27
   229
  return cur!=NULL;
dvander@27
   230
}
dvander@27
   231
dvander@27
   232
SC_FUNC void delete_aliastable(void)
dvander@27
   233
{
dvander@27
   234
  delete_stringpairtable(&alias_tab);
dvander@27
   235
}
dvander@27
   236
dvander@27
   237
/* ----- include paths list -------------------------------------- */
dvander@27
   238
static stringlist includepaths = {NULL, NULL};  /* directory list for include files */
dvander@27
   239
dvander@27
   240
SC_FUNC stringlist *insert_path(char *path)
dvander@27
   241
{
dvander@27
   242
  return insert_string(&includepaths,path);
dvander@27
   243
}
dvander@27
   244
dvander@27
   245
SC_FUNC char *get_path(int index)
dvander@27
   246
{
dvander@27
   247
  return get_string(&includepaths,index);
dvander@27
   248
}
dvander@27
   249
dvander@27
   250
SC_FUNC void delete_pathtable(void)
dvander@27
   251
{
dvander@27
   252
  delete_stringtable(&includepaths);
dvander@27
   253
  assert(includepaths.next==NULL);
dvander@27
   254
}
dvander@27
   255
dvander@27
   256
dvander@27
   257
/* ----- text substitution patterns ------------------------------ */
dvander@27
   258
#if !defined NO_DEFINE
dvander@27
   259
dvander@27
   260
static stringpair substpair = { NULL, NULL, NULL};  /* list of substitution pairs */
dvander@27
   261
dvander@27
   262
static stringpair *substindex['z'-PUBLIC_CHAR+1]; /* quick index to first character */
dvander@27
   263
static void adjustindex(char c)
dvander@27
   264
{
dvander@27
   265
  stringpair *cur;
dvander@27
   266
  assert(c>='A' && c<='Z' || c>='a' && c<='z' || c=='_' || c==PUBLIC_CHAR);
dvander@27
   267
  assert(PUBLIC_CHAR<'A' && 'A'<'_' && '_'<'z');
dvander@27
   268
dvander@27
   269
  for (cur=substpair.next; cur!=NULL && cur->first[0]!=c; cur=cur->next)
dvander@27
   270
    /* nothing */;
dvander@27
   271
  substindex[(int)c-PUBLIC_CHAR]=cur;
dvander@27
   272
}
dvander@27
   273
dvander@27
   274
SC_FUNC stringpair *insert_subst(char *pattern,char *substitution,int prefixlen)
dvander@27
   275
{
dvander@27
   276
  stringpair *cur;
dvander@27
   277
dvander@27
   278
  assert(pattern!=NULL);
dvander@27
   279
  assert(substitution!=NULL);
dvander@27
   280
  if ((cur=insert_stringpair(&substpair,pattern,substitution,prefixlen))==NULL)
dvander@27
   281
    error(103);       /* insufficient memory (fatal error) */
dvander@27
   282
  adjustindex(*pattern);
dvander@27
   283
  return cur;
dvander@27
   284
}
dvander@27
   285
dvander@27
   286
SC_FUNC stringpair *find_subst(char *name,int length)
dvander@27
   287
{
dvander@27
   288
  stringpair *item;
dvander@27
   289
  assert(name!=NULL);
dvander@27
   290
  assert(length>0);
dvander@27
   291
  assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
dvander@27
   292
  item=substindex[(int)*name-PUBLIC_CHAR];
dvander@27
   293
  if (item!=NULL)
dvander@27
   294
    item=find_stringpair(item,name,length);
dvander@27
   295
  return item;
dvander@27
   296
}
dvander@27
   297
dvander@27
   298
SC_FUNC int delete_subst(char *name,int length)
dvander@27
   299
{
dvander@27
   300
  stringpair *item;
dvander@27
   301
  assert(name!=NULL);
dvander@27
   302
  assert(length>0);
dvander@27
   303
  assert(*name>='A' && *name<='Z' || *name>='a' && *name<='z' || *name=='_' || *name==PUBLIC_CHAR);
dvander@27
   304
  item=substindex[(int)*name-PUBLIC_CHAR];
dvander@27
   305
  if (item!=NULL)
dvander@27
   306
    item=find_stringpair(item,name,length);
dvander@27
   307
  if (item==NULL)
dvander@27
   308
    return FALSE;
dvander@27
   309
  delete_stringpair(&substpair,item);
dvander@27
   310
  adjustindex(*name);
dvander@27
   311
  return TRUE;
dvander@27
   312
}
dvander@27
   313
dvander@27
   314
SC_FUNC void delete_substtable(void)
dvander@27
   315
{
dvander@27
   316
  int i;
dvander@27
   317
  delete_stringpairtable(&substpair);
dvander@27
   318
  for (i=0; i<sizeof substindex/sizeof substindex[0]; i++)
dvander@27
   319
    substindex[i]=NULL;
dvander@27
   320
}
dvander@27
   321
dvander@27
   322
#endif /* !defined NO_SUBST */
dvander@27
   323
dvander@27
   324
dvander@27
   325
/* ----- input file list ----------------------------------------- */
dvander@27
   326
static stringlist sourcefiles = {NULL, NULL};
dvander@27
   327
dvander@27
   328
SC_FUNC stringlist *insert_sourcefile(char *string)
dvander@27
   329
{
dvander@27
   330
  return insert_string(&sourcefiles,string);
dvander@27
   331
}
dvander@27
   332
dvander@27
   333
SC_FUNC char *get_sourcefile(int index)
dvander@27
   334
{
dvander@27
   335
  return get_string(&sourcefiles,index);
dvander@27
   336
}
dvander@27
   337
dvander@27
   338
SC_FUNC void delete_sourcefiletable(void)
dvander@27
   339
{
dvander@27
   340
  delete_stringtable(&sourcefiles);
dvander@27
   341
  assert(sourcefiles.next==NULL);
dvander@27
   342
}
dvander@27
   343
dvander@27
   344
dvander@27
   345
/* ----- documentation tags -------------------------------------- */
dvander@27
   346
#if !defined SC_LIGHT
dvander@27
   347
static stringlist docstrings = {NULL, NULL};
dvander@27
   348
dvander@27
   349
SC_FUNC stringlist *insert_docstring(char *string)
dvander@27
   350
{
dvander@27
   351
  return insert_string(&docstrings,string);
dvander@27
   352
}
dvander@27
   353
dvander@27
   354
SC_FUNC char *get_docstring(int index)
dvander@27
   355
{
dvander@27
   356
  return get_string(&docstrings,index);
dvander@27
   357
}
dvander@27
   358
dvander@27
   359
SC_FUNC void delete_docstring(int index)
dvander@27
   360
{
dvander@27
   361
  delete_string(&docstrings,index);
dvander@27
   362
}
dvander@27
   363
dvander@27
   364
SC_FUNC void delete_docstringtable(void)
dvander@27
   365
{
dvander@27
   366
  delete_stringtable(&docstrings);
dvander@27
   367
  assert(docstrings.next==NULL);
dvander@27
   368
}
dvander@27
   369
#endif /* !defined SC_LIGHT */
dvander@27
   370
dvander@27
   371
dvander@27
   372
/* ----- autolisting --------------------------------------------- */
dvander@27
   373
static stringlist autolist = {NULL, NULL};
dvander@27
   374
dvander@27
   375
SC_FUNC stringlist *insert_autolist(char *string)
dvander@27
   376
{
dvander@27
   377
  return insert_string(&autolist,string);
dvander@27
   378
}
dvander@27
   379
dvander@27
   380
SC_FUNC char *get_autolist(int index)
dvander@27
   381
{
dvander@27
   382
  return get_string(&autolist,index);
dvander@27
   383
}
dvander@27
   384
dvander@27
   385
SC_FUNC void delete_autolisttable(void)
dvander@27
   386
{
dvander@27
   387
  delete_stringtable(&autolist);
dvander@27
   388
  assert(autolist.next==NULL);
dvander@27
   389
}
dvander@27
   390
dvander@27
   391
dvander@27
   392
/* ----- debug information --------------------------------------- */
dvander@27
   393
dvander@27
   394
/* These macros are adapted from LibDGG libdgg-int64.h, see
dvander@27
   395
 * http://www.dennougedougakkai-ndd.org/pub/libdgg/
dvander@27
   396
 */
dvander@27
   397
#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
dvander@27
   398
  #define __STDC_FORMAT_MACROS
dvander@27
   399
  #define __STDC_CONSTANT_MACROS
dvander@27
   400
  #include <inttypes.h>         /* automatically includes stdint.h */
dvander@27
   401
#elif (defined _MSC_VER || defined __BORLANDC__) && (defined _I64_MAX || defined HAVE_I64)
dvander@27
   402
  #define PRId64 "I64d"
dvander@27
   403
  #define PRIx64 "I64x"
dvander@27
   404
#else
dvander@27
   405
  #define PRId64 "lld"
dvander@27
   406
  #define PRIx64 "llx"
dvander@27
   407
#endif
dvander@27
   408
#if PAWN_CELL_SIZE==64
dvander@27
   409
  #define PRIdC  PRId64
dvander@27
   410
  #define PRIxC  PRIx64
dvander@27
   411
#elif PAWN_CELL_SIZE==32
dvander@27
   412
  #define PRIdC  "ld"
dvander@27
   413
  #define PRIxC  "lx"
dvander@27
   414
#else
dvander@27
   415
  #define PRIdC  "d"
dvander@27
   416
  #define PRIxC  "x"
dvander@27
   417
#endif
dvander@27
   418
dvander@27
   419
static stringlist dbgstrings = {NULL, NULL};
dvander@27
   420
dvander@27
   421
SC_FUNC stringlist *insert_dbgfile(const char *filename)
dvander@27
   422
{
dvander@27
   423
dvander@27
   424
  if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
dvander@27
   425
    char string[_MAX_PATH+40];
dvander@27
   426
    assert(filename!=NULL);
dvander@27
   427
    assert(strlen(filename)+40<sizeof string);
dvander@27
   428
    sprintf(string,"F:%" PRIxC " %s",code_idx,filename);
dvander@27
   429
    return insert_string(&dbgstrings,string);
dvander@27
   430
  } /* if */
dvander@27
   431
  return NULL;
dvander@27
   432
}
dvander@27
   433
dvander@27
   434
SC_FUNC stringlist *insert_dbgline(int linenr)
dvander@27
   435
{
dvander@27
   436
  if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
dvander@27
   437
    char string[40];
dvander@27
   438
    if (linenr>0)
dvander@27
   439
      linenr--;         /* line numbers are zero-based in the debug information */
dvander@27
   440
    sprintf(string,"L:%" PRIxC " %x",code_idx,linenr);
dvander@27
   441
    return insert_string(&dbgstrings,string);
dvander@27
   442
  } /* if */
dvander@27
   443
  return NULL;
dvander@27
   444
}
dvander@27
   445
dvander@27
   446
SC_FUNC stringlist *insert_dbgsymbol(symbol *sym)
dvander@27
   447
{
dvander@27
   448
  if (sc_status==statWRITE && (sc_debug & sSYMBOLIC)!=0) {
dvander@27
   449
    char string[2*sNAMEMAX+128];
dvander@27
   450
    char symname[2*sNAMEMAX+16];
dvander@27
   451
dvander@27
   452
    funcdisplayname(symname,sym->name);
dvander@27
   453
    /* address tag:name codestart codeend ident vclass [tag:dim ...] */
dvander@27
   454
    if (sym->ident==iFUNCTN) {
dvander@27
   455
      sprintf(string,"S:%" PRIxC " %x:%s %" PRIxC " %" PRIxC " %x %x",
dvander@27
   456
              sym->addr,sym->tag,symname,sym->addr,sym->codeaddr,sym->ident,sym->vclass);
dvander@27
   457
    } else {
dvander@27
   458
      sprintf(string,"S:%" PRIxC " %x:%s %" PRIxC " %" PRIxC " %x %x",
dvander@27
   459
              sym->addr,sym->tag,symname,sym->codeaddr,code_idx,sym->ident,sym->vclass);
dvander@27
   460
    } /* if */
dvander@27
   461
    if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
dvander@27
   462
      #if !defined NDEBUG
dvander@27
   463
        int count=sym->dim.array.level;
dvander@27
   464
      #endif
dvander@27
   465
      symbol *sub;
dvander@27
   466
      strcat(string," [ ");
dvander@27
   467
      for (sub=sym; sub!=NULL; sub=finddepend(sub)) {
dvander@27
   468
        assert(sub->dim.array.level==count--);
dvander@27
   469
        sprintf(string+strlen(string),"%x:%x ",sub->x.tags.index,sub->dim.array.length);
dvander@27
   470
      } /* for */
dvander@27
   471
      strcat(string,"]");
dvander@27
   472
    } /* if */
dvander@27
   473
dvander@27
   474
    return insert_string(&dbgstrings,string);
dvander@27
   475
  } /* if */
dvander@27
   476
  return NULL;
dvander@27
   477
}
dvander@27
   478
dvander@27
   479
SC_FUNC char *get_dbgstring(int index)
dvander@27
   480
{
dvander@27
   481
  return get_string(&dbgstrings,index);
dvander@27
   482
}
dvander@27
   483
dvander@27
   484
SC_FUNC void delete_dbgstringtable(void)
dvander@27
   485
{
dvander@27
   486
  delete_stringtable(&dbgstrings);
dvander@27
   487
  assert(dbgstrings.next==NULL);
dvander@27
   488
}