Fix %include inside %define macros - patch from Karl Wette

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12924 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2012-03-15 20:32:14 +00:00
parent 911ee91de1
commit 425b460a09
8 changed files with 82 additions and 7 deletions

View File

@ -5,6 +5,9 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.5 (in progress)
===========================
2012-03-13: wsfulton
Apply patch #3468362 to fix %include inside %define.
2012-03-13: wsfulton
[Python, Ruby, Octave] Fix #3475492 - iterating through std::vector wrappers of enumerations.

View File

@ -35,3 +35,18 @@ int multiply60(int a) { return a*60; }
int multiply70(int a) { return a*70; }
%}
%define nested_include_1(HEADER)
%include <HEADER>
%enddef
%define nested_include_2(HEADER)
nested_include_1(HEADER);
%enddef
%define nested_include_3(HEADER)
nested_include_2(HEADER);
%enddef
nested_include_1(preproc_include_h1.i);
nested_include_2(preproc_include_h2.i);
nested_include_3(preproc_include_h3.i);

View File

@ -0,0 +1 @@
#define const1 1

View File

@ -0,0 +1 @@
#define const2 2

View File

@ -0,0 +1 @@
#define const3 3

View File

@ -767,6 +767,10 @@ int yylex(void) {
}
if (strcmp(yytext, "%includefile") == 0)
return (INCLUDE);
if (strcmp(yytext, "%beginfile") == 0)
return (BEGINFILE);
if (strcmp(yytext, "%endoffile") == 0)
return (ENDOFFILE);
if (strcmp(yytext, "%val") == 0) {
Swig_warning(WARN_DEPRECATED_VAL, cparse_file, cparse_line, "%%val directive deprecated (ignored).\n");
return (yylex());

View File

@ -1644,6 +1644,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
%token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64
%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD
%token CONST_QUAL VOLATILE REGISTER STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET
%token BEGINFILE ENDOFFILE
%token ILLEGAL CONSTANT
%token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS
%token ENUM
@ -2110,7 +2111,7 @@ fragment_directive: FRAGMENT LPAREN fname COMMA kwargs RPAREN HBLOCK {
%importfile(option1="xyz", ...) "filename" [ declarations ]
------------------------------------------------------------ */
include_directive: includetype options string LBRACKET {
include_directive: includetype options string BEGINFILE {
$1.filename = Copy(cparse_file);
$1.line = cparse_line;
scanner_set_location(NewString($3),1);
@ -2119,7 +2120,7 @@ include_directive: includetype options string LBRACKET {
if (maininput)
scanner_set_main_input_file(NewString(maininput));
}
} interface RBRACKET {
} interface ENDOFFILE {
String *mname = 0;
$$ = $6;
scanner_set_location($1.filename,$1.line+1);

View File

@ -145,6 +145,7 @@ static String *kpp_dline = 0;
static String *kpp_ddefine = 0;
static String *kpp_dinclude = 0;
static String *kpp_dimport = 0;
static String *kpp_dbeginfile = 0;
static String *kpp_dextern = 0;
static String *kpp_LINE = 0;
@ -181,6 +182,7 @@ void Preprocessor_init(void) {
kpp_dinclude = NewString("%include");
kpp_dimport = NewString("%import");
kpp_dbeginfile = NewString("%beginfile");
kpp_dextern = NewString("%extern");
kpp_ddefine = NewString("%define");
kpp_dline = NewString("%line");
@ -229,6 +231,7 @@ void Preprocessor_delete(void) {
Delete(kpp_dinclude);
Delete(kpp_dimport);
Delete(kpp_dbeginfile);
Delete(kpp_dextern);
Delete(kpp_ddefine);
Delete(kpp_dline);
@ -1327,6 +1330,7 @@ String *Preprocessor_parse(String *s) {
int allow = 1;
int level = 0;
int dlevel = 0;
int filelevel = 0;
int mask = 0;
int start_level = 0;
int cpp_lines = 0;
@ -1715,9 +1719,9 @@ String *Preprocessor_parse(String *s) {
s1 = cpp_include(fn, sysfile);
if (s1) {
if (include_all)
Printf(ns, "%%includefile \"%s\" [\n", Swig_filename_escape(Swig_last_file()));
Printf(ns, "%%includefile \"%s\" %%beginfile\n", Swig_filename_escape(Swig_last_file()));
else if (import_all) {
Printf(ns, "%%importfile \"%s\" [\n", Swig_filename_escape(Swig_last_file()));
Printf(ns, "%%importfile \"%s\" %%beginfile\n", Swig_filename_escape(Swig_last_file()));
push_imported();
}
@ -1731,7 +1735,7 @@ String *Preprocessor_parse(String *s) {
}
s2 = Preprocessor_parse(s1);
addline(ns, s2, allow);
Append(ns, "]");
Append(ns, "%endoffile");
if (dirname) {
Swig_pop_directory();
}
@ -1859,7 +1863,7 @@ String *Preprocessor_parse(String *s) {
char *dirname;
copy_location(s, chunk);
add_chunk(ns, chunk, allow);
Printf(ns, "%sfile%s%s%s\"%s\" [\n", decl, options_whitespace, opt, filename_whitespace, Swig_filename_escape(Swig_last_file()));
Printf(ns, "%sfile%s%s%s\"%s\" %%beginfile\n", decl, options_whitespace, opt, filename_whitespace, Swig_filename_escape(Swig_last_file()));
if (Equal(decl, kpp_dimport)) {
push_imported();
}
@ -1878,7 +1882,7 @@ String *Preprocessor_parse(String *s) {
pop_imported();
}
addline(ns, s2, allow);
Append(ns, "]");
Append(ns, "%endoffile");
Delete(s2);
Delete(s1);
}
@ -1887,6 +1891,14 @@ String *Preprocessor_parse(String *s) {
Delete(options_whitespace);
}
state = 1;
} else if (Equal(decl, kpp_dbeginfile)) {
/* Got an internal directive marking the beginning of an included file: %beginfile ... %endoffile */
filelevel++;
start_line = Getline(s);
copy_location(s, chunk);
add_chunk(ns, chunk, allow);
Append(chunk, decl);
state = 120;
} else if (Equal(decl, kpp_dline)) {
/* Got a line directive */
state = 1;
@ -1907,6 +1919,40 @@ String *Preprocessor_parse(String *s) {
}
break;
/* Searching for the end of a %beginfile block */
case 120:
Putc(c, chunk);
if (c == '%') {
const char *bf = "beginfile";
const char *ef = "endoffile";
char statement[10];
int i = 0;
for (i = 0; i < 9;) {
c = Getc(s);
Putc(c, chunk);
statement[i++] = (char)c;
if (strncmp(statement, bf, i) && strncmp(statement, ef, i))
break;
}
c = Getc(s);
Ungetc(c, s);
if ((i == 9) && (isspace(c))) {
if (strncmp(statement, bf, i) == 0) {
++filelevel;
} else if (strncmp(statement, ef, i) == 0) {
--filelevel;
if (!filelevel) {
/* Reached end of included file */
addline(ns, chunk, allow);
Clear(chunk);
copy_location(s, chunk);
state = 1;
}
}
}
}
break;
/* Searching for the end of a %define statement */
case 150:
Putc(c, value);
@ -1957,6 +2003,9 @@ String *Preprocessor_parse(String *s) {
Swig_error(Getfile(s), -1, "Missing #endif for conditional starting on line %d\n", cond_lines[level - 1]);
level--;
}
if (state == 120) {
Swig_error(Getfile(s), -1, "Missing %%endoffile for file inclusion block starting on line %d\n", start_line);
}
if (state == 150) {
Seek(value, 0, SEEK_SET);
Swig_error(Getfile(s), -1, "Missing %%enddef for macro starting on line %d\n", Getline(value));