From e8a6a7a53407fd4c4adc37e8013baf9bc2e4d553 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 12 Jan 2016 06:38:11 -0800 Subject: Print control chars in regexes using \x. * lib.c (out_str_char): Static function becomes extern. * lib.h (out_str_char): Declared. * regex.c (puts_clear_flag, putc_clear_flag): New static functions. (print_class_char): Take semicolon flag argument. Use out_str_char to render characters not escaped locally. Clear the semicolon flag. (paren_print_rec): Take semicolon flag argument, and pass it down. Clear it when printing parentheses. (print_rec): Take semicolon flag argument, and pass down to lower level functions. Use putc_clear_flag and puts_clear_flag instead of put_string and put_char. Use out_str_char for char object not esaped locally. (regex_print): define semi_flag and pass it down to print_rec. --- lib.c | 2 +- lib.h | 1 + regex.c | 123 ++++++++++++++++++++++++++++++++++++---------------------------- 3 files changed, 72 insertions(+), 54 deletions(-) diff --git a/lib.c b/lib.c index d6952482..9fb50a10 100644 --- a/lib.c +++ b/lib.c @@ -8264,7 +8264,7 @@ static val simple_qref_args_p(val args, val pos) } } -static void out_str_char(wchar_t ch, val out, int *semi_flag) +void out_str_char(wchar_t ch, val out, int *semi_flag) { if (*semi_flag && iswxdigit(ch)) put_char(chr(';'), out); diff --git a/lib.h b/lib.h index 1959eb06..83b81c24 100644 --- a/lib.h +++ b/lib.h @@ -940,6 +940,7 @@ val rangep(val obj); val from(val range); val to(val range); val env(void); +void out_str_char(wchar_t ch, val out, int *semi_flag); val obj_print_impl(val obj, val out, val pretty); val obj_print(val obj, val stream); val obj_pprint(val obj, val stream); diff --git a/regex.c b/regex.c index 4d6a60eb..9e770ba3 100644 --- a/regex.c +++ b/regex.c @@ -2029,7 +2029,19 @@ val regexp(val obj) return typeof(obj) == regex_s ? t : nil; } -static void print_class_char(val ch, val first_p, val stream) +static void puts_clear_flag(val str, val stream, int *semi_flag) +{ + *semi_flag = 0; + put_string(str, stream); +} + +static void putc_clear_flag(val ch, val stream, int *semi_flag) +{ + *semi_flag = 0; + put_char(ch, stream); +} + +static void print_class_char(val ch, val first_p, val stream, int *semi_flag) { wchar_t c = c_chr(ch); switch (c) { @@ -2038,58 +2050,62 @@ static void print_class_char(val ch, val first_p, val stream) break; /* fallthrough */ case '-': case '[': case ']': - put_char(chr('\\'), stream); - break; + putc_clear_flag(chr('\\'), stream, semi_flag); + put_char(ch, stream); + return; } - put_char(ch, stream); + out_str_char(c_chr(ch), stream, semi_flag); } -static void print_rec(val exp, val stream); +static void print_rec(val exp, val stream, int *semi_flag); -static void paren_print_rec(val exp, val stream) +static void paren_print_rec(val exp, val stream, int *semi_flag) { - put_char(chr('('), stream); - print_rec(exp, stream); - put_char(chr(')'), stream); + putc_clear_flag(chr('('), stream, semi_flag); + print_rec(exp, stream, semi_flag); + putc_clear_flag(chr(')'), stream, semi_flag); } -static void print_rec(val exp, val stream) +static void print_rec(val exp, val stream, int *semi_flag) { if (exp == space_k) { - put_string(lit("\\s"), stream); + puts_clear_flag(lit("\\s"), stream, semi_flag); } else if (exp == digit_k) { - put_string(lit("\\d"), stream); + puts_clear_flag(lit("\\d"), stream, semi_flag); } else if (exp == word_char_k) { - put_string(lit("\\w"), stream); + puts_clear_flag(lit("\\w"), stream, semi_flag); } else if (exp == cspace_k) { - put_string(lit("\\S"), stream); + puts_clear_flag(lit("\\S"), stream, semi_flag); } else if (exp == cdigit_k) { - put_string(lit("\\D"), stream); + puts_clear_flag(lit("\\D"), stream, semi_flag); } else if (exp == cword_char_k) { - put_string(lit("\\W"), stream); + puts_clear_flag(lit("\\W"), stream, semi_flag); } else if (exp == wild_s) { - put_char(chr('.'), stream); + putc_clear_flag(chr('.'), stream, semi_flag); } else if (chrp(exp)) { wchar_t ch = c_chr(exp); switch (ch) { case '?': case '.': case '*': case '+': case '(': case ')': case '|': case '~': case '&': case '%': case '/': case '\\': - put_char(chr('\\'), stream); + putc_clear_flag(chr('\\'), stream, semi_flag); + put_char(exp, stream); break; - } - put_char(exp, stream); + default: + out_str_char(ch, stream, semi_flag); + } } else if (stringp(exp)) { cnum i; cnum l = c_num(length(exp)); for (i = 0; i < l; i++) - print_rec(chr_str(exp, num(i)), stream); + print_rec(chr_str(exp, num(i)), stream, semi_flag); } else if (consp(exp)) { val sym = first(exp); val args = rest(exp); if (sym == set_s || sym == cset_s) { - put_char(chr('['), stream); + putc_clear_flag(chr('['), stream, semi_flag); + val first_p = t; if (sym == cset_s) { @@ -2100,78 +2116,78 @@ static void print_rec(val exp, val stream) while (args) { val arg = pop(&args); if (consp(arg)) { - print_class_char(car(arg), first_p, stream); - put_char(chr('-'), stream); - print_class_char(cdr(arg), nil, stream); + print_class_char(car(arg), first_p, stream, semi_flag); + putc_clear_flag(chr('-'), stream, semi_flag); + print_class_char(cdr(arg), nil, stream, semi_flag); } else if (symbolp(arg)) { - print_rec(arg, stream); + print_rec(arg, stream, semi_flag); } else { - print_class_char(arg, first_p, stream); + print_class_char(arg, first_p, stream, semi_flag); } first_p = nil; } - put_char(chr(']'), stream); + putc_clear_flag(chr(']'), stream, semi_flag); } else if (sym == compound_s) { for (; args; args = cdr(args)) { val arg = car(args); if (consp(arg) && car(arg) != zeroplus_s && car(arg) != oneplus_s && car(arg) != optional_s && car (arg) != compound_s) - paren_print_rec(arg, stream); + paren_print_rec(arg, stream, semi_flag); else - print_rec(arg, stream); + print_rec(arg, stream, semi_flag); } } else if (sym == zeroplus_s || sym == oneplus_s || sym == optional_s) { val arg = pop(&args); if (consp(arg) && car(arg) != set_s && car(arg) != cset_s) - paren_print_rec(arg, stream); + paren_print_rec(arg, stream, semi_flag); else - print_rec(arg, stream); + print_rec(arg, stream, semi_flag); if (sym == zeroplus_s) - put_char(chr('*'), stream); + putc_clear_flag(chr('*'), stream, semi_flag); else if (sym == oneplus_s) - put_char(chr('+'), stream); + putc_clear_flag(chr('+'), stream, semi_flag); else - put_char(chr('?'), stream); + putc_clear_flag(chr('?'), stream, semi_flag); } else if (sym == compl_s) { val arg = pop(&args); - put_char(chr('~'), stream); + putc_clear_flag(chr('~'), stream, semi_flag); if (consp(arg) && (car(arg) == or_s || car(arg) == and_s)) - paren_print_rec(arg, stream); + paren_print_rec(arg, stream, semi_flag); else - print_rec(arg, stream); + print_rec(arg, stream, semi_flag); } else if (sym == and_s) { val arg1 = pop(&args); val arg2 = pop(&args); if (consp(arg1) && car(arg2) == or_s) - paren_print_rec(arg1, stream); + paren_print_rec(arg1, stream, semi_flag); else - print_rec(arg1, stream); - put_char(chr('&'), stream); + print_rec(arg1, stream, semi_flag); + putc_clear_flag(chr('&'), stream, semi_flag); if (consp(arg2) && car(arg2) == or_s) - paren_print_rec(arg2, stream); + paren_print_rec(arg2, stream, semi_flag); else - print_rec(arg2, stream); + print_rec(arg2, stream, semi_flag); } else if (sym == or_s) { - print_rec(pop(&args), stream); - put_char(chr('|'), stream); - print_rec(pop(&args), stream); + print_rec(pop(&args), stream, semi_flag); + putc_clear_flag(chr('|'), stream, semi_flag); + print_rec(pop(&args), stream, semi_flag); } else if (sym == nongreedy_s) { val arg1 = pop(&args); val arg2 = pop(&args); if (consp(arg1) && car(arg1) != set_s && car(arg1) != cset_s) - paren_print_rec(arg1, stream); + paren_print_rec(arg1, stream, semi_flag); else - print_rec(arg1, stream); - put_char(chr('%'), stream); + print_rec(arg1, stream, semi_flag); + putc_clear_flag(chr('%'), stream, semi_flag); if (consp(arg2) && (car(arg2) == and_s && car(arg2) == or_s)) - paren_print_rec(arg2, stream); + paren_print_rec(arg2, stream, semi_flag); else - print_rec(arg2, stream); + print_rec(arg2, stream, semi_flag); } else { uw_throwf(error_s, lit("bad operator in regex syntax: ~s"), sym, nao); } } else if (exp == t) { - put_string(lit("[]"), stream); + puts_clear_flag(lit("[]"), stream, semi_flag); } else if (exp != nil) { uw_throwf(error_s, lit("bad object in regex syntax: ~s"), exp, nao); } @@ -2180,10 +2196,11 @@ static void print_rec(val exp, val stream) static void regex_print(val obj, val stream, val pretty) { regex_t *regex = coerce(regex_t *, cobj_handle(obj, regex_s)); + int semi_flag = 0; (void) pretty; put_string(lit("#/"), stream); - print_rec(regex->source, stream); + print_rec(regex->source, stream, &semi_flag); put_char(chr('/'), stream); } -- cgit v1.2.3