#include <string.h>
#include <errno.h>
#include <glib.h>
+#include <glib/gstdio.h>
#include "sourcescanner.h"
#include "scannerparser.h"
extern FILE *yyin;
extern int lineno;
+extern char linebuf[2000];
extern char *yytext;
extern int yylex (GISourceScanner *scanner);
static void yyerror (GISourceScanner *scanner, const char *str);
+extern void ctype_free (GISourceType * type);
+
static int last_enum_value = -1;
+static gboolean is_bitfield;
static GHashTable *const_table = NULL;
%}
%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
{
$$ = g_hash_table_lookup (const_table, $1);
if ($$ == NULL) {
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
} else {
$$ = gi_source_symbol_ref ($$);
}
}
| INTEGER
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
if (g_str_has_prefix (yytext, "0x") && strlen (yytext) > 2) {
$$->const_int = strtol (yytext + 2, NULL, 16);
}
| CHARACTER
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| FLOATING
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
+ $$->const_double_set = TRUE;
+ $$->const_double = 0.0;
+ sscanf (yytext, "%lf", &($$->const_double));
}
| strings
| '(' expression ')'
strings
: STRING
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
yytext[strlen (yytext) - 1] = '\0';
$$->const_string = g_strcompress (yytext + 1);
+ if (!g_utf8_validate ($$->const_string, -1, NULL))
+ {
+#if 0
+ g_warning ("Ignoring non-UTF-8 constant string \"%s\"", yytext + 1);
+#endif
+ g_free($$->const_string);
+ $$->const_string = NULL;
+ }
+
}
| strings STRING
{
: primary_expression
| postfix_expression '[' expression ']'
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| postfix_expression '(' argument_expression_list ')'
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| postfix_expression '(' ')'
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| postfix_expression '.' identifier_or_typedef_name
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| postfix_expression ARROW identifier_or_typedef_name
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| postfix_expression PLUSPLUS
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| postfix_expression MINUSMINUS
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
;
: postfix_expression
| PLUSPLUS unary_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| MINUSMINUS unary_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| unary_operator cast_expression
{
$$->const_int = !gi_source_symbol_get_const_boolean ($2);
break;
default:
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
break;
}
}
| SIZEOF unary_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| SIZEOF '(' type_name ')'
{
ctype_free ($3);
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
;
: cast_expression
| multiplicative_expression '*' cast_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int * $3->const_int;
}
| multiplicative_expression '/' cast_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->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);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
- $$->const_int = $1->const_int % $3->const_int;
+ if ($3->const_int != 0) {
+ $$->const_int = $1->const_int % $3->const_int;
+ }
}
;
: multiplicative_expression
| additive_expression '+' multiplicative_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int + $3->const_int;
}
| additive_expression '-' multiplicative_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int - $3->const_int;
}
: additive_expression
| shift_expression SL additive_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int << $3->const_int;
+
+ /* assume this is a bitfield/flags declaration
+ * if a left shift operator is sued in an enum value
+ * This mimics the glib-mkenum behavior.
+ */
+ is_bitfield = TRUE;
}
| shift_expression SR additive_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int >> $3->const_int;
}
: shift_expression
| relational_expression '<' shift_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int < $3->const_int;
}
| relational_expression '>' shift_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int > $3->const_int;
}
| relational_expression LTEQ shift_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int <= $3->const_int;
}
| relational_expression GTEQ shift_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int >= $3->const_int;
}
: relational_expression
| equality_expression EQ relational_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int == $3->const_int;
}
| equality_expression NOTEQ relational_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int != $3->const_int;
}
: equality_expression
| and_expression '&' equality_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int & $3->const_int;
}
: and_expression
| exclusive_or_expression '^' and_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int ^ $3->const_int;
}
: exclusive_or_expression
| inclusive_or_expression '|' exclusive_or_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int = $1->const_int | $3->const_int;
}
: inclusive_or_expression
| logical_and_expression ANDAND inclusive_or_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int =
gi_source_symbol_get_const_boolean ($1) &&
: logical_and_expression
| logical_or_expression OROR logical_and_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_CONST, lineno);
$$->const_int_set = TRUE;
$$->const_int =
gi_source_symbol_get_const_boolean ($1) ||
: conditional_expression
| unary_expression assignment_operator assignment_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
;
expression
: assignment_expression
| expression ',' assignment_expression
+ | EXTENSION expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
;
| type_specifier declaration_specifiers
{
$$ = $1;
- $$->base_type = $2;
+ /* combine basic types like unsigned int and long long */
+ if ($$->type == CTYPE_BASIC_TYPE && $2->type == CTYPE_BASIC_TYPE) {
+ char *name = g_strdup_printf ("%s %s", $$->name, $2->name);
+ g_free ($$->name);
+ $$->name = name;
+ ctype_free ($2);
+ } else {
+ $$->base_type = $2;
+ }
}
| type_specifier
| type_qualifier declaration_specifiers
$$->name = $2;
$$->child_list = $4;
- GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
if ($$->type == CTYPE_STRUCT) {
sym->type = CSYMBOL_TYPE_STRUCT;
} else if ($$->type == CTYPE_UNION) {
struct_declarator
: /* empty, support for anonymous structs and unions */
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| declarator
| ':' constant_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
}
| declarator ':' constant_expression
+ {
+ $$ = $1;
+ if ($3->const_int_set) {
+ $$->const_int_set = TRUE;
+ $$->const_int = $3->const_int;
+ }
+ }
;
enum_specifier
{
$$ = gi_source_enum_new ($2);
$$->child_list = $4;
+ $$->is_bitfield = is_bitfield;
last_enum_value = -1;
}
| ENUM '{' enumerator_list '}'
{
$$ = gi_source_enum_new (NULL);
$$->child_list = $3;
+ $$->is_bitfield = is_bitfield;
last_enum_value = -1;
}
| ENUM identifier_or_typedef_name '{' enumerator_list ',' '}'
{
$$ = gi_source_enum_new ($2);
$$->child_list = $4;
+ $$->is_bitfield = is_bitfield;
last_enum_value = -1;
}
| ENUM '{' enumerator_list ',' '}'
{
$$ = gi_source_enum_new (NULL);
$$->child_list = $3;
+ $$->is_bitfield = is_bitfield;
last_enum_value = -1;
}
| ENUM identifier_or_typedef_name
;
enumerator_list
- : enumerator
+ :
{
- $$ = g_list_append (NULL, $1);
+ /* reset flag before the first enum value */
+ is_bitfield = FALSE;
+ }
+ enumerator
+ {
+ $$ = g_list_append (NULL, $2);
}
| enumerator_list ',' enumerator
{
enumerator
: identifier
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT, lineno);
$$->ident = $1;
$$->const_int_set = TRUE;
$$->const_int = ++last_enum_value;
}
| identifier '=' constant_expression
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_OBJECT, lineno);
$$->ident = $1;
$$->const_int_set = TRUE;
$$->const_int = $3->const_int;
direct_declarator
: identifier
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
$$->ident = $1;
}
| '(' declarator ')'
| direct_declarator '[' assignment_expression ']'
{
$$ = $1;
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
+ gi_source_symbol_merge_type ($$, gi_source_array_new ($3));
}
| direct_declarator '[' ']'
{
$$ = $1;
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
+ gi_source_symbol_merge_type ($$, gi_source_array_new (NULL));
}
- | direct_declarator '(' parameter_type_list ')'
+ | direct_declarator '(' parameter_list ')'
{
GISourceType *func = gi_source_function_new ();
// ignore (void) parameter list
}
;
-parameter_type_list
- : parameter_list
- | parameter_list ',' ELLIPSIS
- ;
-
parameter_list
: parameter_declaration
{
}
| declaration_specifiers
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
$$->base_type = $1;
}
+ | ELLIPSIS
+ {
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_ELLIPSIS, lineno);
+ }
;
identifier_list
: identifier
{
- GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
sym->ident = $1;
$$ = g_list_append (NULL, sym);
}
| identifier_list ',' identifier
{
- GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ GISourceSymbol *sym = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
sym->ident = $3;
$$ = g_list_append ($1, sym);
}
abstract_declarator
: pointer
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
gi_source_symbol_merge_type ($$, $1);
}
| direct_abstract_declarator
}
| '[' ']'
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
+ gi_source_symbol_merge_type ($$, gi_source_array_new (NULL));
}
| '[' assignment_expression ']'
{
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
+ gi_source_symbol_merge_type ($$, gi_source_array_new ($2));
}
| direct_abstract_declarator '[' ']'
{
$$ = $1;
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
+ gi_source_symbol_merge_type ($$, gi_source_array_new (NULL));
}
| direct_abstract_declarator '[' assignment_expression ']'
{
$$ = $1;
- gi_source_symbol_merge_type ($$, gi_source_array_new ());
+ gi_source_symbol_merge_type ($$, gi_source_array_new ($3));
}
| '(' ')'
{
GISourceType *func = gi_source_function_new ();
- $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID);
+ $$ = gi_source_symbol_new (CSYMBOL_TYPE_INVALID, lineno);
gi_source_symbol_merge_type ($$, func);
}
- | '(' parameter_type_list ')'
+ | '(' parameter_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_new (CSYMBOL_TYPE_INVALID, lineno);
gi_source_symbol_merge_type ($$, func);
}
| direct_abstract_declarator '(' ')'
$$ = $1;
gi_source_symbol_merge_type ($$, func);
}
- | direct_abstract_declarator '(' parameter_type_list ')'
+ | direct_abstract_declarator '(' parameter_list ')'
{
GISourceType *func = gi_source_function_new ();
// ignore (void) parameter list
object_macro_define
: object_macro constant_expression
{
- if ($2->const_int_set || $2->const_string != NULL) {
+ if ($2->const_int_set || $2->const_double_set || $2->const_string != NULL) {
$2->ident = $1;
gi_source_scanner_add_symbol (scanner, $2);
gi_source_symbol_unref ($2);
* have valid expressions */
if (!scanner->macro_scan)
{
- fprintf(stderr, "%s:%d: %s\n",
- scanner->current_filename, lineno, s);
+ fprintf(stderr, "%s:%d: %s in '%s' at '%s'\n",
+ scanner->current_filename, lineno, s, linebuf, yytext);
+ }
+}
+
+static int
+eat_hspace (FILE * f)
+{
+ int c;
+ do
+ {
+ c = fgetc (f);
}
+ while (c == ' ' || c == '\t');
+ return c;
+}
+
+static int
+eat_line (FILE * f, int c)
+{
+ while (c != EOF && c != '\n')
+ {
+ c = fgetc (f);
+ }
+ if (c == '\n')
+ {
+ c = fgetc (f);
+ if (c == ' ' || c == '\t')
+ {
+ c = eat_hspace (f);
+ }
+ }
+ return c;
+}
+
+static int
+read_identifier (FILE * f, int c, char **identifier)
+{
+ GString *id = g_string_new ("");
+ while (g_ascii_isalnum (c) || c == '_')
+ {
+ g_string_append_c (id, c);
+ c = fgetc (f);
+ }
+ *identifier = g_string_free (id, FALSE);
+ return c;
+}
+
+void
+gi_source_scanner_parse_macros (GISourceScanner *scanner, GList *filenames)
+{
+ GError *error = NULL;
+ char *tmp_name = NULL;
+ FILE *fmacros =
+ fdopen (g_file_open_tmp ("gen-introspect-XXXXXX.h", &tmp_name, &error),
+ "w+");
+ g_unlink (tmp_name);
+
+ GList *l;
+ for (l = filenames; l != NULL; l = l->next)
+ {
+ FILE *f = fopen (l->data, "r");
+ int line = 1;
+
+ GString *define_line;
+ char *str;
+ gboolean error_line = FALSE;
+ int c = eat_hspace (f);
+ while (c != EOF)
+ {
+ if (c != '#')
+ {
+ /* ignore line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+
+ /* print current location */
+ str = g_strescape (l->data, "");
+ fprintf (fmacros, "# %d \"%s\"\n", line, str);
+ g_free (str);
+
+ c = eat_hspace (f);
+ c = read_identifier (f, c, &str);
+ if (strcmp (str, "define") != 0 || (c != ' ' && c != '\t'))
+ {
+ g_free (str);
+ /* ignore line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+ g_free (str);
+ c = eat_hspace (f);
+ c = read_identifier (f, c, &str);
+ if (strlen (str) == 0 || (c != ' ' && c != '\t' && c != '('))
+ {
+ g_free (str);
+ /* ignore line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+ define_line = g_string_new ("#define ");
+ g_string_append (define_line, str);
+ g_free (str);
+ if (c == '(')
+ {
+ while (c != ')')
+ {
+ g_string_append_c (define_line, c);
+ c = fgetc (f);
+ if (c == EOF || c == '\n')
+ {
+ error_line = TRUE;
+ break;
+ }
+ }
+ if (error_line)
+ {
+ g_string_free (define_line, TRUE);
+ /* ignore line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+
+ g_assert (c == ')');
+ g_string_append_c (define_line, c);
+ c = fgetc (f);
+
+ /* found function-like macro */
+ fprintf (fmacros, "%s\n", define_line->str);
+
+ g_string_free (define_line, TRUE);
+ /* ignore rest of line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+ if (c != ' ' && c != '\t')
+ {
+ g_string_free (define_line, TRUE);
+ /* ignore line */
+ c = eat_line (f, c);
+ line++;
+ continue;
+ }
+ while (c != EOF && c != '\n')
+ {
+ g_string_append_c (define_line, c);
+ c = fgetc (f);
+ if (c == '\\')
+ {
+ c = fgetc (f);
+ if (c == '\n')
+ {
+ /* fold lines when seeing backslash new-line sequence */
+ c = fgetc (f);
+ }
+ else
+ {
+ g_string_append_c (define_line, '\\');
+ }
+ }
+ }
+
+ /* found object-like macro */
+ fprintf (fmacros, "%s\n", define_line->str);
+
+ c = eat_line (f, c);
+ line++;
+ }
+
+ fclose (f);
+ }
+
+ rewind (fmacros);
+ gi_source_scanner_parse_file (scanner, fmacros);
}
gboolean