forked from enlightenment/efl
294 lines
7.1 KiB
C
294 lines
7.1 KiB
C
/* 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;
|
|
}
|