diff --git a/CHANGES.current b/CHANGES.current index 926096cab..4c1e55bc0 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,16 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.10 (in progress) ============================ +2013-04-18: wsfulton + Fix SF Bug #428 - Syntax error when preprocessor macros are defined inside of enum lists, such as: + + typedef enum { + eZero = 0 + #define ONE 1 + } EFoo; + + The macros are silently ignored. + 2013-04-17: wsfulton [C#] Pull patch #34 from BrantKyser to fix smart pointers in conjuction with directors. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 83be90d2d..793055097 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -514,6 +514,7 @@ C_TEST_CASES += \ empty \ enums \ enum_forward \ + enum_macro \ extern_declaration \ funcptr \ function_typedef \ diff --git a/Examples/test-suite/enum_macro.i b/Examples/test-suite/enum_macro.i new file mode 100644 index 000000000..b18e02a84 --- /dev/null +++ b/Examples/test-suite/enum_macro.i @@ -0,0 +1,92 @@ +%module enum_macro + +%inline %{ +enum Greeks1 +{ +#define GREEK1 -1 + alpha1=1, + beta1, + theta1 +}; + +enum Greeks2 +{ + alpha2 = 2, +#define GREEK2 -2 + beta2, + theta2 +}; + +enum Greeks3 +{ + alpha3, + beta3, +#define GREEK3 -3 + theta3 +}; + +enum Greeks4 +{ + alpha4 = 4, + beta4 = 5, + theta4 = 6 +#define GREEK4 -4 +}; + +enum Greeks5 +{ +#define GREEK5 -5 + alpha5, + beta5, +}; + +enum Greeks6 +{ + alpha6, +#define GREEK6 -6 + beta6, +}; + +enum Greeks7 +{ + alpha7, + beta7, +#define GREEK7 -7 +}; + +enum Greeks8 +{ +#define GREEK8 -8 + theta8 +}; + +enum Greeks9 +{ + theta9 +#define GREEK9 -9 +}; + +enum Greeks10 +{ +#define GREEK10 -10 + theta10, +}; + +enum Greeks11 +{ + theta11, +#define GREEK11 -11 +}; + +typedef enum { + theta12 = 0 +#define GREEK12 -12 +} Greeks12; +%} + + +enum Greeks13 +{ +#define GREEK13 -13 +}; + diff --git a/Examples/test-suite/java/enum_macro_runme.java b/Examples/test-suite/java/enum_macro_runme.java new file mode 100644 index 000000000..4ac7409ee --- /dev/null +++ b/Examples/test-suite/java/enum_macro_runme.java @@ -0,0 +1,93 @@ + +import enum_macro.*; + +public class enum_macro_runme { + + static { + try { + System.loadLibrary("enum_macro"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) + { + { + Greeks1 a = Greeks1.alpha1; + a = Greeks1.beta1; + a = Greeks1.theta1; + if (a.swigValue() != 3) + throw new RuntimeException("Greeks1"); + } + { + Greeks2 a = Greeks2.alpha2; + a = Greeks2.beta2; + a = Greeks2.theta2; + if (a.swigValue() != 4) + throw new RuntimeException("Greeks2"); + } + { + Greeks3 a = Greeks3.alpha3; + a = Greeks3.beta3; + a = Greeks3.theta3; + if (a.swigValue() != 2) + throw new RuntimeException("Greeks3"); + } + { + Greeks4 a = Greeks4.alpha4; + a = Greeks4.beta4; + a = Greeks4.theta4; + if (a.swigValue() != 6) + throw new RuntimeException("Greeks4"); + } + { + Greeks5 a = Greeks5.alpha5; + a = Greeks5.beta5; + if (a.swigValue() != 1) + throw new RuntimeException("Greeks5"); + } + { + Greeks6 a = Greeks6.alpha6; + a = Greeks6.beta6; + if (a.swigValue() != 1) + throw new RuntimeException("Greeks6"); + } + { + Greeks7 a = Greeks7.alpha7; + a = Greeks7.beta7; + if (a.swigValue() != 1) + throw new RuntimeException("Greeks7"); + } + { + Greeks8 a = Greeks8.theta8; + if (a.swigValue() != 0) + throw new RuntimeException("Greeks8"); + } + { + Greeks9 a = Greeks9.theta9; + if (a.swigValue() != 0) + throw new RuntimeException("Greeks9"); + } + { + Greeks10 a = Greeks10.theta10; + if (a.swigValue() != 0) + throw new RuntimeException("Greeks10"); + } + { + Greeks11 a = Greeks11.theta11; + if (a.swigValue() != 0) + throw new RuntimeException("Greeks11"); + } + { + Greeks12 a = Greeks12.theta12; + if (a.swigValue() != 0) + throw new RuntimeException("Greeks12"); + } + { + Greeks13 a = null; + } + } +} + diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 74d41079c..92c518e1f 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1788,6 +1788,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) { %type type_specifier primitive_type_list ; %type fname stringtype; %type featattr; +%type optional_constant_directive; %% @@ -5647,29 +5648,31 @@ definetype : { /* scanner_check_typedef(); */ } expr { /* Some stuff for handling enums */ ename : ID { $$ = $1; } - | empty { $$ = (char *) 0;} - ; + | empty { $$ = (char *) 0;} + ; -enumlist : enumlist COMMA edecl { +optional_constant_directive : constant_directive { $$ = $1; } + | empty { $$ = 0; } + ; - /* Ignore if there is a trailing comma in the enum list */ - if ($3) { - Node *leftSibling = Getattr($1,"_last"); - if (!leftSibling) { - leftSibling=$1; - } - set_nextSibling(leftSibling,$3); - Setattr($1,"_last",$3); - } - $$ = $1; - } - | edecl { - $$ = $1; - if ($1) { - Setattr($1,"_last",$1); - } - } - ; +/* Enum lists - any #define macros (constant directives) within the enum list are ignored. Trailing commas accepted. */ +enumlist : enumlist COMMA optional_constant_directive edecl optional_constant_directive { + Node *leftSibling = Getattr($1,"_last"); + set_nextSibling(leftSibling,$4); + Setattr($1,"_last",$4); + $$ = $1; + } + | enumlist COMMA optional_constant_directive { + $$ = $1; + } + | optional_constant_directive edecl optional_constant_directive { + Setattr($2,"_last",$2); + $$ = $2; + } + | optional_constant_directive { + $$ = 0; + } + ; edecl : ID { SwigType *type = NewSwigType(T_INT); @@ -5689,7 +5692,6 @@ edecl : ID { Setattr($$,"value",$1); Delete(type); } - | empty { $$ = 0; } ; etype : expr {