Merge branch 'char-escaping'

* char-escaping:
  Add missing string_constant.i testcase
  changes file update for char wrappers
  C# char wrappers fixes for enum values, static const member char values and %csconst
  D testing added for %dmanifestconst and char constants
  Fix wrapping D constants using %dmanifestconst
  Php fix for enum value of '\0'
  Fix static const char member variables wrappers with %javaconst(1).
  Expand char testing in enums and %constant
  Java char changes file update
  Java enum and static member variable escaping fix for chars
  Add tests for enum values and static const member variables chars containing escape sequences
  Minor documentation tweak

Conflicts:
	CHANGES.current
This commit is contained in:
William S Fulton 2016-03-12 23:27:51 +00:00
commit ac495d5c66
15 changed files with 355 additions and 23 deletions

View file

@ -5,6 +5,26 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.9 (in progress)
===========================
2016-03-12: wsfulton
[Java, C#, D] Fix static const char member variables wrappers with %javaconst(1)
%csconst(1) or %dmanifestconst.
This fixes the case when an integer is used as the initializer, such as:
struct W { static const char w = 100; };
Fix generated code parsing enum values using char escape sequences
when these values appear in the Java code (usually when using %javaconst(1))
such as:
enum X { x1 = '\n', x2 = '\1' };
Similarly for static const member char variables such as:
struct Y { static const char y = '\n'; }
Likewise for D and %dmanifestconstant. For C# and %csconst(1), char
values in C# are now hex escaped as C# doesn't support C octal escaping.
2016-03-11: wsfulton
[Java C#] Add support for treating C++ base classes as Java interfaces
instead of Java proxy classes. This enable some sort of support for

View file

@ -2289,7 +2289,7 @@ The <tt>jniclasscode</tt> pragma is quite useful for adding in a static block fo
%pragma(java) jniclasscode=%{
static {
try {
System.loadLibrary("example");
System.loadLibrary("example");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. \n" + e);
System.exit(1);

View file

@ -12,6 +12,36 @@
#define ESC_CONST '\1'
#define NULL_CONST '\0'
#define SPECIALCHAR 'á'
#define SPECIALCHAR2 '\n'
#define SPECIALCHARA 'A'
#define SPECIALCHARB '\102' // B
#define SPECIALCHARC '\x43' // C
#define SPECIALCHARD 0x44 // D
#define SPECIALCHARE 69 // E
#define SPECIALCHARAE1 'Æ' // AE (latin1 encoded)
#define SPECIALCHARAE2 '\306' // AE (latin1 encoded)
#define SPECIALCHARAE3 '\xC6' // AE (latin1 encoded)
#if defined(SWIGJAVA)
%javaconst(1);
#elif SWIGCSHARP
%csconst(1);
#elif SWIGD
%dmanifestconst;
#endif
#define X_ESC_CONST '\1'
#define X_NULL_CONST '\0'
#define X_SPECIALCHAR 'á'
#define X_SPECIALCHAR2 '\n'
#define X_SPECIALCHARA 'A'
#define X_SPECIALCHARB '\102' // B
#define X_SPECIALCHARC '\x43' // C
#define X_SPECIALCHARD 0x44 // D
#define X_SPECIALCHARE 69 // E
#define X_SPECIALCHARAE1 'Æ' // AE (latin1 encoded)
#define X_SPECIALCHARAE2 '\306' // AE (latin1 encoded)
#define X_SPECIALCHARAE3 '\xC6' // AE (latin1 encoded)
%inline
{

View file

@ -12,4 +12,65 @@ char GetUnprintableChar() {
return 0x7F;
}
static const char globchar0 = '\0';
static const char globchar1 = '\1';
static const char globchar2 = '\n';
static const char globcharA = 'A';
static const char globcharB = '\102'; // B
static const char globcharC = '\x43'; // C
static const char globcharD = 0x44; // D
static const char globcharE = 69; // E
static const char globcharAE1 = 'Æ'; // AE (latin1 encoded)
static const char globcharAE2 = '\306'; // AE (latin1 encoded)
static const char globcharAE3 = '\xC6'; // AE (latin1 encoded)
struct CharTestClass {
static const char memberchar0 = '\0';
static const char memberchar1 = '\1';
static const char memberchar2 = '\n';
static const char membercharA = 'A';
static const char membercharB = '\102'; // B
static const char membercharC = '\x43'; // C
static const char membercharD = 0x44; // D
static const char membercharE = 69; // E
static const char membercharAE1 = 'Æ'; // AE (latin1 encoded)
static const char membercharAE2 = '\306'; // AE (latin1 encoded)
static const char membercharAE3 = '\xC6'; // AE (latin1 encoded)
};
%}
#if defined(SWIGJAVA)
%javaconst(1);
#elif SWIGCSHARP
%csconst(1);
#elif SWIGD
%dmanifestconst;
#endif
%inline %{
static const char x_globchar0 = '\0';
static const char x_globchar1 = '\1';
static const char x_globchar2 = '\n';
static const char x_globcharA = 'A';
static const char x_globcharB = '\102'; // B
static const char x_globcharC = '\x43'; // C
static const char x_globcharD = 0x44; // D
static const char x_globcharE = 69; // E
static const char x_globcharAE1 = 'Æ'; // AE (latin1 encoded)
static const char x_globcharAE2 = '\306'; // AE (latin1 encoded)
static const char x_globcharAE3 = '\xC6'; // AE (latin1 encoded)
struct X_CharTestClass {
static const char memberchar0 = '\0';
static const char memberchar1 = '\1';
static const char memberchar2 = '\n';
static const char membercharA = 'A';
static const char membercharB = '\102'; // B
static const char membercharC = '\x43'; // C
static const char membercharD = 0x44; // D
static const char membercharE = 69; // E
static const char membercharAE1 = 'Æ'; // AE (latin1 encoded)
static const char membercharAE2 = '\306'; // AE (latin1 encoded)
static const char membercharAE3 = '\xC6'; // AE (latin1 encoded)
};
%}

View file

@ -384,6 +384,7 @@ CPP_TEST_CASES += \
static_array_member \
static_const_member \
static_const_member_2 \
string_constants \
struct_initialization_cpp \
struct_value \
symbol_clash \

View file

@ -77,6 +77,10 @@
// char
char chartest1(char c = 'x') { return c; }
char chartest2(char c = '\0') { return c; }
char chartest3(char c = '\1') { return c; }
char chartest4(char c = '\n') { return c; }
char chartest5(char c = '\102') { return c; } // 'B'
char chartest6(char c = '\x43') { return c; } // 'C'
// namespaces
namespace AType {

View file

@ -585,7 +585,56 @@ enum {
};
int globalDifferentTypesTest(int n) { return n; }
}
%}
#if defined(SWIGCSHARP)
%csconstvalue("1") globalenumchar1;
%csconstvalue("'B'") globalenumcharB;
%csconstvalue("1") enumchar1;
%csconstvalue("'B'") enumcharB;
#endif
%inline %{
enum {
globalenumchar0 = '\0',
globalenumchar1 = '\1',
globalenumchar2 = '\n',
globalenumcharA = 'A',
globalenumcharB = '\102', // B
globalenumcharC = '\x43', // C
globalenumcharD = 0x44, // D
globalenumcharE = 69, // E
globalenumcharAE1 = 'Æ', // AE (latin1 encoded)
globalenumcharAE2 = '\306', // AE (latin1 encoded)
globalenumcharAE3 = '\xC6' // AE (latin1 encoded)
};
enum EnumChar {
enumchar0 = '\0',
enumchar1 = '\1',
enumchar2 = '\n',
enumcharA = 'A',
enumcharB = '\102', // B
enumcharC = '\x43', // C
enumcharD = 0x44, // D
enumcharE = 69, // E
enumcharAE1 = 'Æ', // AE (latin1 encoded)
enumcharAE2 = '\306', // AE (latin1 encoded)
enumcharAE3 = '\xC6' // AE (latin1 encoded)
};
struct EnumCharStruct {
enum EnumChar {
enumchar0 = '\0',
enumchar1 = '\1',
enumchar2 = '\n',
enumcharA = 'A',
enumcharB = '\102', // B
enumcharC = '\x43', // C
enumcharD = 0x44, // D
enumcharE = 69, // E
enumcharAE1 = 'Æ', // AE (latin1 encoded)
enumcharAE2 = '\306', // AE (latin1 encoded)
enumcharAE3 = '\xC6' // AE (latin1 encoded)
};
};
%}
#if defined(SWIGJAVA)
@ -594,6 +643,50 @@ int globalDifferentTypesTest(int n) { return n; }
%csconst(0);
#endif
%inline %{
enum {
x_globalenumchar0 = '\0',
x_globalenumchar1 = '\1',
x_globalenumchar2 = '\n',
x_globalenumcharA = 'A',
x_globalenumcharB = '\102', // B
x_globalenumcharC = '\x43', // C
x_globalenumcharD = 0x44, // D
x_globalenumcharE = 69, // E
x_globalenumcharAE1 = 'Æ', // AE (latin1 encoded)
x_globalenumcharAE2 = '\306', // AE (latin1 encoded)
x_globalenumcharAE3 = '\xC6' // AE (latin1 encoded)
};
enum X_EnumChar {
x_enumchar0 = '\0',
x_enumchar1 = '\1',
x_enumchar2 = '\n',
x_enumcharA = 'A',
x_enumcharB = '\102', // B
x_enumcharC = '\x43', // C
x_enumcharD = 0x44, // D
x_enumcharE = 69, // E
x_enumcharAE1 = 'Æ', // AE (latin1 encoded)
x_enumcharAE2 = '\306', // AE (latin1 encoded)
x_enumcharAE3 = '\xC6' // AE (latin1 encoded)
};
struct X_EnumCharStruct {
enum X_EnumChar {
enumchar0 = '\0',
enumchar1 = '\1',
enumchar2 = '\n',
enumcharA = 'A',
enumcharB = '\102', // B
enumcharC = '\x43', // C
enumcharD = 0x44, // D
enumcharE = 69, // E
enumcharAE1 = 'Æ', // AE (latin1 encoded)
enumcharAE2 = '\306', // AE (latin1 encoded)
enumcharAE3 = '\xC6' // AE (latin1 encoded)
};
};
%}
%inline %{
namespace DifferentSpace {
enum DifferentTypesNoConst {
@ -614,5 +707,4 @@ enum {
global_typedefaultint_noconst
};
}
%}

View file

@ -136,5 +136,23 @@ def run(module_name):
if default_args.CDA().cdefaultargs_test2() != 1:
raise RuntimeError
if default_args.chartest1() != 'x':
raise RuntimeError
if default_args.chartest2() != '\0':
raise RuntimeError
if default_args.chartest3() != '\1':
raise RuntimeError
if default_args.chartest4() != '\n':
raise RuntimeError
if default_args.chartest5() != 'B':
raise RuntimeError
if default_args.chartest6() != 'C':
raise RuntimeError
if __name__ == "__main__":
run('default_args')

View file

@ -0,0 +1,44 @@
%module string_constants
// Test unusual string constants
%warnfilter(SWIGWARN_TYPEMAP_CHARLEAK);
#if defined(SWIGCSHARP)
%csconst(1);
%csconstvalue("\"AEIOU\\n\"") SS1;
%csconstvalue("\"AEIOU\\n\"") SS2;
#endif
#if defined(SWIGJAVA)
%javaconst(1);
#endif
%inline %{
#define SS1 "ÆÎOU\n"
#define AA1 "A\rB\nC"
#define EE1 "\124\125\126"
#define XX1 "\x57\x58\x59"
#define ZS1 "\0"
#define ES1 ""
%}
%constant SS2="ÆÎOU\n";
%constant AA2="A\rB\nC";
%constant EE2="\124\125\126";
%constant XX2="\x57\x58\x59";
%constant ZS2="\0";
%constant ES2="";
%inline %{
static const char *SS3 = "ÆÎOU\n";
static const char *AA3 = "A\rB\nC";
static const char *EE3 = "\124\125\126";
static const char *XX3 = "\x57\x58\x59";
static const char *ZS3 = "\0";
static const char *ES3 = "";
struct things {
const char * defarguments1(const char *SS4 = "ÆÎOU\n") { return SS4; }
const char * defarguments2(const char *AA4 = "A\rB\nC") { return AA4; }
const char * defarguments3(const char *EE4 = "\124\125\126") { return EE4; }
const char * defarguments4(const char *XX4 = "\x57\x58\x59") { return XX4; }
const char * defarguments5(const char *ZS4 = "\0") { return ZS4; }
const char * defarguments6(const char *ES4 = "") { return ES4; }
};
%}

View file

@ -2926,6 +2926,14 @@ c_decl : storage_class type declarator initializer c_decl_tail {
Setattr($$,"throws",$4.throws);
Setattr($$,"throw",$4.throwf);
Setattr($$,"noexcept",$4.nexcept);
if ($4.val && $4.type) {
/* store initializer type as it might be different to the declared type */
SwigType *valuetype = NewSwigType($4.type);
if (Len(valuetype) > 0)
Setattr($$,"valuetype",valuetype);
else
Delete(valuetype);
}
if (!$5) {
if (Len(scanner_ccode)) {
String *code = Copy(scanner_ccode);

View file

@ -1320,7 +1320,7 @@ public:
const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
Setattr(n, "enumvalue", val);
} else if (swigtype == T_CHAR) {
String *val = NewStringf("'%s'", Getattr(n, "enumvalue"));
String *val = NewStringf("'%(hexescape)s'", Getattr(n, "enumvalue"));
Setattr(n, "enumvalue", val);
Delete(val);
}
@ -1444,6 +1444,7 @@ public:
virtual int constantWrapper(Node *n) {
String *symname = Getattr(n, "sym:name");
SwigType *t = Getattr(n, "type");
SwigType *valuetype = Getattr(n, "valuetype");
ParmList *l = Getattr(n, "parms");
String *tm;
String *return_type = NewString("");
@ -1496,13 +1497,15 @@ public:
Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t, 0));
}
// Default (octal) escaping is no good - change to hex escaped value
String *hexescaped_value = Getattr(n, "rawvalue") ? NewStringf("%(hexescape)s", Getattr(n, "rawvalue")) : 0;
// Add the stripped quotes back in
String *new_value = NewString("");
if (SwigType_type(t) == T_STRING) {
Printf(new_value, "\"%s\"", Copy(Getattr(n, "value")));
Printf(new_value, "\"%s\"", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value")));
Setattr(n, "value", new_value);
} else if (SwigType_type(t) == T_CHAR) {
Printf(new_value, "\'%s\'", Copy(Getattr(n, "value")));
Printf(new_value, "\'%s\'", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value")));
Setattr(n, "value", new_value);
}
@ -1543,10 +1546,14 @@ public:
} else {
// Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code
if (Getattr(n, "wrappedasconstant")) {
if (SwigType_type(t) == T_CHAR)
Printf(constants_code, "\'%s\';\n", Getattr(n, "staticmembervariableHandler:value"));
else
if (SwigType_type(t) == T_CHAR) {
if (SwigType_type(valuetype) == T_CHAR)
Printf(constants_code, "\'%(hexescape)s\';\n", Getattr(n, "staticmembervariableHandler:value"));
else
Printf(constants_code, "(char)%s;\n", Getattr(n, "staticmembervariableHandler:value"));
} else {
Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
}
} else {
Printf(constants_code, "%s;\n", Getattr(n, "value"));
}

View file

@ -910,7 +910,7 @@ public:
const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
Setattr(n, "enumvalue", val);
} else if (swigtype == T_CHAR) {
String *val = NewStringf("'%s'", Getattr(n, "enumvalue"));
String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue"));
Setattr(n, "enumvalue", val);
Delete(val);
}
@ -1423,6 +1423,7 @@ public:
String *constants_code = NewString("");
SwigType *t = Getattr(n, "type");
SwigType *valuetype = Getattr(n, "valuetype");
ParmList *l = Getattr(n, "parms");
// Attach the non-standard typemaps to the parameter list.
@ -1470,16 +1471,21 @@ public:
Printf(constants_code, "%s;\n", override_value);
} else {
// Just take the value from the C definition and hope it compiles in D.
String* value = Getattr(n, "wrappedasconstant") ?
Getattr(n, "staticmembervariableHandler:value") : Getattr(n, "value");
// Add the stripped quotes back in.
if (SwigType_type(t) == T_STRING) {
Printf(constants_code, "\"%s\";\n", value);
} else if (SwigType_type(t) == T_CHAR) {
Printf(constants_code, "\'%s\';\n", value);
if (Getattr(n, "wrappedasconstant")) {
if (SwigType_type(valuetype) == T_CHAR)
Printf(constants_code, "\'%(escape)s\';\n", Getattr(n, "staticmembervariableHandler:value"));
else
Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
} else {
Printf(constants_code, "%s;\n", value);
// Add the stripped quotes back in.
String* value = Getattr(n, "value");
if (SwigType_type(t) == T_STRING) {
Printf(constants_code, "\"%s\";\n", value);
} else if (SwigType_type(t) == T_CHAR) {
Printf(constants_code, "\'%s\';\n", value);
} else {
Printf(constants_code, "%s;\n", value);
}
}
}

View file

@ -1380,7 +1380,7 @@ public:
const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
Setattr(n, "enumvalue", val);
} else if (swigtype == T_CHAR) {
String *val = NewStringf("'%s'", Getattr(n, "enumvalue"));
String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue"));
Setattr(n, "enumvalue", val);
Delete(val);
}
@ -1486,6 +1486,7 @@ public:
virtual int constantWrapper(Node *n) {
String *symname = Getattr(n, "sym:name");
SwigType *t = Getattr(n, "type");
SwigType *valuetype = Getattr(n, "valuetype");
ParmList *l = Getattr(n, "parms");
String *tm;
String *return_type = NewString("");
@ -1577,8 +1578,8 @@ public:
} else {
// Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code
if (Getattr(n, "wrappedasconstant")) {
if (SwigType_type(t) == T_CHAR)
Printf(constants_code, "\'%s\';\n", Getattr(n, "staticmembervariableHandler:value"));
if (SwigType_type(valuetype) == T_CHAR)
Printf(constants_code, "\'%(escape)s\';\n", Getattr(n, "staticmembervariableHandler:value"));
else
Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
} else {

View file

@ -1904,7 +1904,7 @@ done:
enumvalue = GetChar(n, "enumvalueex");
}
if (enumvalue) {
if (enumvalue && *Char(enumvalue)) {
// Check for a simple constant expression which is valid in PHP.
// If we find one, initialise the const member with it; otherwise
// we initialise it using the C/C++ wrapped constant.
@ -1916,7 +1916,8 @@ done:
break;
}
}
if (!*p) set_to = enumvalue;
if (!*p)
set_to = enumvalue;
}
if (wrapping_member_constant) {

View file

@ -309,6 +309,7 @@ int Swig_storage_isstatic(Node *n) {
* Swig_string_escape()
*
* Takes a string object and produces a string with escape codes added to it.
* Octal escaping is used.
* ----------------------------------------------------------------------------- */
String *Swig_string_escape(String *s) {
@ -342,6 +343,43 @@ String *Swig_string_escape(String *s) {
return ns;
}
/* -----------------------------------------------------------------------------
* Swig_string_hexescape()
*
* Takes a string object and produces a string with escape codes added to it.
* Hex escaping is used.
* ----------------------------------------------------------------------------- */
String *Swig_string_hexescape(String *s) {
String *ns;
int c;
ns = NewStringEmpty();
while ((c = Getc(s)) != EOF) {
if (c == '\n') {
Printf(ns, "\\n");
} else if (c == '\r') {
Printf(ns, "\\r");
} else if (c == '\t') {
Printf(ns, "\\t");
} else if (c == '\\') {
Printf(ns, "\\\\");
} else if (c == '\'') {
Printf(ns, "\\'");
} else if (c == '\"') {
Printf(ns, "\\\"");
} else if (c == ' ') {
Putc(c, ns);
} else if (!isgraph(c)) {
if (c < 0)
c += UCHAR_MAX + 1;
Printf(ns, "\\x%X", c);
} else {
Putc(c, ns);
}
}
return ns;
}
/* -----------------------------------------------------------------------------
* Swig_string_upper()
@ -1425,6 +1463,7 @@ String *Swig_pcre_version(void) {
void Swig_init() {
/* Set some useful string encoding methods */
DohEncoding("escape", Swig_string_escape);
DohEncoding("hexescape", Swig_string_hexescape);
DohEncoding("upper", Swig_string_upper);
DohEncoding("lower", Swig_string_lower);
DohEncoding("title", Swig_string_title);