diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2009-11-12 22:48:15 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2009-11-12 22:48:15 -0800 |
commit | 673d5f3b84d276fb29233d6a3f485ccfe330be13 (patch) | |
tree | b1447ce861394a8b5873589ecb03659f2c5506fe | |
parent | 8367c03ef07473cff4f1b6f0645e1ce9ae17c94c (diff) | |
download | txr-673d5f3b84d276fb29233d6a3f485ccfe330be13.tar.gz txr-673d5f3b84d276fb29233d6a3f485ccfe330be13.tar.bz2 txr-673d5f3b84d276fb29233d6a3f485ccfe330be13.zip |
Continuing wchar_t conversion. Making sure all stdio calls
use wide character functions so that there is no illicit
mixing. (But the goal is to replace this usage with txr streams).
-rw-r--r-- | ChangeLog | 34 | ||||
-rw-r--r-- | gc.c | 5 | ||||
-rw-r--r-- | lib.c | 20 | ||||
-rw-r--r-- | match.c | 18 | ||||
-rw-r--r-- | parser.h | 2 | ||||
-rw-r--r-- | parser.l | 82 | ||||
-rw-r--r-- | stream.c | 41 | ||||
-rw-r--r-- | stream.h | 6 | ||||
-rw-r--r-- | txr.c | 123 | ||||
-rw-r--r-- | unwind.c | 4 | ||||
-rw-r--r-- | unwind.h | 18 |
11 files changed, 189 insertions, 164 deletions
@@ -1,5 +1,39 @@ 2009-11-12 Kaz Kylheku <kkylheku@gmail.com> + Continuing wchar_t conversion. Making sure all stdio calls + use wide character functions so that there is no illicit + mixing. (But the goal is to replace this usage with txr streams). + + * lib.c (list, cobj_print_op, obj_print, obj_pprint): Use + wide string literals and I/O functions. + + * match.c (debuglcf): Converted to wchar_t. + (dump_bindings, match_line, match_lines, extract): Use wide string + literal and I/O function. + + * parser.h (yyerrorf): Declaration updated. + + * parser.l (yyerror): Use wide-string yyerrorf. Users of + yyerror continue to pass multibyte strings. + (yyerrorf): Converted to wchar_t. + (yybadtoken, grammar): Use wide string literals to call yyerrorf. + + * stream.c (struct strm_ops): vcformat changed to wchar_t. + (stdio_vcformat, string_out_vcformat, vcformat, cformat): Likewise. + + * stream.h (vformat, vcformat, cformat): Declarations updated. + + * txr.c (oom_realloc_handler, help, hint, txr_main): Use wide string + literals and I/O functions. + + * unwind.c (uw_throwcf, uw_errorcf): Converted to wchar_t. + + * unwind.h (uw_throwcf, uw_errorcf): Declarations updated. + (internal_error, numeric_assert, range_bug_unless): Macros + fixed to use wide string literals. + +2009-11-12 Kaz Kylheku <kkylheku@gmail.com> + * utf8.c (utf8_from): Fix total breakage. Was writing out incomplete wide characters on internal state transtions while traversing a single multi-byte character. @@ -30,6 +30,7 @@ #include <assert.h> #include <setjmp.h> #include <dirent.h> +#include <wchar.h> #include "lib.h" #include "stream.h" #include "hash.h" @@ -321,9 +322,9 @@ static void sweep(void) continue; if (0 && dbg) { - fprintf(stderr, "%ls: finalizing: ", progname); + fwprintf(stderr, L"%ls: finalizing: ", progname); obj_print(block, std_error); - putc('\n', stderr); + putwc('\n', stderr); } finalize(block); block->t.type |= FREE; @@ -542,7 +542,7 @@ obj_t *list(obj_t *first, ...) do { *ptr++ = next; if (ptr == array + 32) - internal_error("runaway arguments in list function"); + internal_error(L"runaway arguments in list function"); next = va_arg(vl, obj_t *); } while (next != nao); @@ -1533,7 +1533,7 @@ void cobj_print_op(obj_t *obj, obj_t *out) { put_cstring(out, L"#<"); obj_print(obj->co.cls, out); - cformat(out, ": %p>", obj->co.handle); + cformat(out, L": %p>", obj->co.handle); } obj_t *assoc(obj_t *list, obj_t *key) @@ -1856,7 +1856,7 @@ void obj_print(obj_t *obj, obj_t *out) if (iswprint(*ptr)) put_cchar(out, *ptr); else - cformat(out, "\\%03o", (int) *ptr); + cformat(out, L"\\%03o", (int) *ptr); } } put_cchar(out, '"'); @@ -1882,19 +1882,19 @@ void obj_print(obj_t *obj, obj_t *out) if (iswprint(ch)) put_cchar(out, ch); else - cformat(out, "\\%03o", ch); + cformat(out, L"\\%03o", ch); } put_cchar(out, '\''); } return; case NUM: - cformat(out, "%ld", c_num(obj)); + cformat(out, L"%ld", c_num(obj)); return; case SYM: put_string(out, symbol_name(obj)); return; case FUN: - cformat(out, "#<function: f%d>", (int) obj->f.functype); + cformat(out, L"#<function: f%d>", (int) obj->f.functype); return; case VEC: { @@ -1917,7 +1917,7 @@ void obj_print(obj_t *obj, obj_t *out) return; } - cformat(out, "#<garbage: %p>", (void *) obj); + cformat(out, L"#<garbage: %p>", (void *) obj); } void obj_pprint(obj_t *obj, obj_t *out) @@ -1954,13 +1954,13 @@ void obj_pprint(obj_t *obj, obj_t *out) put_char(out, obj); return; case NUM: - cformat(out, "%ld", c_num(obj)); + cformat(out, L"%ld", c_num(obj)); return; case SYM: put_string(out, symbol_name(obj)); return; case FUN: - cformat(out, "#<function: f%d>", (int) obj->f.functype); + cformat(out, L"#<function: f%d>", (int) obj->f.functype); return; case VEC: { @@ -1983,7 +1983,7 @@ void obj_pprint(obj_t *obj, obj_t *out) return; } - cformat(out, "#<garbage: %p>", (void *) obj); + cformat(out, L"#<garbage: %p>", (void *) obj); } void init(const wchar_t *pn, void *(*oom)(void *, size_t), @@ -69,7 +69,7 @@ static void debuglf(obj_t *line, const wchar_t *fmt, ...) } } -static void debuglcf(obj_t *line, const char *fmt, ...) +static void debuglcf(obj_t *line, const wchar_t *fmt, ...) { if (opt_loglevel >= 2) { va_list vl; @@ -171,7 +171,7 @@ void dump_var(const wchar_t *name, wchar_t *pfx1, size_t len1, void dump_bindings(obj_t *bindings) { if (opt_loglevel >= 2) { - fputs("raw_bindings:\n", stderr); + fputws(L"raw_bindings:\n", stderr); dump(bindings, std_error); } @@ -280,15 +280,15 @@ obj_t *match_line(obj_t *bindings, obj_t *specline, obj_t *dataline, file, data_lineno, nao); \ debuglf(spec_lineno, L" ~a", dataline, nao); \ if (c_num(pos) < 77) \ - debuglcf(spec_lineno, " %*s^", (int) c_num(pos), "") + debuglcf(spec_lineno, L" %*ls^", (int) c_num(pos), L"") #define LOG_MATCH(KIND, EXTENT) \ debuglf(spec_lineno, KIND L" matched, position ~a-~a (~a:~a)", \ pos, EXTENT, file, data_lineno, nao); \ debuglf(spec_lineno, L" ~a", dataline, nao); \ if (c_num(EXTENT) < 77) \ - debuglcf(spec_lineno, " %*s%-*s^", (int) c_num(pos), \ - "", (int) (c_num(EXTENT) - c_num(pos)), "^") + debuglcf(spec_lineno, L" %*ls%-*ls^", (int) c_num(pos), \ + L"", (int) (c_num(EXTENT) - c_num(pos)), L"^") for (;;) { obj_t *elem; @@ -1227,7 +1227,7 @@ repeat_spec_same_data: } if (success) { - debuglcf(spec_linenum, "collect matched %s:%ld", + debuglcf(spec_linenum, L"collect matched %ls:%ld", c_str(first(files)), data_lineno); for (iter = new_bindings; iter && iter != bindings; @@ -1254,7 +1254,7 @@ repeat_spec_same_data: } debuglcf(spec_linenum, - "collect advancing from line %ld to %ld", + L"collect advancing from line %ld to %ld", data_lineno, new_lineno); data = new_data; @@ -1686,7 +1686,7 @@ repeat_spec_same_data: if (consp(success)) { debuglcf(spec_linenum, - "function matched; advancing from line %ld to %ld", + L"function matched; advancing from line %ld to %ld", data_lineno, c_num(cdr(success))); data = car(success); data_lineno = c_num(cdr(success)); @@ -1743,7 +1743,7 @@ int extract(obj_t *spec, obj_t *files, obj_t *predefined_bindings) } if (!success) - puts("false"); + fputws(L"false", stdout); } return success ? 0 : EXIT_FAILURE; @@ -32,5 +32,5 @@ extern const wchar_t *spec_file; extern obj_t *spec_file_str; int yyparse(void); obj_t *get_spec(void); -void yyerrorf(const char *s, ...); +void yyerrorf(const wchar_t *s, ...); void yybadtoken(int tok, const char *context); @@ -67,17 +67,17 @@ int errors; void yyerror(const char *s) { - yyerrorf("%s", s); + yyerrorf(L"%s", s); } -void yyerrorf(const char *s, ...) +void yyerrorf(const wchar_t *s, ...) { if (opt_loglevel >= 1) { va_list vl; va_start (vl, s); - fprintf(stderr, "%ls: (%ls:%ld): ", progname, spec_file, lineno); - vfprintf(stderr, s, vl); - putc('\n', stderr); + fwprintf(stderr, L"%ls: (%ls:%ld): ", progname, spec_file, lineno); + vfwprintf(stderr, s, vl); + putwc('\n', stderr); va_end (vl); } errors++; @@ -85,48 +85,48 @@ void yyerrorf(const char *s, ...) void yybadtoken(int tok, const char *context) { - const char *problem = 0; + const wchar_t *problem = 0; switch (tok) { - case TEXT: problem = "text"; break; - case IDENT: problem = "identifier"; break; - case ALL: problem = "\"all\""; break; - case SOME: problem = "\"some\""; break; - case NONE: problem = "\"none\""; break; - case MAYBE: problem = "\"maybe\""; break; - case CASES: problem = "\"cases\""; break; - case AND: problem = "\"and\""; break; - case OR: problem = "\"or\""; break; - case END: problem = "\"end\""; break; - case COLLECT: problem = "\"collect\""; break; - case UNTIL: problem = "\"until\""; break; - case COLL: problem = "\"coll\""; break; - case OUTPUT: problem = "\"output\""; break; - case REPEAT: problem = "\"repeat\""; break; - case REP: problem = "\"rep\""; break; - case SINGLE: problem = "\"single\""; break; - case FIRST: problem = "\"first\""; break; - case LAST: problem = "\"last\""; break; - case EMPTY: problem = "\"empty\""; break; - case DEFINE: problem = "\"define\""; break; - case TRY: problem = "\"try\""; break; - case CATCH: problem = "\"catch\""; break; - case FINALLY: problem = "\"finally\""; break; - case NUMBER: problem = "\"number\""; break; - case REGCHAR: problem = "regular expression character"; break; - case LITCHAR: problem = "string literal character"; break; + case TEXT: problem = L"text"; break; + case IDENT: problem = L"identifier"; break; + case ALL: problem = L"\"all\""; break; + case SOME: problem = L"\"some\""; break; + case NONE: problem = L"\"none\""; break; + case MAYBE: problem = L"\"maybe\""; break; + case CASES: problem = L"\"cases\""; break; + case AND: problem = L"\"and\""; break; + case OR: problem = L"\"or\""; break; + case END: problem = L"\"end\""; break; + case COLLECT: problem = L"\"collect\""; break; + case UNTIL: problem = L"\"until\""; break; + case COLL: problem = L"\"coll\""; break; + case OUTPUT: problem = L"\"output\""; break; + case REPEAT: problem = L"\"repeat\""; break; + case REP: problem = L"\"rep\""; break; + case SINGLE: problem = L"\"single\""; break; + case FIRST: problem = L"\"first\""; break; + case LAST: problem = L"\"last\""; break; + case EMPTY: problem = L"\"empty\""; break; + case DEFINE: problem = L"\"define\""; break; + case TRY: problem = L"\"try\""; break; + case CATCH: problem = L"\"catch\""; break; + case FINALLY: problem = L"\"finally\""; break; + case NUMBER: problem = L"\"number\""; break; + case REGCHAR: problem = L"regular expression character"; break; + case LITCHAR: problem = L"string literal character"; break; } if (problem != 0) if (context) - yyerrorf("misplaced %s in %s", problem, context); + yyerrorf(L"misplaced %ls in %ls", problem, context); else - yyerrorf("unexpected %s", problem); + yyerrorf(L"unexpected %ls", problem); else if (context) - yyerrorf("unterminated %s", context); + yyerrorf(L"unterminated %ls", context); else - yyerrorf("unexpected end of input"); + yyerrorf(L"unexpected end of input"); } static wchar_t char_esc(int letter) @@ -396,11 +396,11 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} } <SPECIAL,NESTED>{UANYN} { - yyerrorf("bad character in directive: '%s'", yytext); + yyerrorf(L"bad character in directive: '%s'", yytext); } <SPECIAL,NESTED>. { - yyerrorf("non-UTF-8 byte in directive: '\\x%02x'", + yyerrorf(L"non-UTF-8 byte in directive: '\\x%02x'", (unsigned char) yytext[0]); } @@ -458,7 +458,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} } <REGEX>. { - yyerrorf("non-UTF-8 byte in regex: '\\x%02x'", + yyerrorf(L"non-UTF-8 byte in regex: '\\x%02x'", (unsigned char) yytext[0]); } @@ -547,7 +547,7 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} } <STRLIT,CHRLIT,QSILIT>. { - yyerrorf("non-UTF-8 byte in literal: '\\x%02x'", + yyerrorf(L"non-UTF-8 byte in literal: '\\x%02x'", (unsigned char) yytext[0]); } @@ -54,7 +54,7 @@ struct strm_ops { obj_t *(*put_char)(obj_t *, wchar_t); obj_t *(*get_line)(obj_t *); obj_t *(*get_char)(obj_t *); - obj_t *(*vcformat)(obj_t *, const char *fmt, va_list vl); + obj_t *(*vcformat)(obj_t *, const wchar_t *fmt, va_list vl); obj_t *(*vformat)(obj_t *, const wchar_t *fmt, va_list vl); obj_t *(*close)(obj_t *, obj_t *); }; @@ -227,12 +227,12 @@ obj_t *stdio_get_char(obj_t *stream) return nil; } -obj_t *stdio_vcformat(obj_t *stream, const char *fmt, va_list vl) +obj_t *stdio_vcformat(obj_t *stream, const wchar_t *fmt, va_list vl) { struct stdio_handle *h = (struct stdio_handle *) stream->co.handle; if (h->f) { - int n = vfprintf(h->f, fmt, vl); + int n = vfwprintf(h->f, fmt, vl); return (n >= 0) ? num(n) : stdio_maybe_write_error(stream); } return nil; @@ -426,19 +426,18 @@ static obj_t *string_out_put_char(obj_t *stream, wchar_t ch) return string_out_put_string(stream, mini); } -obj_t *string_out_vcformat(obj_t *stream, const char *fmt, va_list vl) +obj_t *string_out_vcformat(obj_t *stream, const wchar_t *fmt, va_list vl) { struct string_output *so = (struct string_output *) stream->co.handle; if (so == 0) { return nil; } else { - int nchars, nchars2, nchars3; - char dummy_buf[1]; + int nchars, nchars2; + wchar_t dummy_buf[1]; size_t old_size = so->size; size_t required_size; va_list vl_copy; - char *utf8_buf; #if defined va_copy va_copy (vl_copy, vl); @@ -448,7 +447,7 @@ obj_t *string_out_vcformat(obj_t *stream, const char *fmt, va_list vl) vl_copy = vl; #endif - nchars = vsnprintf(dummy_buf, 0, fmt, vl_copy); + nchars = vswprintf(dummy_buf, 0, fmt, vl_copy); #if defined va_copy || defined __va_copy va_end (vl_copy); @@ -456,31 +455,21 @@ obj_t *string_out_vcformat(obj_t *stream, const char *fmt, va_list vl) bug_unless (nchars >= 0); - utf8_buf = chk_malloc(nchars + 1); - nchars2 = vsnprintf(utf8_buf, nchars + 1, fmt, vl); - bug_unless (nchars == nchars2); - - nchars3 = utf8_from(0, utf8_buf); + required_size = so->fill + nchars + 1; - required_size = so->fill + nchars3 + 1; - - if (required_size < so->fill) { - free(utf8_buf); + if (required_size < so->fill) return nil; - } while (so->size <= required_size) { so->size *= 2; - if (so->size < old_size) { - free(utf8_buf); + if (so->size < old_size) return nil; - } } so->buf = chk_realloc(so->buf, so->size * sizeof *so->buf); - utf8_from(so->buf, utf8_buf); - free(utf8_buf); - so->fill += nchars3; + nchars2 = vswprintf(so->buf + so->fill, so->size-so->fill, fmt, vl); + bug_unless (nchars == nchars2); + so->fill += nchars; return t; } } @@ -668,7 +657,7 @@ obj_t *vformat(obj_t *stream, const wchar_t *str, va_list vl) } } -obj_t *vcformat(obj_t *stream, const char *string, va_list vl) +obj_t *vcformat(obj_t *stream, const wchar_t *string, va_list vl) { type_check (stream, COBJ); type_assert (stream->co.cls == stream_t, (L"~a is not a stream", stream)); @@ -696,7 +685,7 @@ obj_t *format(obj_t *stream, const wchar_t *str, ...) } } -obj_t *cformat(obj_t *stream, const char *string, ...) +obj_t *cformat(obj_t *stream, const wchar_t *string, ...) { type_check (stream, COBJ); type_assert (stream->co.cls == stream_t, (L"~a is not a stream", stream)); @@ -35,10 +35,10 @@ obj_t *make_dir_stream(DIR *); obj_t *close_stream(obj_t *stream, obj_t *throw_on_error); obj_t *get_line(obj_t *); obj_t *get_char(obj_t *); -obj_t *vformat(obj_t *stream, const wchar_t *string, va_list); /* nao-term */ -obj_t *vcformat(obj_t *stream, const char *string, va_list); /* printf-style */ +obj_t *vformat(obj_t *stream, const wchar_t *string, va_list); +obj_t *vcformat(obj_t *stream, const wchar_t *string, va_list); obj_t *format(obj_t *stream, const wchar_t *string, ...); -obj_t *cformat(obj_t *stream, const char *string, ...); +obj_t *cformat(obj_t *stream, const wchar_t *string, ...); obj_t *put_string(obj_t *stream, obj_t *string); obj_t *put_line(obj_t *stream, obj_t *string); obj_t *put_cstring(obj_t *stream, const wchar_t *); @@ -54,66 +54,66 @@ obj_t *spec_file_str; */ void *oom_realloc_handler(void *old, size_t size) { - fprintf(stderr, "%ls: out of memory\n", progname); - puts("false"); + fwprintf(stderr, L"%ls: out of memory\n", progname); + fputws(L"false", stderr); abort(); } void help(void) { - const char *text = -"\n" -"txr version %ls\n" -"\n" -"copyright 2009, Kaz Kylheku <kkylheku@gmail.com>\n" -"\n" -"usage:\n" -"\n" -" %ls [ options ] query-file { data-file }*\n" -"\n" -"The query-file or data-file arguments may be specified as -, in which case\n" -"standard input is used. All data-file arguments which begin with a !\n" -"character are treated as command pipes. Those which begin with a $\n" -"are interpreted as directories to read. Leading arguments which begin\n" -"with a - followed by one or more characters, and which are not arguments to\n" -"options are interpreted as options. The -- option indicates the end of the\n" -"options.\n" -"\n" -"If no data-file arguments sare supplied, then the query itself must open a\n" -"a data source prior to attempting to make any pattern match, or it will\n" -"simply fail due to a match which has run out of data.\n" -"\n" -"options:\n" -"\n" -"-Dvar=value Pre-define variable var, with the given value.\n" -" A list value can be specified using commas.\n" -"-Dvar Predefine variable var, with empty string value.\n" -"-q Quiet: don't report errors during query matching.\n" -"-v Verbose: extra logging from matcher.\n" -"-b Don't dump list of bindings.\n" -"-a num Generate array variables up to num-dimensions.\n" -" Default is 1. Additional dimensions are fudged\n" -" by generating numeric suffixes\n" -"-c query-text The query is read from the query-text argument\n" -" itself. The query-file argument is omitted in\n" -" this case; the first argument is a data file.\n" -"-f query-file Specify the query-file as an option argument.\n" -" option, instead of the query-file argument.\n" -" This allows #! scripts to pass options through\n" -" to the utility.\n" -"--help You already know!\n" -"--version Display program version\n" -"\n" -"Options that take no argument can be combined. The -q and -v options\n" -"are mutually exclusive; the right-most one dominates.\n" -"\n" + const wchar_t *text = +L"\n" +L"txr version %ls\n" +L"\n" +L"copyright 2009, Kaz Kylheku <kkylheku@gmail.com>\n" +L"\n" +L"usage:\n" +L"\n" +L" %ls [ options ] query-file { data-file }*\n" +L"\n" +L"The query-file or data-file arguments may be specified as -, in which case\n" +L"standard input is used. All data-file arguments which begin with a !\n" +L"character are treated as command pipes. Those which begin with a $\n" +L"are interpreted as directories to read. Leading arguments which begin\n" +L"with a - followed by one or more characters, and which are not arguments to\n" +L"options are interpreted as options. The -- option indicates the end of the\n" +L"options.\n" +L"\n" +L"If no data-file arguments sare supplied, then the query itself must open a\n" +L"a data source prior to attempting to make any pattern match, or it will\n" +L"simply fail due to a match which has run out of data.\n" +L"\n" +L"options:\n" +L"\n" +L"-Dvar=value Pre-define variable var, with the given value.\n" +L" A list value can be specified using commas.\n" +L"-Dvar Predefine variable var, with empty string value.\n" +L"-q Quiet: don't report errors during query matching.\n" +L"-v Verbose: extra logging from matcher.\n" +L"-b Don't dump list of bindings.\n" +L"-a num Generate array variables up to num-dimensions.\n" +L" Default is 1. Additional dimensions are fudged\n" +L" by generating numeric suffixes\n" +L"-c query-text The query is read from the query-text argument\n" +L" itself. The query-file argument is omitted in\n" +L" this case; the first argument is a data file.\n" +L"-f query-file Specify the query-file as an option argument.\n" +L" option, instead of the query-file argument.\n" +L" This allows #! scripts to pass options through\n" +L" to the utility.\n" +L"--help You already know!\n" +L"--version Display program version\n" +L"\n" +L"Options that take no argument can be combined. The -q and -v options\n" +L"are mutually exclusive; the right-most one dominates.\n" +L"\n" ; - fprintf(stdout, text, version, progname); + fwprintf(stdout, text, version, progname); } void hint(void) { - fprintf(stderr, "%ls: incorrect arguments: try --help\n", progname); + fwprintf(stderr, L"%ls: incorrect arguments: try --help\n", progname); } obj_t *remove_hash_bang_line(obj_t *spec) @@ -215,7 +215,7 @@ static int txr_main(int argc, char **argv) } if (!strcmp(*argv, "--version")) { - printf("%ls: version %ls\n", progname, version); + wprintf(L"%ls: version %ls\n", progname, version); return 0; } @@ -230,7 +230,7 @@ static int txr_main(int argc, char **argv) char opt = (*argv)[1]; if (argc == 1) { - fprintf(stderr, "%ls: option %c needs argument\n", progname, opt); + fwprintf(stderr, L"%ls: option %c needs argument\n", progname, opt); return EXIT_FAILURE; } @@ -241,8 +241,8 @@ static int txr_main(int argc, char **argv) case 'a': val = strtol(*argv, &errp, 10); if (*errp != 0) { - fprintf(stderr, "%ls: option %c needs numeric argument, not %s\n", - progname, opt, *argv); + fwprintf(stderr, L"%ls: option %c needs numeric argument, not %s\n", + progname, opt, *argv); return EXIT_FAILURE; } @@ -282,14 +282,15 @@ static int txr_main(int argc, char **argv) case 'a': case 'c': case 'D': - fprintf(stderr, "%ls: option -%c does not clump\n", progname, *popt); + fwprintf(stderr, L"%ls: option -%c does not clump\n", + progname, *popt); return EXIT_FAILURE; case '-': - fprintf(stderr, "%ls: unrecognized long option: --%s\n", - progname, popt + 1); + fwprintf(stderr, L"%ls: unrecognized long option: --%s\n", + progname, popt + 1); return EXIT_FAILURE; default: - fprintf(stderr, "%ls: unrecognized option: %c\n", progname, *popt); + fwprintf(stderr, L"%ls: unrecognized option: %c\n", progname, *popt); return EXIT_FAILURE; } } @@ -299,7 +300,7 @@ static int txr_main(int argc, char **argv) } if (specstring && spec_file_str) { - fprintf(stderr, "%ls: cannot specify both -f and -c\n", progname); + fwprintf(stderr, L"%ls: cannot specify both -f and -c\n", progname); return EXIT_FAILURE; } @@ -311,7 +312,7 @@ static int txr_main(int argc, char **argv) if (wcscmp(c_str(spec_file_str), L"-") != 0) { FILE *in = w_fopen(c_str(spec_file_str), L"r"); if (in == 0) - uw_throwcf(file_error, "unable to open %s", c_str(spec_file_str)); + uw_throwcf(file_error, L"unable to open %ls", c_str(spec_file_str)); yyin_stream = make_stdio_stream(in, spec_file_str, t, nil); } else { spec_file = L"stdin"; @@ -325,7 +326,7 @@ static int txr_main(int argc, char **argv) if (strcmp(*argv, "-") != 0) { FILE *in = fopen(*argv, "r"); if (in == 0) - uw_throwcf(file_error, "unable to open %s", *argv); + uw_throwcf(file_error, L"unable to open %s", *argv); yyin_stream = make_stdio_stream(in, string_utf8(*argv), t, nil); spec_file = utf8_dup_from(*argv); } else { @@ -264,7 +264,7 @@ obj_t *uw_errorf(const wchar_t *fmt, ...) abort(); } -obj_t *uw_throwcf(obj_t *sym, const char *fmt, ...) +obj_t *uw_throwcf(obj_t *sym, const wchar_t *fmt, ...) { va_list vl; obj_t *stream = make_string_output_stream(); @@ -277,7 +277,7 @@ obj_t *uw_throwcf(obj_t *sym, const char *fmt, ...) abort(); } -obj_t *uw_errorcf(const char *fmt, ...) +obj_t *uw_errorcf(const wchar_t *fmt, ...) { va_list vl; obj_t *stream = make_string_output_stream(); @@ -81,8 +81,8 @@ void uw_push_catch(uw_frame_t *, obj_t *matches); noreturn obj_t *uw_throw(obj_t *sym, obj_t *exception); noreturn obj_t *uw_throwf(obj_t *sym, const wchar_t *fmt, ...); noreturn obj_t *uw_errorf(const wchar_t *fmt, ...); -noreturn obj_t *uw_throwcf(obj_t *sym, const char *fmt, ...); -noreturn obj_t *uw_errorcf(const char *fmt, ...); +noreturn obj_t *uw_throwcf(obj_t *sym, const wchar_t *fmt, ...); +noreturn obj_t *uw_errorcf(const wchar_t *fmt, ...); obj_t *uw_register_subtype(obj_t *sub, obj_t *super); obj_t *uw_exception_subtype_p(obj_t *sub, obj_t *sup); void uw_continue(uw_frame_t *curr, uw_frame_t *target); @@ -150,7 +150,7 @@ noreturn obj_t *type_mismatch(const wchar_t *, ...); #define internal_error(STR) \ uw_throwcf(internal_err, \ - "%s:%d %s", __FILE__, \ + L"%s:%d %ls", __FILE__, \ __LINE__, STR) #define type_assert(EXPR, ARGS) \ @@ -164,12 +164,12 @@ noreturn obj_t *type_mismatch(const wchar_t *, ...); #define numeric_assert(EXPR) \ if (!(EXPR)) \ - uw_throwcf(numeric_err, "%s", \ - "assertion " #EXPR \ - " failed") + uw_throwcf(numeric_err, L"%ls", \ + L"assertion " #EXPR \ + L" failed") #define range_bug_unless(EXPR) \ if (!(EXPR)) \ - uw_throwcf(range_err, "%s", \ - "assertion" #EXPR \ - " failed") + uw_throwcf(range_err, L"%ls", \ + L"assertion" #EXPR \ + L" failed") |