Re: Fwd: dependency tee from c parser entities downto token

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




I'll come up with a patch to implement this scheme when I have
time to and send it, it might take a while.

Can you keep the change to the core sparse library (e.g. adding
hook in parser and pre-processor) as a separate patch? You can
send that part out for review earlier if other part of your dependency
analyse is not ready yet.

I appended a diff for review. Is this kind of interface ok?
This is kind of not a patch to apply, rather I want to avoid to put
effort in it and you telling me later I am too intrusive...:). So
can you give a ok or comment...

Interface so far:
struct preprocess_hook {
	def      : called when #define is processed
	args_beg : called before argument expasnion
	args_end : called after argument expasnion
	body_beg : called before body expansion
	body_end : called after body expansion
	post     : called after preprocess
};
All of there I found are needed. There might be more to be added...

I also introduce a tokentype TOKEN_M_EMPTY so that I can track
empty expansion. To filter these out again I add the post hook.

-- Konrad









Chris


diff --git a/lib.c b/lib.c
index 396e9f1..554d6c4 100644
--- a/lib.c
+++ b/lib.c
@@ -974,7 +974,8 @@ struct symbol_list * __sparse(char *filename)
 	res = sparse_keep_tokens(filename);
 
 	/* Drop the tokens for this file after parsing */
-	clear_token_alloc();
+	if (!PPHOOKEN())
+		clear_token_alloc();
 
 	/* And return it */
 	return res;
diff --git a/pre-process.c b/pre-process.c
index 8a16f8b..99ee5a4 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -30,6 +30,8 @@
 
 static int false_nesting = 0;
 
+struct preprocess_hook *preprocess_hook = NULL;
+
 #define INCLUDEPATHS 300
 const char *includepath[INCLUDEPATHS+1] = {
 	"",
@@ -74,9 +76,10 @@ static const char **dirafter_includepath = includepath + 3;
 static struct token *alloc_token(struct position *pos)
 {
 	struct token *token = __alloc_token(0);
-
-	token->pos.stream = pos->stream;
-	token->pos.line = pos->line;
+	if (PPHOOKEN()) {
+		token->pos.stream = pos->stream;
+		token->pos.line = pos->line;
+	}
 	token->pos.pos = pos->pos;
 	token->pos.whitespace = 1;
 	return token;
@@ -106,7 +109,7 @@ static void replace_with_integer(struct token *token, unsigned int val)
 	token->number = buf;
 }
 
-static struct symbol *lookup_macro(struct ident *ident)
+struct symbol *lookup_macro(struct ident *ident)
 {
 	struct symbol *sym = lookup_symbol(ident, NS_MACRO | NS_UNDEF);
 	if (sym && sym->namespace != NS_MACRO)
@@ -231,28 +234,17 @@ static struct token *collect_arg(struct token *prev, int vararg, struct position
 		} else if (match_op(next, ',') && !nesting && !vararg) {
 			break;
 		}
-		next->pos.stream = pos->stream;
-		next->pos.line = pos->line;
-		next->pos.pos = pos->pos;
+		if (!PPHOOKEN()) {
+			next->pos.stream = pos->stream;
+			next->pos.line = pos->line;
+			next->pos.pos = pos->pos;
+		}
 		p = &next->next;
 	}
 	*p = &eof_token_entry;
 	return next;
 }
 
-/*
- * We store arglist as <counter> [arg1] <number of uses for arg1> ... eof
- */
-
-struct arg {
-	struct token *arg;
-	struct token *expanded;
-	struct token *str;
-	int n_normal;
-	int n_quoted;
-	int n_str;
-};
-
 static int collect_arguments(struct token *start, struct token *arglist, struct arg *args, struct token *what)
 {
 	int wanted = arglist->count.normal;
@@ -476,6 +468,8 @@ static struct token *dup_token(struct token *token, struct position *streampos,
 {
 	struct token *alloc = alloc_token(streampos);
 	token_type(alloc) = token_type(token);
+	alloc->pos.stream = pos->stream;
+	alloc->pos.line = pos->line;
 	alloc->pos.newline = pos->newline;
 	alloc->pos.whitespace = pos->whitespace;
 	alloc->number = token->number;
@@ -618,13 +612,21 @@ static int expand(struct token **list, struct symbol *sym)
 			return 1;
 		if (!collect_arguments(token->next, sym->arglist, args, token))
 			return 1;
+
+		PPHOOK (args_beg, token, nargs, args);
 		expand_arguments(nargs, args);
+		PPHOOK (args_end, token, nargs, args);
 	}
 
 	expanding->tainted = 1;
 
 	last = token->next;
+
+	PPHOOK (body_beg, token, sym->expansion);
+
 	tail = substitute(list, sym->expansion, args);
+	PPHOOK (body_end, token, list, tail);
+
 	*tail = last;
 
 	return 0;
@@ -893,6 +895,8 @@ static int token_list_different(struct token *list1, struct token *list2)
 			return 0;
 		if (!list1 || !list2)
 			return 1;
+		while(PPHOOKEN() && token_type(list1) == TOKEN_M_EMPTY) list1 = list1->next;
+		while(PPHOOKEN() && token_type(list2) == TOKEN_M_EMPTY) list2 = list2->next;
 		if (token_different(list1, list2))
 			return 1;
 		list1 = list1->next;
@@ -1140,6 +1144,8 @@ static int do_handle_define(struct stream *stream, struct token **line, struct t
 
 	ret = 1;
 	sym = lookup_symbol(name, NS_MACRO | NS_UNDEF);
+	PPHOOK (def, left, &expansion);
+	
 	if (sym) {
 		int clean;
 
@@ -1835,6 +1841,7 @@ struct token * preprocess(struct token *token)
 	preprocessing = 1;
 	init_preprocessor();
 	do_preprocess(&token);
+	PPHOOK(post, &token);
 
 	// Drop all expressions from preprocessing, they're not used any more.
 	// This is not true when we have multiple files, though ;/
diff --git a/token.h b/token.h
index cd29233..0111d23 100644
--- a/token.h
+++ b/token.h
@@ -84,6 +84,7 @@ enum token_type {
 	TOKEN_IF,
 	TOKEN_SKIP_GROUPS,
 	TOKEN_ELSE,
+	TOKEN_M_EMPTY,
 };
 
 /* Combination tokens */
@@ -171,6 +172,32 @@ struct token {
 	};
 };
 
+/*
+ * We store arglist as <counter> [arg1] <number of uses for arg1> ... eof
+ */
+
+struct arg {
+	struct token *arg;
+	struct token *expanded;
+	struct token *str;
+	int n_normal;
+	int n_quoted;
+	int n_str;
+};
+
+struct preprocess_hook {
+	void (*def)(struct token *macro, struct token **ex);
+	void (*args_beg)(struct token *macro, int count, struct arg *a);
+	void (*args_end)(struct token *macro, int count, struct arg *a);
+	void (*body_beg)(struct token *macro, struct token *body);
+	void (*body_end)(struct token *macro, struct token **rep, struct token **reptail);
+	void (*post)(struct token **token);
+	
+	
+};
+#define PPHOOK(n, args... ) if (preprocess_hook && preprocess_hook->n) preprocess_hook->n( args );
+#define PPHOOKEN() (preprocess_hook != 0) 
+
 #define MAX_STRING 4095
 
 static inline struct token *containing_token(struct token **p)
@@ -188,7 +215,9 @@ static inline struct token *containing_token(struct token **p)
  */
 extern struct token eof_token_entry;
 #define eof_token(x) ((x) == &eof_token_entry)
+extern struct preprocess_hook *preprocess_hook;
 
+extern struct symbol *lookup_macro(struct ident *ident);
 extern int init_stream(const char *, int fd, const char **next_path);
 extern const char *stream_name(int stream);
 extern struct ident *hash_ident(struct ident *);

[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux