Allowing arbitrary length #\xNNNN char literals.

This commit is contained in:
Alex Shinn 2012-06-10 17:50:42 +09:00
parent 8d5ea4cdf4
commit dc70094472

61
sexp.c
View file

@ -2683,37 +2683,42 @@ sexp sexp_read_raw (sexp ctx, sexp in) {
goto scan_loop; goto scan_loop;
case '\\': case '\\':
c1 = sexp_read_char(ctx, in); c1 = sexp_read_char(ctx, in);
res = sexp_read_symbol(ctx, in, c1, 0); c2 = sexp_read_char(ctx, in);
if (sexp_stringp(res)) { sexp_push_char(ctx, c2, in);
str = sexp_string_data(res); if ((c1 == 'x' || c1 == 'X') && (sexp_isxdigit(c2))) {
if (sexp_string_length(res) == 0) res = sexp_read_number(ctx, in, 16);
res = if (sexp_fixnump(res) && sexp_unbox_fixnum(res) >= 0 && sexp_unbox_fixnum(res) <= 0x10FFFF)
sexp_read_error(ctx, "unexpected end of character literal", res = sexp_make_character(sexp_unbox_fixnum(res));
SEXP_NULL, in); else if (!sexp_exceptionp(res))
if (sexp_string_length(res) == 1) { res = sexp_read_error(ctx, "bad character #\\x literal", res, in);
res = sexp_make_character(c1); } else {
} else if ((c1 == 'x' || c1 == 'X') && res = sexp_read_symbol(ctx, in, c1, 0);
sexp_isxdigit((unsigned char)(str[1])) if (sexp_stringp(res)) {
&& sexp_isxdigit((unsigned char)(str[2])) && str[3] == '\0') { str = sexp_string_data(res);
res = sexp_make_character(16 * digit_value(str[1]) if (sexp_string_length(res) == 0)
+ digit_value(str[2])); res =
} else { sexp_read_error(ctx, "unexpected end of character literal",
res = 0; SEXP_NULL, in);
for (c2=0; c2 < sexp_num_char_names; c2++) { if (sexp_string_length(res) == 1) {
if (strcasecmp(str, sexp_char_names[c2].name) == 0) { res = sexp_make_character(c1);
res = sexp_make_character(sexp_char_names[c2].ch); } else {
break; res = 0;
for (c2=0; c2 < sexp_num_char_names; c2++) {
if (strcasecmp(str, sexp_char_names[c2].name) == 0) {
res = sexp_make_character(sexp_char_names[c2].ch);
break;
}
} }
} if (!res) {
if (!res) {
#if SEXP_USE_UTF8_STRINGS #if SEXP_USE_UTF8_STRINGS
if ((c1=sexp_decode_utf8_char((unsigned char*)str)) > 0) { if ((c1=sexp_decode_utf8_char((unsigned char*)str)) > 0) {
res = sexp_make_character(c1); res = sexp_make_character(c1);
break; break;
} }
#endif #endif
tmp = sexp_c_string(ctx, str, -1); tmp = sexp_c_string(ctx, str, -1);
res = sexp_read_error(ctx, "unknown character name", tmp, in); res = sexp_read_error(ctx, "unknown character name", tmp, in);
}
} }
} }
} }