mirror of
https://github.com/odin-lang/Odin.git
synced 2026-03-03 23:28:20 +00:00
fmt.printf("%q", str); (quotes strings)
This commit is contained in:
@@ -593,11 +593,35 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
|
||||
fmt_bad_verb(fi, verb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fmt_string :: proc(fi: ^Info, s: string, verb: rune) {
|
||||
switch verb {
|
||||
case 's', 'v':
|
||||
strings.write_string(fi.buf, s);
|
||||
|
||||
case 'q': // quoted string
|
||||
quote: byte = '"';
|
||||
strings.write_byte(fi.buf, quote);
|
||||
for width := 0; len(s) > 0; s = s[width:] {
|
||||
r := rune(s[0]);
|
||||
width = 1;
|
||||
if r >= utf8.RUNE_SELF {
|
||||
r, width = utf8.decode_rune_in_string(s);
|
||||
}
|
||||
if width == 1 && r == utf8.RUNE_ERROR {
|
||||
strings.write_byte(fi.buf, '\\');
|
||||
strings.write_byte(fi.buf, 'x');
|
||||
strings.write_byte(fi.buf, __DIGITS_LOWER[s[0]>>4]);
|
||||
strings.write_byte(fi.buf, __DIGITS_LOWER[s[0]&0xf]);
|
||||
continue;
|
||||
}
|
||||
|
||||
strings.write_escaped_rune(fi.buf, r, quote);
|
||||
|
||||
}
|
||||
strings.write_byte(fi.buf, quote);
|
||||
|
||||
case 'x', 'X':
|
||||
space := fi.space;
|
||||
fi.space = false;
|
||||
|
||||
@@ -62,25 +62,25 @@ write_bytes :: proc(b: ^Builder, x: []byte) {
|
||||
}
|
||||
|
||||
|
||||
write_encoded_rune :: proc(b: ^Builder, r: rune) {
|
||||
write_byte(b, '\'');
|
||||
write_encoded_rune :: proc(b: ^Builder, r: rune, write_quote := true) {
|
||||
if write_quote do write_byte(b, '\'');
|
||||
switch r {
|
||||
case '\a': write_string(b, "\\a");
|
||||
case '\b': write_string(b, "\\b");
|
||||
case '\e': write_string(b, "\\e");
|
||||
case '\f': write_string(b, "\\f");
|
||||
case '\n': write_string(b, "\\n");
|
||||
case '\r': write_string(b, "\\r");
|
||||
case '\t': write_string(b, "\\t");
|
||||
case '\v': write_string(b, "\\v");
|
||||
case '\a': write_string(b, `\a"`);
|
||||
case '\b': write_string(b, `\b"`);
|
||||
case '\e': write_string(b, `\e"`);
|
||||
case '\f': write_string(b, `\f"`);
|
||||
case '\n': write_string(b, `\n"`);
|
||||
case '\r': write_string(b, `\r"`);
|
||||
case '\t': write_string(b, `\t"`);
|
||||
case '\v': write_string(b, `\v"`);
|
||||
case:
|
||||
if r < 32 {
|
||||
write_string(b, "\\x");
|
||||
write_string(b, `\x`);
|
||||
buf: [2]byte;
|
||||
s := strconv.append_bits(buf[:], u64(r), 16, true, 64, strconv.digits, nil);
|
||||
switch len(s) {
|
||||
case 0: write_string(b, "00");
|
||||
case 1: write_rune(b, '0');
|
||||
case 1: write_byte(b, '0');
|
||||
case 2: write_string(b, s);
|
||||
}
|
||||
} else {
|
||||
@@ -88,7 +88,69 @@ write_encoded_rune :: proc(b: ^Builder, r: rune) {
|
||||
}
|
||||
|
||||
}
|
||||
write_byte(b, '\'');
|
||||
if write_quote do write_byte(b, '\'');
|
||||
}
|
||||
|
||||
|
||||
write_escaped_rune :: proc(b: ^Builder, r: rune, quote: byte) {
|
||||
static DIGITS_LOWER := "0123456789abcdefx";
|
||||
|
||||
is_printable :: proc(r: rune) -> bool {
|
||||
if r <= 0xff {
|
||||
switch r {
|
||||
case 0x20..0x7e:
|
||||
return true;
|
||||
case 0xa1..0xff: // ¡ through ÿ except for the soft hyphen
|
||||
return r != 0xad; //
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(bill): A proper unicode library will be needed!
|
||||
return false;
|
||||
}
|
||||
|
||||
if r == rune(quote) || r == '\\' {
|
||||
write_byte(b, '\\');
|
||||
write_byte(b, byte(r));
|
||||
return;
|
||||
} else if is_printable(r) {
|
||||
write_encoded_rune(b, r, false);
|
||||
return;
|
||||
}
|
||||
switch r {
|
||||
case '\a': write_string(b, `\a`);
|
||||
case '\b': write_string(b, `\b`);
|
||||
case '\e': write_string(b, `\e`);
|
||||
case '\f': write_string(b, `\f`);
|
||||
case '\n': write_string(b, `\n`);
|
||||
case '\r': write_string(b, `\r`);
|
||||
case '\t': write_string(b, `\t`);
|
||||
case '\v': write_string(b, `\v`);
|
||||
case:
|
||||
switch {
|
||||
case r < ' ':
|
||||
write_byte(b, '\\');
|
||||
write_byte(b, 'x');
|
||||
write_byte(b, DIGITS_LOWER[byte(r)>>4]);
|
||||
write_byte(b, DIGITS_LOWER[byte(r)&0xf]);
|
||||
|
||||
case r > utf8.MAX_RUNE:
|
||||
r = 0xfffd;
|
||||
fallthrough;
|
||||
case r < 0x10000:
|
||||
write_byte(b, '\\');
|
||||
write_byte(b, 'u');
|
||||
for s := 12; s >= 0; s -= 4 {
|
||||
write_byte(b, DIGITS_LOWER[r>>uint(s) & 0xf]);
|
||||
}
|
||||
case:
|
||||
write_byte(b, '\\');
|
||||
write_byte(b, 'U');
|
||||
for s := 28; s >= 0; s -= 4 {
|
||||
write_byte(b, DIGITS_LOWER[r>>uint(s) & 0xf]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user