diff options
author | Carl Worth <cworth@cworth.org> | 2010-05-18 22:10:04 -0700 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2010-05-18 22:10:04 -0700 |
commit | a807fb72c45888b5ff915aa08d8bd10069be4a2e (patch) | |
tree | b324a1585d64d7e61979ce38c9f20d803446c3f5 /glcpp.h | |
parent | d476db38fe21f5e6061a7d93dbd5a9991b91bf59 (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.h | 77 |
1 files changed, 68 insertions, 9 deletions
@@ -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 |