summaryrefslogtreecommitdiff
path: root/glcpp.h
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2010-05-18 22:10:04 -0700
committerCarl Worth <cworth@cworth.org>2010-05-18 22:10:04 -0700
commita807fb72c45888b5ff915aa08d8bd10069be4a2e (patch)
treeb324a1585d64d7e61979ce38c9f20d803446c3f5 /glcpp.h
parentd476db38fe21f5e6061a7d93dbd5a9991b91bf59 (diff)
Rewrite macro handling to support function-like macro invocation in macro values
The rewrite her discards the functions that did direct, recursive expansion of macro values. Instead, the parser now pushes the macro definition string over to a stack of buffers for the lexer. This way, macro expansion gets access to all parsing machinery. This isn't a small change, but the result is simpler than before (I think). It passes the entire test suite, including the four tests added with the previous commit that were failing before.
Diffstat (limited to 'glcpp.h')
-rw-r--r--glcpp.h77
1 files changed, 68 insertions, 9 deletions
diff --git a/glcpp.h b/glcpp.h
index 7966a2a3d2..81f7d14c5b 100644
--- a/glcpp.h
+++ b/glcpp.h
@@ -24,11 +24,13 @@
#ifndef GLCPP_H
#define GLCPP_H
+#include <talloc.h>
+
#include "hash_table.h"
#define yyscan_t void*
-/* Some data types used for parser value. */
+/* Some data types used for parser values. */
typedef struct string_node {
const char *str;
@@ -52,6 +54,56 @@ typedef struct argument_list {
typedef struct glcpp_parser glcpp_parser_t;
+/* Support for temporarily lexing/parsing tokens from a string. */
+
+typedef struct glcpp_lex_node {
+ void *buffer;
+ struct glcpp_lex_node *next;
+} glcpp_lex_node_t;
+
+typedef struct {
+ glcpp_parser_t *parser;
+ glcpp_lex_node_t *head;
+} glcpp_lex_stack_t;
+
+void
+glcpp_lex_stack_push (glcpp_lex_stack_t *stack, const char *string);
+
+int
+glcpp_lex_stack_pop (glcpp_lex_stack_t *stack);
+
+typedef enum {
+ TOKEN_CLASS_ARGUMENT,
+ TOKEN_CLASS_IDENTIFIER,
+ TOKEN_CLASS_FUNC_MACRO,
+ TOKEN_CLASS_OBJ_MACRO
+} token_class_t;
+
+token_class_t
+glcpp_parser_classify_token (glcpp_parser_t *parser,
+ const char *identifier,
+ int *parameter_index);
+
+typedef struct {
+ int is_function;
+ string_list_t *parameters;
+ const char *identifier;
+ const char *replacement;
+} macro_t;
+
+typedef struct expansion_node {
+ macro_t *macro;
+ argument_list_t *arguments;
+ struct expansion_node *next;
+} expansion_node_t;
+
+struct glcpp_parser {
+ yyscan_t scanner;
+ struct hash_table *defines;
+ expansion_node_t *expansions;
+ glcpp_lex_stack_t *lex_stack;
+};
+
glcpp_parser_t *
glcpp_parser_create (void);
@@ -61,15 +113,17 @@ glcpp_parser_parse (glcpp_parser_t *parser);
void
glcpp_parser_destroy (glcpp_parser_t *parser);
-typedef enum {
- MACRO_TYPE_UNDEFINED,
- MACRO_TYPE_OBJECT,
- MACRO_TYPE_FUNCTION
-} macro_type_t;
+void
+glcpp_parser_push_expansion_macro (glcpp_parser_t *parser,
+ macro_t *macro,
+ argument_list_t *arguments);
-macro_type_t
-glcpp_parser_macro_type (glcpp_parser_t *parser,
- const char *identifier);
+void
+glcpp_parser_push_expansion_argument (glcpp_parser_t *parser,
+ int argument_index);
+
+void
+glcpp_parser_pop_expansion (glcpp_parser_t *parser);
/* Generated by glcpp-lex.l to glcpp-lex.c */
@@ -91,10 +145,15 @@ yyparse (glcpp_parser_t *parser);
#define xtalloc(ctx, type) (type *)xtalloc_named_const(ctx, sizeof(type), #type)
+#define xtalloc_size(ctx, size) xtalloc_named_const(ctx, size, __location__)
+
void *
xtalloc_named_const (const void *context, size_t size, const char *name);
char *
xtalloc_strdup (const void *t, const char *p);
+char *
+xtalloc_strndup (const void *t, const char *p, size_t n);
+
#endif