Change the length of strings created from fixed-size buffers.
Use the usual C rule for NUL-terminated strings instead of discarding all the trailing NUL characters. This was unexpected (as buffers in C code are not necessarily always padded with NULs to their full length) and also inconsistent among languages as this was only done for those of them using typemaps/strings.swg but not for C# or Java, for example, which terminated the string at the first NUL even before this change. Notice that this patch couldn't use strlen() or wcslen() with possibly not NUL-terminated strings, so we had to add [our own equivalents of] strnlen() and wcsnlen() and use them instead. This required adding yet another parameter to string typemap macros, so update the example using them accordingly too.
This commit is contained in:
parent
ad02cb98e6
commit
88a0e228a9
8 changed files with 75 additions and 20 deletions
|
|
@ -5,6 +5,14 @@ See the RELEASENOTES file for a summary of changes in each release.
|
||||||
Version 3.0.0 (in progress)
|
Version 3.0.0 (in progress)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
2013-12-23: vadz
|
||||||
|
[Octave, Perl, Python, R, Ruby, Tcl] Change the length of strings created from fixed-size char
|
||||||
|
buffers in C code.
|
||||||
|
|
||||||
|
This is a potential backwards compatibility break: a "char buf[5]" containing "ho\0la" was
|
||||||
|
returned as a string of length 5 before, but is returned as a string of length 2 now. Apply
|
||||||
|
"char FIXSIZE[ANY]" typemaps to explicitly choose the old behaviour.
|
||||||
|
|
||||||
2013-12-23: talby
|
2013-12-23: talby
|
||||||
[Perl] Add support for directors.
|
[Perl] Add support for directors.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,17 @@ SWIG_FromXMLChPtrAndSize(const XMLCh* input, size_t size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%fragment("SWIG_XMLStringNLen","header") {
|
||||||
|
size_t
|
||||||
|
SWIG_XMLStringNLen(const XMLCh* s, size_t maxlen)
|
||||||
|
{
|
||||||
|
const XMLCh *p;
|
||||||
|
for (p = s; maxlen-- && *p; p++)
|
||||||
|
;
|
||||||
|
return p - s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
%init {
|
%init {
|
||||||
if (!SWIG_UTF8Transcoder()) {
|
if (!SWIG_UTF8Transcoder()) {
|
||||||
croak("ERROR: XML::Xerces: INIT: Could not create UTF-8 transcoder");
|
croak("ERROR: XML::Xerces: INIT: Could not create UTF-8 transcoder");
|
||||||
|
|
@ -106,6 +117,7 @@ SWIG_FromXMLChPtrAndSize(const XMLCh* input, size_t size)
|
||||||
SWIG_AsXMLChPtrAndSize,
|
SWIG_AsXMLChPtrAndSize,
|
||||||
SWIG_FromXMLChPtrAndSize,
|
SWIG_FromXMLChPtrAndSize,
|
||||||
XERCES_CPP_NAMESPACE::XMLString::stringLen,
|
XERCES_CPP_NAMESPACE::XMLString::stringLen,
|
||||||
|
SWIG_XMLStringNLen,
|
||||||
"<XMLCh.h>", INT_MIN, INT_MAX);
|
"<XMLCh.h>", INT_MIN, INT_MAX);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ $t->{var_paramd} = $primitive_types::sct_paramd;
|
||||||
$t->{var_paramc} = $primitive_types::sct_paramc;
|
$t->{var_paramc} = $primitive_types::sct_paramc;
|
||||||
ok($t->v_check(), 'v_check');
|
ok($t->v_check(), 'v_check');
|
||||||
|
|
||||||
is($primitive_types::def_namet, "ho\0la", "namet");
|
is($primitive_types::def_namet, "hola", "namet");
|
||||||
$t->{var_namet} = $primitive_types::def_namet;
|
$t->{var_namet} = $primitive_types::def_namet;
|
||||||
is($t->{var_namet}, $primitive_types::def_namet, "namet");
|
is($t->{var_namet}, $primitive_types::def_namet, "namet");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@
|
||||||
char* const def_pchar = (char *const)"hello";
|
char* const def_pchar = (char *const)"hello";
|
||||||
const char* const def_pcharc = "hija";
|
const char* const def_pcharc = "hija";
|
||||||
|
|
||||||
const namet def_namet = {'h','o',0, 'l','a'};
|
const namet def_namet = {'h','o','l','a', 0};
|
||||||
|
|
||||||
extern namet gbl_namet;
|
extern namet gbl_namet;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ t.var_paramc = sct_paramc
|
||||||
t.v_check()
|
t.v_check()
|
||||||
|
|
||||||
# this value contains a '0' char!
|
# this value contains a '0' char!
|
||||||
if def_namet != 'ho\0la':
|
if def_namet != 'hola':
|
||||||
print "bad namet", def_namet
|
print "bad namet", def_namet
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,19 @@ SWIG_pchar_descriptor(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%fragment("SWIG_strnlen","header",fragment="SWIG_FromCharPtrAndSize") {
|
||||||
|
size_t
|
||||||
|
SWIG_strnlen(const char* s, size_t maxlen)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
for (p = s; maxlen-- && *p; p++)
|
||||||
|
;
|
||||||
|
return p - s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
%include <typemaps/strings.swg>
|
%include <typemaps/strings.swg>
|
||||||
%typemaps_string(%checkcode(STRING), %checkcode(CHAR),
|
%typemaps_string(%checkcode(STRING), %checkcode(CHAR),
|
||||||
char, Char, SWIG_AsCharPtrAndSize, SWIG_FromCharPtrAndSize, strlen,
|
char, Char, SWIG_AsCharPtrAndSize, SWIG_FromCharPtrAndSize,
|
||||||
|
strlen, SWIG_strnlen,
|
||||||
"<limits.h>", CHAR_MIN, CHAR_MAX)
|
"<limits.h>", CHAR_MIN, CHAR_MAX)
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
SWIG_AsCharPtrAndSize,
|
SWIG_AsCharPtrAndSize,
|
||||||
SWIG_FromCharPtrAndSize,
|
SWIG_FromCharPtrAndSize,
|
||||||
SWIG_CharPtrLen,
|
SWIG_CharPtrLen,
|
||||||
|
SWIG_CharBufLen,
|
||||||
SWIG_AsCharPtr,
|
SWIG_AsCharPtr,
|
||||||
SWIG_FromCharPtr,
|
SWIG_FromCharPtr,
|
||||||
SWIG_AsCharArray,
|
SWIG_AsCharArray,
|
||||||
|
|
@ -276,12 +277,13 @@
|
||||||
}
|
}
|
||||||
%typemap(freearg) const Char (&)[ANY] "";
|
%typemap(freearg) const Char (&)[ANY] "";
|
||||||
|
|
||||||
%typemap(out,fragment=#SWIG_FromCharPtrAndSize)
|
%typemap(out,fragment=#SWIG_FromCharPtrAndSize,fragment=#SWIG_CharBufLen)
|
||||||
Char [ANY], const Char[ANY]
|
Char [ANY], const Char[ANY]
|
||||||
{
|
{
|
||||||
size_t size = $1_dim0;
|
|
||||||
%#ifndef SWIG_PRESERVE_CARRAY_SIZE
|
%#ifndef SWIG_PRESERVE_CARRAY_SIZE
|
||||||
while (size && ($1[size - 1] == '\0')) --size;
|
size_t size = SWIG_CharBufLen($1, $1_dim0);
|
||||||
|
%#else
|
||||||
|
size_t size = $1_dim0;
|
||||||
%#endif
|
%#endif
|
||||||
%set_output(SWIG_FromCharPtrAndSize($1, size));
|
%set_output(SWIG_FromCharPtrAndSize($1, size));
|
||||||
}
|
}
|
||||||
|
|
@ -298,23 +300,25 @@
|
||||||
|
|
||||||
/* varout */
|
/* varout */
|
||||||
|
|
||||||
%typemap(varout,noblock=1,fragment=#SWIG_FromCharPtrAndSize)
|
%typemap(varout,noblock=1,fragment=#SWIG_CharBufLen)
|
||||||
Char [ANY], const Char [ANY] {
|
Char [ANY], const Char [ANY] {
|
||||||
size_t size = $1_dim0;
|
|
||||||
%#ifndef SWIG_PRESERVE_CARRAY_SIZE
|
%#ifndef SWIG_PRESERVE_CARRAY_SIZE
|
||||||
while (size && ($1[size - 1] == '\0')) --size;
|
size_t size = SWIG_CharBufLen($1, $1_dim0);
|
||||||
|
%#else
|
||||||
|
size_t size = $1_dim0;
|
||||||
%#endif
|
%#endif
|
||||||
%set_varoutput(SWIG_FromCharPtrAndSize($1, size));
|
%set_varoutput(SWIG_FromCharPtrAndSize($1, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* constant */
|
/* constant */
|
||||||
|
|
||||||
%typemap(constcode,fragment=#SWIG_FromCharPtrAndSize)
|
%typemap(constcode,fragment=#SWIG_CharBufLen)
|
||||||
Char [ANY], const Char [ANY]
|
Char [ANY], const Char [ANY]
|
||||||
{
|
{
|
||||||
size_t size = $value_dim0;
|
|
||||||
%#ifndef SWIG_PRESERVE_CARRAY_SIZE
|
%#ifndef SWIG_PRESERVE_CARRAY_SIZE
|
||||||
while (size && ($value[size - 1] == '\0')) --size;
|
size_t size = SWIG_CharBufLen($1, $1_dim0);
|
||||||
|
%#else
|
||||||
|
size_t size = $value_dim0;
|
||||||
%#endif
|
%#endif
|
||||||
%set_constant("$symname", SWIG_FromCharPtrAndSize($value,size));
|
%set_constant("$symname", SWIG_FromCharPtrAndSize($value,size));
|
||||||
}
|
}
|
||||||
|
|
@ -323,12 +327,13 @@
|
||||||
#if defined(SWIG_DIRECTOR_TYPEMAPS)
|
#if defined(SWIG_DIRECTOR_TYPEMAPS)
|
||||||
|
|
||||||
/* directorin */
|
/* directorin */
|
||||||
%typemap(directorin,fragment=#SWIG_FromCharPtrAndSize)
|
%typemap(directorin,fragment=#SWIG_CharBufLen)
|
||||||
Char [ANY], const Char [ANY]
|
Char [ANY], const Char [ANY]
|
||||||
{
|
{
|
||||||
size_t size = $1_dim0;
|
|
||||||
%#ifndef SWIG_PRESERVE_CARRAY_SIZE
|
%#ifndef SWIG_PRESERVE_CARRAY_SIZE
|
||||||
while (size && ($1[size - 1] == '\0')) --size;
|
size_t size = SWIG_CharBufLen($1, $1_dim0);
|
||||||
|
%#else
|
||||||
|
size_t size = $1_dim0;
|
||||||
%#endif
|
%#endif
|
||||||
$input = SWIG_FromCharPtrAndSize($1, size);
|
$input = SWIG_FromCharPtrAndSize($1, size);
|
||||||
}
|
}
|
||||||
|
|
@ -360,12 +365,13 @@
|
||||||
|
|
||||||
/* throws */
|
/* throws */
|
||||||
|
|
||||||
%typemap(throws,fragment=#SWIG_FromCharPtrAndSize)
|
%typemap(throws,fragment=#SWIG_CharBufLen)
|
||||||
Char [ANY], const Char[ANY]
|
Char [ANY], const Char[ANY]
|
||||||
{
|
{
|
||||||
size_t size = $1_dim0;
|
|
||||||
%#ifndef SWIG_PRESERVE_CARRAY_SIZE
|
%#ifndef SWIG_PRESERVE_CARRAY_SIZE
|
||||||
while (size && ($1[size - 1] == '\0')) --size;
|
size_t size = SWIG_CharBufLen($1, $1_dim0);
|
||||||
|
%#else
|
||||||
|
size_t size = $1_dim0;
|
||||||
%#endif
|
%#endif
|
||||||
%raise(SWIG_FromCharPtrAndSize($1, size), "$type", 0);
|
%raise(SWIG_FromCharPtrAndSize($1, size), "$type", 0);
|
||||||
}
|
}
|
||||||
|
|
@ -499,6 +505,7 @@
|
||||||
SWIG_AsCharPtrAndSize,
|
SWIG_AsCharPtrAndSize,
|
||||||
SWIG_FromCharPtrAndSize,
|
SWIG_FromCharPtrAndSize,
|
||||||
SWIG_CharPtrLen,
|
SWIG_CharPtrLen,
|
||||||
|
SWIG_CharBufLen,
|
||||||
SWIG_NewCopyCharArray,
|
SWIG_NewCopyCharArray,
|
||||||
SWIG_DeleteCharArray,
|
SWIG_DeleteCharArray,
|
||||||
FragLimits, CHAR_MIN, CHAR_MAX)
|
FragLimits, CHAR_MIN, CHAR_MAX)
|
||||||
|
|
@ -586,6 +593,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
|
||||||
SWIG_AsCharPtrAndSize,
|
SWIG_AsCharPtrAndSize,
|
||||||
SWIG_FromCharPtrAndSize,
|
SWIG_FromCharPtrAndSize,
|
||||||
SWIG_CharPtrLen,
|
SWIG_CharPtrLen,
|
||||||
|
SWIG_CharBufLen,
|
||||||
SWIG_As##CharName##Ptr,
|
SWIG_As##CharName##Ptr,
|
||||||
SWIG_From##CharName##Ptr,
|
SWIG_From##CharName##Ptr,
|
||||||
SWIG_As##CharName##Array,
|
SWIG_As##CharName##Array,
|
||||||
|
|
@ -604,12 +612,14 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
|
||||||
SWIG_AsCharPtrAndSize,
|
SWIG_AsCharPtrAndSize,
|
||||||
SWIG_FromCharPtrAndSize,
|
SWIG_FromCharPtrAndSize,
|
||||||
SWIG_CharPtrLen,
|
SWIG_CharPtrLen,
|
||||||
|
SWIG_CharBufLen,
|
||||||
FragLimits, CHAR_MIN, CHAR_MAX)
|
FragLimits, CHAR_MIN, CHAR_MAX)
|
||||||
%_typemap2_string(StringCode, CharCode,
|
%_typemap2_string(StringCode, CharCode,
|
||||||
Char, CharName,
|
Char, CharName,
|
||||||
SWIG_AsCharPtrAndSize,
|
SWIG_AsCharPtrAndSize,
|
||||||
SWIG_FromCharPtrAndSize,
|
SWIG_FromCharPtrAndSize,
|
||||||
SWIG_CharPtrLen,
|
SWIG_CharPtrLen,
|
||||||
|
SWIG_CharBufLen,
|
||||||
%new_copy_array,
|
%new_copy_array,
|
||||||
%delete_array,
|
%delete_array,
|
||||||
FragLimits, CHAR_MIN, CHAR_MAX)
|
FragLimits, CHAR_MIN, CHAR_MAX)
|
||||||
|
|
@ -624,6 +634,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
|
||||||
SWIG_AsCharPtrAndSize,
|
SWIG_AsCharPtrAndSize,
|
||||||
SWIG_FromCharPtrAndSize,
|
SWIG_FromCharPtrAndSize,
|
||||||
SWIG_CharPtrLen,
|
SWIG_CharPtrLen,
|
||||||
|
SWIG_CharBufLen,
|
||||||
SWIG_NewCopyCharArray,
|
SWIG_NewCopyCharArray,
|
||||||
SWIG_DeleteCharArray,
|
SWIG_DeleteCharArray,
|
||||||
FragLimits, CHAR_MIN, CHAR_MAX)
|
FragLimits, CHAR_MIN, CHAR_MAX)
|
||||||
|
|
@ -632,6 +643,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val)
|
||||||
SWIG_AsCharPtrAndSize,
|
SWIG_AsCharPtrAndSize,
|
||||||
SWIG_FromCharPtrAndSize,
|
SWIG_FromCharPtrAndSize,
|
||||||
SWIG_CharPtrLen,
|
SWIG_CharPtrLen,
|
||||||
|
SWIG_CharBufLen,
|
||||||
SWIG_NewCopyCharArray,
|
SWIG_NewCopyCharArray,
|
||||||
SWIG_DeleteCharArray,
|
SWIG_DeleteCharArray,
|
||||||
FragLimits, CHAR_MIN, CHAR_MAX)
|
FragLimits, CHAR_MIN, CHAR_MAX)
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,20 @@ SWIG_pwchar_descriptor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%fragment("SWIG_wcsnlen","header",fragment="SWIG_FromWCharPtrAndSize") {
|
||||||
|
size_t
|
||||||
|
SWIG_wcsnlen(const wchar_t* s, size_t maxlen)
|
||||||
|
{
|
||||||
|
const wchar_t *p;
|
||||||
|
for (p = s; maxlen-- && *p; p++)
|
||||||
|
;
|
||||||
|
return p - s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
%include <typemaps/strings.swg>
|
%include <typemaps/strings.swg>
|
||||||
%typemaps_string(%checkcode(UNISTRING), %checkcode(UNICHAR),
|
%typemaps_string(%checkcode(UNISTRING), %checkcode(UNICHAR),
|
||||||
wchar_t, WChar, SWIG_AsWCharPtrAndSize, SWIG_FromWCharPtrAndSize, wcslen,
|
wchar_t, WChar, SWIG_AsWCharPtrAndSize, SWIG_FromWCharPtrAndSize,
|
||||||
|
wcslen, SWIG_wcsnlen,
|
||||||
"<wchar.h>", WCHAR_MIN, WCHAR_MAX)
|
"<wchar.h>", WCHAR_MIN, WCHAR_MAX)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue