blob: 54f6701f856d5402357ef1f942b191c6087c4eee [file] [log] [blame]
/* TODO:
---- HIGHEST PRIORITY ----
* #ifndef
* #if/#elif - Bearbeitung
* leere argument-/tokenlists erlauben
* Anzahl der Argumente checken (auch zuviele ergeben einen Error)
* bei REDEFINING und allowredefinition=0 tokenlist genau ueberpruefen
* Aufteilen in mehrere Sourcen main.c pplists.c etc.
* Einige Variablen umbenennen (x,y,i,j,l,n etc =8)
-----------------------------------------------------------------
* Verbesserungen:
* - Nach malloc()/vor free() ueberpruefen ob NULL-Pointer
* - Statt per dlen per Ptr2EOL abfragen..
* Fragen an Volker:
* - _ alleine ein Identifier ? Ja
---- LOWEST PRIORITY ----
* - Token loeschen, wenn nur noch TokenList benutzt wird.
* - ParseIdent.. optimieren
* - Rest optimieren =8)
* - PreParsing umschreiben.. __LINE__ muss mit der echten
* Zeilennummer uebereinstimmen (die LFs drinlassen)
*/
/*
* PreProcessor
* $VER: VBPP V0.00 (19 Sep 1995)
* (w) 1995 by Thorsten Schaaps
*/
#include <time.h>
#include "vbc.h"
#include "vbpp.h"
/*vb: */
static char FILE_[]=__FILE__;
/*vb: */
char pp_version[] = "vbpp V0.00 (w) 1995 by Thorsten Schaaps";
/* #define MAXIFNESTING 1024 *//*vb: ifnesting==incnesting */
FILE *in[MAXINCNESTING]; /* Sourcefiles */
int zn[MAXINCNESTING]; /* Zeilennummern */
char *filenames[MAXINCNESTING]; /* Filenamen */
int incnesting; /* aktuelle Verschachtelungstiefe */
unsigned long linenr; /* Zeilennummer */
char *incpath[MAXINCPATHS] =
{"vinclude:"}; /* Includepfade */
int incpathc = 1; /* Anzahl der Includepfade */
char ppstring[MAXPPINPUT];
int cmtnesting = 0; /* aktuelle Kommentar-Versch.-Tiefe */
/*int ifnesting; *//*vb: *//* aktuelle IF-Tiefe */
/*vb: ifnesting==incnesting */
short ifstatus[MAXINCNESTING]; /* Array fuer Status-Verschachtelung */
int if_cnt; /* Zaehler fuer #if's waehrend do_output=0 */
int abs_if_cnt; /* zaehlt auch waehrend do_output */
int do_output = 1; /* Flag zur Erzeugung eines Outputs */
struct strnode *strlist;
struct mnode *mlist;
int did_expand;
/* Temporaere Debugging-Routinen */
void PrintSN(struct strnode *tl)
{
switch (tl->type) {
case NORMAL:
printf(" Normal........:");
break;
case PP_IDENT:
printf(" Identifier....:");
break;
case ARGUMENT:
printf(" Argument Nr.%2d:", tl->number);
break;
case NUMBER:
printf(" Number........:");
break;
case PP_STR:
printf(" String........:");
break;
case SPACE:
printf(" Space.........:");
break;
case SPECIAL:
printf(" Special..Nr.%2d:", tl->flags);
break;
default:
printf(" unknown..Nr.%2d:", tl->type);
break;
}
printf(" %s\n", tl->str);
}
void PrintTL(struct strnode *tl)
{
#ifdef bla
if (tl) {
printf("TokenList:\n");
while (tl) {
PrintSN(tl);
tl = tl->next;
}
}
#endif
}
/* ******* Listen-Funktionen ******* */
/* AddMakroNode - Fuegt eine Node an den Anfang einer Liste ein */
void AddMakroNode(struct mnode **list, struct mnode *node)
{
if (DEBUG & 32)
puts("AddMakroNode");
if (node) {
node->prev = NULL;
node->next = *list;
*list = node;
if (node->next)
node->next->prev = node;
}
}
/* AddStrNode - Fuegt eine Node in die Liste ein */
void AddStrNode(struct strnode **list, struct strnode *node, char *str)
{
if (DEBUG & 32)
puts("AddStrNode");
if (node || str) {
if (!node)
node = (struct strnode *) malloc(sizeof(struct strnode));
/* HIER: Rueckgabewert wegen Fehler ! */
if (!node) {
error(196);
} else {
node->prev = NULL;
node->next = *list;
if (str)
node->str = str;
*list = node;
if (node->next)
node->next->prev = node;
}
}
}
/* AddStrNodeBehind - Fuegt eine Node ans Ende der Liste ein */
void AddStrNodeBehind(struct strnode **list, struct strnode *node, char *str)
{
struct strnode *listnode;
if (DEBUG & 32)
puts("AddStrNodeBehind");
if (node || str) {
if (!node)
node = (struct strnode *) malloc(sizeof(struct strnode));
if (!node) {
error(196);
} else {
if (!*list) {
node->prev = NULL;
node->next = NULL;
*list = node;
} else {
listnode = *list;
while (listnode->next) {
listnode = listnode->next;
}
node->prev = listnode;
node->next = NULL;
listnode->next = node;
}
if (str)
node->str = str;
}
}
}
/* RemMakroNode - Entfernt eine Node aus der Liste ohne sie zu loeschen */
void RemMakroNode(struct mnode **list, struct mnode *node)
{
if (DEBUG & 32)
puts("RemMakroNode");
if (node->prev) {
if (node->next)
node->next->prev = node->prev;
node->prev->next = node->next;
} else {
if (node->next)
node->next->prev = NULL;
*list = node->next;
}
node->next = node->prev = NULL;
}
/* InsertMakroNode - Setzt eine Node hinter einer anderen ein */
void InsertMakroNode(struct mnode **list, struct mnode *node, struct mnode *behind)
{
if (DEBUG & 32)
puts("InsertMakroNode");
if (behind) {
node->prev = behind;
node->next = behind->next;
behind->next = node;
if (node->next)
node->next->prev = node;
} else
AddMakroNode(list, node);
}
/* RemStrNode - Entfernt eine Node aus der Liste ohne sie zu loeschen */
void RemStrNode(struct strnode **list, struct strnode *node)
{
if (DEBUG & 32)
puts("RemStrNode");
if (node->prev) {
if (node->next)
node->next->prev = node->prev;
node->prev->next = node->next;
} else {
if (node->next)
node->next->prev = NULL;
*list = node->next;
}
node->next = node->prev = NULL;
}
/* FindMakroNode - sucht den passenden Eintrag in der Liste
* len=0 - der gesamte String muss uebereinstimmen
* len>0 - die ersten len Zeichen muessen stimmen
*/
struct mnode *FindMakroNode(struct mnode *list, char *str, int len)
{
if (DEBUG & 32)
puts("FindMakroNode");
while (list) {
if (len) {
if ((strlen(list->name) == len) && (!strncmp(list->name, str, len)))
return (list);
} else {
if (!strcmp(list->name, str))
return (list);
}
list = list->next;
}
return (0);
}
/* DelMakroNode - gibt den gesamten Speicher einer Node frei, ist list#NULL
* wird die Node vorher aus der Liste entfernt
*/
void DelMakroNode(struct mnode **list, struct mnode *node)
{
if (DEBUG & 32)
puts("DelMakroNode");
if (node) {
if (list && *list)
RemMakroNode(list, node);
if (node->name)
free(node->name);
if (node->args)
free(node->args);
if (node->token)
free(node->token);
if (node->tokenlist)
DelStrList(&node->tokenlist);
free(node);
}
}
/* DelStrNode - gibt den gesamten Speicher einer Node frei, ist list#NULL
* wird die Node vorher aus der Liste entfernt
*/
void DelStrNode(struct strnode **list, struct strnode *node)
{
if (DEBUG & 32)
puts("DelStrNode");
if (node) {
if (list && *list)
RemStrNode(list, node);
if (node->str)
free(node->str);
free(node);
}
}
void MergeStrNodes(struct strnode *prev, struct strnode *next)
{
/* next will now be deleted and prev->str will be */
/* the joined strings from prev&next */
char *newstr;
/*vb: */
char c, *s, *d;
if (DEBUG & 32)
puts("MergeStrNodes");
newstr = (char *) malloc(prev->len + next->len + 1);
/*vb: string-Routinen ersetzt (hoffentlich schneller)
strcpy(newstr,prev->str);
strcat(newstr,next->str);
*/
d = newstr;
s = prev->str;
do {
c = *s++;
*d++ = c;
} while (c);
d--;
s = next->str;
do {
c = *s++;
*d++ = c;
} while (c);
if (prev->str)
free(prev->str); /*vb: wenn prev->str==0 knallts doch schon oben? */
prev->str = newstr;
prev->len += next->len;
DelStrNode(NULL, next);
}
/* DelMakroList - loescht eine gesamte Liste */
void DelMakroList(struct mnode **list)
{
if (DEBUG & 32)
puts("DelMakroList");
while (*list)
DelMakroNode(list, *list);
/* *list=NULL; *//*vb: *list==0 */
}
/* DelStrList - loescht eine gesamte Liste samt der Nodes/Strings */
void DelStrList(struct strnode **list)
{
if (DEBUG & 32)
puts("DelStrList");
while (*list)
DelStrNode(list, *list);
/* *list=NULL; *//*vb: *list==0 */
}
/* AllocSpace - erzeugt eine StrNode vom Typ Space */
struct strnode *AllocSpace()
{
struct strnode *newnode;
char *newstr;
if (DEBUG & 32)
puts("AllocSpace");
newstr = (char *) malloc(2);
if (newstr) {
newstr[0] = ' ';
newstr[1] = 0;
newnode = (struct strnode *) malloc(sizeof(struct strnode));
if (newnode) {
newnode->str = newstr;
newnode->type = SPACE;
newnode->len = 1;
newnode->next = newnode->prev = NULL;
newnode->flags = newnode->number = 0;
return (newnode);
}
}
return (NULL);
}
/* CloneStrList - erstellt eine exakte Kopie der Liste oder eines Ausschnittes */
/* wenn listend#NULL */
struct strnode *CloneStrList(struct strnode *list, struct strnode *listend)
{
struct strnode *prevnode = NULL, *newnode, *newlist = NULL;
char *newstr;
if (DEBUG & 32)
puts("CloneStrList");
while (list) {
newnode = (struct strnode *) malloc(sizeof(struct strnode));
if (!newnode) {
DelStrList(&newlist);
return (NULL);
}
newstr = (char *) malloc(list->len + 1);
if (!newstr) {
free(newnode);
DelStrList(&newlist);
return (NULL);
}
strcpy(newstr, list->str);
newnode->str = newstr;
newnode->len = list->len;
newnode->flags = list->flags;
newnode->type = list->type;
newnode->number = list->number;
newnode->next = NULL;
newnode->prev = prevnode;
if (prevnode)
prevnode->next = newnode;
else
newlist = newnode;
prevnode = newnode;
if (listend && list == listend)
list = NULL;
else
list = list->next;
}
return (newlist);
}
/* DoMakroFunction - erstellt eine StrList entsprechend des Function-Makros */
struct strnode *DoMakroFunction(struct mnode *makro)
{
struct strnode *result = NULL;
char *newstr = NULL, *timestr = NULL;
int len, type;
time_t timevalue;
if (DEBUG & 32)
puts("DoMakroFunction");
if (makro->flags & FUNCTION) {
switch (makro->funcnum) {
case FUNCLINE:
newstr = (char *) malloc(11);
if (!newstr)
return (NULL);
sprintf(newstr, "%lu", linenr);
len = strlen(newstr);
type = NUMBER;
break;
case FUNCFILE:
len = strlen(filenames[incnesting]);
newstr = (char *) malloc(len + 1 + 2);
if (!newstr)
return (NULL);
*newstr = '\"';
strcpy((newstr + 1), filenames[incnesting]);
strcat(newstr, "\"");
type = PP_STR;
break;
case FUNCDATE:
type = PP_STR;
newstr = (char *) malloc(14);
if (!newstr)
return (NULL);
timevalue = time(0);
timestr = ctime(&timevalue);
newstr[0] = '\"';
strncpy(newstr + 1, timestr + 4, 7); /* copy 'Mmm dd ' */
strcpy(newstr + 8, timestr + 20); /* copy 'yyyy' */
newstr[12] = '\"';
newstr[13] = 0;
len = 13;
break;
case FUNCTIME:
type = PP_STR;
newstr = (char *) malloc(11);
if (!newstr)
return (NULL);
timevalue = time(0);
timestr = ctime(&timevalue);
newstr[0] = '\"';
strncpy(newstr + 1, timestr + 11, 8); /* copy 'hh:mm:ss' */
newstr[9] = '\"';
newstr[10] = 0;
len = 10;
break;
default:
return (NULL);
break;
}
result = (struct strnode *) malloc(sizeof(struct strnode));
if (!result) {
if (newstr)
free(newstr);
return (NULL);
}
result->prev = result->next = NULL;
result->str = newstr;
result->len = len;
result->number = result->flags = 0;
result->type = type;
}
return (result);
}
/* ******* String-Funktionen ****** */
/* Str2List - parsed einen String in eine StrList */
struct strnode *Str2List(char *str)
{
struct strnode *newlist = NULL, *newnode = NULL;
char *temp, *string;
int length, type, flags;
if (DEBUG & 32)
puts("Str2List");
while (*str) {
flags = 0;
/*vb: casts eingefuegt */
if (isspace((unsigned char) *str)) { /* Spaces parsen */
temp = str + 1;
length = 1;
while (*temp && isspace((unsigned char) *temp)) {
temp++;
length++;
}
type = SPACE;
} else if (*str == '\"') { /* String parsen */
temp = str + 1;
length = 2;
while (*temp && *temp != '\"')
if (*temp == '\\') {
temp += 2;
length += 2;
} else {
temp++;
length++;
}
type = PP_STR;
} else if (*str == '\'') { /* String parsen */
temp = str + 1;
length = 2;
while (*temp && *temp != '\'')
if (*temp == '\\') {
temp += 2;
length += 2;
} else {
temp++;
length++;
}
type = PP_STR;
} else if (isdigit((unsigned char) *str) || (*str == '.' && isdigit((unsigned char) *(str + 1)))) {
/* Zahlen parsen */
temp = str;
length = 0;
while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
temp++;
length++;
}
if (*temp == '.') {
temp++;
length++;
if (isdigit((unsigned char) *temp) || *temp == 'e' || *temp == 'E')
while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
temp++;
length++;
}
}
if (*(temp - 1) == 'e' || *(temp - 1) == 'E')
if (isdigit((unsigned char) *temp) || *temp == '+' || *temp == '-') {
temp++;
length++;
while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
temp++;
length++;
}
}
type = NUMBER;
} else if (isalpha((unsigned char) *str) || *str == '_') { /* moegl. Identifier parsen */
temp = str + 1;
length = 1;
while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
temp++;
length++;
}
type = PP_IDENT;
} else if (*str) { /* alles andere als einzelne Zeichen */
length = 1;
type = NORMAL;
}
string = (char *) malloc(length + 1);
if (!string) {
error(196);
DelStrList(&newlist);
return (NULL);
}
strncpy(string, str, length);
string[length] = 0;
str += length;
newnode = (struct strnode *) malloc(sizeof(struct strnode));
if (!newnode) {
error(196);
if (string)
free(string);
return (NULL);
}
newnode->str = string;
newnode->len = length;
newnode->flags = flags;
newnode->type = type;
AddStrNodeBehind(&newlist, newnode, NULL);
}
return (newlist);
}
/* List2Str - schreibt eine Liste als String zurueck */
int List2Str(struct strnode *list, char *str, int maxchars)
{
int len = 0;
char c, *p;
if (DEBUG & 32)
puts("List2Str");
*str = 0;
if (list) {
while (list) {
if ((len + (list->len)) > (maxchars - 1)) {
error(177);
return (0);
} else {
/*vb: */
p = list->str;
do {
c = *p++;
*str++ = c;
} while (c);
str--;
/* strcat(str,list->str); */
len += list->len;
}
list = list->next;
}
return (len + 1);
} else {
*str = 0;
return (1);
}
}
/* ListLen - ermittelt die Laenge einer Str-Liste (in Zeichen) */
int ListLen(struct strnode *list)
{
int len = 0;
while (list) {
len += list->len;
list = list->next;
}
return (len);
}
/* ListStrLen - ermittelt die Laenge einer Str-List als String */
/* d.h. mit " am Anfang und Ende, sowie einem \ vor */
/* jedem \ und " */
int ListStrLen(struct strnode *list)
{
int len = 2;
while (list) {
if (list->type == SPACE)
len++;
else {
len += list->len;
if (list->type == PP_STR && list->str[0] == '\"')
len += 2;
else if (list->type == NORMAL && list->str[0] == '\\')
len++;
}
list = list->next;
}
return (len);
}
/* CopyList2StrStr - kopiert eine Str-List als String um */
/* d.h. mit " am Anfang und Ende, sowie einem \ vor */
/* jedem \ und " */
CopyList2StrStr(struct strnode * list, char *str)
{
int len;
if (DEBUG & 32)
puts("CopyList2StrStr");
str[0] = 0;
if (list) {
strcpy(str, "\"");
len = 1;
while (list) {
if (list->type == SPACE) {
len++;
strcat(str, " ");
} else {
len += list->len;
if (list->type == PP_STR && list->str[0] == '\"') {
strcat(str, "\\");
strncat(str, list->str, list->len - 1);
strcat(str, "\\\"");
} else if (list->type == NORMAL && list->str[0] == '\\') {
strcat(str, "\\");
strcat(str, list->str);
} else
strcat(str, list->str);
}
list = list->next;
}
strcat(str, "\"");
len++;
}
return (len);
}
/* NextToSpecial - checked, ob die StrNode neben einem # oder ## steht */
int NextToSpecial(struct strnode *node)
{
struct strnode *search;
if (DEBUG & 32)
puts("NextToSpecial");
if (node->prev) {
search = node->prev;
while (search && search->type == SPACE)
search = search->prev;
if (search && search->type == SPECIAL)
return (search->flags);
}
if (node->next) {
search = node->next;
while (search && search->type == SPACE)
search = search->next;
/* Hinter der Node ist ein # (ToString) ohne Bedeutung */
if (search && search->type == SPECIAL
&& search->flags == KILLSPACES)
return (KILLSPACES);
}
return (NONE);
}
/* FindBracket - sucht das passende Gegenstueck zu der (, auf die Node zeigt */
/* dabei werden verschachtelte Klammern beachtet */
struct strnode *FindBracket(struct strnode *node)
{
if (DEBUG & 32)
puts("FindBracket");
if (node && node->next && node->type == NORMAL && node->str[0] == '(') {
do {
node = node->next;
if (node && node->type == NORMAL) {
if (node->str[0] == ')')
return (node);
if (node->str[0] == '(')
node = FindBracket(node);
}
} while (node);
return (NULL);
} else
return (NULL);
}
/* CloneArg - gibt eine Liste zurueck, die das n. Argument des Makros enthaelt */
struct strnode *CloneArg(struct strnode *list, int n, int *error)
{
int argnum = 0;
struct strnode *start;
if (error)
*error = OK;
if (list) {
if (DEBUG & 32)
printf("CloneArg\n");
if (list->type == PP_IDENT)
list = list->next;
while (list && list->type == SPACE)
list = list->next;
if (list && list->type == NORMAL && list->str[0] == '(') {
list = list->next; /* Skip ( */
if (DEBUG & 32)
printf("- IDENT skipped, ( found\n");
while (list && (argnum < n)) {
if (list->type == NORMAL) {
if (list->str[0] == ')')
list = NULL;
if (list && list->str[0] == '(')
list = (FindBracket(list))->next;
if (list && list->str[0] == ',')
argnum++;
}
if (list)
list = list->next;
}
while (list && list->type == SPACE)
list = list->next;
if (list) {
if (list->type == NORMAL && (list->str[0] == ')' || list->str[0] == ',')) { /* HIER evtl. ein Space erzeugen */
return (NULL);
}
start = list;
} else {
if (error)
*error = ARG_EXPECTED;
return (NULL);
}
if (DEBUG & 32)
printf("- Okay, Arg-Start found: %s\n", start->str);
while (list && (argnum == n)) {
if (list->type == NORMAL) {
switch (list->str[0]) {
case ')':
case ',':
argnum++;
list = list->prev;
break;
case '(':
list = FindBracket(list);
default:
if (list)
list = list->next;
break;
}
} else if (list)
list = list->next;
}
while (list && list->type == SPACE)
list = list->prev;
if (DEBUG & 32)
printf("- Okay, Arg-End found: %s\n", list->str);
return (CloneStrList(start, list));
} else {
if (error)
*error = ARG_EXPECTED;
return (NULL);
}
} else
return (NULL);
}
/* ExpandArgMakro - ersetzt ein Makro mit Argumenten */
int ExpandArgMakro(struct mnode *makro, struct strnode **list,
struct strnode **pos)
{
struct strnode *clone, *temp, *temp1, *arg, *new;
struct strnode *prev, *next;
struct mnode *prevmakro;
char *newstr;
int spec, len, x;
clone = CloneStrList(makro->tokenlist, NULL);
if (!clone)
return (OUT_OF_MEM);
if (DEBUG & 32)
printf("ExpandArgMakro - Clone build.\n");
temp = clone;
while (temp) {
if (temp->type == ARGUMENT) {
arg = CloneArg(*pos, temp->number, &x);
if (!arg) {
DelStrList(&clone);
return (x);
}
if (DEBUG & 32) {
printf("ARGUMENT:\n");
PrintTL(arg);
printf("Argument found - ");
}
if (spec = NextToSpecial(temp)) {
/* nicht expandieren, nur einsetzen */
if (spec == TOSTRING) {
if (DEBUG & 32)
printf("next to #\n");
/* als String einsetzen */
new = (struct strnode *) malloc(sizeof(struct strnode));
if (!new) {
DelStrList(&clone);
DelStrList(&arg);
return (OUT_OF_MEM);
}
len = ListStrLen(arg);
newstr = (char *) malloc(len + 1);
if (!newstr) {
DelStrList(&clone);
DelStrList(&arg);
if (new)
free(new);
return (OUT_OF_MEM);
}
CopyList2StrStr(arg, newstr);
DelStrList(&arg);
new->len = len + 2;
new->flags = new->number = 0;
new->type = PP_STR;
new->str = newstr;
prev = temp->prev;
next = temp->next;
DelStrNode(NULL, temp); /* Argument */
while (prev && prev->type == SPACE) {
temp = prev->prev;
DelStrNode(&clone, prev);
prev = temp;
}
if (prev && prev->type == SPECIAL && prev->flags == TOSTRING) {
temp = prev->prev;
DelStrNode(&clone, prev);
prev = temp;
} else
ierror(0);
new->prev = prev;
if (prev)
prev->next = new;
else
clone = new;
new->next = next;
if (next)
next->prev = new;
temp = new;
} else {
/* Einfach nur einsetzen */
if (DEBUG & 32)
printf("next to ##\n");
prev = temp->prev;
next = temp->next;
DelStrNode(NULL, temp);
arg->prev = prev;
if (prev)
prev->next = arg;
else
clone = arg;
while (arg->next)
arg = arg->next;
arg->next = next;
if (next)
next->prev = arg;
temp = arg;
}
} else {
/* expandieren und einsetzen */
if (DEBUG & 32)
printf("normal arg\n");
if (x = ExpandList(&arg)) {
DelStrList(&clone);
DelStrList(&arg);
return (x);
}
if (DEBUG & 32) {
printf("expanded arg:\n");
PrintTL(arg);
}
prev = temp->prev;
next = temp->next;
DelStrNode(NULL, temp);
arg->prev = prev;
if (prev)
prev->next = arg;
else
clone = arg;
while (arg->next)
arg = arg->next;
arg->next = next;
if (next)
next->prev = arg;
temp = arg;
} /* of N2Special */
}
if (temp)
temp = temp->next;
}
if (DEBUG & 32)
printf("Arguments expanded.\n");
temp = clone;
while (temp) {
if (temp->type == SPECIAL && temp->flags == KILLSPACES) {
prev = temp->prev;
next = temp->next;
if ((prev->type == PP_IDENT || prev->type == NUMBER)) {
switch (next->type) {
case NUMBER: /* merge -> ident */
case PP_IDENT:
RemStrNode(&clone, next);
MergeStrNodes(prev, next);
next = temp->next;
/* next will now be deleted and prev->str will be */
/* the joined strings from prev&next */
default: /* no merge / del ## */
DelStrNode(&clone, temp);
temp = next;
break;
} /* of switch */
} else {
DelStrNode(&clone, temp);
temp = next;
}
}
if (temp)
temp = temp->next;
}
/* 'makro' aus mlist ausklinken */
prevmakro = makro->prev;
RemMakroNode(&mlist, makro);
/* alles expandieren */
if (!(x = ExpandList(&clone))) {
/* akt. StrNode durch clone-Liste ersetzen */
if (DEBUG & 32) {
printf("Complete Makro expanded\n");
PrintTL(clone);
}
/* clone anstelle von pos in list einsetzen */
prev = (*pos)->prev;
next = (*pos)->next;
DelStrNode(NULL, *pos);
#ifdef bla
while (next && next->type == SPACE) {
temp = next->next;
DelStrNode(NULL, next); /* SPACE zwischen Makro und Args loeschen */
next = temp;
}
#endif
while (next && next->type == SPACE)
next = next->next;
/* SPACE hinter Makro ueberspringen */
if (next && next->type == NORMAL && next->str[0] == '(') {
temp = next;
next = FindBracket(temp);
if (next)
next = next->next;
do {
temp1 = temp->next;
DelStrNode(NULL, temp); /* ARG-List hinter Makro loeschen */
temp = temp1;
} while (temp != next);
} else {
ierror(0);
}
/* vor clone ein SPACE einsetzen, wenn nicht PREV==SPACE */
/*vb: hier !prev|| wegen Enforcerhit eingesetzt; waere prev&& besser? */
if (!prev || prev->type != SPACE) {
if (temp = AllocSpace()) {
temp->next = clone;
if (clone)
clone->prev = temp;
clone = temp;
}
}
clone->prev = prev;
if (prev)
prev->next = clone;
else
*list = clone;
while (clone->next)
clone = clone->next;
/* nach clone ein SPACE einsetzen, wenn nicht NEXT==SPACE */
/*vb: hier !next|| wegen Enforcerhit eingesetzt; waere next&& besser? */
if (!next || next->type != SPACE) {
if (temp = AllocSpace()) {
temp->prev = clone;
if (clone)
clone->next = temp;
clone = temp;
}
}
*pos = clone;
clone->next = next;
if (next)
next->prev = clone;
/* 'makro' wieder einsetzen */
InsertMakroNode(&mlist, makro, prevmakro);
return (OK);
} else {
InsertMakroNode(&mlist, makro, prevmakro);
return (x);
}
}
/* ExpandList - ersetzt alle Makros in der Liste */
int ExpandList(struct strnode **list)
{
struct mnode *found, *before;
struct strnode *clone, *beforestr, *afterstr, *listtemp, *temp2,
*temp3;
int result = OK;
if (DEBUG & 32)
puts("ExpandList");
listtemp = *list;
while (listtemp) {
if (listtemp->type == PP_IDENT) {
found = FindMakroNode(mlist, listtemp->str, 0);
if (found) {
/*vb: merken, ob mind. ein Makro expandiert wurde */
did_expand = 1;
if (found->flags & PARAMETER) {
/* Makro mit Argument(en) */
if (DEBUG & 32)
printf("Makro with args\n");
temp2 = listtemp->next;
while (temp2 && temp2->type == SPACE)
temp2 = temp2->next;
if (temp2 && temp2->type == NORMAL && temp2->str[0] == '(')
if (result = ExpandArgMakro(found, list, &listtemp))
return (result);
} else {
/* Makro ohne Argument */
/* ExpandNormMakro - expandiert ein Makro ohne Argumente */
/* Parameter: s.o. */
if (found->flags & FUNCTION) {
clone = DoMakroFunction(found);
} else {
clone = CloneStrList(found->tokenlist, NULL);
}
if (!clone)
return (OUT_OF_MEM);
/* akt. MakroNode ausklinken um rekursive Exp. zu verhindern */
before = found->prev;
RemMakroNode(&mlist, found);
if (!(result = ExpandList(&clone))) {
/* akt. StrNode durch clone-Liste ersetzen */
beforestr = listtemp->prev;
afterstr = listtemp->next;
DelStrNode(NULL, listtemp);
listtemp = afterstr;
clone->prev = beforestr;
if (beforestr)
beforestr->next = clone;
else
*list = clone;
while (clone->next)
clone = clone->next;
clone->next = afterstr;
if (afterstr)
afterstr->prev = clone;
/* akt. Makronode wieder einsetzen */
InsertMakroNode(&mlist, found, before);
} else {
/* akt. Makronode wieder einsetzen */
InsertMakroNode(&mlist, found, before);
return (result);
}
}
}
}
if (listtemp)
listtemp = listtemp->next;
}
return (OK);
}
/* ParseIdentifier - parsed den Input-Define-String und haengt das Makro */
/* in die Liste */
struct mnode *ParseIdentifier(char *str)
{
int x, numargs = 0, flags = 0, len = 0;
char *name = NULL, *args = NULL, *token = NULL, *temp, *temp2, *argtemp;
struct mnode *newmakro, *found;
struct strnode *tokenlist = NULL, *templist, *arglist = NULL, *templist2;
struct strnode *next, *prev;
if (DEBUG & 32)
puts("ParseIdentifier");
/*vb: casts eingefuegt */
while (isspace((unsigned char) *str)) {
str++;
}
if (!(isalpha((unsigned char) *str) || *str == '_')) {
error(178);
return (0);
}
temp = str;
while (isalnum((unsigned char) *temp) || (*temp == '_')) {
temp++;
len++;
}
/* auf schon vorhandene (evtl. FESTE) Definition suchen */
found = FindMakroNode(mlist, str, len);
if (found && (found->flags & NOREDEF)) {
error(179);
return (0);
}
/*vb: */
if (1) {
/* Okay, ist egal, wie das alte Makro aussah */
/*vb: */
if (found && !(c_flags[15] & USEDFLAG)) {
error(197);
}
temp = name = (char *) malloc(len + 1); /* Speicher fuer Name-String belegen */
if (!name) {
error(196);
return (0);
}
for (x = 0; x < len; x++) {
*temp++ = *str++;
} /* Namen kopieren */
*temp = 0;
if (*str == '(') {
flags |= PARAMETER;
str++; /* jump over '(' */
temp = str;
len = 0;
/*vb: casts eingefuegt */
while (*temp && (*temp != ')'))
if (!(isspace((unsigned char) *temp))) {
len++;
temp++;
} else {
temp++;
}
if (*temp == 0) {
error(180);
if (name)
free(name);
return (0);
}
args = temp = (char *) malloc(len + 1);
if (!args) {
error(196);
if (name)
free(name);
return (0);
}
for (x = 0; x < len;)
if (!(isspace((unsigned char) *str))) {
x++;
*temp++ = *str++;
} else {
str++;
}
*temp = 0;
str++; /* jump over ')' */
/* Argumentliste parsen und auf Fehler pruefen */
temp = args;
while (*temp && (isalpha((unsigned char) *temp) || *temp == '_')) {
temp++;
while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
temp++;
}
if (!(*temp) || *temp == ',') {
numargs++;
if ((*temp == ',') && (isalpha((unsigned char) *(temp + 1)) || *(temp + 1) == '_'))
temp++;
}
}
if (*temp) {
if (args)
free(args);
if (name)
free(name);
if (*temp == ',') {
error(181);
} else {
error(182);
}
return (0);
}
}
while (isspace((unsigned char) *str))
str++; /* Skip Spaces */
/* HIER: pruefen, ob tokenlist erstellt werden konnte (leere tokenlist->ok) */
tokenlist = Str2List(str);
if (DEBUG & 32)
printf(" - build TokenList\n");
templist = tokenlist;
while (templist) {
if ((templist->type == NORMAL) && (!strcmp(templist->str, "#"))) {
if ((templist->next) && (templist->next->type == NORMAL)
&& (!strcmp(templist->next->str, "#"))) {
/* ## KILLSPACES */
if ((templist->prev) && (templist->next->next)) {
templist->type = SPECIAL;
templist->flags = KILLSPACES;
DelStrNode(&tokenlist, templist->next);
} else {
error(183);
if (name)
free(name);
if (args)
free(args);
if (tokenlist)
DelStrList(&tokenlist);
return (0);
}
}
}
templist = templist->next;
}
/* Token parsen/kopieren */
if ((flags & PARAMETER)) { /* Argumente parsen */
arglist = NULL;
temp = temp2 = args;
while (*temp) {
len = 0;
while (*temp && *temp != ',') {
temp++;
len++;
}
if (*temp == ',')
temp++;
argtemp = (char *) malloc(len + 1);
if (!argtemp) {
error(196);
if (name)
free(name);
if (args)
free(args);
if (arglist)
DelStrList(&arglist);
if (tokenlist)
DelStrList(&tokenlist);
return (0);
}
strncpy(argtemp, temp2, len);
temp2 = temp;
*(argtemp + len) = 0;
AddStrNodeBehind(&arglist, NULL, argtemp);
}
templist = tokenlist;
while (templist) {
if (templist->type == PP_IDENT) {
x = 0;
templist2 = arglist;
while (templist2) {
if (!strcmp(templist->str, templist2->str)) {
templist->type = ARGUMENT;
templist->number = x;
}
x++;
templist2 = templist2->next;
}
}
templist = templist->next;
}
DelStrList(&arglist);
if (DEBUG & 32)
printf(" - Arguments found.\n");
/* #-Specials korrigieren, nachdem die Argumente erkannt wurden */
templist = tokenlist;
while (templist) {
if ((templist->type == NORMAL) && (!strcmp(templist->str, "#"))) {
if ((templist->next) && (templist->next->type == ARGUMENT)) {
templist->type = SPECIAL;
templist->flags = TOSTRING;
} else {
error(184);
if (name)
free(name);
if (args)
free(args);
if (arglist)
DelStrList(&arglist);
if (tokenlist)
DelStrList(&tokenlist);
return (0);
}
}
templist = templist->next;
}
if (DEBUG & 32)
printf(" - Special-# corrected.\n");
} else { /* Token kopieren */
temp = str;
len = 0;
while ((*temp) && (*temp != '\n')) {
temp++;
len++;
}
temp = token = (char *) malloc(len + 1);
if (!token) {
error(196);
if (name)
free(name);
if (args)
free(args);
if (tokenlist)
DelStrList(&tokenlist);
return (0);
}
for (x = 0; x < len; x++) {
*temp++ = *str++;
}
*temp = 0;
}
templist = tokenlist;
while (templist) {
if (templist->type == SPECIAL && templist->flags == KILLSPACES) {
next = templist->next;
prev = templist->prev;
/* Kill Spaces before/after ## */
while (prev && prev->type == SPACE) {
templist2 = prev->prev;
DelStrNode(&tokenlist, prev);
prev = templist2;
}
while (next && next->type == SPACE) {
templist2 = next->next;
DelStrNode(&tokenlist, next);
next = templist2;
}
if ((!next) || (!prev))
ierror(0);
if (next->type != ARGUMENT && prev->type != ARGUMENT) {
if ((prev->type == PP_IDENT || prev->type == NUMBER)) {
switch (next->type) {
case NUMBER: /* merge -> ident */
case PP_IDENT:
RemStrNode(&tokenlist, next);
MergeStrNodes(prev, next);
next = templist->next;
/* next will now be deleted and prev->str will be */
/* the joined strings from prev&next */
default: /* no merge / del ## */
DelStrNode(&tokenlist, templist);
templist = next;
break;
} /* of switch */
} else {
DelStrNode(&tokenlist, templist);
templist = next;
}
}
}
if (templist)
templist = templist->next;
}
/* erst HIER bei allowredefinition=0 abfragen ?? */
if (newmakro = (struct mnode *) malloc(sizeof(struct mnode))) {
newmakro->name = name;
newmakro->args = args;
newmakro->token = token;
newmakro->tokenlist = tokenlist;
newmakro->flags = flags;
newmakro->funcnum = 0;
AddMakroNode(&mlist, newmakro);
} else {
error(196);
if (name)
free(name);
if (token)
free(token);
if (args)
free(args);
if (tokenlist)
DelStrList(&tokenlist);
}
return (newmakro);
} else {
/*vb: das ist irgendwie Unsinn hier, glaube ich */
ierror(0);
/* HIER: ueberpruefen, ob Macrodefinitionen uebereinstimmen, sonst Error */
if (*temp == '(') {
if (found->flags & PARAMETER) {
temp++; /* skip ( */
} else {
error(185);
return (NULL);
}
}
/* HIER nur noch tokenlisten vergleichen */
}
if (DEBUG & 32)
printf("ParseIdent falls of\n");
}
/* PreParse - 3-Zeichen-Folgen ersetzen, \+CR Zeilen anhaengen, usw.. */
int PreParse()
{
char *src, *dest, *dest2;
int slen, dlen = 0;
int cat = 0; /*vb: um zu merken, ob Zeilen mit \ verbunden werden */
dest2 = string;
if (DEBUG & 32)
puts("PreParse");
if (!fgets(ppstring, MAXPPINPUT, in[incnesting])) {
if (cmtnesting)
error(186);
/*vb: */
/* if(ifstatus[incnesting]) error(186); */
/* ifnesting--; */
if (DEBUG & 32)
printf("-- end of file ifnesting-1:%d\n\n", incnesting);
if (incnesting) {
fclose(in[incnesting]);
incnesting--;
return (pp_nextline());
} else
return (0);
} else if (DEBUG & 32)
printf("gets1:%s\n", ppstring); /*vb: */
if ((strlen(ppstring) == (MAXPPINPUT - 1)) && (ppstring[MAXPPINPUT - 2] != '\n')) {
error(177);
return (0);
}
zn[incnesting]++;
linenr = zn[incnesting];
do {
/* Zeilen einlesen, bis kein Kommentar mehr */
/* Zeilen einlesen bis kein \ mehr am Ende */
do {
/* Source-String an Dest-String anhaengen und ??x-Folgen ersetzen */
/*vb: das killt sonst das angehaengte wieder */
if (cat == 0) {
dest = src = ppstring;
slen = 0;
}
do {
if (*src != '\n') {
if ((*src == '?') && (*(src + 1) == '?') && !(c_flags[16] & USEDFLAG)) {
switch (*(src + 2)) {
case '=':
*dest++ = '#';
src += 2;
break;
case '/':
*dest++ = '\\';
src += 2;
break;
case '\'':
*dest++ = '^';
src += 2;
break;
case '(':
*dest++ = '[';
src += 2;
break;
case ')':
*dest++ = ']';
src += 2;
break;
case '!':
*dest++ = '|';
src += 2;
break;
case '<':
*dest++ = '{';
src += 2;
break;
case '>':
*dest++ = '}';
src += 2;
break;
case '-':
*dest++ = '~';
src += 2;
break;
default:
*dest++ = *src;
break;
} /* of switch */
} else {
*dest++ = *src;
}
if (slen < MAXPPINPUT) {
slen++;
} else {
error(177);
return (0);
}
}
} while (*src++);
src = dest;
/* dest->lastchar+2/NULL+1 (dest-1)-> 0 (dest-2)->lastchar */
if (*(dest - 2) == '\\') {
/*vb: sollte das slen statt dlen sein? */
if (fgets(src, MAXPPINPUT - dlen, in[incnesting])) {
if (DEBUG & 32)
printf("gets2:%s\n", src); /*vb: */
/* Hier auf LF+0 abfragen */
dest -= 2;
zn[incnesting]++;
cat = 1; /*vb: merken, dass Zeilen verbunden wurden */
}
}
} while (*dest == '\\');
src = ppstring;
while (*src) {
/* ' Strings ueberlesen */
if ((*src == '\'') && (!cmtnesting)) {
if (dlen < MAXINPUT) {
*dest2++ = *src++;
dlen++;
} else {
error(177);
return (0);
}
while (*src && *src != '\'') {
if (*src == '\\') {
*dest2++ = *src++;
dlen++;
};
if (dlen < MAXINPUT) {
*dest2++ = *src++;
dlen++;
} else {
error(177);
return (0);
}
}
if (dlen < MAXINPUT) {
*dest2++ = *src++;
dlen++;
} else {
error(177);
return (0);
}
}
/* " Strings ueberlesen */
if ((*src == '\"') && (!cmtnesting)) {
*dest2++ = *src++;
dlen++;
while (*src && *src != '\"') {
if (*src == '\\') {
*dest2++ = *src++;
dlen++;
};
if (dlen < MAXINPUT) {
*dest2++ = *src++;
dlen++;
} else {
error(177);
return (0);
}
}
if (dlen < MAXINPUT) {
*dest2++ = *src++;
dlen++;
} else {
error(177);
return (0);
}
}
/* Kommentare weglassen */
if ((*src == '/') && (*(src + 1) == '*')) {
src += 2;
if (dlen < MAXINPUT) {
*dest2++ = ' ';
dlen++;
} else {
error(177);
return (0);
}
if ((cmtnesting && (c_flags[13] & USEDFLAG)) || (!cmtnesting))
cmtnesting++;
else
error(198);
} else {
if ((*src == '*') && (*(src + 1) == '/') && cmtnesting) {
src += 2;
cmtnesting--;
}
}
/* C++-Comment weglassen */
if ((!cmtnesting) && (*src == '/') && (*(src + 1) == '/') && (c_flags[14] & USEDFLAG))
*src = 0;
if (!cmtnesting) {
if (*src) {
*dest2++ = *src++;
}
if (dlen < MAXINPUT) {
dlen++;
} else {
error(177);
return (0);
}
} else {
if (*src)
src++;
}
}
if (cmtnesting) {
if (!fgets(ppstring, MAXPPINPUT, in[incnesting])) {
if (cmtnesting)
error(186);
if (incnesting) {
fclose(in[incnesting]);
incnesting--;
return (pp_nextline());
} else
return (0);
} else if (DEBUG & 32)
printf("gets2:%s\n", ppstring); /*vb: */
if ((strlen(ppstring) == (MAXPPINPUT - 1)) && (ppstring[MAXPPINPUT - 2] != '\n')) {
error(177);
return (0);
}
zn[incnesting]++;
}
} while (cmtnesting);
/*vb: das ueberschreibt den Speicher */
#if 0
*dest2-- = 0;
while (isspace(*dest2))
*dest2-- = 0; /* Spaces killen */
#endif
/*vb: hoffe, das ist besser */
*dest2 = 0;
while (dest2 > string && isspace((unsigned char) *--dest2))
*dest2 = 0;
return (1);
}
/* **************** PreProcessor ***************** */
int pp_init(void)
{
char *macroname;
struct mnode *macronode;
if (!(c_flags[6] & USEDFLAG))
printf("%s\n", pp_version);
incnesting = /*ifnesting= */ -1; /*vb: */
cmtnesting = if_cnt = abs_if_cnt = 0;
mlist = NULL;
strlist = NULL;
macroname = (char *) malloc(9);
if (!macroname)
return (0);
strcpy(macroname, "__LINE__");
macronode = (struct mnode *) malloc(sizeof(struct mnode));
if (!macronode) {
if (macroname)
free(macroname);
return (0);
}
macronode->name = macroname;
macronode->args = macronode->token = NULL;
macronode->tokenlist = NULL;
macronode->flags = FUNCTION | NODELETE | NOREDEF;
macronode->funcnum = FUNCLINE;
AddMakroNode(&mlist, macronode);
macroname = (char *) malloc(9);
if (!macroname)
return (0);
strcpy(macroname, "__FILE__");
macronode = (struct mnode *) malloc(sizeof(struct mnode));
if (!macronode) {
if (macroname)
free(macroname);
DelMakroList(&mlist);
return (0);
}
macronode->name = macroname;
macronode->args = macronode->token = NULL;
macronode->tokenlist = NULL;
macronode->flags = FUNCTION | NODELETE | NOREDEF;
macronode->funcnum = FUNCFILE;
AddMakroNode(&mlist, macronode);
macroname = (char *) malloc(9);
if (!macroname)
return (0);
strcpy(macroname, "__DATE__");
macronode = (struct mnode *) malloc(sizeof(struct mnode));
if (!macronode) {
if (macroname)
free(macroname);
DelMakroList(&mlist);
return (0);
}
macronode->name = macroname;
macronode->args = macronode->token = NULL;
macronode->tokenlist = NULL;
macronode->flags = FUNCTION | NODELETE | NOREDEF;
macronode->funcnum = FUNCDATE;
AddMakroNode(&mlist, macronode);
macroname = (char *) malloc(9);
if (!macroname)
return (0);
strcpy(macroname, "__TIME__");
macronode = (struct mnode *) malloc(sizeof(struct mnode));
if (!macronode) {
if (macroname)
free(macroname);
DelMakroList(&mlist);
return (0);
}
macronode->name = macroname;
macronode->args = macronode->token = NULL;
macronode->tokenlist = NULL;
macronode->flags = FUNCTION | NODELETE | NOREDEF;
macronode->funcnum = FUNCTIME;
AddMakroNode(&mlist, macronode);
macroname = (char *) malloc(9);
if (!macroname)
return (0);
strcpy(macroname, "__STDC__");
macronode = (struct mnode *) malloc(sizeof(struct mnode));
if (!macronode) {
if (macroname)
free(macroname);
DelMakroList(&mlist);
return (0);
}
macronode->name = macroname;
macronode->args = NULL;
macroname = (char *) malloc(2);
if (!macroname) {
if (macronode->name)
free(macronode->name);
if (macronode)
free(macronode);
DelMakroList(&mlist);
return (0);
}
strcpy(macroname, "1");
macronode->token = macroname;
macronode->tokenlist = Str2List(macroname);
if (!macronode->tokenlist) {
if (macronode->name)
free(macronode->name);
if (macronode->token)
free(macronode->token);
if (macronode)
free(macronode);
DelMakroList(&mlist);
return (0);
}
macronode->flags = NODELETE;
macronode->funcnum = 0;
AddMakroNode(&mlist, macronode);
return (1);
}
void pp_free(void)
{
int i;
if (DEBUG & 32)
puts("pp_free");
/*vb: Schleifenindex korrekt gesetzt */
for (i = incnesting; i >= 0; i--)
if (in[i])
fclose(in[i]);
DelMakroList(&mlist);
DelStrList(&strlist);
}
int pp_include(char *f)
{
if (DEBUG & 32)
printf("trying to include %s\n", f); /*vb: */
if (incnesting >= MAXINCNESTING - 1) {
error(187);
return (0);
}
/*vb: */
/* if(ifnesting>=MAXIFNESTING-1) {error("Too many nested #ifs or #includes",0);return(0);} */
incnesting++;
/* ifnesting++; *//*vb: */
ifstatus[incnesting] = 0; /*vb: */
if (DEBUG & 32)
printf("-- include: ifnesting:%d ifstatus:0 \n\n", incnesting);
in[incnesting] = fopen(f, "r");
if (!in[incnesting]) {
incnesting--;
return (0);
}
filenames[incnesting] = f;
zn[incnesting] = linenr = 0;
return (1);
}
/* ********************** Main-Function ******************* */
int pp_nextline(void)
{
char *src, *dest, *temp;
int complete_len, len, i, result;
struct mnode *makro;
struct strnode *linelist, *inclinelist;
if (DEBUG & 32)
puts("pp_nextline");
dest = string;
dest[0] = 0;
/* String vorbereiten, 3ZF ersetzen, \-Zeilen anhaengen, Kommentare loeschen */
if (!PreParse())
return (0);
/* Ueberpruefung auf PreProcessor-Commands */
src = string;
/*vb: casts eingefuegt */
while (isspace((unsigned char) *src)) {
src++;
} /* SkipSpaces */
if (*src == '#') { /* #-Direktive gefunden */
src++; /* # ueberlesen */
while (isspace((unsigned char) *src)) {
src++;
} /* SkipSpaces */
/*vb: Direktiven, die nichts mit #if etc. zu tun haben, nach hinten */
/* IFDEF */
if (!strncmp(src, "ifdef", 5)) {
src += 5;
abs_if_cnt++; /*vb: */
if (isspace((unsigned char) *src)) {
while (isspace((unsigned char) *src)) {
src++;
}
/* identifier suchen */
if (do_output) {
/*vb: */
/* if(ifnesting>=MAXIFNESTING-1) {error("Too many nested #if's",0); return(0);} */
/* ifnesting++; */
temp = src;
len = 0;
while ((isalnum((unsigned char) *temp)) || (*temp == '_')) {
temp++;
len++;
}
makro = FindMakroNode(mlist, src, len);
if (DEBUG & 32)
printf("-- #ifdef found, ");
if (makro) {
/*vb: */
ifstatus[incnesting] = 1; /* Bedingung == TRUE */
if (DEBUG & 32)
printf(" condition '%s' found (TRUE)\n", makro->name);
} else {
/*vb: */
ifstatus[incnesting] = 2; /* Bedingung == FALSE */
do_output = 0;
if (DEBUG & 32)
printf(" condition not found (FALSE)\n\n");
}
} else {
if_cnt++;
if (DEBUG & 32)
printf("-- #ifdef found and if_cnt increased\n\n");
}
string[0] = 0; /*vb: yo */
return (1);
}
} /* EO IFDEF */
/* IFNDEF */
if (!strncmp(src, "ifndef", 6)) {
src += 6;
abs_if_cnt++; /*vb: */
if (isspace((unsigned char) *src)) {
while (isspace((unsigned char) *src)) {
src++;
}
/* identifier suchen */
if (do_output) {
/*vb: */
/* if(ifnesting>=MAXIFNESTING-1) {error("Too many nested #if's",0); return(0);} */
/* ifnesting++; */
temp = src;
len = 0;
while ((isalnum((unsigned char) *temp)) || (*temp == '_')) {
temp++;
len++;
}
if (DEBUG & 32)
printf("-- FindMakroNode: len=%d temp=%p\n", len, (void*)temp);
makro = FindMakroNode(mlist, src, len);
if (DEBUG & 32)
printf("-- #ifndef found, ");
if (!makro) {
/*vb: */
ifstatus[incnesting] = 1; /* Bedingung == TRUE (Makro not existing) */
if (DEBUG & 32)
printf(" condition not found (TRUE)\n\n");
} else {
/*vb: */
ifstatus[incnesting] = 2; /* Bedingung == FALSE */
do_output = 0;
if (DEBUG & 32)
printf(" condition '%s' found (FALSE)\n\n", makro->name);
}
/* HIER: string[0]=0; */
} else {
if_cnt++;
if (DEBUG & 32)
printf("-- #ifndef found and if_cnt increased\n\n");
}
string[0] = 0; /*vb: */
return (1);
}
} /* EO IFNDEF */
/* IF */
if (!strncmp(src, "if", 2)) {
src += 2;
abs_if_cnt++; /*vb: */
if (isspace((unsigned char) *src)) {
while (isspace((unsigned char) *src)) {
src++;
}
/* Bedingung auswerten */
printf("****** WARNING ******* #if is not yet implemented\n");
string[0] = 0; /*vb: */
return (1);
}
} /* EO IF */
/* ELIF */
if (!strncmp(src, "elif", 4)) {
src += 4;
if (isspace((unsigned char) *src)) {
while (isspace((unsigned char) *src)) {
src++;
}
/* Bedingung auswerten */
printf("****** WARNING ******* #elif is not yet implemented\n");
string[0] = 0; /*vb: */
return (1);
}
} /* EO ELIF */
/* ELSE */
if (!strncmp(src, "else", 4)) {
src += 4;
if (isspace((unsigned char) *src) || *src == 0) {
while (isspace((unsigned char) *src)) {
src++;
}
if (!if_cnt) {
switch (ifstatus[incnesting]) { /*vb: */
case 0:
error(188);
return (0);
break;
case 1:
do_output = 0;
/* HIER: auf #endif suchen SearchENDIF(); */
/* HIER: ifnesting--; do_output=1; */
break;
case 2:
ifstatus[incnesting] = 3; /*vb: */
do_output = 1;
break;
case 3:
error(189);
return (0);
break;
}
}
string[0] = 0; /*vb: */
return (1);
}
} /* EO ELSE */
/* ENDIF */
if (!strncmp(src, "endif", 5)) {
src += 5;
abs_if_cnt--; /*vb: */
if (isspace((unsigned char) *src) || *src == 0) {
while (isspace((unsigned char) *src)) {
src++;
}
/* HIER: Auf Zeilenende testen */
if (DEBUG & 32)
printf("-- #endif found, ");
if (if_cnt) {
if_cnt--;
if (DEBUG & 32)
printf("if_cnt decreased (to %d)\n", if_cnt);
} else {
if (DEBUG & 32)
printf("ifnesting: %d ifstatus: %d\n", incnesting, ifstatus[incnesting]);
if (abs_if_cnt < 0 /*(incnesting==-1)||ifstatus[incnesting]==0 */ ) { /*vb: */
error(190);
return (0);
}
/* ifnesting--; *//*vb: */
/* HIER: evtl. do_output entsprechend ifstatus[] setzen */
/*vb: natuerlich */
do_output = 1;
ifstatus[incnesting] = abs_if_cnt > 0; /*vb: 1 oder 0 */
}
string[0] = 0; /*vb: ja */
return (1);
}
} /* EO ENDIF */
/*vb: andere Direktiven gegebenenfalls ueberspringen */
if (!do_output) {
if (DEBUG & 32)
printf("do_output==0 => skipping: %s\n", src);
string[0] = 0;
return (1);
}
/* DEFINE */
if ( /*(do_output)&& */ (!strncmp(src, "define", 6))) { /*vb: */
if (DEBUG & 32)
printf("#define found\n");
src += 6;
if (isspace((unsigned char) *src)) {
while (isspace((unsigned char) *src)) {
src++;
}
if (ParseIdentifier(src)) {
string[0] = 0;
return (1);
} else {
if (DEBUG & 32)
printf("ParseIdent returned 0\n");
return (0);
}
}
} /* EO DEFINE */
/* UNDEF */
if ( /*(do_output)&& */ (!strncmp(src, "undef", 5))) { /*vb: */
src += 5;
if (isspace((unsigned char) *src)) {
while (isspace((unsigned char) *src)) {
src++;
}
temp = src;
len = 0;
while ((isalnum((unsigned char) *temp)) || (*temp == '_')) {
temp++;
len++;
}
makro = FindMakroNode(mlist, src, len);
if (makro->flags & NODELETE) {
error(199);
} else {
DelMakroNode(&mlist, makro);
}
while (isspace((unsigned char) *temp)) {
temp++;
}
if (*temp != 0 && *temp != '\n') {
error(200);
}
string[0] = 0;
return (1);
}
} /* EO UNDEF */
/* INCLUDE */
if ( /*(do_output)&& */ (!strncmp(src, "include", 7))) { /*vb: */
src += 7;
if (isspace((unsigned char) *src)) {
while (isspace((unsigned char) *src)) {
src++;
}
if (*src != '<' && *src != '\"') {
/* Versuchen den Rest zu expandieren */
inclinelist = Str2List(src);
if (!ExpandList(&inclinelist)) {
if (List2Str(inclinelist, src, MAXINPUT - (src - string))) {
/* HIER exit ? */
}
} else {
error(191); /* HIER exit ? */
}
}
/*vb: geaendert, so dass #include "..." auch noch im Standardpfad sucht */
if (DEBUG & 32)
printf("includename=%s\n", src);
if (*src == '<' || *src == '\"') {
char *m = src, c;
if (*src == '<')
c = '>';
else
c = '\"';
if (*src == '\"') {
/* im aktuellen Verzeichnis suchen und includen */
src++;
temp = src;
len = 0;
while (*temp != '\"') {
temp++;
len++;
}
temp++;
while (isspace((unsigned char) *temp))
temp++;
if (*temp) {
error(200);
}
temp = (char *) malloc(len + 1);
if (temp) {
strncpy(temp, src, len);
*(temp + len) = 0;
if (pp_include(temp)) {
AddStrNode(&strlist, NULL, temp);
string[0] = 0;
return (1);
} else {
if (temp)
free(temp);
/*vb:
error("pp: cannot open file to include",0);
return(0); */
}
} else {
error(196);
} /* HIER: Exit? */
}
/* in den Standard-Verzeichnissen suchen und includen */
src = m;
src++;
temp = src;
len = 0;
while (*temp != c && *temp != 0) {
temp++;
len++;
} /*vb: sicherer */
temp++;
while (isspace((unsigned char) *temp))
temp++;
if (*temp) {
error(200);
}
temp = NULL;
for (i = 0; i < incpathc; i++) {
complete_len = strlen(incpath[i]) + len;
temp = (char *) malloc(complete_len + 1);
if (temp) {
strcpy(temp, incpath[i]);
strncat(temp, src, len);
*(temp + complete_len) = 0;
if (pp_include(temp)) {
AddStrNode(&strlist, NULL, temp);
if (DEBUG & 32)
printf("include <%s> found\n", temp);
string[0] = 0;
return (1);
} else {
if (temp)
free(temp);
}
} else {
error(196);
} /* HIER: Exit ? */
} /* of FOR i */
error(191);
return (0);
} else {
error(192);
return (0);
}
} else {
error(193);
return (0);
}
} /* EO INCLUDE */
/* LINE */
if (!strncmp(src, "line", 4)) {
src += 4;
if (isspace((unsigned char) *src)) {
return (1); /* Ignorieren und an Compiler weiterreichen */
}
} /* EO LINE */
/* ERROR */
if (!strncmp(src, "error", 5)) {
src += 5;
if (isspace((unsigned char) *src)) {
while (isspace((unsigned char) *src)) {
src++;
}
return (1);
}
} /* EO ERROR */
/* PRAGMA */
if (!strncmp(src, "pragma", 6)) {
src += 6;
if (isspace((unsigned char) *src)) {
while (isspace((unsigned char) *src)) {
src++;
}
return (1);
}
} /* EO PRAGMA */
/* Unknown */
/* if(do_output){ */
/*vb: */
error(193);
return (0);
/* } *//*vb: */
} else if (do_output) {
/* Normale Anweisung. Komplette Zeile expandieren */
/*vb: */
linelist = Str2List(string);
if (DEBUG & 32)
PrintTL(linelist);
/*vb: */
did_expand = 0;
if (result = ExpandList(&linelist)) {
switch (result) {
case OUT_OF_MEM:
error(196);
break;
case NUM_OF_ARGS:
error(194);
break;
case ARG_EXPECTED:
error(195);
break;
default:
ierror(0);
break;
}
DelStrList(&linelist);
return (0);
}
if (DEBUG & 32)
PrintTL(linelist);
/*vb: List2Str nur aufrufen, falls etwas expandiert wurde */
if (did_expand && !List2Str(linelist, string, MAXINPUT)) {
DelStrList(&linelist);
return (0);
}
DelStrList(&linelist);
/*vb: */
} else
string[0] = 0;
return (1);
}