/* 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 #endif #include #include #include #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 index) { stringlist *cur = includepaths.next; while (cur && index-- > 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; }