Refactor PYTHON::convertValue
Remove multiple return statements for upcoming commits.
This commit is contained in:
parent
a89a4d9e84
commit
0a70498591
1 changed files with 85 additions and 77 deletions
|
|
@ -1889,6 +1889,8 @@ public:
|
|||
String *convertValue(String *v, SwigType *t) {
|
||||
const char *const s = Char(v);
|
||||
char *end;
|
||||
String *result = NIL;
|
||||
bool fail = false;
|
||||
|
||||
// Check if this is a number in any base.
|
||||
long value = strtol(s, &end, 0);
|
||||
|
|
@ -1897,97 +1899,103 @@ public:
|
|||
if (errno == ERANGE) {
|
||||
// There was an overflow, we could try representing the value as Python
|
||||
// long integer literal, but for now don't bother with it.
|
||||
return NIL;
|
||||
}
|
||||
fail = true;
|
||||
} else {
|
||||
if (*end != '\0') {
|
||||
// If there is a suffix after the number, we can safely ignore any
|
||||
// combination of "l" and "u", but not anything else (again, stuff like
|
||||
// "LL" could be handled, but we don't bother to do it currently).
|
||||
bool seen_long = false;
|
||||
for (char* p = end; *p != '\0'; ++p) {
|
||||
switch (*p) {
|
||||
case 'l':
|
||||
case 'L':
|
||||
// Bail out on "LL".
|
||||
if (seen_long) {
|
||||
fail = true;
|
||||
break;
|
||||
}
|
||||
seen_long = true;
|
||||
break;
|
||||
|
||||
if (*end != '\0') {
|
||||
// If there is a suffix after the number, we can safely ignore any
|
||||
// combination of "l" and "u", but not anything else (again, stuff like
|
||||
// "LL" could be handled, but we don't bother to do it currently).
|
||||
bool seen_long = false;
|
||||
for (char* p = end; *p != '\0'; ++p) {
|
||||
switch (*p) {
|
||||
case 'l':
|
||||
case 'L':
|
||||
// Bail out on "LL".
|
||||
if (seen_long)
|
||||
return NIL;
|
||||
seen_long = true;
|
||||
break;
|
||||
case 'u':
|
||||
case 'U':
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
case 'U':
|
||||
break;
|
||||
|
||||
default:
|
||||
// Except that our suffix could actually be the fractional part of
|
||||
// a floating point number, so we still have to check for this.
|
||||
return convertDoubleValue(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow integers as the default value for a bool parameter.
|
||||
if (Cmp(t, "bool") == 0)
|
||||
return NewString(value ? "True" : "False");
|
||||
|
||||
// Deal with the values starting with 0 first as they can be octal or
|
||||
// hexadecimal numbers or even pointers.
|
||||
if (s[0] == '0') {
|
||||
if (Len(v) == 1) {
|
||||
// This is just a lone 0, but it needs to be represented differently
|
||||
// in Python depending on whether it's a zero or a null pointer.
|
||||
if (isPointerType(t))
|
||||
return NewString("None");
|
||||
else
|
||||
return v;
|
||||
} else if (s[1] == 'x' || s[1] == 'X') {
|
||||
// This must have been a hex number, we can use it directly in Python,
|
||||
// so nothing to do here.
|
||||
} else {
|
||||
// This must have been an octal number, we have to change its prefix
|
||||
// to be "0o" in Python 3 only (and as long as we still support Python
|
||||
// 2.5, this can't be done unconditionally).
|
||||
if (py3) {
|
||||
if (end - s > 1) {
|
||||
String *res = NewString("0o");
|
||||
Append(res, NewStringWithSize(s + 1, end - s - 1));
|
||||
return res;
|
||||
default:
|
||||
// Except that our suffix could actually be the fractional part of
|
||||
// a floating point number, so we still have to check for this.
|
||||
result = convertDoubleValue(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid unnecessary string allocation in the common case when we don't
|
||||
// need to remove any suffix.
|
||||
return *end == '\0' ? v : NewStringWithSize(s, end - s);
|
||||
if (!fail) {
|
||||
// Allow integers as the default value for a bool parameter.
|
||||
if (Cmp(t, "bool") == 0) {
|
||||
result = NewString(value ? "True" : "False");
|
||||
} else {
|
||||
// Deal with the values starting with 0 first as they can be octal or
|
||||
// hexadecimal numbers or even pointers.
|
||||
if (s[0] == '0') {
|
||||
if (Len(v) == 1) {
|
||||
// This is just a lone 0, but it needs to be represented differently
|
||||
// in Python depending on whether it's a zero or a null pointer.
|
||||
if (isPointerType(t))
|
||||
result = NewString("None");
|
||||
else
|
||||
result = v;
|
||||
} else if (s[1] == 'x' || s[1] == 'X') {
|
||||
// This must have been a hex number, we can use it directly in Python,
|
||||
// so nothing to do here.
|
||||
} else {
|
||||
// This must have been an octal number, we have to change its prefix
|
||||
// to be "0o" in Python 3 only (and as long as we still support Python
|
||||
// 2.5, this can't be done unconditionally).
|
||||
if (py3) {
|
||||
if (end - s > 1) {
|
||||
result = NewString("0o");
|
||||
Append(result, NewStringWithSize(s + 1, end - s - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid unnecessary string allocation in the common case when we don't
|
||||
// need to remove any suffix.
|
||||
if (!result)
|
||||
result = *end == '\0' ? v : NewStringWithSize(s, end - s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this is a floating point number (notice that it wasn't
|
||||
// necessarily parsed as a long above, consider e.g. ".123").
|
||||
if (String *res = convertDoubleValue(v)) {
|
||||
return res;
|
||||
}
|
||||
if (!fail && !result) {
|
||||
result = convertDoubleValue(v);
|
||||
if (!result) {
|
||||
if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0)
|
||||
result = NewString("True");
|
||||
else if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
|
||||
result = NewString("False");
|
||||
else if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0)
|
||||
result = isPointerType(t) ? NewString("None") : NewString("0");
|
||||
|
||||
if (Strcmp(v, "true") == 0 || Strcmp(v, "TRUE") == 0)
|
||||
return NewString("True");
|
||||
if (Strcmp(v, "false") == 0 || Strcmp(v, "FALSE") == 0)
|
||||
return NewString("False");
|
||||
if (Strcmp(v, "NULL") == 0 || Strcmp(v, "nullptr") == 0)
|
||||
return isPointerType(t) ? NewString("None") : NewString("0");
|
||||
|
||||
// This could also be an enum type, default value of which could be
|
||||
// representable in Python if it doesn't include any scope (which could,
|
||||
// but currently is not, translated).
|
||||
if (!Strchr(s, ':')) {
|
||||
Node *lookup = Swig_symbol_clookup(v, 0);
|
||||
if (lookup) {
|
||||
if (Cmp(Getattr(lookup, "nodeType"), "enumitem") == 0)
|
||||
return Getattr(lookup, "sym:name");
|
||||
// This could also be an enum type, default value of which could be
|
||||
// representable in Python if it doesn't include any scope (which could,
|
||||
// but currently is not, translated).
|
||||
else if (!Strchr(s, ':')) {
|
||||
Node *lookup = Swig_symbol_clookup(v, 0);
|
||||
if (lookup) {
|
||||
if (Cmp(Getattr(lookup, "nodeType"), "enumitem") == 0)
|
||||
result = Getattr(lookup, "sym:name");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NIL;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue