From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/parser.l | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 85d33d6e86a..710b6e37636 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -89,6 +89,13 @@ struct { } import_stack[MAX_IMPORT_DEPTH]; int import_stack_ptr = 0;
+struct import +{ + const char *name; + struct list entry; +}; +static struct list imports = LIST_INIT( imports ); + /* converts an integer in string form to an unsigned long and prints an error * on overflow */ static unsigned int xstrtoul(const char *nptr, char **endptr, int base) @@ -513,28 +520,20 @@ void pop_import(void) import_stack_ptr--; }
-struct imports { - char *name; - struct imports *next; -} *first_import; - int do_import(char *fname) { FILE *f; char *path, *name; - struct imports *import; + struct import *import; int ptr = import_stack_ptr; int ret;
- import = first_import; - while (import && strcmp(import->name, fname)) - import = import->next; - if (import) return 0; /* already imported */ + LIST_FOR_EACH_ENTRY( import, &imports, struct import, entry ) + if (!strcmp( import->name, fname )) return 0; /* already imported */
- import = xmalloc(sizeof(struct imports)); - import->name = xstrdup(fname); - import->next = first_import; - first_import = import; + import = xmalloc( sizeof(struct import) ); + import->name = xstrdup( fname ); + list_add_tail( &imports, &import->entry );
/* don't search for a file name with a path in the include directories, * for compatibility with MIDL */
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/parser.h | 2 +- tools/widl/parser.l | 36 ++++++++++++++++++++---------------- tools/widl/parser.y | 15 ++++----------- 3 files changed, 25 insertions(+), 28 deletions(-)
diff --git a/tools/widl/parser.h b/tools/widl/parser.h index 83832ecfcd8..f465fafa03c 100644 --- a/tools/widl/parser.h +++ b/tools/widl/parser.h @@ -29,7 +29,7 @@ extern int parser_debug; extern int yy_flex_debug;
extern int import_stack_ptr; -int do_import(char *fname); +void push_import( char *import_name ); void pop_import(void);
#define parse_only import_stack_ptr diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 710b6e37636..47783cbacb3 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -512,7 +512,7 @@ void pop_import(void) { int ptr = import_stack_ptr-1;
- fclose(yyin); + if (yyin) fclose( yyin ); yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( import_stack[ptr].state ); input_name = import_stack[ptr].input_name; @@ -520,7 +520,7 @@ void pop_import(void) import_stack_ptr--; }
-int do_import(char *fname) +void push_import( char *import_name ) { FILE *f; char *path, *name; @@ -528,26 +528,32 @@ int do_import(char *fname) int ptr = import_stack_ptr; int ret;
+ if (import_stack_ptr == MAX_IMPORT_DEPTH) + error_loc("Exceeded max import depth\n"); + + import_stack[ptr].state = YY_CURRENT_BUFFER; + import_stack[ptr].input_name = input_name; + import_stack[ptr].line_number = line_number; + import_stack_ptr++; + yyin = NULL; + + /* reset buffer for <<EOF>>, in case import fails or already imported */ + yy_scan_string( "" ); + LIST_FOR_EACH_ENTRY( import, &imports, struct import, entry ) - if (!strcmp( import->name, fname )) return 0; /* already imported */ + if (!strcmp( import->name, import_name )) return; /* already imported */
import = xmalloc( sizeof(struct import) ); - import->name = xstrdup( fname ); + import->name = xstrdup( import_name ); list_add_tail( &imports, &import->entry );
/* don't search for a file name with a path in the include directories, * for compatibility with MIDL */ - if (strchr( fname, '/' ) || strchr( fname, '\' )) - path = xstrdup( fname ); - else if (!(path = wpp_find_include( fname, input_name ))) - error_loc("Unable to open include file %s\n", fname); + if (strchr( import_name, '/' ) || strchr( import_name, '\' )) + path = xstrdup( import_name ); + else if (!(path = wpp_find_include( import_name, input_name ))) + error_loc( "Unable to open include file %s\n", import_name );
- if (import_stack_ptr == MAX_IMPORT_DEPTH) - error_loc("Exceeded max import depth\n"); - - import_stack[ptr].input_name = input_name; - import_stack[ptr].line_number = line_number; - import_stack_ptr++; input_name = path; line_number = 1;
@@ -562,9 +568,7 @@ int do_import(char *fname) if((f = fopen(name, "r")) == NULL) error_loc("Unable to open %s\n", name);
- import_stack[ptr].state = YY_CURRENT_BUFFER; yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); - return 1; }
static void switch_to_acf(void) diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 6777a281ec7..031e5482792 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -331,7 +331,7 @@ int parser_lex( PARSER_STYPE *yylval ); %type <str> libraryhdr callconv cppquote importlib import %type <str> typename m_typename %type <uuid> uuid_string -%type <import> import_start +%type <str> import_start %type <typelib> library_start librarydef %type <statement> statement typedef pragma_warning %type <stmt_list> gbl_statements imp_statements int_statements @@ -504,17 +504,10 @@ typedecl:
cppquote: tCPPQUOTE '(' aSTRING ')' { $$ = $3; } ; -import_start: tIMPORT aSTRING ';' { $$ = xmalloc(sizeof(struct _import_t)); - $$->name = $2; - $$->import_performed = do_import($2); - if (!$$->import_performed) yychar = aEOF; - } - ;
-import: import_start imp_statements aEOF { $$ = $1->name; - if ($1->import_performed) pop_import(); - free($1); - } +import_start: tIMPORT aSTRING ';' { $$ = $2; push_import($2); } + ; +import: import_start imp_statements aEOF { pop_import(); } ;
importlib: tIMPORTLIB '(' aSTRING ')'
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/parser.h | 4 +-- tools/widl/parser.l | 66 +++++++++++++++++++++++++-------------------- tools/widl/widl.c | 2 -- 3 files changed, 38 insertions(+), 34 deletions(-)
diff --git a/tools/widl/parser.h b/tools/widl/parser.h index f465fafa03c..abe215de02f 100644 --- a/tools/widl/parser.h +++ b/tools/widl/parser.h @@ -28,12 +28,10 @@ extern char *parser_text; extern int parser_debug; extern int yy_flex_debug;
-extern int import_stack_ptr; +extern int parse_only; void push_import( char *import_name ); void pop_import(void);
-#define parse_only import_stack_ptr - int is_type(const char *name);
int do_warning(const char *toggle, warning_list_t *wnum); diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 47783cbacb3..89383fe810e 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -81,13 +81,15 @@ static void switch_to_acf(void);
static warning_list_t *disabled_warnings = NULL;
-#define MAX_IMPORT_DEPTH 20 -struct { - YY_BUFFER_STATE state; - char *input_name; - int line_number; -} import_stack[MAX_IMPORT_DEPTH]; -int import_stack_ptr = 0; +struct import_state +{ + YY_BUFFER_STATE buffer; + char *input_name; + int line_number; + struct list entry; +}; +static struct list import_stack = LIST_INIT( import_stack ); +int parse_only = 0;
struct import { @@ -159,7 +161,8 @@ struct uuid *parse_uuid(const char *u) } <PP_PRAGMA>midl_echo[^\n]* yyless(9); yy_pop_state(); return tCPPQUOTE; <PP_PRAGMA>winrt[^\n]* { - if(import_stack_ptr) { + if (!list_empty( &import_stack )) + { if(!winrt_mode) error_loc("winrt IDL file imported in non-winrt mode\n"); }else { @@ -234,7 +237,7 @@ SAFEARRAY{ws}*/( return tSAFEARRAY; <INITIAL,ATTR>... return ELLIPSIS; <INITIAL,ATTR>. return yytext[0]; <<EOF>> { - if (import_stack_ptr) + if (!list_empty( &import_stack )) return aEOF; if (acf_name) { @@ -510,32 +513,38 @@ static char *get_buffered_cstring(void)
void pop_import(void) { - int ptr = import_stack_ptr-1; - - if (yyin) fclose( yyin ); - yy_delete_buffer( YY_CURRENT_BUFFER ); - yy_switch_to_buffer( import_stack[ptr].state ); - input_name = import_stack[ptr].input_name; - line_number = import_stack[ptr].line_number; - import_stack_ptr--; + struct list *entry = list_head( &import_stack ); + struct import_state *state; + assert( entry ); + + state = LIST_ENTRY( entry, struct import_state, entry ); + list_remove( &state->entry ); + parse_only = !list_empty( &import_stack ); + + if (yyin) fclose( yyin ); + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( state->buffer ); + input_name = state->input_name; + line_number = state->line_number; + free( state ); }
void push_import( char *import_name ) { + struct import_state *state; FILE *f; char *path, *name; struct import *import; - int ptr = import_stack_ptr; int ret;
- if (import_stack_ptr == MAX_IMPORT_DEPTH) - error_loc("Exceeded max import depth\n"); + state = xmalloc( sizeof(struct import_state )); + list_add_head( &import_stack, &state->entry ); + parse_only = !list_empty( &import_stack );
- import_stack[ptr].state = YY_CURRENT_BUFFER; - import_stack[ptr].input_name = input_name; - import_stack[ptr].line_number = line_number; - import_stack_ptr++; - yyin = NULL; + state->buffer = YY_CURRENT_BUFFER; + state->input_name = input_name; + state->line_number = line_number; + input_name = NULL;
/* reset buffer for <<EOF>>, in case import fails or already imported */ yy_scan_string( "" ); @@ -573,12 +582,12 @@ void push_import( char *import_name )
static void switch_to_acf(void) { - int ptr = import_stack_ptr; - int ret; char *name; + int ret; FILE *f;
- assert(import_stack_ptr == 0); + if (yyin) fclose( yyin ); + yy_delete_buffer( YY_CURRENT_BUFFER );
input_name = acf_name; acf_name = NULL; @@ -595,7 +604,6 @@ static void switch_to_acf(void) if((f = fopen(name, "r")) == NULL) error_loc("Unable to open %s\n", name);
- import_stack[ptr].state = YY_CURRENT_BUFFER; yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); }
diff --git a/tools/widl/widl.c b/tools/widl/widl.c index 1bc52a2a3a2..f259f0abe20 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -871,8 +871,6 @@ int main(int argc,char *argv[]) init_types(); ret = parser_parse();
- fclose(parser_in); - if(ret) { exit(1); }
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/widl.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-)
diff --git a/tools/widl/widl.c b/tools/widl/widl.c index f259f0abe20..7ed3bfd1f8c 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -836,29 +836,20 @@ int main(int argc,char *argv[])
atexit(rm_tempfile); input = input_name; + if (preprocess_only) exit( wpp_parse( input_name, stdout ) ); + if (!no_preprocess) { - chat("Starting preprocess\n"); - - if (!preprocess_only) - { - FILE *output; - char *name = make_temp_file( header_name, NULL ); - - if (!(output = fopen(name, "wt"))) - error("Could not open fd %s for writing\n", name); + FILE *output; + char *name;
- ret = wpp_parse( input_name, output ); - fclose( output ); - input = name; - } - else - { - ret = wpp_parse( input_name, stdout ); - } + name = make_temp_file( header_name, NULL ); + if (!(output = fopen( name, "wt" ))) error( "Could not open fd %s for writing\n", name ); + ret = wpp_parse( input_name, output ); + fclose( output ); + input = name;
- if(ret) exit(1); - if(preprocess_only) exit(0); + if (ret) exit( 1 ); }
if(!(parser_in = fopen(input, "r"))) {
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/parser.h | 3 ++- tools/widl/parser.l | 51 ++++++++++----------------------------------- tools/widl/widl.c | 27 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 41 deletions(-)
diff --git a/tools/widl/parser.h b/tools/widl/parser.h index abe215de02f..81418fca160 100644 --- a/tools/widl/parser.h +++ b/tools/widl/parser.h @@ -37,6 +37,7 @@ int is_type(const char *name); int do_warning(const char *toggle, warning_list_t *wnum); int is_warning_enabled(int warning);
-extern char *temp_name; +extern char *find_input_file( const char *name, const char *parent ); +extern FILE *open_input_file( const char *path );
#endif diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 89383fe810e..92955516e9e 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -524,6 +524,7 @@ void pop_import(void) if (yyin) fclose( yyin ); yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( state->buffer ); + free( input_name ); input_name = state->input_name; line_number = state->line_number; free( state ); @@ -532,10 +533,8 @@ void pop_import(void) void push_import( char *import_name ) { struct import_state *state; - FILE *f; - char *path, *name; struct import *import; - int ret; + FILE *file;
state = xmalloc( sizeof(struct import_state )); list_add_head( &import_stack, &state->entry ); @@ -556,55 +555,27 @@ void push_import( char *import_name ) import->name = xstrdup( import_name ); list_add_tail( &imports, &import->entry );
- /* don't search for a file name with a path in the include directories, - * for compatibility with MIDL */ - if (strchr( import_name, '/' ) || strchr( import_name, '\' )) - path = xstrdup( import_name ); - else if (!(path = wpp_find_include( import_name, input_name ))) - error_loc( "Unable to open include file %s\n", import_name ); - - input_name = path; + input_name = find_input_file( import_name, input_name ); + file = open_input_file( input_name ); line_number = 1;
- name = make_temp_file( "widl-pp", NULL ); - if (!(f = fopen(name, "wt"))) - error("Could not open fd %s for writing\n", name); - - ret = wpp_parse( path, f ); - fclose( f ); - if (ret) exit(1); - - if((f = fopen(name, "r")) == NULL) - error_loc("Unable to open %s\n", name); - - yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); + yy_switch_to_buffer( yy_create_buffer( file, YY_BUF_SIZE ) ); }
static void switch_to_acf(void) { - char *name; - int ret; - FILE *f; + FILE *file;
if (yyin) fclose( yyin ); yy_delete_buffer( YY_CURRENT_BUFFER ); + free( input_name );
- input_name = acf_name; - acf_name = NULL; + input_name = xstrdup( acf_name ); + file = open_input_file( input_name ); line_number = 1; + acf_name = NULL;
- name = make_temp_file( "widl-acf", NULL ); - if (!(f = fopen(name, "wt"))) - error("Could not open fd %s for writing\n", name); - - ret = wpp_parse(input_name, f); - fclose(f); - if (ret) exit(1); - - if((f = fopen(name, "r")) == NULL) - error_loc("Unable to open %s\n", name); - - yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); + yy_switch_to_buffer( yy_create_buffer( file, YY_BUF_SIZE ) ); }
static void warning_disable(int warning) diff --git a/tools/widl/widl.c b/tools/widl/widl.c index 7ed3bfd1f8c..7c83b4b3ac0 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -893,3 +893,30 @@ static void rm_tempfile(void) unlink(typelib_name); remove_temp_files(); } + +char *find_input_file( const char *name, const char *parent ) +{ + char *path; + + /* don't search for a file name with a path in the include directories, for compatibility with MIDL */ + if (strchr( name, '/' ) || strchr( name, '\' )) path = xstrdup( name ); + else if (!(path = wpp_find_include( name, parent ))) error_loc( "Unable to open include file %s\n", name ); + + return path; +} + +FILE *open_input_file( const char *path ) +{ + FILE *file; + char *name; + int ret; + + name = make_temp_file( "widl", NULL ); + if (!(file = fopen( name, "wt" ))) error_loc( "Could not open %s for writing\n", name ); + ret = wpp_parse( path, file ); + fclose( file ); + if (ret) exit( 1 ); + + if (!(file = fopen( name, "r" ))) error_loc( "Unable to open %s\n", name ); + return file; +}
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/widl.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/widl/widl.c b/tools/widl/widl.c index 7c83b4b3ac0..513fbe507f7 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -911,6 +911,12 @@ FILE *open_input_file( const char *path ) char *name; int ret;
+ if (no_preprocess) + { + if (!(file = fopen( path, "r" ))) error_loc( "Unable to open %s\n", path ); + return file; + } + name = make_temp_file( "widl", NULL ); if (!(file = fopen( name, "wt" ))) error_loc( "Could not open %s for writing\n", name ); ret = wpp_parse( path, file );
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/widl.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-)
diff --git a/tools/widl/widl.c b/tools/widl/widl.c index 513fbe507f7..2cb1b59ac45 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -701,7 +701,6 @@ int main(int argc,char *argv[]) int i; int ret = 0; struct strarray files; - char *input;
init_signals( exit_on_signal ); init_argv0_dir( argv[0] ); @@ -835,27 +834,8 @@ int main(int argc,char *argv[]) wpp_add_cmdline_define("_WIN32=1");
atexit(rm_tempfile); - input = input_name; if (preprocess_only) exit( wpp_parse( input_name, stdout ) ); - - if (!no_preprocess) - { - FILE *output; - char *name; - - name = make_temp_file( header_name, NULL ); - if (!(output = fopen( name, "wt" ))) error( "Could not open fd %s for writing\n", name ); - ret = wpp_parse( input_name, output ); - fclose( output ); - input = name; - - if (ret) exit( 1 ); - } - - if(!(parser_in = fopen(input, "r"))) { - fprintf(stderr, "Could not open %s for input\n", input); - return 1; - } + parser_in = open_input_file( input_name );
header_token = make_token(header_name);
Jacek Caban (@jacek) commented about tools/widl/widl.c:
char *name; int ret;
- if (no_preprocess)
- {
if (!(file = fopen( path, "r" ))) error_loc( "Unable to open %s\n", path );
return file;
- }
What's the reason for that? I'm not sure how useful -N is in the first place, but allowing importing IDLs that require preprocessing does not seem wrong.
On Wed Mar 15 16:32:04 2023 +0000, Jacek Caban wrote:
What's the reason for that? I'm not sure how useful -N is in the first place, but allowing importing IDLs that require preprocessing does not seem wrong.
I don't know if it's very useful either, but I believe (though it's been a long time since I checked this) that it is how MIDL behaves: when preprocessing is disabled it is disabled globally.
It's mostly there to use `open_input_file` for the main file in the next change.
On Wed Mar 15 17:28:17 2023 +0000, Rémi Bernon wrote:
I don't know if it's very useful either, but I believe (though it's been a long time since I checked this) that it is how MIDL behaves: when preprocessing is disabled it is disabled globally. It's mostly there to use `open_input_file` for the main file in the next change.
What's the midl option for disabling preprocessor? I couldn't find it.
Note that this change can potentially break working reasonable scenarios, like importing SDK IDLs in a IDL file that doesn't use preprocessor and then building it with -N. It's probably not a big deal as I don't expect -N to be popular, but if using the helper in main is the only reason for the change, I'd suggest to handle no_preprocess in main instead. You may still use the helper for the rest of the job.
What's the midl option for disabling preprocessor? I couldn't find it.
It's `-nocpp`.
Note that this change can potentially break working reasonable scenarios, like importing SDK IDLs in a IDL file that doesn't use preprocessor and then building it with -N. It's probably not a big deal as I don't expect -N to be popular, but if using the helper in main is the only reason for the change, I'd suggest to handle no_preprocess in main instead. You may still use the helper for the rest of the job.
Sure, makes sense.
On Thu Mar 16 12:32:40 2023 +0000, Rémi Bernon wrote:
What's the midl option for disabling preprocessor? I couldn't find it.
It's `-nocpp`.
Note that this change can potentially break working reasonable
scenarios, like importing SDK IDLs in a IDL file that doesn't use preprocessor and then building it with -N. It's probably not a big deal as I don't expect -N to be popular, but if using the helper in main is the only reason for the change, I'd suggest to handle no_preprocess in main instead. You may still use the helper for the rest of the job. Sure, makes sense.
Fwiw that midl option is handy to run it without a full compiler tool suite. For instance like I wanted to do -and which I still believe we should do- to test IDL compilation, while keeping `import` mechanism working.
On Thu Mar 16 12:56:08 2023 +0000, Rémi Bernon wrote:
Fwiw that midl option is handy to run it without a full compiler tool suite. For instance like I wanted to do -and which I still believe we should do- to test IDL compilation, while keeping `import` mechanism working.
Okay, I see, midl indeed disables preprocessing entirely. Fine with me then.
This merge request was approved by Jacek Caban.