summaryrefslogtreecommitdiff
path: root/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c231
1 files changed, 163 insertions, 68 deletions
diff --git a/parse.c b/parse.c
index 935c61d..66a4b6e 100644
--- a/parse.c
+++ b/parse.c
@@ -24,7 +24,7 @@ used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from The Open Group.
*/
-/* $XFree86: xc/config/makedepend/parse.c,v 1.11 2001/12/17 20:52:22 dawes Exp $ */
+/* $XFree86: xc/config/makedepend/parse.c,v 1.14 2004/03/10 15:49:20 tsi Exp $ */
#include "def.h"
@@ -61,7 +61,7 @@ gobble(struct filepointer *filep, struct inclist *file,
(type == ELIFGUESSFALSE))
type = gobble(filep, file, file_red);
if (type == ELSE)
- (void)gobble(filep, file, file_red);
+ (void)gobble(filep, file, file_red);
break;
case ELSE:
case ENDIF:
@@ -101,8 +101,8 @@ gobble(struct filepointer *filep, struct inclist *file,
/*
* Decide what type of # directive this line is.
*/
-static int
-deftype (char *line, struct filepointer *filep,
+static int
+deftype (char *line, struct filepointer *filep,
struct inclist *file_red, struct inclist *file, int parse_it)
{
register char *p;
@@ -202,7 +202,7 @@ deftype (char *line, struct filepointer *filep,
if (!*p || *p == '"' || *p == '<')
break;
- sym = isdefined(p, file_red, NULL);
+ sym = isdefined(p, file_red, NULL);
if (!sym)
break;
@@ -212,7 +212,7 @@ deftype (char *line, struct filepointer *filep,
(*sym) -> s_name,
(*sym) -> s_value));
/* mark file as having included a 'soft include' */
- file->i_flags |= INCLUDED_SYM;
+ file->i_flags |= INCLUDED_SYM;
}
/*
@@ -322,7 +322,7 @@ zero_value(char *filename,
}
void
-define2(char *name, char *val, struct inclist *file)
+define2(char *name, char *args, char *val, struct inclist *file)
{
int first, last, below;
register struct symtab **sp = NULL, **dest;
@@ -359,14 +359,14 @@ define2(char *name, char *val, struct inclist *file)
if (s2[-1] == '\0') break;
/* If exact match, set sp and break */
- if (*--s1 == *--s2)
+ if (*--s1 == *--s2)
{
sp = file->i_defs + middle;
break;
}
/* If name > i_defs[middle] ... */
- if (*s1 > *s2)
+ if (*s1 > *s2)
{
below = first;
first = middle + 1;
@@ -379,11 +379,19 @@ define2(char *name, char *val, struct inclist *file)
}
/* Search is done. If we found an exact match to the symbol name,
- just replace its s_value */
+ just replace its s_args and s_value if they are changed */
if (sp != NULL)
{
debug(1,("redefining %s from %s to %s in file %s\n",
name, (*sp)->s_value, val, file->i_file));
+
+ if ( (*sp)->s_args )
+ free((*sp)->s_args);
+ if (args)
+ (*sp)->s_args = copy(args);
+ else
+ (*sp)->s_args = NULL;
+
free((*sp)->s_value);
(*sp)->s_value = copy(val);
return;
@@ -402,6 +410,10 @@ define2(char *name, char *val, struct inclist *file)
debug(1,("defining %s to %s in file %s\n", name, val, file->i_file));
stab->s_name = copy(name);
+ if (args)
+ stab->s_args = copy(args);
+ else
+ stab->s_args = NULL;
stab->s_value = copy(val);
*sp = stab;
}
@@ -409,20 +421,99 @@ define2(char *name, char *val, struct inclist *file)
void
define(char *def, struct inclist *file)
{
+#define S_ARGS_BUFLEN 1024 /* we dont expect too much macro parameters usage */
+static char args[S_ARGS_BUFLEN];
+
char *val;
+ char *p_args = args;
+ int fix_args = 0, var_args = 0, loop = 1;
+ char *p_tmp;
+
+ args[0] = '\0';
/* Separate symbol name and its value */
val = def;
while (isalnum(*val) || *val == '_')
val++;
+
+ if (*val == '(') /* is this macro definition with parameters? */
+ {
+ *val++ = '\0';
+
+ do /* parse the parametere list */
+ {
+ while (*val == ' ' || *val == '\t')
+ val++;
+
+ /* extract next parameter name */
+ if (*val == '.')
+ { /* it should be the var-args parameter: "..." */
+ var_args++;
+ p_tmp = p_args;
+ while (*val == '.')
+ {
+ *p_args++ = *val++;
+ if (p_args >= &args[S_ARGS_BUFLEN-1])
+ fatalerr("args buffer full failure in insert_defn()\n");
+ }
+ *p_args = '\0';
+ if (strcmp(p_tmp,"...")!=0)
+ {
+ fprintf(stderr, "unrecognized qualifier, should be \"...\" for-args\n");
+ }
+ }
+ else
+ { /* regular parameter name */
+ fix_args++;
+ while (isalnum(*val) || *val == '_')
+ {
+ *p_args++ = *val++;
+ if (p_args >= &args[S_ARGS_BUFLEN-1])
+ fatalerr("args buffer full failure in insert_defn()\n");
+ }
+ }
+ while (*val == ' ' || *val == '\t')
+ val++;
+
+ if (*val == ',')
+ {
+ if (var_args)
+ {
+ fprintf(stderr, "there are more arguments after the first var-args qualifier\n");
+ }
+
+ *p_args++ = ','; /* we are using the , as a reserved char */
+ if (p_args >= &args[S_ARGS_BUFLEN-1])
+ fatalerr("args buffer full failure in insert_defn()\n");
+ val++;
+ }
+ else
+ if (*val == ')')
+ {
+ *p_args = '\0';
+ val++;
+ loop=0;
+ }
+ else
+ {
+ fprintf(stderr, "trailing ) on macro arguments missing\n");
+ loop=0;
+ }
+ } while (loop);
+ }
+
if (*val)
*val++ = '\0';
while (*val == ' ' || *val == '\t')
val++;
- if (!*val)
+ if (!*val) /* define statements without a value will get a value of 1 */
val = "1";
- define2(def, val, file);
+
+ if (args && (strlen(args)>0))
+ define2(def, args, val, file);
+ else
+ define2(def, NULL, val, file);
}
struct symtab **
@@ -442,29 +533,29 @@ slookup(char *symbol, struct inclist *file)
s1 = symbol;
s2 = file->i_defs[middle]->s_name;
while (*s1++ == *s2++)
- if (s2[-1] == '\0') break;
+ if (s2[-1] == '\0') break;
/* If exact match, we're done */
- if (*--s1 == *--s2)
+ if (*--s1 == *--s2)
{
- return file->i_defs + middle;
+ return file->i_defs + middle;
}
/* If symbol > i_defs[middle] ... */
- if (*s1 > *s2)
+ if (*s1 > *s2)
{
- first = middle + 1;
+ first = middle + 1;
}
/* else ... */
else
{
- last = middle - 1;
+ last = middle - 1;
}
}
return(NULL);
}
-static int
+static int
merge2defines(struct inclist *file1, struct inclist *file2)
{
int i;
@@ -477,59 +568,59 @@ merge2defines(struct inclist *file1, struct inclist *file2)
if (file2->i_merged[i]==FALSE)
return 0;
- {
+ { /* local var encapsulation */
int first1 = 0;
int last1 = file1->i_ndefs - 1;
int first2 = 0;
int last2 = file2->i_ndefs - 1;
- int first=0;
- struct symtab** i_defs = NULL;
+ int first=0;
+ struct symtab** i_defs = NULL;
int deflen=file1->i_ndefs+file2->i_ndefs;
debug(2,("merging %s into %s\n",
file2->i_file, file1->i_file));
- if (deflen>0)
- {
- /* make sure deflen % SYMTABINC == 0 is still true */
- deflen += (SYMTABINC - deflen % SYMTABINC) % SYMTABINC;
- i_defs=(struct symtab**)
+ if (deflen>0)
+ {
+ /* make sure deflen % SYMTABINC == 0 is still true */
+ deflen += (SYMTABINC - deflen % SYMTABINC) % SYMTABINC;
+ i_defs=(struct symtab**)
malloc(deflen*sizeof(struct symtab*));
- if (i_defs==NULL) return 0;
- }
-
- while ((last1 >= first1) && (last2 >= first2))
- {
- char *s1=file1->i_defs[first1]->s_name;
- char *s2=file2->i_defs[first2]->s_name;
-
- if (strcmp(s1,s2) < 0)
- i_defs[first++]=file1->i_defs[first1++];
- else if (strcmp(s1,s2) > 0)
- i_defs[first++]=file2->i_defs[first2++];
- else /* equal */
- {
- i_defs[first++]=file2->i_defs[first2++];
- first1++;
- }
- }
- while (last1 >= first1)
- {
- i_defs[first++]=file1->i_defs[first1++];
- }
- while (last2 >= first2)
- {
- i_defs[first++]=file2->i_defs[first2++];
- }
-
- if (file1->i_defs) free(file1->i_defs);
- file1->i_defs=i_defs;
- file1->i_ndefs=first;
-
+ if (i_defs==NULL) return 0;
+ }
+
+ while ((last1 >= first1) && (last2 >= first2))
+ {
+ char *s1=file1->i_defs[first1]->s_name;
+ char *s2=file2->i_defs[first2]->s_name;
+
+ if (strcmp(s1,s2) < 0)
+ i_defs[first++]=file1->i_defs[first1++];
+ else if (strcmp(s1,s2) > 0)
+ i_defs[first++]=file2->i_defs[first2++];
+ else /* equal */
+ {
+ i_defs[first++]=file2->i_defs[first2++];
+ first1++;
+ }
+ }
+ while (last1 >= first1)
+ {
+ i_defs[first++]=file1->i_defs[first1++];
+ }
+ while (last2 >= first2)
+ {
+ i_defs[first++]=file2->i_defs[first2++];
+ }
+
+ if (file1->i_defs) free(file1->i_defs);
+ file1->i_defs=i_defs;
+ file1->i_ndefs=first;
+
return 1;
- }
+ }
}
void
@@ -546,7 +637,7 @@ undefine(char *symbol, struct inclist *file)
}
int
-find_includes(struct filepointer *filep, struct inclist *file,
+find_includes(struct filepointer *filep, struct inclist *file,
struct inclist *file_red, int recursion, boolean failOK)
{
struct inclist *inclistp;
@@ -587,8 +678,11 @@ find_includes(struct filepointer *filep, struct inclist *file,
break;
case IFDEF:
case IFNDEF:
- if ((type == IFDEF && isdefined(line, file_red, NULL))
- || (type == IFNDEF && !isdefined(line, file_red, NULL))) {
+ {
+ int isdef = (isdefined(line, file_red, NULL) != NULL);
+ if (type == IFNDEF) isdef = !isdef;
+
+ if (isdef) {
debug(1,(type == IFNDEF ?
"line %d: %s !def'd in %s via %s%s\n" : "",
filep->f_line, line,
@@ -610,11 +704,12 @@ find_includes(struct filepointer *filep, struct inclist *file,
find_includes(filep, file,
file_red, recursion+1, failOK);
else if (type == ELIF)
- goto doif;
+ goto doif;
else if (type == ELIFFALSE || type == ELIFGUESSFALSE)
- goto doiffalse;
+ goto doiffalse;
}
- break;
+ }
+ break;
case ELSE:
case ELIFFALSE:
case ELIFGUESSFALSE:
@@ -652,13 +747,13 @@ find_includes(struct filepointer *filep, struct inclist *file,
break;
case ERROR:
case WARNING:
- warning("%s", file_red->i_file);
+ warning("%s", file_red->i_file);
if (file_red != file)
warning1(" (reading %s)", file->i_file);
warning1(", line %d: %s\n",
filep->f_line, line);
- break;
-
+ break;
+
case PRAGMA:
case IDENT:
case SCCS: