diff --git a/tools/widl/parser.l b/tools/widl/parser.l index a7bc76aa75c..5e9217a1efb 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -30,6 +30,7 @@ hex 0x{hexd}+ uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12} %x QUOTE +%x pp_line %{ @@ -69,6 +70,8 @@ static int kw_token(const char *kw); #define MAX_IMPORT_DEPTH 10 struct { YY_BUFFER_STATE state; + char *input_name; + int line_number; char *temp_name; } import_stack[MAX_IMPORT_DEPTH]; int import_stack_ptr = 0; @@ -103,7 +106,26 @@ static UUID* parse_uuid(const char*u) ************************************************************************** */ %% -^#.* +^{ws}*\#{ws}* yy_push_state(pp_line); +[^\n]* { + int lineno; + char *cptr, *fname; + yy_pop_state(); + lineno = (int)strtol(yytext, &cptr, 10); + if(!lineno) + yyerror("Malformed '#...' line-directive; invalid linenumber"); + fname = strchr(cptr, '"'); + if(!fname) + yyerror("Malformed '#...' line-directive; missing filename"); + fname++; + cptr = strchr(fname, '"'); + if(!cptr) + yyerror("Malformed '#...' line-directive; missing terminating \""); + *cptr = '\0'; + line_number = lineno - 1; /* We didn't read the newline */ + free( input_name ); + input_name = xstrdup(fname); + } \" yy_push_state(QUOTE); cbufidx = 0; \" { yy_pop_state(); @@ -127,7 +149,7 @@ static UUID* parse_uuid(const char*u) return aNUM; } {cident} return kw_token(yytext); -\n +\n line_number++; {ws} \<\< return SHL; \>\> return SHR; @@ -314,6 +336,9 @@ static void pop_import(void) free(temp_name); } temp_name = import_stack[ptr].temp_name; + free( input_name ); + input_name = import_stack[ptr].input_name; + line_number = import_stack[ptr].line_number; import_stack_ptr--; } @@ -325,14 +350,15 @@ struct imports { int do_import(char *fname) { FILE *f; - char *hname, *path; + char *hname, *path, *p; struct imports *import; int ptr = import_stack_ptr; int ret; if (!parse_only) { hname = dup_basename(fname, ".idl"); - strcat(hname, ".h"); + p = hname + strlen(hname) - 2; + if (p <= hname || strcmp( p, ".h" )) strcat(hname, ".h"); fprintf(header, "#include \"%s\"\n", hname); free(hname); @@ -352,10 +378,13 @@ int do_import(char *fname) yyerror("Unable to open include file %s", fname); import_stack[ptr].temp_name = temp_name; + import_stack[ptr].input_name = input_name; + import_stack[ptr].line_number = line_number; import_stack_ptr++; + input_name = path; + line_number = 1; ret = wpp_parse_temp( path, NULL, &temp_name ); - free( path ); if (ret) exit(1); if((f = fopen(temp_name, "r")) == NULL) diff --git a/tools/widl/utils.c b/tools/widl/utils.c index 0420e1c6d5d..c28d8173e67 100644 --- a/tools/widl/utils.c +++ b/tools/widl/utils.c @@ -50,7 +50,7 @@ void make_print(char *str) static void generic_msg(const char *s, const char *t, const char *n, va_list ap) { - fprintf(stderr, "%s:%d:%d: %s: ", input_name ? input_name : "stdin", line_number, char_number, t); + fprintf(stderr, "%s:%d: %s: ", input_name ? input_name : "stdin", line_number, t); vfprintf(stderr, s, ap); #ifdef WANT_NEAR_INDICATION { diff --git a/tools/widl/widl.c b/tools/widl/widl.c index 4678514cf1e..69bb83221ce 100644 --- a/tools/widl/widl.c +++ b/tools/widl/widl.c @@ -99,7 +99,6 @@ char *proxy_token; char *temp_name; int line_number = 1; -int char_number = 1; FILE *header; FILE *proxy; @@ -180,7 +179,7 @@ int main(int argc,char *argv[]) } if(optind < argc) { - input_name = argv[optind]; + input_name = xstrdup(argv[optind]); } else { fprintf(stderr, usage); @@ -266,7 +265,7 @@ int main(int argc,char *argv[]) if(ret) { exit(1); } - + header_name = NULL; return 0; } @@ -275,6 +274,8 @@ static void rm_tempfile(void) abort_import(); if(temp_name) unlink(temp_name); + if (header_name) + unlink( header_name ); } static void segvhandler(int sig)