Similar to the patch for decoding numbers, puts the handling of character decoding into a designated function with the same style caller interface. Removes one nested level and decoding logic from `dlang_parse_string'.
Added some more tests, which brings overall coverage of this code to all but 3 lines, two of which I have checked and are genuinely unreachable. ---
commit de5523a4ff9d755940fc7dc5beadb65f0aafd0df Author: Iain Buclaw <ibuc...@gdcproject.org> Date: Sat Apr 15 13:10:43 2017 +0200 libiberty/ChangeLog: 2017-04-15 Iain Buclaw <ibuc...@gdcproject.org> * d-demangle.c (dlang_hexdigit): New function. (ascii2hex): Remove function. (dlang_parse_string): Update to call dlang_hexdigit. * testsuite/d-demangle-expected: Add tests. diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c index 84a7186..ed97d2d 100644 --- a/libiberty/d-demangle.c +++ b/libiberty/d-demangle.c @@ -223,6 +223,34 @@ dlang_number (const char *mangled, long *ret) return mangled; } +/* Extract the hex-digit from MANGLED, and assign the result to RET. + Return the remaining string on success or NULL on failure. */ +static const char * +dlang_hexdigit (const char *mangled, char *ret) +{ + char c; + + /* Return NULL if trying to extract something that isn't a hexdigit. */ + if (mangled == NULL || !ISXDIGIT (mangled[0]) || !ISXDIGIT (mangled[1])) + return NULL; + + c = mangled[0]; + if (!ISDIGIT (c)) + *ret = (c - (ISUPPER (c) ? 'A' : 'a') + 10); + else + *ret = (c - '0'); + + c = mangled[1]; + if (!ISDIGIT (c)) + *ret = (*ret << 4) | (c - (ISUPPER (c) ? 'A' : 'a') + 10); + else + *ret = (*ret << 4) | (c - '0'); + + mangled += 2; + + return mangled; +} + /* Demangle the calling convention from MANGLED and append it to DECL. Return the remaining string on success or NULL on failure. */ static const char * @@ -1070,22 +1098,6 @@ dlang_parse_real (string *decl, const char *mangled) return mangled; } -/* Convert VAL from an ascii hexdigit to value. */ -static char -ascii2hex (char val) -{ - if (val >= 'a' && val <= 'f') - return (val - 'a' + 10); - - if (val >= 'A' && val <= 'F') - return (val - 'A' + 10); - - if (val >= '0' && val <= '9') - return (val - '0'); - - return 0; -} - /* Extract the string value from MANGLED and append it to DECL. Return the remaining string on success or NULL on failure. */ static const char * @@ -1103,48 +1115,45 @@ dlang_parse_string (string *decl, const char *mangled) string_append (decl, "\""); while (len--) { - if (ISXDIGIT (mangled[0]) && ISXDIGIT (mangled[1])) + char val; + const char *endptr = dlang_hexdigit (mangled, &val); + + if (endptr == NULL) + return NULL; + + /* Sanitize white and non-printable characters. */ + switch (val) { - char a = ascii2hex (mangled[0]); - char b = ascii2hex (mangled[1]); - char val = (a << 4) | b; + case ' ': + string_append (decl, " "); + break; + case '\t': + string_append (decl, "\\t"); + break; + case '\n': + string_append (decl, "\\n"); + break; + case '\r': + string_append (decl, "\\r"); + break; + case '\f': + string_append (decl, "\\f"); + break; + case '\v': + string_append (decl, "\\v"); + break; - /* Sanitize white and non-printable characters. */ - switch (val) + default: + if (ISPRINT (val)) + string_appendn (decl, &val, 1); + else { - case ' ': - string_append (decl, " "); - break; - case '\t': - string_append (decl, "\\t"); - break; - case '\n': - string_append (decl, "\\n"); - break; - case '\r': - string_append (decl, "\\r"); - break; - case '\f': - string_append (decl, "\\f"); - break; - case '\v': - string_append (decl, "\\v"); - break; - - default: - if (ISPRINT (val)) - string_appendn (decl, &val, 1); - else - { - string_append (decl, "\\x"); - string_appendn (decl, mangled, 2); - } + string_append (decl, "\\x"); + string_appendn (decl, mangled, 2); } } - else - return NULL; - mangled += 2; + mangled = endptr; } string_append (decl, "\""); diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected index 9fc1551..8c349fd 100644 --- a/libiberty/testsuite/d-demangle-expected +++ b/libiberty/testsuite/d-demangle-expected @@ -850,6 +850,14 @@ _D8demangle22__T4testVG3uw3_616263Zv demangle.test!("abc"w) # --format=dlang +_D8demangle16__T4testVAyaa0_Zv +demangle.test!("") +# +--format=dlang +_D8demangle32__T4testVAyaa8_20090a0d0c0b00ffZv +demangle.test!(" \t\n\r\f\v\x00\xff") +# +--format=dlang _D8demangle22__T4testVAiA4i1i2i3i4Zv demangle.test!([1, 2, 3, 4]) # @@ -1068,10 +1076,18 @@ _D15__T4testVfe0p1Zv _D15__T4testVfe0p1Zv # --format=dlang +_D15__T4testVAyaa1_ +_D15__T4testVAyaa1_ +# +--format=dlang _D16__T4testVAyaa0aZv _D16__T4testVAyaa0aZv # --format=dlang +_D18__T4testVAyaa1_0GZv +_D18__T4testVAyaa1_0GZv +# +--format=dlang _D18__T4testVAyaa1_YYZv _D18__T4testVAyaa1_YYZv # @@ -1228,6 +1244,14 @@ _D8demangle34__T2fnVai97Vai9Vai0Vui257Vwi65537Z2fnFZv demangle.fn!('a', '\x09', '\x00', '\u0101', '\U00010001').fn() # --format=dlang +_D8demangle39__T2fnVAyaa12_d0bfd180d0b8d0bcd0b5d180Z2fnFZv +demangle.fn!("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xbc\xd0\xb5\xd1\x80").fn() +# +--format=dlang +_D8demangle26__T2fnVAyaa6_e4b896e7958cZ2fnFZv +demangle.fn!("\xe4\xb8\x96\xe7\x95\x8c").fn() +# +--format=dlang _D2gc11gctemplates56__T8mkBitmapTS3std5range13__T4iotaTiTiZ4iotaFiiZ6ResultZ8mkBitmapFNbNiNfPmmZv gc.gctemplates.mkBitmap!(std.range.iota!(int, int).iota(int, int).Result).mkBitmap(ulong*, ulong) #