diff options
author | Johan Dahlin <johan@gnome.org> | 2008-03-25 20:53:32 +0000 |
---|---|---|
committer | Johan Dahlin <johan@src.gnome.org> | 2008-03-25 20:53:32 +0000 |
commit | 66ab1202b6499e030c32c9d0d3432e0b09bee7db (patch) | |
tree | ad2a54a99ea71cf5c42afd03810a761f09096fb8 | |
parent | 07d433428ed39ef43d0204cb44a75cb31d38016a (diff) | |
download | gobject-introspection-66ab1202b6499e030c32c9d0d3432e0b09bee7db.tar.gz |
Move the scanner to a separate library.
2008-03-25 Johan Dahlin <johan@gnome.org>
* Makefile.am:
* configure.ac:
* giscanner/Makefile.am:
* giscanner/sourcescanner.c:
* giscanner/sourcescanner.h:
* tools/Makefile.am:
* tools/grealpath.h:
* tools/sourcescanner.c:
* tools/sourcescanner.h:
Move the scanner to a separate library.
svn path=/trunk/; revision=164
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | giscanner/Makefile.am | 25 | ||||
-rw-r--r-- | giscanner/grealpath.h (renamed from tools/grealpath.h) | 0 | ||||
-rw-r--r-- | giscanner/scannerlexer.l | 394 | ||||
-rw-r--r-- | giscanner/scannerparser.y | 1268 | ||||
-rw-r--r-- | giscanner/sourcescanner.c (renamed from tools/sourcescanner.c) | 7 | ||||
-rw-r--r-- | giscanner/sourcescanner.h (renamed from tools/sourcescanner.h) | 6 | ||||
-rw-r--r-- | tools/Makefile.am | 36 |
10 files changed, 1731 insertions, 22 deletions
@@ -1,3 +1,17 @@ +2008-03-25 Johan Dahlin <johan@gnome.org> + + * Makefile.am: + * configure.ac: + * giscanner/Makefile.am: + * giscanner/sourcescanner.c: + * giscanner/sourcescanner.h: + * tools/Makefile.am: + * tools/grealpath.h: + * tools/sourcescanner.c: + * tools/sourcescanner.h: + + Move the scanner to a separate library. + 2008-03-23 Johan Dahlin <johan@gnome.org> * tools/Makefile.am: diff --git a/Makefile.am b/Makefile.am index 189f1d72..32d16280 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ ## Process this file with automake to produce Makefile.in ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = gidl girepository tools tests +SUBDIRS = gidl girepository giscanner tools tests DIST_SUBDIRS = m4 $(SUBDIRS) pkgconfigdir = $(libdir)/pkgconfig diff --git a/configure.ac b/configure.ac index 00cbc3c4..5ca163df 100644 --- a/configure.ac +++ b/configure.ac @@ -94,6 +94,7 @@ AC_CHECK_FUNCS([memchr strchr strspn strstr strtol strtoull]) AC_CONFIG_FILES([Makefile gidl/Makefile girepository/Makefile + giscanner/Makefile m4/Makefile tools/Makefile tests/Makefile diff --git a/giscanner/Makefile.am b/giscanner/Makefile.am new file mode 100644 index 00000000..30ed3352 --- /dev/null +++ b/giscanner/Makefile.am @@ -0,0 +1,25 @@ +## Process this file with automake to produce Makefile.in + +INCLUDES = -I$(top_srcdir)/girepository +BUILT_SOURCES = scannerparser.c scannerparser.h scannerlexer.c scannerlexer.h + +CLEANFILES = scannerparser.c scannerparser.h scannerlexer.c scannerlexer.h +AM_YFLAGS = -d -t + +# Why do I have to do this automake? +scannerlexer.h: scannerlexer.c + +noinst_LTLIBRARIES = libgiscanner.la + +libgiscanner_la_SOURCES = \ + sourcescanner.c \ + sourcescanner.h \ + scannerlexer.l \ + scannerparser.y \ + grealpath.h +libgiscanner_la_LIBADD = $(GOBJECT_LIBS) +libgiscanner_la_CFLAGS = $(GOBJECT_CFLAGS) + +GCOVSOURCES = $(libgiscanner_la_SOURCES) + +include $(top_srcdir)/gcov.mak diff --git a/tools/grealpath.h b/giscanner/grealpath.h index ca88190b..ca88190b 100644 --- a/tools/grealpath.h +++ b/giscanner/grealpath.h diff --git a/giscanner/scannerlexer.l b/giscanner/scannerlexer.l new file mode 100644 index 00000000..03455d73 --- /dev/null +++ b/giscanner/scannerlexer.l @@ -0,0 +1,394 @@ +/* -*- Mode: C -*- +/* GObject introspection: C lexer + * + * Copyright (c) 1997 Sandro Sigala <ssigala@globalnet.it> + * Copyright (c) 2007-2008 Jürg Billeter <j@bitron.ch> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +%{ +#include <ctype.h> +#include <stdio.h> + +#include <glib.h> +#include "sourcescanner.h" +#include "scannerparser.h" +#include "grealpath.h" + +int lineno; + +extern int yylex (GISourceScanner *scanner); +#define YY_DECL int yylex (GISourceScanner *scanner) +static int yywrap (void); +static void parse_comment (GISourceScanner *scanner); +static void process_directive (GISourceScanner *scanner); +static int check_identifier (GISourceScanner *scanner, const char *); +%} + +intsuffix ([uU][lL]?)|([lL][uU]?) +fracconst ([0-9]*\.[0-9]+)|([0-9]+\.) +exppart [eE][-+]?[0-9]+ +floatsuffix [fFlL] +chartext ([^\'])|(\\.) +stringtext ([^\"])|(\\.) + +%% + +"\n" { ++lineno; } /* " */ +[\t\f\v\r ]+ { /* Ignore whitespace. */ } + +"/*" { parse_comment(scanner); } +"//".* { } + +"#define "[a-zA-Z_][a-zA-Z_0-9]*"(" { yyless (yyleng - 1); return FUNCTION_MACRO; } +"#define "[a-zA-Z_][a-zA-Z_0-9]* { return OBJECT_MACRO; } + +"#" { process_directive(scanner); } + +"{" { return '{'; } +"<%" { return '{'; } +"}" { return '}'; } +"%>" { return '}'; } +"[" { return '['; } +"<:" { return '['; } +"]" { return ']'; } +":>" { return ']'; } +"(" { return '('; } +")" { return ')'; } +";" { return ';'; } +":" { return ':'; } +"..." { return ELLIPSIS; } +"?" { return '?'; } +"." { return '.'; } +"+" { return '+'; } +"-" { return '-'; } +"*" { return '*'; } +"/" { return '/'; } +"%" { return '%'; } +"^" { return '^'; } +"&" { return '&'; } +"|" { return '|'; } +"~" { return '~'; } +"!" { return '!'; } +"=" { return '='; } +"<" { return '<'; } +">" { return '>'; } +"+=" { return ADDEQ; } +"-=" { return SUBEQ; } +"*=" { return MULEQ; } +"/=" { return DIVEQ; } +"%=" { return MODEQ; } +"^=" { return XOREQ; } +"&=" { return ANDEQ; } +"|=" { return OREQ; } +"<<" { return SL; } +">>" { return SR; } +"<<=" { return SLEQ; } +">>=" { return SREQ; } +"==" { return EQ; } +"!=" { return NOTEQ; } +"<=" { return LTEQ; } +">=" { return GTEQ; } +"&&" { return ANDAND; } +"||" { return OROR; } +"++" { return PLUSPLUS; } +"--" { return MINUSMINUS; } +"," { return ','; } +"->" { return ARROW; } + +[a-zA-Z_][a-zA-Z_0-9]* { if (scanner->macro_scan) return IDENTIFIER; else REJECT; } + +"auto" { return AUTO; } +"_Bool" { return BOOL; } +"break" { return BREAK; } +"case" { return CASE; } +"char" { return CHAR; } +"const" { return CONST; } +"continue" { return CONTINUE; } +"default" { return DEFAULT; } +"do" { return DO; } +"double" { return DOUBLE; } +"else" { return ELSE; } +"enum" { return ENUM; } +"extern" { return EXTERN; } +"float" { return FLOAT; } +"for" { return FOR; } +"goto" { return GOTO; } +"if" { return IF; } +"inline" { return INLINE; } +"int" { return INT; } +"long" { return LONG; } +"register" { return REGISTER; } +"restrict" { return RESTRICT; } +"return" { return RETURN; } +"short" { return SHORT; } +"signed" { return SIGNED; } +"sizeof" { return SIZEOF; } +"static" { return STATIC; } +"struct" { return STRUCT; } +"switch" { return SWITCH; } +"typedef" { return TYPEDEF; } +"union" { return UNION; } +"unsigned" { return UNSIGNED; } +"void" { return VOID; } +"volatile" { return VOLATILE; } +"while" { return WHILE; } + +[a-zA-Z_][a-zA-Z_0-9]* { return check_identifier(scanner, yytext); } + +"0"[xX][0-9a-fA-F]+{intsuffix}? { return INTEGER; } +"0"[0-7]+{intsuffix}? { return INTEGER; } +[0-9]+{intsuffix}? { return INTEGER; } + +{fracconst}{exppart}?{floatsuffix}? { return FLOATING; } +[0-9]+{exppart}{floatsuffix}? { return FLOATING; } + +"'"{chartext}*"'" { return CHARACTER; } +"L'"{chartext}*"'" { return CHARACTER; } + +"\""{stringtext}*"\"" { return STRING; } +"L\""{stringtext}*"\"" { return STRING; } + +. { fprintf(stderr, "%s:%d: unexpected character `%c'\n", scanner->current_filename, lineno, yytext[0]); } + +%% + +static int +yywrap (void) +{ + return 1; +} + + +static void +parse_gtkdoc (GISourceScanner *scanner, + gchar *symbol, + int *c1, + int *c2) +{ + gboolean isline = FALSE; + gchar line[256]; + int i; + gchar **parts; + GISourceDirective *directive; + char *name,*value; + GSList *directives; + GSList *options = NULL; + char *rname; + + i = 0; + do + { + *c1 = *c2; + if (*c1 == '\n') + { + isline = TRUE; + break; + } + if (i >= 256) + break; + line[i++] = *c1; + *c2 = input(); + } while (*c2 != EOF && !(*c1 == '*' && *c2 == '/')); + + if (!isline) + return; + + line[i] = '\0'; + + parts = g_strsplit (line, ": ", 3); + + if (g_strv_length (parts) >= 2) + { + name = parts[0]; + + if (g_strv_length (parts) == 3) + { + char *ptr = parts[1]; + GString *current = NULL; + gboolean open = (*ptr == '('); + + current = g_string_new (""); + value = parts[2]; + + while (*ptr++) + { + if (*ptr == '(') + open = TRUE; + else if (*ptr != ')' && open) + g_string_append_c (current, *ptr); + else if (*ptr == ')') { + options = g_slist_prepend (options, g_strdup (current->str)); + open = FALSE; + } + } + g_string_free (current, TRUE); + } + else + value = parts[1]; + } + else /* parts == 1 */ + { + name = parts[0]; + value = NULL; + } + + /* + * This is a special case for return values, name will only be + * 'eturn' or a valid name, check the call site. + * Context-sensitive parsing would probably be the right way to go + */ + if (g_ascii_strncasecmp ("eturn", name, 5) == 0) + rname = "return"; + else + rname = name; + + directive = gi_source_directive_new (rname, value, options); + directives = g_hash_table_lookup (scanner->directives_map, symbol); + directives = g_slist_prepend (directives, directive); + g_hash_table_replace (scanner->directives_map, + g_strdup (symbol), directives); + + g_strfreev (parts); + +} + + +static void +parse_comment (GISourceScanner *scanner) +{ + GString *symbol = NULL; + gboolean startofline = FALSE, have_symbol = FALSE, start1 = FALSE, start_symbol = FALSE; + int c1, c2; + + c1 = input(); + c2 = input(); + + while (c2 != EOF && !(c1 == '*' && c2 == '/')) + { + if (c1 == ':') + have_symbol = TRUE; + else if (c1 == '\n') + start1 = TRUE; + else if (c1 == '*' && start1) + start_symbol = TRUE; + else if (!have_symbol && start_symbol) + { + if (!symbol) + symbol = g_string_new (""); + if (c1 != ' ') + g_string_append_c (symbol, c1); + } + + if (c1 == '\n') + { + ++lineno; + startofline = TRUE; + } + + c1 = c2; + c2 = input(); + + if ((c1 != '*' && c1 != ' ')) + startofline = FALSE; + + if (startofline && (c1 == ' ') && (c2 == '@' || (c2 == 'r') || (c2 == 'R'))) + { + c1 = c2; + c2 = input(); + if (symbol) + parse_gtkdoc (scanner, symbol->str, &c1, &c2); + } + } + + if (symbol) + g_string_free (symbol, TRUE); + +} + +static int +check_identifier (GISourceScanner *scanner, + const char *s) +{ + /* + * This function checks if `s' is a type name or an + * identifier. + */ + + if (gi_source_scanner_is_typedef (scanner, s)) { + return TYPEDEF_NAME; + } else if (strcmp (s, "__builtin_va_list") == 0) { + return TYPEDEF_NAME; + } + + return IDENTIFIER; +} + +static void +process_directive (GISourceScanner *scanner) +{ + /* extract current filename from #line directives */ + GString *filename_builder; + gboolean in_string, found_filename; + + lineno = 0; + found_filename = FALSE; + in_string = FALSE; + filename_builder = g_string_new (""); + + int c = input (); + while (c != EOF && c != '\n') { + if (!in_string) { + if (c == '\"') { + in_string = TRUE; + found_filename = TRUE; + } else if (c >= '0' && c <= '9') { + if (!found_filename) { + lineno = lineno * 10 + (c - '0'); + } + } + } else { + if (c == '\"') { + in_string = FALSE; + } else if (c == '\\') { + g_string_append_c (filename_builder, c); + c = input (); + g_string_append_c (filename_builder, c); + } else { + g_string_append_c (filename_builder, c); + } + } + c = input (); + } + + if (filename_builder->len > 0) { + char *filename = g_strcompress (filename_builder->str); + g_free (scanner->current_filename); + scanner->current_filename = g_realpath(filename); + g_free(filename); + } + + g_string_free (filename_builder, TRUE); +} + diff --git a/giscanner/scannerparser.y b/giscanner/scannerparser.y new file mode 100644 index 00000000..45d67891 --- /dev/null +++ b/giscanner/scannerparser.y @@ -0,0 +1,1268 @@ +/* GObject introspection: C parser + * + * Copyright (c) 1997 Sandro Sigala <ssigala@globalnet.it> + * Copyright (c) 2007-2008 Jürg Billeter <j@bitron.ch> + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +%{ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <glib.h> +#include "sourcescanner.h" +#include "scannerparser.h" + +extern FILE *yyin; +extern int lineno; +extern char *yytext; + +extern int yylex (GISourceScanner *scanner); +static void yyerror (GISourceScanner *scanner, const char *str); + +static int last_enum_value = -1; +static GHashTable *const_table = NULL; +%} + +%error-verbose +%union { + char *str; + GList *list; + GISourceSymbol *symbol; + GISourceType *ctype; + StorageClassSpecifier storage_class_specifier; + TypeQualifier type_qualifier; + FunctionSpecifier function_specifier; + UnaryOperator unary_operator; +} + +%parse-param { GISourceScanner* scanner } +%lex-param { GISourceScanner* scanner } + +%token <str> IDENTIFIER "identifier" +%token <str> TYPEDEF_NAME "typedef-name" + +%token INTEGER FLOATING CHARACTER STRING + +%token ELLIPSIS ADDEQ SUBEQ MULEQ DIVEQ MODEQ XOREQ ANDEQ OREQ SL SR +%token SLEQ SREQ EQ NOTEQ LTEQ GTEQ ANDAND OROR PLUSPLUS MINUSMINUS ARROW + +%token AUTO BOOL BREAK CASE CHAR CONST CONTINUE DEFAULT DO DOUBLE ELSE ENUM +%token EXTERN FLOAT FOR GOTO IF INLINE INT LONG REGISTER RESTRICT RETURN SHORT +%token SIGNED SIZEOF STATIC STRUCT SWITCH TYPEDEF UNION UNSIGNED VOID VOLATILE +%token WHILE + +%token FUNCTION_MACRO OBJECT_MACRO + +%start translation_unit + +%type <ctype> declaration_specifiers +%type <ctype> enum_specifier +%type <ctype> pointer +%type <ctype> specifier_qualifier_list +%type <ctype> type_name +%type <ctype> struct_or_union +%type <ctype> struct_or_union_specifier +%type <ctype> type_specifier +%type <str> identifier +%type <str> typedef_name +%type <str> identifier_or_typedef_name +%type <symbol> abstract_declarator +%type <symbol> init_declarator +%type <symbol> declarator +%type <symbol> enumerator +%type <symbol> direct_abstract_declarator +%type <symbol> direct_declarator +%type <symbol> parameter_declaration +%type <symbol> struct_declarator +%type <list> enumerator_list +%type <list> identifier_list +%type <list> init_declarator_list +%type <list> parameter_type_list +%type <list> parameter_list +%type <list> struct_declaration +%type <list> struct_declaration_list +%type <list> struct_declarator_list +%type <storage_class_specifier> storage_class_specifier +%type <type_qualifier> type_qualifier +%type <type_qualifier> type_qualifier_list +%type <function_specifier> function_specifier +%type <symbol> expression +%type <symbol> constant_expression +%type <symbol> conditional_expression +%type <symbol> logical_and_expression +%type <symbol> logical_or_expression +%type <symbol> inclusive_or_expression +%type <symbol> exclusive_or_expression +%type <symbol> multiplicative_expression +%type <symbol> additive_expression +%type <symbol> shift_expression +%type <symbol> relational_expression +%type <symbol> equality_expression +%type <symbol> and_expression +%type <symbol> cast_expression +%type <symbol> assignment_expression +%type <symbol> unary_expression +%type <symbol> postfix_expression +%type <symbol> primary_expression +%type <unary_operator> unary_operator +%type <str> function_macro +%type <str> object_macro +%type <symbol> strings + +%% + +/* A.2.1 Expressions. */ + +primary_expression + : identifier + { + $$ = g_hash_table_lookup (const_table, $1); + if ($$ == NULL) { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } else { + $$ = gi_source_symbol_ref ($$); + } + } + | INTEGER + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + if (g_str_has_prefix (yytext, "0x") && strlen (yytext) > 2) { + $$->const_int = strtol (yytext + 2, NULL, 16); + } else if (g_str_has_prefix (yytext, "0") && strlen (yytext) > 1) { + $$->const_int = strtol (yytext + 1, NULL, 8); + } else { + $$->const_int = atoi (yytext); + } + } + | CHARACTER + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | FLOATING + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | strings + | '(' expression ')' + { + $$ = $2; + } + ; + +/* concatenate adjacent string literal tokens */ +strings + : STRING + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + yytext[strlen (yytext) - 1] = '\0'; + $$->const_string = g_strcompress (yytext + 1); + } + | strings STRING + { + char *strings, *string2; + $$ = $1; + yytext[strlen (yytext) - 1] = '\0'; + string2 = g_strcompress (yytext + 1); + strings = g_strconcat ($$->const_string, string2, NULL); + g_free ($$->const_string); + g_free (string2); + $$->const_string = strings; + } + ; + +identifier + : IDENTIFIER + { + $$ = g_strdup (yytext); + } + ; + +identifier_or_typedef_name + : identifier + | typedef_name + ; + +postfix_expression + : primary_expression + | postfix_expression '[' expression ']' + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | postfix_expression '(' argument_expression_list ')' + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | postfix_expression '(' ')' + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | postfix_expression '.' identifier_or_typedef_name + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | postfix_expression ARROW identifier_or_typedef_name + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | postfix_expression PLUSPLUS + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | postfix_expression MINUSMINUS + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + ; + +argument_expression_list + : assignment_expression + | argument_expression_list ',' assignment_expression + ; + +unary_expression + : postfix_expression + | PLUSPLUS unary_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | MINUSMINUS unary_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | unary_operator cast_expression + { + switch ($1) { + case UNARY_PLUS: + $$ = $2; + break; + case UNARY_MINUS: + $$ = $2; + $$->const_int = -$2->const_int; + break; + case UNARY_BITWISE_COMPLEMENT: + $$ = $2; + $$->const_int = ~$2->const_int; + break; + case UNARY_LOGICAL_NEGATION: + $$ = $2; + $$->const_int = !gi_source_symbol_get_const_boolean ($2); + break; + default: + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + break; + } + } + | SIZEOF unary_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | SIZEOF '(' type_name ')' + { + ctype_free ($3); + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + ; + +unary_operator + : '&' + { + $$ = UNARY_ADDRESS_OF; + } + | '*' + { + $$ = UNARY_POINTER_INDIRECTION; + } + | '+' + { + $$ = UNARY_PLUS; + } + | '-' + { + $$ = UNARY_MINUS; + } + | '~' + { + $$ = UNARY_BITWISE_COMPLEMENT; + } + | '!' + { + $$ = UNARY_LOGICAL_NEGATION; + } + ; + +cast_expression + : unary_expression + | '(' type_name ')' cast_expression + { + ctype_free ($2); + $$ = $4; + } + ; + +multiplicative_expression + : cast_expression + | multiplicative_expression '*' cast_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int * $3->const_int; + } + | multiplicative_expression '/' cast_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + if ($3->const_int != 0) { + $$->const_int = $1->const_int / $3->const_int; + } + } + | multiplicative_expression '%' cast_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int % $3->const_int; + } + ; + +additive_expression + : multiplicative_expression + | additive_expression '+' multiplicative_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int + $3->const_int; + } + | additive_expression '-' multiplicative_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int - $3->const_int; + } + ; + +shift_expression + : additive_expression + | shift_expression SL additive_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int << $3->const_int; + } + | shift_expression SR additive_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int >> $3->const_int; + } + ; + +relational_expression + : shift_expression + | relational_expression '<' shift_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int < $3->const_int; + } + | relational_expression '>' shift_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int > $3->const_int; + } + | relational_expression LTEQ shift_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int <= $3->const_int; + } + | relational_expression GTEQ shift_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int >= $3->const_int; + } + ; + +equality_expression + : relational_expression + | equality_expression EQ relational_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int == $3->const_int; + } + | equality_expression NOTEQ relational_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int != $3->const_int; + } + ; + +and_expression + : equality_expression + | and_expression '&' equality_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int & $3->const_int; + } + ; + +exclusive_or_expression + : and_expression + | exclusive_or_expression '^' and_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int ^ $3->const_int; + } + ; + +inclusive_or_expression + : exclusive_or_expression + | inclusive_or_expression '|' exclusive_or_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = $1->const_int | $3->const_int; + } + ; + +logical_and_expression + : inclusive_or_expression + | logical_and_expression ANDAND inclusive_or_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = + gi_source_symbol_get_const_boolean ($1) && + gi_source_symbol_get_const_boolean ($3); + } + ; + +logical_or_expression + : logical_and_expression + | logical_or_expression OROR logical_and_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST); + $$->const_int_set = TRUE; + $$->const_int = + gi_source_symbol_get_const_boolean ($1) || + gi_source_symbol_get_const_boolean ($3); + } + ; + +conditional_expression + : logical_or_expression + | logical_or_expression '?' expression ':' conditional_expression + { + $$ = gi_source_symbol_get_const_boolean ($1) ? $3 : $5; + } + ; + +assignment_expression + : conditional_expression + | unary_expression assignment_operator assignment_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + ; + +assignment_operator + : '=' + | MULEQ + | DIVEQ + | MODEQ + | ADDEQ + | SUBEQ + | SLEQ + | SREQ + | ANDEQ + | XOREQ + | OREQ + ; + +expression + : assignment_expression + | expression ',' assignment_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + ; + +constant_expression + : conditional_expression + ; + +/* A.2.2 Declarations. */ + +declaration + : declaration_specifiers init_declarator_list ';' + { + GList *l; + for (l = $2; l != NULL; l = l->next) { + GISourceSymbol *sym = l->data; + gi_source_symbol_merge_type (sym, gi_source_type_copy ($1)); + if ($1->storage_class_specifier & STORAGE_CLASS_TYPEDEF) { + sym->type = CSYMBOL_TYPE_TYPEDEF; + } else if (sym->base_type->type == CTYPE_FUNCTION) { + sym->type = CSYMBOL_TYPE_FUNCTION; + } else { + sym->type = CSYMBOL_TYPE_OBJECT; + } + gi_source_scanner_add_symbol (scanner, sym); + gi_source_symbol_unref (sym); + } + ctype_free ($1); + } + | declaration_specifiers ';' + { + ctype_free ($1); + } + ; + +declaration_specifiers + : storage_class_specifier declaration_specifiers + { + $$ = $2; + $$->storage_class_specifier |= $1; + } + | storage_class_specifier + { + $$ = gi_source_type_new (CTYPE_INVALID); + $$->storage_class_specifier |= $1; + } + | type_specifier declaration_specifiers + { + $$ = $1; + $$->base_type = $2; + } + | type_specifier + | type_qualifier declaration_specifiers + { + $$ = $2; + $$->type_qualifier |= $1; + } + | type_qualifier + { + $$ = gi_source_type_new (CTYPE_INVALID); + $$->type_qualifier |= $1; + } + | function_specifier declaration_specifiers + { + $$ = $2; + $$->function_specifier |= $1; + } + | function_specifier + { + $$ = gi_source_type_new (CTYPE_INVALID); + $$->function_specifier |= $1; + } + ; + +init_declarator_list + : init_declarator + { + $$ = g_list_append (NULL, $1); + } + | init_declarator_list ',' init_declarator + { + $$ = g_list_append ($1, $3); + } + ; + +init_declarator + : declarator + | declarator '=' initializer + ; + +storage_class_specifier + : TYPEDEF + { + $$ = STORAGE_CLASS_TYPEDEF; + } + | EXTERN + { + $$ = STORAGE_CLASS_EXTERN; + } + | STATIC + { + $$ = STORAGE_CLASS_STATIC; + } + | AUTO + { + $$ = STORAGE_CLASS_AUTO; + } + | REGISTER + { + $$ = STORAGE_CLASS_REGISTER; + } + ; + +type_specifier + : VOID + { + $$ = gi_source_type_new (CTYPE_VOID); + } + | CHAR + { + $$ = gi_source_basic_type_new ("char"); + } + | SHORT + { + $$ = gi_source_basic_type_new ("short"); + } + | INT + { + $$ = gi_source_basic_type_new ("int"); + } + | LONG + { + $$ = gi_source_basic_type_new ("long"); + } + | FLOAT + { + $$ = gi_source_basic_type_new ("float"); + } + | DOUBLE + { + $$ = gi_source_basic_type_new ("double"); + } + | SIGNED + { + $$ = gi_source_basic_type_new ("signed"); + } + | UNSIGNED + { + $$ = gi_source_basic_type_new ("unsigned"); + } + | BOOL + { + $$ = gi_source_basic_type_new ("bool"); + } + | struct_or_union_specifier + | enum_specifier + | typedef_name + { + $$ = gi_source_typedef_new ($1); + g_free ($1); + } + ; + +struct_or_union_specifier + : struct_or_union identifier_or_typedef_name '{' struct_declaration_list '}' + { + $$ = $1; + $$->name = $2; + $$->child_list = $4; + + GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + if ($$->type == CTYPE_STRUCT) { + sym->type = CSYMBOL_TYPE_STRUCT; + } else if ($$->type == CTYPE_UNION) { + sym->type = CSYMBOL_TYPE_UNION; + } else { + g_assert_not_reached (); + } + sym->ident = g_strdup ($$->name); + sym->base_type = gi_source_type_copy ($$); + gi_source_scanner_add_symbol (scanner, sym); + gi_source_symbol_unref (sym); + } + | struct_or_union '{' struct_declaration_list '}' + { + $$ = $1; + $$->child_list = $3; + } + | struct_or_union identifier_or_typedef_name + { + $$ = $1; + $$->name = $2; + } + ; + +struct_or_union + : STRUCT + { + $$ = gi_source_struct_new (NULL); + } + | UNION + { + $$ = gi_source_union_new (NULL); + } + ; + +struct_declaration_list + : struct_declaration + | struct_declaration_list struct_declaration + { + $$ = g_list_concat ($1, $2); + } + ; + +struct_declaration + : specifier_qualifier_list struct_declarator_list ';' + { + GList *l; + $$ = NULL; + for (l = $2; l != NULL; l = l->next) { + GISourceSymbol *sym = l->data; + if ($1->storage_class_specifier & STORAGE_CLASS_TYPEDEF) { + sym->type = CSYMBOL_TYPE_TYPEDEF; + } + gi_source_symbol_merge_type (sym, gi_source_type_copy ($1)); + $$ = g_list_append ($$, sym); + } + ctype_free ($1); + } + ; + +specifier_qualifier_list + : type_specifier specifier_qualifier_list + { + $$ = $1; + $$->base_type = $2; + } + | type_specifier + | type_qualifier specifier_qualifier_list + { + $$ = $2; + $$->type_qualifier |= $1; + } + | type_qualifier + { + $$ = gi_source_type_new (CTYPE_INVALID); + $$->type_qualifier |= $1; + } + ; + +struct_declarator_list + : struct_declarator + { + $$ = g_list_append (NULL, $1); + } + | struct_declarator_list ',' struct_declarator + { + $$ = g_list_append ($1, $3); + } + ; + +struct_declarator + : /* empty, support for anonymous structs and unions */ + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | declarator + | ':' constant_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + } + | declarator ':' constant_expression + ; + +enum_specifier + : ENUM identifier_or_typedef_name '{' enumerator_list '}' + { + $$ = gi_source_enum_new ($2); + $$->child_list = $4; + last_enum_value = -1; + } + | ENUM '{' enumerator_list '}' + { + $$ = gi_source_enum_new (NULL); + $$->child_list = $3; + last_enum_value = -1; + } + | ENUM identifier_or_typedef_name '{' enumerator_list ',' '}' + { + $$ = gi_source_enum_new ($2); + $$->child_list = $4; + last_enum_value = -1; + } + | ENUM '{' enumerator_list ',' '}' + { + $$ = gi_source_enum_new (NULL); + $$->child_list = $3; + last_enum_value = -1; + } + | ENUM identifier_or_typedef_name + { + $$ = gi_source_enum_new ($2); + } + ; + +enumerator_list + : enumerator + { + $$ = g_list_append (NULL, $1); + } + | enumerator_list ',' enumerator + { + $$ = g_list_append ($1, $3); + } + ; + +enumerator + : identifier + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT); + $$->ident = $1; + $$->const_int_set = TRUE; + $$->const_int = ++last_enum_value; + g_hash_table_insert (const_table, g_strdup ($$->ident), gi_source_symbol_ref ($$)); + } + | identifier '=' constant_expression + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT); + $$->ident = $1; + $$->const_int_set = TRUE; + $$->const_int = $3->const_int; + last_enum_value = $$->const_int; + g_hash_table_insert (const_table, g_strdup ($$->ident), gi_source_symbol_ref ($$)); + } + ; + +type_qualifier + : CONST + { + $$ = TYPE_QUALIFIER_CONST; + } + | RESTRICT + { + $$ = TYPE_QUALIFIER_RESTRICT; + } + | VOLATILE + { + $$ = TYPE_QUALIFIER_VOLATILE; + } + ; + +function_specifier + : INLINE + { + $$ = FUNCTION_INLINE; + } + ; + +declarator + : pointer direct_declarator + { + $$ = $2; + gi_source_symbol_merge_type ($$, $1); + } + | direct_declarator + ; + +direct_declarator + : identifier + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + $$->ident = $1; + } + | '(' declarator ')' + { + $$ = $2; + } + | direct_declarator '[' assignment_expression ']' + { + $$ = $1; + gi_source_symbol_merge_type ($$, gi_source_array_new ()); + } + | direct_declarator '[' ']' + { + $$ = $1; + gi_source_symbol_merge_type ($$, gi_source_array_new ()); + } + | direct_declarator '(' parameter_type_list ')' + { + GISourceType *func = gi_source_function_new (); + // ignore (void) parameter list + if ($3 != NULL && ($3->next != NULL || ((GISourceSymbol *) $3->data)->base_type->type != CTYPE_VOID)) { + func->child_list = $3; + } + $$ = $1; + gi_source_symbol_merge_type ($$, func); + } + | direct_declarator '(' identifier_list ')' + { + GISourceType *func = gi_source_function_new (); + func->child_list = $3; + $$ = $1; + gi_source_symbol_merge_type ($$, func); + } + | direct_declarator '(' ')' + { + GISourceType *func = gi_source_function_new (); + $$ = $1; + gi_source_symbol_merge_type ($$, func); + } + ; + +pointer + : '*' type_qualifier_list + { + $$ = gi_source_pointer_new (NULL); + $$->type_qualifier = $2; + } + | '*' + { + $$ = gi_source_pointer_new (NULL); + } + | '*' type_qualifier_list pointer + { + $$ = gi_source_pointer_new ($3); + $$->type_qualifier = $2; + } + | '*' pointer + { + $$ = gi_source_pointer_new ($2); + } + ; + +type_qualifier_list + : type_qualifier + | type_qualifier_list type_qualifier + { + $$ = $1 | $2; + } + ; + +parameter_type_list + : parameter_list + | parameter_list ',' ELLIPSIS + ; + +parameter_list + : parameter_declaration + { + $$ = g_list_append (NULL, $1); + } + | parameter_list ',' parameter_declaration + { + $$ = g_list_append ($1, $3); + } + ; + +parameter_declaration + : declaration_specifiers declarator + { + $$ = $2; + gi_source_symbol_merge_type ($$, $1); + } + | declaration_specifiers abstract_declarator + { + $$ = $2; + gi_source_symbol_merge_type ($$, $1); + } + | declaration_specifiers + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + $$->base_type = $1; + } + ; + +identifier_list + : identifier + { + GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + sym->ident = $1; + $$ = g_list_append (NULL, sym); + } + | identifier_list ',' identifier + { + GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + sym->ident = $3; + $$ = g_list_append ($1, sym); + } + ; + +type_name + : specifier_qualifier_list + | specifier_qualifier_list abstract_declarator + ; + +abstract_declarator + : pointer + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + gi_source_symbol_merge_type ($$, $1); + } + | direct_abstract_declarator + | pointer direct_abstract_declarator + { + $$ = $2; + gi_source_symbol_merge_type ($$, $1); + } + ; + +direct_abstract_declarator + : '(' abstract_declarator ')' + { + $$ = $2; + } + | '[' ']' + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + gi_source_symbol_merge_type ($$, gi_source_array_new ()); + } + | '[' assignment_expression ']' + { + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + gi_source_symbol_merge_type ($$, gi_source_array_new ()); + } + | direct_abstract_declarator '[' ']' + { + $$ = $1; + gi_source_symbol_merge_type ($$, gi_source_array_new ()); + } + | direct_abstract_declarator '[' assignment_expression ']' + { + $$ = $1; + gi_source_symbol_merge_type ($$, gi_source_array_new ()); + } + | '(' ')' + { + GISourceType *func = gi_source_function_new (); + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + gi_source_symbol_merge_type ($$, func); + } + | '(' parameter_type_list ')' + { + GISourceType *func = gi_source_function_new (); + // ignore (void) parameter list + if ($2 != NULL && ($2->next != NULL || ((GISourceSymbol *) $2->data)->base_type->type != CTYPE_VOID)) { + func->child_list = $2; + } + $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID); + gi_source_symbol_merge_type ($$, func); + } + | direct_abstract_declarator '(' ')' + { + GISourceType *func = gi_source_function_new (); + $$ = $1; + gi_source_symbol_merge_type ($$, func); + } + | direct_abstract_declarator '(' parameter_type_list ')' + { + GISourceType *func = gi_source_function_new (); + // ignore (void) parameter list + if ($3 != NULL && ($3->next != NULL || ((GISourceSymbol *) $3->data)->base_type->type != CTYPE_VOID)) { + func->child_list = $3; + } + $$ = $1; + gi_source_symbol_merge_type ($$, func); + } + ; + +typedef_name + : TYPEDEF_NAME + { + $$ = g_strdup (yytext); + } + ; + +initializer + : assignment_expression + | '{' initializer_list '}' + | '{' initializer_list ',' '}' + ; + +initializer_list + : initializer + | initializer_list ',' initializer + ; + +/* A.2.3 Statements. */ + +statement + : labeled_statement + | compound_statement + | expression_statement + | selection_statement + | iteration_statement + | jump_statement + ; + +labeled_statement + : identifier_or_typedef_name ':' statement + | CASE constant_expression ':' statement + | DEFAULT ':' statement + ; + +compound_statement + : '{' '}' + | '{' block_item_list '}' + ; + +block_item_list + : block_item + | block_item_list block_item + ; + +block_item + : declaration + | statement + ; + +expression_statement + : ';' + | expression ';' + ; + +selection_statement + : IF '(' expression ')' statement + | IF '(' expression ')' statement ELSE statement + | SWITCH '(' expression ')' statement + ; + +iteration_statement + : WHILE '(' expression ')' statement + | DO statement WHILE '(' expression ')' ';' + | FOR '(' ';' ';' ')' statement + | FOR '(' expression ';' ';' ')' statement + | FOR '(' ';' expression ';' ')' statement + | FOR '(' expression ';' expression ';' ')' statement + | FOR '(' ';' ';' expression ')' statement + | FOR '(' expression ';' ';' expression ')' statement + | FOR '(' ';' expression ';' expression ')' statement + | FOR '(' expression ';' expression ';' expression ')' statement + ; + +jump_statement + : GOTO identifier_or_typedef_name ';' + | CONTINUE ';' + | BREAK ';' + | RETURN ';' + | RETURN expression ';' + ; + +/* A.2.4 External definitions. */ + +translation_unit + : external_declaration + | translation_unit external_declaration + ; + +external_declaration + : function_definition + | declaration + | macro + ; + +function_definition + : declaration_specifiers declarator declaration_list compound_statement + | declaration_specifiers declarator compound_statement + ; + +declaration_list + : declaration + | declaration_list declaration + ; + +/* Macros */ + +function_macro + : FUNCTION_MACRO + { + $$ = g_strdup (yytext + strlen ("#define ")); + } + ; + +object_macro + : OBJECT_MACRO + { + $$ = g_strdup (yytext + strlen ("#define ")); + } + ; + +function_macro_define + : function_macro '(' identifier_list ')' + ; + +object_macro_define + : object_macro constant_expression + { + if ($2->const_int_set || $2->const_string != NULL) { + $2->ident = $1; + gi_source_scanner_add_symbol (scanner, $2); + gi_source_symbol_unref ($2); + } + } + ; + +macro + : function_macro_define + | object_macro_define + | error + ; + +%% +static void +yyerror (GISourceScanner *scanner, const char *s) +{ + /* ignore errors while doing a macro scan as not all object macros + * have valid expressions */ + if (!scanner->macro_scan) + { + fprintf(stderr, "%s:%d: %s\n", + scanner->current_filename, lineno, s); + } +} + +gboolean +gi_source_scanner_parse_file (GISourceScanner *scanner, FILE *file) +{ + g_return_val_if_fail (file != NULL, FALSE); + + const_table = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify)gi_source_symbol_unref); + + lineno = 1; + yyin = file; + yyparse (scanner); + + g_hash_table_destroy (const_table); + const_table = NULL; + + yyin = NULL; + + return TRUE; +} + +gboolean +gi_source_scanner_lex_filename (GISourceScanner *scanner, const gchar *filename) +{ + yyin = fopen (filename, "r"); + + while (yylex (scanner) != YYEOF) + ; + + fclose (yyin); + + return TRUE; +} diff --git a/tools/sourcescanner.c b/giscanner/sourcescanner.c index 8354b1b5..bb916e88 100644 --- a/tools/sourcescanner.c +++ b/giscanner/sourcescanner.c @@ -236,6 +236,13 @@ gi_source_scanner_is_typedef (GISourceScanner *scanner, } void +gi_source_scanner_set_macro_scan (GISourceScanner *scanner, + gboolean macro_scan) +{ + scanner->macro_scan = macro_scan; +} + +void gi_source_scanner_add_symbol (GISourceScanner *scanner, GISourceSymbol *symbol) { diff --git a/tools/sourcescanner.h b/giscanner/sourcescanner.h index 71236ce9..c1365e02 100644 --- a/tools/sourcescanner.h +++ b/giscanner/sourcescanner.h @@ -125,14 +125,14 @@ struct _GISourceType FunctionSpecifier function_specifier; char *name; GISourceType *base_type; - GList *child_list; + GList *child_list; /* list of GISourceSymbol */ }; struct _GISourceDirective { char *name; char *value; - GSList *options; + GSList *options; /* list of options (key=value) */ }; GISourceScanner * gi_source_scanner_new (void); @@ -140,6 +140,8 @@ gboolean gi_source_scanner_lex_filename (GISourceScanner *igener const gchar *filename); gboolean gi_source_scanner_parse_file (GISourceScanner *igenerator, FILE *file); +void gi_source_scanner_set_macro_scan (GISourceScanner *scanner, + gboolean macro_scan); GSList * gi_source_scanner_get_symbols (GISourceScanner *scanner); void gi_source_scanner_free (GISourceScanner *scanner); diff --git a/tools/Makefile.am b/tools/Makefile.am index 46fff6bf..545050a9 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,16 +1,14 @@ ## Process this file with automake to produce Makefile.in -INCLUDES = -DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\"" -BUILT_SOURCES = scannerparser.c scannerparser.h scannerlexer.c scannerlexer.h \ - gmetadata-header.c +INCLUDES = \ + -DGIREPO_DEFAULT_SEARCH_PATH="\"$(libdir)\"" \ + -I$(top_srcdir)/girepository \ + -I$(top_srcdir)/giscanner +BUILT_SOURCES = gmetadata-header.c -CLEANFILES = scannerparser.c scannerparser.h scannerlexer.c scannerlexer.h gmetadata-header.c -AM_YFLAGS = -d -t +CLEANFILES = gmetadata-header.c EXTRA_DIST = quote-file.sh -# Why do I have to do this automake? -scannerlexer.h: scannerlexer.c - noinst_LTLIBRARIES = libgirepository-parser.la bin_PROGRAMS = g-idl-compiler g-idl-generate g-idl-scanner @@ -32,28 +30,28 @@ libgirepository_parser_la_SOURCES = \ gidlcompilertypenode.h \ gmetadata-header.c -libgirepository_parser_la_CFLAGS = $(GIREPO_CFLAGS) -I$(top_srcdir)/girepository +libgirepository_parser_la_CFLAGS = $(GIREPO_CFLAGS) g_idl_compiler_SOURCES = compiler.c -g_idl_compiler_CFLAGS = $(GIREPO_CFLAGS) -I$(top_srcdir)/girepository +g_idl_compiler_CFLAGS = $(GIREPO_CFLAGS) g_idl_compiler_LDADD = $(GIREPO_LIBS) $(top_builddir)/girepository/libgirepository.la libgirepository-parser.la g_idl_generate_SOURCES = generate.c -g_idl_generate_CFLAGS = $(GIREPO_CFLAGS) -I$(top_srcdir)/girepository +g_idl_generate_CFLAGS = $(GIREPO_CFLAGS) g_idl_generate_LDADD = $(GIREPO_LIBS) $(top_builddir)/girepository/libgirepository.la g_idl_scanner_SOURCES = \ - sourcescanner.c \ - sourcescanner.h \ scanner.c \ scanner.h \ - scannerlexer.l \ - scannerparser.y \ gidlwriter.c \ - gidlwriter.h \ - grealpath.h -g_idl_scanner_CFLAGS = $(GIREPO_CFLAGS) $(SCANNER_CFLAGS) -I$(top_srcdir)/girepository -g_idl_scanner_LDADD = $(GIREPO_LIBS) $(SCANNER_LIBS) $(top_builddir)/girepository/libgirepository.la libgirepository-parser.la + gidlwriter.h +g_idl_scanner_CFLAGS = $(GIREPO_CFLAGS) $(SCANNER_CFLAGS) +g_idl_scanner_LDADD = \ + $(GIREPO_LIBS) \ + $(SCANNER_LIBS) \ + $(top_builddir)/girepository/libgirepository.la \ + $(top_builddir)/giscanner/libgiscanner.la \ + libgirepository-parser.la GCOVSOURCES = \ $(libgirepository_la_SOURCES) \ |