Merge pull request #1118 from ojwb/r-enum-improvements

[R] Improve handling of enums
This commit is contained in:
Joseph Wang 2017-10-10 04:45:34 +08:00 • committed by GitHub
commit 8c9b06c9c0

View file

@ -14,8 +14,6 @@
#include "swigmod.h" #include "swigmod.h"
#include "cparse.h" #include "cparse.h"
static const double DEFAULT_NUMBER = .0000123456712312312323;
static String* replaceInitialDash(const String *name) static String* replaceInitialDash(const String *name)
{ {
String *retval; String *retval;
@ -264,13 +262,16 @@ static void replaceRClass(String *tm, SwigType *type) {
Delete(tmp); Delete(tmp_base); Delete(tmp_ref); Delete(tmp); Delete(tmp_base); Delete(tmp_ref);
} }
static double getNumber(String *value) { static bool getNumber(String *value, int* result) {
double d = DEFAULT_NUMBER;
if(Char(value)) { if(Char(value)) {
if(sscanf(Char(value), "%lf", &d) != 1) // Check the conversion processed the whole of value by having %c at
return(DEFAULT_NUMBER); // the end of the format, and checking that only the first value is
// converted. We don't want to convert "3+7" -> 3.
char dummy;
if (sscanf(Char(value), "%i%c", result, &dummy) == 1)
return true;
} }
return(d); return false;
} }
class R : public Language { class R : public Language {
@ -1228,16 +1229,28 @@ int R::enumDeclaration(Node *n) {
name = Getattr(c, "name"); name = Getattr(c, "name");
String *val = Getattr(c, "enumvalue"); String *val = Getattr(c, "enumvalue");
if(val && Char(val)) { if(val && Char(val)) {
int inval = (int) getNumber(val); int inval;
if(inval == DEFAULT_NUMBER) if (!getNumber(val, &inval)) {
value++; // Conversion failed - use the string value in val.
else } else {
val = NULL;
value = inval; value = inval;
} else }
} else {
val = NULL;
value++; value++;
}
Printf(scode, "%s%s%s'%s' = %d%s\n", tab8, tab8, tab8, name, value, if (val != NULL) {
nextSibling(c) ? ", " : ""); // This won't work in general, but will at least handle cases like (3)
// and 3+7, and when it doesn't work, it'll fail noisly rather than
// quietly using the wrong enum value like we used to.
Printf(scode, "%s%s%s'%s' = %s%s\n", tab8, tab8, tab8, name, val,
nextSibling(c) ? ", " : "");
} else {
Printf(scode, "%s%s%s'%s' = %d%s\n", tab8, tab8, tab8, name, value,
nextSibling(c) ? ", " : "");
}
// } // }
} }