Straighten out handling of char and string constants

Fixes #904
Fixes #1907
Fixes #2579
Fixes #2990
This commit is contained in:
Olly Betts 2024-08-17 16:12:11 +12:00
parent c6aca7eb08
commit 7a8c9fdfa8
33 changed files with 362 additions and 343 deletions

View File

@ -7,6 +7,9 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.3.0 (in progress)
===========================
2024-08-17: olly
#904 #1907 #2579 Fix string literal and character literal wrapping bugs.
2024-08-15: olly
Fix parsing of octal string escapes. We now stop when the next
character is digit 8 or 9, and stop after 3 octal digits even if

View File

@ -21,6 +21,7 @@
#define SPECIALCHARAE1 'Æ' // AE (latin1 encoded)
#define SPECIALCHARAE2 '\306' // AE (latin1 encoded)
#define SPECIALCHARAE3 '\xC6' // AE (latin1 encoded)
#define SPECIALCHARPAREN (';')
#if defined(SWIGJAVA)
%javaconst(1);
@ -42,9 +43,11 @@
#define X_SPECIALCHARAE1 'Æ' // AE (latin1 encoded)
#define X_SPECIALCHARAE2 '\306' // AE (latin1 encoded)
#define X_SPECIALCHARAE3 '\xC6' // AE (latin1 encoded)
#define X_SPECIALCHARPAREN (';')
%inline
{
const int ia = (int)'a';
const int ib = 'b';
const int iparen = (';');
}

View File

@ -64,3 +64,6 @@ public:
std::is_trivially_destructible<T>::value>
test_alignof_too;
};
%constant int WSTRING_LIT_LEN1 = (sizeof(L"1234")/sizeof(wchar_t) - 1);
%constant int WSTRING_LIT_LEN2 = (sizeof(L"12" L"34")/sizeof(wchar_t) - 1);

View File

@ -49,6 +49,13 @@ static constexpr auto Bad4 = &one;
%}
%inline %{
// Concatenation of a literal with an encoding prefix and one without
// was added in C++11.
static auto wstring_lit_len1 = sizeof(L"123" "456") / sizeof(wchar_t) - 1;
static auto wstring_lit_len2 = sizeof("123" L"456") / sizeof(wchar_t) - 1;
%}
%inline %{
// FIXME: Not currently handled by SWIG's parser:

View File

@ -0,0 +1,13 @@
using System;
using string_constantsNamespace;
public class runme {
static void Main() {
assert( string_constants.QQ1 == "\x000800! \x00018b00!" );
assert( string_constants.QQ2 == "\x000800! \x00018b00!" );
}
static void assert(bool assertion) {
if (!assertion)
throw new ApplicationException("test failed");
}
}

View File

@ -18,4 +18,8 @@ struct A
// SWIG 4.2.0 and earlier.
int g(int b = (compl 1 or not 2) xor (3 and 4) xor (3 bitand 6) xor (3 bitor 5) xor (2 + 2 not_eq 5)) { return b; }
};
const unsigned char LASTCHAR1 = "hello world"[sizeof"hello world" - 2];
const unsigned char LASTCHAR2 = "bye"[sizeof("bye") - 2];
%}

View File

@ -174,3 +174,16 @@ public:
}
%}
#if defined(SWIGJAVA)
%javaconst(1);
#elif SWIGCSHARP
%csconst(1);
#elif SWIGD
%dmanifestconst;
#endif
%inline %{
const std::string aString = "something";
%}
%constant std::string MY_STRING = "";
%constant std::string MY_STRING_2 = "OK";

View File

@ -15,4 +15,7 @@ check::equal(YY, yy());
check::equal(constant_expr::XX, constant_expr::xx());
check::equal(constant_expr::YY, constant_expr::yy());
check::equal(WSTRING_LIT_LEN1, 4);
check::equal(WSTRING_LIT_LEN2, 4);
check::done();

View File

@ -5,7 +5,7 @@ require "tests.php";
// No new functions
check::functions(array());
check::classes(array('cpp11_auto_variable'));
check::globals(array('f', 't', 'zero', 'one', 'la', 'da', 'fa', 'lc', 'dc', 'fc', 'pi_approx', 'Bar', 'Bar2', 'Bar3', 'Foo', 'Foo2', 'Foo3', 'NOEXCEPT_FUNC'));
check::globals(array('f', 't', 'zero', 'one', 'la', 'da', 'fa', 'lc', 'dc', 'fc', 'pi_approx', 'wstring_lit_len1', 'wstring_lit_len2', 'Bar', 'Bar2', 'Bar3', 'Foo', 'Foo2', 'Foo3', 'NOEXCEPT_FUNC'));
check::equal(f_get(), false);
check::equal(gettype(f_get()), "boolean");
@ -38,3 +38,6 @@ check::equal(dc_get(), 1.0);
// PHP doesn't have a native "long double" type, so SWIG/PHP doesn't have
// typemaps for it and so it should get wrapped as an opaque type.
check::str_contains(lc_get(), "SWIGPointer(");
check::equal(wstring_lit_len1_get(), 6);
check::equal(wstring_lit_len2_get(), 6);

View File

@ -19,6 +19,7 @@
#define ZS1 "\0"
#define ES1 ""
#define QQ1 "\b00! \18\14200!"
#define PR1 ("paren")
%}
%constant SS2="ÆÎOU\n";
%constant AA2="A\rB\nC";
@ -27,6 +28,7 @@
%constant ZS2="\0";
%constant ES2="";
%constant QQ2="\b00! \18\14200!";
%constant PR2=("paren");
%inline %{
static const char *SS3 = "ÆÎOU\n";
@ -36,6 +38,7 @@ static const char *XX3 = "\x57\x58\x59";
static const char *ZS3 = "\0";
static const char *ES3 = "";
static const char *QQ3 = "\b00! \18\14200!";
static const char *PR3 = ("paren");
struct things {
const char * defarguments1(const char *SS4 = "ÆÎOU\n") { return SS4; }
const char * defarguments2(const char *AA4 = "A\rB\nC") { return AA4; }
@ -44,5 +47,6 @@ struct things {
const char * defarguments5(const char *ZS4 = "\0") { return ZS4; }
const char * defarguments6(const char *ES4 = "") { return ES4; }
const char * defarguments7(const char *QQ4 = "\b00! \18\14200!") { return QQ4; }
const char * defarguments8(const char *PR4 = ("paren")) { return PR4; }
};
%}

View File

@ -80,6 +80,4 @@ extern "C" {
if (wrnfilter) Swig_warnfilter(wrnfilter,0); \
}
#define COMPOUND_EXPR_VAL(dtype) \
((dtype).type == T_CHAR || (dtype).type == T_WCHAR ? (dtype).rawval : (dtype).val)
#endif

View File

@ -1609,8 +1609,54 @@ static String *add_qualifier_to_declarator(SwigType *type, SwigType *qualifier)
const char *id;
List *bases;
struct Define {
// The value of the expression as C/C++ code.
String *val;
String *rawval;
// If type is a string or char type, this is the actual value of that
// string or char type as a String. This is useful in cases where we
// want to emit the string in the target language - we could just try
// emitting the C/C++ code for the literal, but that won't always be
// a valid string literal in most target languages.
//
// SWIG's scanner reads the string or character literal in the source code
// and interprets quoting and escape sequences. Concatenation of adjacent
// string literals is currently handled here in the parser (though
// technically it should happen before parsing).
//
// stringval holds the actual value of the string (from the scanner,
// taking into account concatenation of adjacent string literals).
// Then val is created by escaping stringval using SWIG's %(escape)s
// Printf specification, and adding the appropriate quotes (and
// an L-prefix for wide literals). So val is also a C/C++ source
// representation of the string, but may not be the same representation
// as in the source code (it should be equivalent though).
//
// Some examples:
//
// C/C++ source stringval val Notes
// ------------- ----------- --------- -------
// "bar" bar "bar"
// "b\x61r" bar "bar"
// "b\141r" bar "bar"
// "b" "ar" bar "bar"
// u8"bar" bar "bar" C++11
// R"bar" bar "bar" C++11
// "\228\22" "8" "\"8\""
// "\\\"\'" \"' "\\\"\'"
// R"(\"')" \"' "\\\"\'" C++11
// L"bar" bar L"bar"
// L"b" L"ar" bar L"bar"
// L"b" "ar" bar L"bar" C++11
// "b" L"ar" bar L"bar" C++11
// 'x' x 'x'
// '\"' " '\"'
// '\42' " '\"'
// '\042' " '\"'
// '\x22' " '\"'
//
// Zero bytes are allowed in stringval (DOH's String can hold a string
// with embedded zero bytes), but handling may currently be buggy in
// places.
String *stringval;
int type;
/* The type code for the argument when the top level operator is unary.
* This is useful because our grammar parses cases such as (7)*6 as a
@ -2054,7 +2100,7 @@ constant_directive : CONSTANT identifier EQUAL definetype SEMI {
Setattr($$, "name", $identifier);
Setattr($$, "type", type);
Setattr($$, "value", $definetype.val);
if ($definetype.rawval) Setattr($$, "rawval", $definetype.rawval);
if ($definetype.stringval) Setattr($$, "stringval", $definetype.stringval);
Setattr($$, "storage", "%constant");
SetFlag($$, "feature:immutable");
add_symbols($$);
@ -2074,7 +2120,7 @@ constant_directive : CONSTANT identifier EQUAL definetype SEMI {
Setattr($$, "name", $declarator.id);
Setattr($$, "type", $type);
Setattr($$, "value", $def_args.val);
if ($def_args.rawval) Setattr($$, "rawval", $def_args.rawval);
if ($def_args.stringval) Setattr($$, "stringval", $def_args.stringval);
Setattr($$, "storage", "%constant");
SetFlag($$, "feature:immutable");
add_symbols($$);
@ -2093,7 +2139,7 @@ constant_directive : CONSTANT identifier EQUAL definetype SEMI {
Setattr($$, "name", $direct_declarator.id);
Setattr($$, "type", $type);
Setattr($$, "value", $def_args.val);
if ($def_args.rawval) Setattr($$, "rawval", $def_args.rawval);
if ($def_args.stringval) Setattr($$, "stringval", $def_args.stringval);
Setattr($$, "storage", "%constant");
SetFlag($$, "feature:immutable");
add_symbols($$);
@ -3186,6 +3232,7 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail {
Setattr($$,"decl",decl);
Setattr($$,"parms",$declarator.parms);
Setattr($$,"value",$initializer.val);
if ($initializer.stringval) Setattr($$, "stringval", $initializer.stringval);
Setattr($$,"throws",$cpp_const.throws);
Setattr($$,"throw",$cpp_const.throwf);
Setattr($$,"noexcept",$cpp_const.nexcept);
@ -3416,6 +3463,7 @@ c_decl : storage_class type declarator cpp_const initializer c_decl_tail {
Setattr($$, "name", $idcolon);
Setattr($$, "decl", NewStringEmpty());
Setattr($$, "value", $definetype.val);
if ($definetype.stringval) Setattr($$, "stringval", $definetype.stringval);
Setattr($$, "valuetype", type);
}
;
@ -3434,6 +3482,7 @@ c_decl_tail : SEMI {
Setattr($$,"decl",$declarator.type);
Setattr($$,"parms",$declarator.parms);
Setattr($$,"value",$initializer.val);
if ($initializer.stringval) Setattr($$, "stringval", $initializer.stringval);
Setattr($$,"throws",$cpp_const.throws);
Setattr($$,"throw",$cpp_const.throwf);
Setattr($$,"noexcept",$cpp_const.nexcept);
@ -4458,7 +4507,8 @@ templateparameter : templcpptype def_args {
$$ = NewParmWithoutFileLineInfo($templcpptype, 0);
Setfile($$, cparse_file);
Setline($$, cparse_line);
Setattr($$, "value", $def_args.rawval ? $def_args.rawval : $def_args.val);
Setattr($$, "value", $def_args.val);
if ($def_args.stringval) Setattr($$, "stringval", $def_args.stringval);
}
| TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon def_args {
$$ = NewParmWithoutFileLineInfo(NewStringf("template< %s > %s %s", ParmList_str_defaultargs($template_parms), $cpptype, $idcolon), $idcolon);
@ -5259,6 +5309,7 @@ valparm : parm {
Setfile($$,cparse_file);
Setline($$,cparse_line);
Setattr($$,"value",$valexpr.val);
if ($valexpr.stringval) Setattr($$, "stringval", $valexpr.stringval);
}
;
@ -5286,7 +5337,7 @@ def_args : EQUAL definetype {
| EQUAL LBRACE {
if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
$$.val = NewString(scanner_ccode);
$$.rawval = 0;
$$.stringval = 0;
$$.type = T_UNKNOWN;
$$.unary_arg_type = 0;
$$.bitfield = 0;
@ -5297,7 +5348,7 @@ def_args : EQUAL definetype {
}
| COLON expr {
$$.val = 0;
$$.rawval = 0;
$$.stringval = 0;
$$.type = 0;
$$.bitfield = $expr.val;
$$.throws = 0;
@ -5307,7 +5358,7 @@ def_args : EQUAL definetype {
}
| %empty {
$$.val = 0;
$$.rawval = 0;
$$.stringval = 0;
$$.type = T_UNKNOWN;
$$.unary_arg_type = 0;
$$.bitfield = 0;
@ -5320,16 +5371,16 @@ def_args : EQUAL definetype {
parameter_declarator : declarator def_args {
$$ = $declarator;
$$.defarg = $def_args.rawval ? $def_args.rawval : $def_args.val;
$$.defarg = $def_args.val;
}
| abstract_declarator def_args {
$$ = $abstract_declarator;
$$.defarg = $def_args.rawval ? $def_args.rawval : $def_args.val;
$$.defarg = $def_args.val;
}
| def_args {
$$.type = 0;
$$.id = 0;
$$.defarg = $def_args.rawval ? $def_args.rawval : $def_args.val;
$$.defarg = $def_args.val;
}
/* Member function pointers with qualifiers. eg.
int f(short (Funcs::*parm)(bool) const); */
@ -6373,11 +6424,6 @@ type_specifier : TYPE_INT {
definetype : expr {
$$ = $expr;
if ($$.type == T_STRING) {
$$.rawval = NewStringf("\"%(escape)s\"",$$.val);
} else if ($$.type != T_CHAR && $$.type != T_WSTRING && $$.type != T_WCHAR) {
$$.rawval = NewStringf("%s", $$.val);
}
$$.qualifier = 0;
$$.refqualifier = 0;
$$.bitfield = 0;
@ -6396,7 +6442,7 @@ default_delete : deleted_definition
/* For C++ deleted definition '= delete' */
deleted_definition : DELETE_KW {
$$.val = NewString("delete");
$$.rawval = 0;
$$.stringval = 0;
$$.type = T_STRING;
$$.unary_arg_type = 0;
$$.qualifier = 0;
@ -6412,7 +6458,7 @@ deleted_definition : DELETE_KW {
/* For C++ explicitly defaulted functions '= default' */
explicit_default : DEFAULT {
$$.val = NewString("default");
$$.rawval = 0;
$$.stringval = 0;
$$.type = T_STRING;
$$.unary_arg_type = 0;
$$.qualifier = 0;
@ -6526,6 +6572,9 @@ edecl : identifier {
Setattr($$,"type",type);
SetFlag($$,"feature:immutable");
Setattr($$,"enumvalue", $etype.val);
if ($etype.stringval) {
Setattr($$, "enumstringval", $etype.stringval);
}
Setattr($$,"value",$identifier);
Delete(type);
}
@ -6615,10 +6664,40 @@ exprmem : ID[lhs] ARROW ID[rhs] {
exprsimple : exprnum
| exprmem
| string {
$$.val = $string;
$$.type = T_STRING;
$$.unary_arg_type = 0;
}
$$.stringval = $string;
$$.val = NewStringf("\"%(escape)s\"", $string);
$$.type = T_STRING;
$$.unary_arg_type = 0;
}
| wstring {
$$.stringval = $wstring;
$$.val = NewStringf("L\"%(escape)s\"", $wstring);
$$.type = T_WSTRING;
$$.unary_arg_type = 0;
}
| CHARCONST {
$$.stringval = $CHARCONST;
$$.val = NewStringf("'%(escape)s'", $CHARCONST);
$$.type = T_CHAR;
$$.unary_arg_type = 0;
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
| WCHARCONST {
$$.stringval = $WCHARCONST;
$$.val = NewStringf("L'%(escape)s'", $WCHARCONST);
$$.type = T_WCHAR;
$$.unary_arg_type = 0;
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
/* In sizeof(X) X can be a type or expression. We don't actually
* need to parse X as the type of sizeof is always size_t (which
* SWIG handles as T_ULONG), so we just skip to the closing ')' and
@ -6662,43 +6741,6 @@ exprsimple : exprnum
$$.type = T_ULONG;
$$.unary_arg_type = 0;
}
| wstring {
$$.val = $wstring;
$$.rawval = NewStringf("L\"%s\"", $$.val);
$$.type = T_WSTRING;
$$.unary_arg_type = 0;
}
| CHARCONST {
$$.val = NewString($CHARCONST);
if (Len($$.val)) {
$$.rawval = NewStringf("'%(escape)s'", $$.val);
} else {
$$.rawval = NewString("'\\0'");
}
$$.type = T_CHAR;
$$.unary_arg_type = 0;
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
| WCHARCONST {
$$.val = NewString($WCHARCONST);
if (Len($$.val)) {
$$.rawval = NewStringf("L\'%s\'", $$.val);
} else {
$$.rawval = NewString("L'\\0'");
}
$$.type = T_WCHAR;
$$.unary_arg_type = 0;
$$.bitfield = 0;
$$.throws = 0;
$$.throwf = 0;
$$.nexcept = 0;
$$.final = 0;
}
;
valexpr : exprsimple
@ -6707,8 +6749,8 @@ valexpr : exprsimple
/* grouping */
| LPAREN expr RPAREN %prec CAST {
$$.val = NewStringf("(%s)",$expr.val);
if ($expr.rawval) {
$$.rawval = NewStringf("(%s)",$expr.rawval);
if ($expr.stringval) {
$$.stringval = Copy($expr.stringval);
}
$$.type = $expr.type;
}
@ -6797,7 +6839,7 @@ valexpr : exprsimple
| AND expr {
$$ = $expr;
$$.val = NewStringf("&%s", $expr.val);
$$.rawval = 0;
$$.stringval = 0;
/* Record the type code for expr so we can properly handle
* cases such as (6)&7 which get parsed using this rule then
* the rule for a C-style cast.
@ -6817,7 +6859,7 @@ valexpr : exprsimple
| STAR expr {
$$ = $expr;
$$.val = NewStringf("*%s", $expr.val);
$$.rawval = 0;
$$.stringval = 0;
/* Record the type code for expr so we can properly handle
* cases such as (6)*7 which get parsed using this rule then
* the rule for a C-style cast.
@ -6849,59 +6891,59 @@ exprnum : NUM_INT
;
exprcompound : expr[lhs] PLUS expr[rhs] {
$$.val = NewStringf("%s+%s", COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s+%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] MINUS expr[rhs] {
$$.val = NewStringf("%s-%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s-%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] STAR expr[rhs] {
$$.val = NewStringf("%s*%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s*%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] SLASH expr[rhs] {
$$.val = NewStringf("%s/%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s/%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] MODULO expr[rhs] {
$$.val = NewStringf("%s%%%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s%%%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] AND expr[rhs] {
$$.val = NewStringf("%s&%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s&%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] OR expr[rhs] {
$$.val = NewStringf("%s|%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s|%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] XOR expr[rhs] {
$$.val = NewStringf("%s^%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s^%s", $lhs.val, $rhs.val);
$$.type = promote($lhs.type,$rhs.type);
}
| expr[lhs] LSHIFT expr[rhs] {
$$.val = NewStringf("%s << %s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s << %s", $lhs.val, $rhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] RSHIFT expr[rhs] {
$$.val = NewStringf("%s >> %s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s >> %s", $lhs.val, $rhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] LAND expr[rhs] {
$$.val = NewStringf("%s&&%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s&&%s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] LOR expr[rhs] {
$$.val = NewStringf("%s||%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s||%s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] EQUALTO expr[rhs] {
$$.val = NewStringf("%s==%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s==%s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] NOTEQUALTO expr[rhs] {
$$.val = NewStringf("%s!=%s",COMPOUND_EXPR_VAL($lhs),COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s!=%s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
/* Trying to parse `>` in the general case results in conflicts
@ -6909,7 +6951,7 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
* parentheses and we can handle that case.
*/
| LPAREN expr[lhs] GREATERTHAN expr[rhs] RPAREN {
$$.val = NewStringf("(%s > %s)", COMPOUND_EXPR_VAL($lhs), COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("(%s > %s)", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
@ -6919,15 +6961,15 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
* covers all user-reported cases.
*/
| LPAREN exprsimple[lhs] LESSTHAN expr[rhs] RPAREN {
$$.val = NewStringf("(%s < %s)", COMPOUND_EXPR_VAL($lhs), COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("(%s < %s)", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] GREATERTHANOREQUALTO expr[rhs] {
$$.val = NewStringf("%s >= %s", COMPOUND_EXPR_VAL($lhs), COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s >= %s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] LESSTHANOREQUALTO expr[rhs] {
$$.val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL($lhs), COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s <= %s", $lhs.val, $rhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
@ -6943,59 +6985,59 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
//
// = += -= *= /= %= ^= &= |= <<= >>= , .* ->*.
| expr[lhs] PLUS ELLIPSIS {
$$.val = NewStringf("%s+...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s+...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] MINUS ELLIPSIS {
$$.val = NewStringf("%s-...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s-...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] STAR ELLIPSIS {
$$.val = NewStringf("%s*...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s*...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] SLASH ELLIPSIS {
$$.val = NewStringf("%s/...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s/...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] MODULO ELLIPSIS {
$$.val = NewStringf("%s%%...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s%%...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] AND ELLIPSIS {
$$.val = NewStringf("%s&...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s&...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] OR ELLIPSIS {
$$.val = NewStringf("%s|...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s|...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] XOR ELLIPSIS {
$$.val = NewStringf("%s^...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s^...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] LSHIFT ELLIPSIS {
$$.val = NewStringf("%s << ...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s << ...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] RSHIFT ELLIPSIS {
$$.val = NewStringf("%s >> ...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s >> ...", $lhs.val);
$$.type = promote_type($lhs.type);
}
| expr[lhs] LAND ELLIPSIS {
$$.val = NewStringf("%s&&...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s&&...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] LOR ELLIPSIS {
$$.val = NewStringf("%s||...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s||...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] EQUALTO ELLIPSIS {
$$.val = NewStringf("%s==...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s==...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] NOTEQUALTO ELLIPSIS {
$$.val = NewStringf("%s!=...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s!=...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
/* Trying to parse `>` in the general case results in conflicts
@ -7003,7 +7045,7 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
* parentheses and we can handle that case.
*/
| LPAREN expr[lhs] GREATERTHAN ELLIPSIS RPAREN {
$$.val = NewStringf("(%s > ...)", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("(%s > ...)", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
/* Similarly for `<` except trying to handle exprcompound on the
@ -7012,20 +7054,20 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
* covers all user-reported cases.
*/
| LPAREN exprsimple[lhs] LESSTHAN ELLIPSIS RPAREN {
$$.val = NewStringf("(%s < %s)", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("(%s < %s)", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] GREATERTHANOREQUALTO ELLIPSIS {
$$.val = NewStringf("%s >= ...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s >= ...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] LESSTHANOREQUALTO ELLIPSIS {
$$.val = NewStringf("%s <= ...", COMPOUND_EXPR_VAL($lhs));
$$.val = NewStringf("%s <= ...", $lhs.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| expr[lhs] LESSEQUALGREATER expr[rhs] {
$$.val = NewStringf("%s <=> %s", COMPOUND_EXPR_VAL($lhs), COMPOUND_EXPR_VAL($rhs));
$$.val = NewStringf("%s <=> %s", $lhs.val, $rhs.val);
/* `<=>` returns one of `std::strong_ordering`,
* `std::partial_ordering` or `std::weak_ordering`. The main
* thing to do with the return value in this context is to
@ -7039,7 +7081,7 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
$$.unary_arg_type = 0;
}
| expr[expr1] QUESTIONMARK expr[expr2] COLON expr[expr3] %prec QUESTIONMARK {
$$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($expr1), COMPOUND_EXPR_VAL($expr2), COMPOUND_EXPR_VAL($expr3));
$$.val = NewStringf("%s?%s:%s", $expr1.val, $expr2.val, $expr3.val);
/* This may not be exactly right, but is probably good enough
* for the purposes of parsing constant expressions. */
$$.type = promote($expr2.type, $expr3.type);
@ -7067,7 +7109,7 @@ exprcompound : expr[lhs] PLUS expr[rhs] {
$$.type = promote_type($in.type);
}
| LNOT expr[in] {
$$.val = NewStringf("!%s",COMPOUND_EXPR_VAL($in));
$$.val = NewStringf("!%s", $in.val);
$$.type = cparse_cplusplus ? T_BOOL : T_INT;
}
| type LPAREN {
@ -7540,16 +7582,21 @@ string : string[in] STRING {
}
| STRING { $$ = NewString($STRING);}
;
/* Concatenated wide strings: L"str1" L"str2" */
wstring : wstring[in] WSTRING {
$$ = NewStringf("%s%s", $in, $WSTRING);
}
/* Concatenated wide string and normal string literal: L"str1" "str2" */
/*not all the compilers support this concatenation mode, so perhaps better to postpone it*/
/*| wstring STRING { here $STRING comes unescaped, we have to escape it back first via NewStringf("%(escape)s)"
$$ = NewStringf("%s%s", $wstring, $STRING);
}*/
| WSTRING { $$ = NewString($WSTRING);}
wstring : wstring[in] WSTRING {
// Concatenated wide strings: L"str1" L"str2"
$$ = NewStringf("%s%s", $in, $WSTRING);
}
| wstring[in] STRING {
// Concatenated wide string and normal string literal: L"str1" "str2" (C++11).
$$ = NewStringf("%s%s", $in, $STRING);
}
| string[in] WSTRING {
// Concatenated normal string and wide string literal: "str1" L"str2" (C++11).
$$ = NewStringf("%s%s", $in, $WSTRING);
}
| WSTRING {
$$ = NewString($WSTRING);
}
;
stringbrace : string

View File

@ -1344,9 +1344,13 @@ public:
const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
Setattr(n, "enumvalue", val);
} else if (swigtype == T_CHAR) {
String *val = NewStringf("'%(hexescape)s'", Getattr(n, "enumvalue"));
Setattr(n, "enumvalue", val);
Delete(val);
String *enumstringval = Getattr(n, "enumstringval");
if (enumstringval) {
// Escape character literal for C#.
String *val = NewStringf("'%(csharpescape)s'", enumstringval);
Setattr(n, "enumvalue", val);
Delete(val);
}
}
{
@ -1468,12 +1472,12 @@ 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("");
String *constants_code = NewString("");
Swig_save("constantWrapper", n, "value", NIL);
// The value as C# code.
String *csvalue = Copy(Getattr(n, "value"));
Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:cstype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:cstype:outattributes", NIL);
bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
@ -1521,16 +1525,23 @@ 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\"", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value")));
Setattr(n, "value", new_value);
} else if (SwigType_type(t) == T_CHAR) {
Printf(new_value, "\'%s\'", hexescaped_value ? hexescaped_value : Copy(Getattr(n, "value")));
Setattr(n, "value", new_value);
if (Getattr(n, "stringval")) {
char quote = 0;
switch (SwigType_type(t)) {
case T_STRING:
case T_WSTRING:
quote = '\"';
break;
case T_CHAR:
case T_WCHAR:
quote = '\'';
break;
}
if (quote) {
// Escape character literal for C#.
Delete(csvalue);
csvalue = NewStringf("%c%(csharpescape)s%c", quote, Getattr(n, "stringval"), quote);
}
}
const String *outattributes = Getattr(n, "tmap:cstype:outattributes");
@ -1571,15 +1582,16 @@ public:
// 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) {
if (SwigType_type(valuetype) == T_CHAR)
Printf(constants_code, "\'%(hexescape)s\';\n", Getattr(n, "staticmembervariableHandler:value"));
String *stringval = Getattr(n, "stringval");
if (stringval)
Printf(constants_code, "'%(csharpescape)s';\n", stringval);
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"));
Printf(constants_code, "%s;\n", csvalue);
}
}
@ -1593,9 +1605,9 @@ public:
}
// Cleanup
Swig_restore(n);
Delete(new_value);
Delete(return_type);
Delete(constants_code);
Delete(csvalue);
return SWIG_OK;
}

View File

@ -950,10 +950,6 @@ public:
if (swigtype == T_BOOL) {
const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
Setattr(n, "enumvalue", val);
} else if (swigtype == T_CHAR) {
String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue"));
Setattr(n, "enumvalue", val);
Delete(val);
}
// Emit the enum item.
@ -1449,20 +1445,8 @@ public:
// Note that this is only called for global constants, static member
// constants are already handled in staticmemberfunctionHandler().
Swig_save("constantWrapper", n, "value", NIL);
Swig_save("constantWrapper", n, "tmap:ctype:out", "tmap:imtype:out", "tmap:dtype:out", "tmap:out:null", "tmap:imtype:outattributes", "tmap:dtype:outattributes", NIL);
// Add the stripped quotes back in.
String *old_value = Getattr(n, "value");
SwigType *t = Getattr(n, "type");
if (SwigType_type(t) == T_STRING) {
Setattr(n, "value", NewStringf("\"%s\"", old_value));
Delete(old_value);
} else if (SwigType_type(t) == T_CHAR) {
Setattr(n, "value", NewStringf("\'%s\'", old_value));
Delete(old_value);
}
SetFlag(n, "feature:immutable");
int result = globalvariableHandler(n);
@ -1472,7 +1456,6 @@ 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.
@ -1505,20 +1488,9 @@ public:
} else {
// Just take the value from the C definition and hope it compiles in D.
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"));
Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
} else {
// 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);
}
Printf(constants_code, "%s;\n", Getattr(n, "value"));
}
}

View File

@ -1803,28 +1803,31 @@ private:
virtual int constantWrapper(Node *n) {
SwigType *type = Getattr(n, "type");
if (!SwigType_issimple(type) && SwigType_type(type) != T_STRING) {
return goComplexConstant(n, type);
}
if (Swig_storage_isstatic(n)) {
return goComplexConstant(n, type);
}
String *go_name = buildGoName(Getattr(n, "sym:name"), false, false);
String *tm = goType(n, type);
String *value = Getattr(n, "value");
String *copy = NULL;
if (SwigType_type(type) == T_BOOL) {
if (Cmp(value, "true") != 0 && Cmp(value, "false") != 0) {
int typecode = SwigType_type(type);
if (typecode == T_STRING) {
String *stringval = Getattr(n, "stringval");
if (!stringval) {
return goComplexConstant(n, type);
}
} else if (SwigType_type(type) == T_STRING || SwigType_type(type) == T_CHAR) {
// Backslash sequences are somewhat different in Go and C/C++.
if (Strchr(value, '\\') != 0) {
copy = NewStringf("\"%(goescape)s\"", stringval);
value = copy;
} else if (typecode == T_CHAR) {
String *stringval = Getattr(n, "stringval");
if (!stringval || Len(stringval) != 1) {
return goComplexConstant(n, type);
}
// Backslash sequences are somewhat different in Go and C/C++.
copy = NewStringf("'%(goescape)s'", stringval);
value = copy;
} else if (!SwigType_issimple(type)) {
return goComplexConstant(n, type);
} else if (Swig_storage_isstatic(n)) {
return goComplexConstant(n, type);
} else if (typecode == T_BOOL) {
if (Cmp(value, "true") != 0 && Cmp(value, "false") != 0) {
return goComplexConstant(n, type);
}
} else {
@ -1865,29 +1868,23 @@ private:
}
}
if (need_copy) {
copy = Copy(value);
if (!copy) copy = Copy(value);
Replaceall(copy, p + len, "");
value = copy;
}
}
String *go_name = buildGoName(Getattr(n, "sym:name"), false, false);
if (!checkNameConflict(go_name, n, NULL)) {
Delete(tm);
Delete(go_name);
Delete(copy);
return SWIG_NOWRAP;
}
Printv(f_go_wrappers, "const ", go_name, " ", tm, " = ", NULL);
if (SwigType_type(type) == T_STRING) {
Printv(f_go_wrappers, "\"", value, "\"", NULL);
} else if (SwigType_type(type) == T_CHAR) {
Printv(f_go_wrappers, "'", value, "'", NULL);
} else {
Printv(f_go_wrappers, value, NULL);
}
String *tm = goType(n, type);
Printv(f_go_wrappers, "\n", NULL);
Printv(f_go_wrappers, "const ", go_name, " ", tm, " = ", value, "\n", NIL);
Delete(tm);
Delete(go_name);
@ -1977,10 +1974,9 @@ private:
return SWIG_NOWRAP;
}
String *rawval = Getattr(n, "rawval");
if (rawval && Len(rawval)) {
if (!Getattr(n, "stringval") && !Getattr(n, "enumvalueDeclaration:sym:name")) {
// Based on Swig_VargetToFunction
String *nname = NewStringf("(%s)", rawval);
String *nname = NewStringf("(%s)", Getattr(n, "value"));
String *call;
if (SwigType_isclass(type)) {
call = NewStringf("%s", nname);
@ -1996,28 +1992,12 @@ private:
String *get = NewString("");
Printv(get, Swig_cresult_name(), " = ", NULL);
char quote;
if (Getattr(n, "wrappedasconstant")) {
quote = '\0';
} else if (SwigType_type(type) == T_CHAR) {
quote = '\'';
} else if (SwigType_type(type) == T_STRING) {
if (SwigType_type(type) == T_STRING) {
Printv(get, "(char *)", NULL);
quote = '"';
} else {
quote = '\0';
}
if (quote != '\0') {
Printf(get, "%c", quote);
}
Printv(get, Getattr(n, "value"), NULL);
if (quote != '\0') {
Printf(get, "%c", quote);
}
Printv(get, ";\n", NULL);
Setattr(n, "wrap:action", get);

View File

@ -1262,8 +1262,7 @@ public:
char *name = GetChar(n, "name");
char *iname = GetChar(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
int constasvar = GetFlag(n, "feature:constasvar");

View File

@ -1422,9 +1422,11 @@ public:
const char *val = Equal(Getattr(n, "enumvalue"), "true") ? "1" : "0";
Setattr(n, "enumvalue", val);
} else if (swigtype == T_CHAR) {
String *val = NewStringf("'%(escape)s'", Getattr(n, "enumvalue"));
Setattr(n, "enumvalue", val);
Delete(val);
if (Getattr(n, "enumstringval")) {
String *val = NewStringf("'%(escape)s'", Getattr(n, "enumstringval"));
Setattr(n, "enumvalue", val);
Delete(val);
}
}
{
@ -1540,12 +1542,10 @@ 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("");
String *constants_code = NewString("");
Swig_save("constantWrapper", n, "value", NIL);
// Translate and write javadoc comment if flagged
if (doxygen && doxygenTranslator->hasDocumentation(n)) {
@ -1598,16 +1598,6 @@ public:
Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t, 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")));
Setattr(n, "value", new_value);
} else if (SwigType_type(t) == T_CHAR) {
Printf(new_value, "\'%s\'", Copy(Getattr(n, "value")));
Setattr(n, "value", new_value);
}
const String *methodmods = Getattr(n, "feature:java:methodmodifiers");
methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string);
@ -1641,12 +1631,9 @@ 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(valuetype) == T_CHAR)
Printf(constants_code, "\'%(escape)s\';\n", Getattr(n, "staticmembervariableHandler:value"));
else
Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value"));
} else {
Printf(constants_code, "%s;\n", Getattr(n, "value"));
Printf(constants_code, "%s;\n", Getattr(n, "value"));
}
}
@ -1660,7 +1647,6 @@ public:
}
// Cleanup
Swig_restore(n);
Delete(new_value);
Delete(return_type);
Delete(constants_code);
return SWIG_OK;

View File

@ -1207,8 +1207,7 @@ int JSEmitter::emitConstant(Node *n) {
SwigType *type = Getattr(n, "type");
String *iname = Getattr(n, "sym:name");
String *wname = Swig_name_get(Getattr(current_namespace, NAME_MANGLED), iname);
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
// HACK: forcing usage of cppvalue for v8 (which turned out to fix typedef_struct.i, et. al)
if (State::IsSet(state.globals(FORCE_CPP)) && Getattr(n, "cppvalue") != NULL) {

View File

@ -629,24 +629,9 @@ int Language::constantDirective(Node *n) {
if (!ImportMode) {
Swig_require("constantDirective", n, "name", "?value", NIL);
String *name = Getattr(n, "name");
String *value = Getattr(n, "value");
if (!value) {
value = Copy(name);
} else {
/* if (checkAttribute(n,"type","char")) {
value = NewString(value);
} else {
value = NewStringf("%(escape)s", value);
}
*/
Setattr(n, "rawvalue", value);
value = NewStringf("%(escape)s", value);
if (!Len(value))
Append(value, "\\0");
/* Printf(stdout,"'%s' = '%s'\n", name, value); */
if (!Getattr(n, "value")) {
Setattr(n, "value", Getattr(n, "name"));
}
Setattr(n, "value", value);
this->constantWrapper(n);
Swig_restore(n);
return SWIG_OK;

View File

@ -1053,8 +1053,7 @@ public:
lua_name = iname;
String *nsname = Copy(iname);
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
String *tm;
String *lua_name_v2 = 0;
String *tm_v2 = 0;

View File

@ -564,53 +564,21 @@ public:
SwigType *type = Getattr(n, "type");
String *value = Getattr(n, "value");
String *var_name = NewString("");
String *proc_name = NewString("");
String *rvalue = NewString("");
String *temp = NewString("");
String *tm;
// Make a static variable;
Printf(var_name, "_wrap_const_%s", Swig_name_mangle_string(Getattr(n, "sym:name")));
// Build the name for scheme.
Printv(proc_name, iname, NIL);
Replaceall(proc_name, "_", "-");
if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) {
Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
return SWIG_NOWRAP;
}
// See if there's a typemap
Printv(rvalue, value, NIL);
if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) {
temp = Copy(rvalue);
Clear(rvalue);
Printv(rvalue, "\"", temp, "\"", NIL);
}
if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) {
Delete(temp);
temp = Copy(rvalue);
Clear(rvalue);
Printv(rvalue, "'", temp, "'", NIL);
}
// See if there's a typemap
if ((tm = Swig_typemap_lookup("constant", n, name, 0))) {
Replaceall(tm, "$value", rvalue);
Replaceall(tm, "$value", value);
Printf(f_init, "%s\n", tm);
} else {
// Create variable and assign it a value
Printf(f_header, "static %s = ", SwigType_lstr(type, var_name));
bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
if ((SwigType_type(type) == T_STRING)) {
Printf(f_header, "\"%s\";\n", value);
} else if (SwigType_type(type) == T_CHAR && !is_enum_item) {
Printf(f_header, "\'%s\';\n", value);
} else {
Printf(f_header, "%s;\n", value);
}
// Create a static variable and assign it a value
String *var_name = NewStringf("_wrap_const_%s", Swig_name_mangle_string(Getattr(n, "sym:name")));
Printf(f_header, "static %s = %s;\n", SwigType_lstr(type, var_name), value);
// Now create a variable declaration
@ -626,10 +594,8 @@ public:
variableWrapper(nn);
Delete(nn);
}
Delete(var_name);
}
Delete(proc_name);
Delete(rvalue);
Delete(temp);
return SWIG_OK;
}

View File

@ -898,8 +898,7 @@ public:
virtual int constantWrapper(Node *n) {
String *name = Getattr(n, "feature:symname");
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
SwigType *qname = Getattr(n, "qualified:name");
if (qname)

View File

@ -893,8 +893,7 @@ public:
String *name = Getattr(n, "name");
String *iname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
String *cppvalue = Getattr(n, "cppvalue");
String *tm;

View File

@ -1079,8 +1079,7 @@ public:
String *name = Getattr(n, "name");
String *iname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
String *tm;
if (!addSymbol(iname, n))

View File

@ -1696,8 +1696,7 @@ public:
String *name = GetChar(n, "name");
String *iname = GetChar(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
String *tm;
if (!addSymbol(iname, n))

View File

@ -3612,8 +3612,7 @@ public:
String *name = Getattr(n, "name");
String *iname = Getattr(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
String *tm;
int have_tm = 0;
int have_builtin_symname = 0;

View File

@ -1186,9 +1186,11 @@ int R::enumvalueDeclaration(Node *n) {
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"));
Setattr(n, "enumvalue", val);
Delete(val);
if (Getattr(n, "enumstringval")) {
String *val = NewStringf("'%(escape)s'", Getattr(n, "enumstringval"));
Setattr(n, "enumvalue", val);
Delete(val);
}
}
if (GetFlag(parent, "scopedenum")) {

View File

@ -2296,8 +2296,7 @@ public:
char *iname = GetChar(n, "sym:name");
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
if (current == CLASS_CONST) {
iname = klass->strip(iname);

View File

@ -690,8 +690,7 @@ public:
String *nodeName = Getattr(node, "name");
SwigType *type = Getattr(node, "type");
String *constantName = Getattr(node, "sym:name");
String *rawValue = Getattr(node, "rawval");
String *constantValue = rawValue ? rawValue : Getattr(node, "value");
String *constantValue = Getattr(node, "value");
String *constantTypemap = NULL;
// If feature scilab:const enabled, constants & enums are wrapped to Scilab variables

View File

@ -661,8 +661,7 @@ public:
String *iname = Getattr(n, "sym:name");
String *nsname = !namespace_option ? Copy(iname) : NewStringf("%s::%s", ns_name, iname);
SwigType *type = Getattr(n, "type");
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
String *value = Getattr(n, "value");
String *tm;
if (!addSymbol(iname, n))

View File

@ -1645,9 +1645,7 @@ int Swig_VargetToFunction(Node *n, int flags) {
} else {
String *nname = 0;
if (Equal(nodeType(n), "constant")) {
String *rawval = Getattr(n, "rawval");
String *value = rawval ? rawval : Getattr(n, "value");
nname = NewStringf("(%s)", value);
nname = NewStringf("(%s)", Getattr(n, "value"));
} else {
nname = SwigType_namestr(name);
}

View File

@ -12,6 +12,7 @@
* ----------------------------------------------------------------------------- */
#include "swig.h"
#include <assert.h>
#include <errno.h>
#include <ctype.h>
#include <limits.h>
@ -353,7 +354,8 @@ 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.
* Octal escaping is used. The result is used for literal strings and characters
* in C/C++ and also Java and R.
* ----------------------------------------------------------------------------- */
String *Swig_string_escape(String *s) {
@ -372,12 +374,11 @@ String *Swig_string_escape(String *s) {
Printf(ns, "\\'");
} else if (c == '\"') {
Printf(ns, "\\\"");
} else if (c == ' ') {
} else if (c >= 32 && c < 127) {
Putc(c, ns);
} else if (!isgraph(c)) {
} else {
int next_c = Getc(s);
if (c < 0)
c += UCHAR_MAX + 1;
assert(c >= 0);
if (next_c >= '0' && next_c < '8') {
/* We need to emit 3 octal digits. */
Printf(ns, "\\%03o", c);
@ -386,8 +387,6 @@ String *Swig_string_escape(String *s) {
}
c = next_c;
continue;
} else {
Putc(c, ns);
}
c = Getc(s);
}
@ -395,13 +394,13 @@ String *Swig_string_escape(String *s) {
}
/* -----------------------------------------------------------------------------
* Swig_string_hexescape()
* Swig_string_csharpescape()
*
* Takes a string object and produces a string with escape codes added to it.
* Hex escaping is used.
* Takes a string object and produces a string with escape codes added to it
* suitable for use as a C# string or character literal.
* ----------------------------------------------------------------------------- */
static String *Swig_string_hexescape(String *s) {
static String *Swig_string_csharpescape(String *s) {
String *ns;
int c;
ns = NewStringEmpty();
@ -419,14 +418,46 @@ static String *Swig_string_hexescape(String *s) {
Printf(ns, "\\'");
} else if (c == '\"') {
Printf(ns, "\\\"");
} else if (c == ' ') {
} else if (c >= 32 && c < 127) {
Putc(c, ns);
} else if (!isgraph(c)) {
if (c < 0)
c += UCHAR_MAX + 1;
Printf(ns, "\\x%X", c);
} else {
assert(c >= 0);
// Emit 4 hex digits in case the next character is a hex digit.
Printf(ns, "\\x%04X", c);
}
}
return ns;
}
/* -----------------------------------------------------------------------------
* Swig_string_goescape()
*
* Takes a string object and produces a string with escape codes added to it
* suitable for use as a Go string or character literal.
* ----------------------------------------------------------------------------- */
static String *Swig_string_goescape(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 >= 32 && c < 127 && c != '\'' && c != '"') {
Putc(c, ns);
} else {
// In Go, \' isn't valid in a double quoted string, while \" isn't valid
// in a single quoted rune, so to avoid needing two different escaping
// functions we always escape both using hex escapes.
assert(c >= 0);
Printf(ns, "\\x%02x", c);
}
}
return ns;
@ -1422,7 +1453,8 @@ Node *Swig_item_in_list(List *list, const_String_or_char_ptr name) {
void Swig_init(void) {
/* Set some useful string encoding methods */
DohEncoding("escape", Swig_string_escape);
DohEncoding("hexescape", Swig_string_hexescape);
DohEncoding("csharpescape", Swig_string_csharpescape);
DohEncoding("goescape", Swig_string_goescape);
DohEncoding("upper", Swig_string_upper);
DohEncoding("lower", Swig_string_lower);
DohEncoding("title", Swig_string_title);

View File

@ -1098,10 +1098,8 @@ static int look(Scanner *s) {
Delitem(s->text, DOH_END);
return SWIG_TOKEN_WSTRING;
} else if (c == '\\') {
if ((c = nextchar(s)) == 0) {
Swig_error(cparse_file, cparse_start_line, "Unterminated wide string\n");
return SWIG_TOKEN_ERROR;
}
Delitem(s->text, DOH_END);
get_escape(s);
}
break;
@ -1114,10 +1112,8 @@ static int look(Scanner *s) {
Delitem(s->text, DOH_END);
return (SWIG_TOKEN_WCHAR);
} else if (c == '\\') {
if ((c = nextchar(s)) == 0) {
Swig_error(cparse_file, cparse_start_line, "Unterminated wide character literal\n");
return SWIG_TOKEN_ERROR;
}
Delitem(s->text, DOH_END);
get_escape(s);
}
break;