diff --git a/CHANGES.current b/CHANGES.current index d87daeec6..ce8efe1bf 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,12 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.1.0 (in progress) =========================== +2022-03-08: olly + #1006 SWIG now copes with an interface filename specified on the + command line which contains a closing parenthesis `)`, and more + generally with attributes to `%include` and `%import` which + are quoted and contain parentheses. + 2022-03-07: Omar Medina [Tcl] https://sourceforge.net/p/swig/bugs/1290/ Fix SWIG_AsWCharPtrAndSize() to actually assign to result diff --git a/Examples/test-suite/import_nomodule.i b/Examples/test-suite/import_nomodule.i index 48e119517..2794ad5f3 100644 --- a/Examples/test-suite/import_nomodule.i +++ b/Examples/test-suite/import_nomodule.i @@ -6,7 +6,9 @@ // For Python %warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Bar; // Base class 'Foo' ignored - unknown module name for base. Either import the appropriate module interface file or specify the name of the module in the %import directive. -%import "import_nomodule.h" +// The "dummy=" attribute is a regression test for #1006, fixed in SWIG 4.1.0. +// SWIG didn't used to take quoting into account when finding the closing `)`. +%import(dummy=")foo\"") "import_nomodule.h" #if !defined(SWIGJAVA) && !defined(SWIGRUBY) && !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGPYTHON_BUILTIN) && !defined(SWIGPHP) diff --git a/Source/Preprocessor/cpp.c b/Source/Preprocessor/cpp.c index 439788b4b..34ace2d77 100644 --- a/Source/Preprocessor/cpp.c +++ b/Source/Preprocessor/cpp.c @@ -741,14 +741,35 @@ static String *get_options(String *str) { opt = NewString("("); while (((c = Getc(str)) != EOF)) { Putc(c, opt); - if (c == ')') { - level--; - if (!level) - return opt; + switch (c) { + case ')': + level--; + if (!level) + return opt; + break; + case '(': + level++; + break; + case '"': + /* Skip over quoted strings */ + while (1) { + c = Getc(str); + if (c == EOF) + goto bad; + Putc(c, opt); + if (c == '"') + break; + if (c == '\\') { + c = Getc(str); + if (c == EOF) + goto bad; + Putc(c, opt); + } + } + break; } - if (c == '(') - level++; } +bad: Delete(opt); return 0; } else {