You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
293 lines
7.1 KiB
293 lines
7.1 KiB
/* Small compiler - maintenance of various lists |
|
* |
|
* Name list (aliases) |
|
* Include path list |
|
* |
|
* Copyright (c) ITB CompuPhase, 2001-2003 |
|
* |
|
* This software is provided "as-is", without any express or implied warranty. |
|
* In no event will the authors be held liable for any damages arising from |
|
* the use of this software. |
|
* |
|
* Permission is granted to anyone to use this software for any purpose, |
|
* including commercial applications, and to alter it and redistribute it |
|
* freely, subject to the following restrictions: |
|
* |
|
* 1. The origin of this software must not be misrepresented; you must not |
|
* claim that you wrote the original software. If you use this software in |
|
* a product, an acknowledgment in the product documentation would be |
|
* appreciated but is not required. |
|
* 2. Altered source versions must be plainly marked as such, and must not be |
|
* misrepresented as being the original software. |
|
* 3. This notice may not be removed or altered from any source distribution. |
|
* |
|
* Version: $Id$ |
|
*/ |
|
|
|
|
|
#ifdef HAVE_CONFIG_H |
|
# include <config.h> |
|
#endif |
|
|
|
#include <assert.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include "embryo_cc_sc.h" |
|
|
|
static stringpair * |
|
insert_stringpair(stringpair * root, char *first, char *second, int matchlength) |
|
{ |
|
stringpair *cur, *pred; |
|
|
|
assert(root != NULL); |
|
assert(first != NULL); |
|
assert(second != NULL); |
|
/* create a new node, and check whether all is okay */ |
|
if (!(cur = (stringpair *)malloc(sizeof(stringpair)))) |
|
return NULL; |
|
cur->first = strdup(first); |
|
cur->second = strdup(second); |
|
cur->matchlength = matchlength; |
|
if (!cur->first || !cur->second) |
|
{ |
|
if (cur->first) |
|
free(cur->first); |
|
if (cur->second) |
|
free(cur->second); |
|
free(cur); |
|
return NULL; |
|
} /* if */ |
|
/* link the node to the tree, find the position */ |
|
for (pred = root; pred->next && strcmp(pred->next->first, first) < 0; |
|
pred = pred->next) |
|
/* nothing */ ; |
|
cur->next = pred->next; |
|
pred->next = cur; |
|
return cur; |
|
} |
|
|
|
static void |
|
delete_stringpairtable(stringpair * root) |
|
{ |
|
stringpair *cur, *next; |
|
|
|
assert(root != NULL); |
|
cur = root->next; |
|
while (cur) |
|
{ |
|
next = cur->next; |
|
assert(cur->first != NULL); |
|
assert(cur->second != NULL); |
|
free(cur->first); |
|
free(cur->second); |
|
free(cur); |
|
cur = next; |
|
} /* while */ |
|
memset(root, 0, sizeof(stringpair)); |
|
} |
|
|
|
static stringpair * |
|
find_stringpair(stringpair * cur, char *first, int matchlength) |
|
{ |
|
int result = 0; |
|
|
|
assert(matchlength > 0); /* the function cannot handle zero-length comparison */ |
|
assert(first != NULL); |
|
while (cur && result <= 0) |
|
{ |
|
result = (int)*cur->first - (int)*first; |
|
if (result == 0 && matchlength == cur->matchlength) |
|
{ |
|
result = strncmp(cur->first, first, matchlength); |
|
if (result == 0) |
|
return cur; |
|
} /* if */ |
|
cur = cur->next; |
|
} /* while */ |
|
return NULL; |
|
} |
|
|
|
static int |
|
delete_stringpair(stringpair * root, stringpair * item) |
|
{ |
|
stringpair *cur; |
|
|
|
assert(root != NULL); |
|
cur = root; |
|
while (cur->next) |
|
{ |
|
if (cur->next == item) |
|
{ |
|
cur->next = item->next; /* unlink from list */ |
|
assert(item->first != NULL); |
|
assert(item->second != NULL); |
|
free(item->first); |
|
free(item->second); |
|
free(item); |
|
return TRUE; |
|
} /* if */ |
|
cur = cur->next; |
|
} /* while */ |
|
return FALSE; |
|
} |
|
|
|
/* ----- alias table --------------------------------------------- */ |
|
static stringpair alias_tab = { NULL, NULL, NULL, 0 }; /* alias table */ |
|
|
|
stringpair * |
|
insert_alias(char *name, char *alias) |
|
{ |
|
stringpair *cur; |
|
|
|
assert(name != NULL); |
|
assert(strlen(name) <= sNAMEMAX); |
|
assert(alias != NULL); |
|
assert(strlen(alias) <= sEXPMAX); |
|
if (!(cur = insert_stringpair(&alias_tab, name, alias, strlen(name)))) |
|
error(103); /* insufficient memory (fatal error) */ |
|
return cur; |
|
} |
|
|
|
int |
|
lookup_alias(char *target, char *name) |
|
{ |
|
stringpair *cur = |
|
find_stringpair(alias_tab.next, name, strlen(name)); |
|
if (cur) |
|
{ |
|
assert(strlen(cur->second) <= sEXPMAX); |
|
strcpy(target, cur->second); |
|
} /* if */ |
|
return !!cur; |
|
} |
|
|
|
void |
|
delete_aliastable(void) |
|
{ |
|
delete_stringpairtable(&alias_tab); |
|
} |
|
|
|
/* ----- include paths list -------------------------------------- */ |
|
static stringlist includepaths = { NULL, NULL }; /* directory list for include files */ |
|
|
|
stringlist * |
|
insert_path(char *path) |
|
{ |
|
stringlist *cur; |
|
|
|
assert(path != NULL); |
|
if (!(cur = (stringlist *)malloc(sizeof(stringlist)))) |
|
error(103); /* insufficient memory (fatal error) */ |
|
if (!(cur->line = strdup(path))) |
|
error(103); /* insufficient memory (fatal error) */ |
|
cur->next = includepaths.next; |
|
includepaths.next = cur; |
|
return cur; |
|
} |
|
|
|
char * |
|
get_path(int idx) |
|
{ |
|
stringlist *cur = includepaths.next; |
|
|
|
while (cur && idx-- > 0) |
|
cur = cur->next; |
|
if (cur) |
|
{ |
|
assert(cur->line != NULL); |
|
return cur->line; |
|
} /* if */ |
|
return NULL; |
|
} |
|
|
|
void |
|
delete_pathtable(void) |
|
{ |
|
stringlist *cur = includepaths.next, *next; |
|
|
|
while (cur) |
|
{ |
|
next = cur->next; |
|
assert(cur->line != NULL); |
|
free(cur->line); |
|
free(cur); |
|
cur = next; |
|
} /* while */ |
|
memset(&includepaths, 0, sizeof(stringlist)); |
|
} |
|
|
|
/* ----- text substitution patterns ------------------------------ */ |
|
|
|
static stringpair substpair = { NULL, NULL, NULL, 0 }; /* list of substitution pairs */ |
|
static stringpair *substindex['z' - 'A' + 1]; /* quick index to first character */ |
|
|
|
static void |
|
adjustindex(char c) |
|
{ |
|
stringpair *cur; |
|
|
|
assert((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_'); |
|
assert('A' < '_' && '_' < 'z'); |
|
|
|
for (cur = substpair.next; cur && cur->first[0] != c; |
|
cur = cur->next) |
|
/* nothing */ ; |
|
substindex[(int)c - 'A'] = cur; |
|
} |
|
|
|
stringpair * |
|
insert_subst(char *pattern, char *substitution, int prefixlen) |
|
{ |
|
stringpair *cur; |
|
|
|
assert(pattern != NULL); |
|
assert(substitution != NULL); |
|
if (!(cur = insert_stringpair(&substpair, pattern, substitution, prefixlen))) |
|
error(103); /* insufficient memory (fatal error) */ |
|
adjustindex(*pattern); |
|
return cur; |
|
} |
|
|
|
stringpair * |
|
find_subst(char *name, int length) |
|
{ |
|
stringpair *item; |
|
|
|
assert(name != NULL); |
|
assert(length > 0); |
|
assert((*name >= 'A' && *name <= 'Z') || (*name >= 'a' && *name <= 'z') |
|
|| *name == '_'); |
|
item = substindex[(int)*name - 'A']; |
|
if (item) |
|
item = find_stringpair(item, name, length); |
|
return item; |
|
} |
|
|
|
int |
|
delete_subst(char *name, int length) |
|
{ |
|
stringpair *item; |
|
|
|
assert(name != NULL); |
|
assert(length > 0); |
|
assert((*name >= 'A' && *name <= 'Z') || (*name >= 'a' && *name <= 'z') |
|
|| *name == '_'); |
|
item = substindex[(int)*name - 'A']; |
|
if (item) |
|
item = find_stringpair(item, name, length); |
|
if (!item) |
|
return FALSE; |
|
delete_stringpair(&substpair, item); |
|
adjustindex(*name); |
|
return TRUE; |
|
} |
|
|
|
void |
|
delete_substtable(void) |
|
{ |
|
int i; |
|
|
|
delete_stringpairtable(&substpair); |
|
for (i = 0; i < (int)(sizeof(substindex) / sizeof(substindex[0])); i++) |
|
substindex[i] = NULL; |
|
}
|
|
|