diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2013-10-24 21:49:52 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2013-10-24 21:49:52 -0700 |
commit | c6862a210f48ee4fd2d7fe7ad0e4eca11bea9963 (patch) | |
tree | ea18db3c64d4edfd8dc17784211d382a434fca45 | |
parent | b7f9a8f2e02872fea86827b034278c399fb052dc (diff) | |
download | txr-c6862a210f48ee4fd2d7fe7ad0e4eca11bea9963.tar.gz txr-c6862a210f48ee4fd2d7fe7ad0e4eca11bea9963.tar.bz2 txr-c6862a210f48ee4fd2d7fe7ad0e4eca11bea9963.zip |
Ouch! Turns out the code base has numerous unintended
deviations from C90, like mixed declations and
statements. GCC doesn't diagnose these without the
--pedantic flag.
* configure: GCC's --ansi flag should be spelled -ansi.
* lib.c (split_str, obj_print): Reorder declaration before statements.
(make_sym): Fix similar problem by eliminating a statement.
(funcall1, funcall2, funcall3, funcall4): Use assignment to initialize
local array with non-constant elements. This is actually good for
performance because we only initialize those parts of the array that
we use.
* lib.h (struct func): Change functype member to unsigned,
since enum-typed bitfields are a GCC extension.
* match.c (ml_all, mf_all): Use assignments to initialize local
struct with non-constants.
(do_txeval, v_collect): Slightly revise unwinding macrology with help
of new macros to avoid mixing declarations and statements.
(spec_bind): Removed spurious semicolon from macro expansion.
(v_gather): Reorder two lines to avoid mixed decls and
statements.
(match_filter): Move declaration of ret a few lines up, ahead of
statements.
* unwind.c (uw_pop_until): New function.
* unwind.h (uw_pop_until): Declared.
(uw_mark_frame, uw_fast_return): New macros.
-rw-r--r-- | ChangeLog | 34 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | lib.c | 30 | ||||
-rw-r--r-- | lib.h | 2 | ||||
-rw-r--r-- | match.c | 37 | ||||
-rw-r--r-- | unwind.c | 6 | ||||
-rw-r--r-- | unwind.h | 13 |
7 files changed, 99 insertions, 25 deletions
@@ -1,3 +1,37 @@ +2013-10-24 Kaz Kylheku <kaz@kylheku.com> + + Ouch! Turns out the code base has numerous unintended + deviations from C90, like mixed declations and + statements. GCC doesn't diagnose these without the + --pedantic flag. + + * configure: GCC's --ansi flag should be spelled -ansi. + + * lib.c (split_str, obj_print): Reorder declaration before statements. + (make_sym): Fix similar problem by eliminating a statement. + (funcall1, funcall2, funcall3, funcall4): Use assignment to initialize + local array with non-constant elements. This is actually good for + performance because we only initialize those parts of the array that + we use. + + * lib.h (struct func): Change functype member to unsigned, + since enum-typed bitfields are a GCC extension. + + * match.c (ml_all, mf_all): Use assignments to initialize local + struct with non-constants. + (do_txeval, v_collect): Slightly revise unwinding macrology with help + of new macros to avoid mixing declarations and statements. + (spec_bind): Removed spurious semicolon from macro expansion. + (v_gather): Reorder two lines to avoid mixed decls and + statements. + (match_filter): Move declaration of ret a few lines up, ahead of + statements. + + * unwind.c (uw_pop_until): New function. + + * unwind.h (uw_pop_until): Declared. + (uw_mark_frame, uw_fast_return): New macros. + 2013-10-23 Kaz Kylheku <kaz@kylheku.com> * genvim.txr: Split long lines of keywords. @@ -81,7 +81,7 @@ yacc='$(cross)$(tool_prefix)$(yaccname)' yacc_given= nm='$(cross)$(tool_prefix)nm' opt_flags=-O2 -lang_flags='--ansi -D_XOPEN_SOURCE=2' +lang_flags='-ansi -D_XOPEN_SOURCE=2' diag_flags='-Wall -Wmissing-prototypes -Wstrict-prototypes' debug_flags=-g inline= @@ -2007,11 +2007,11 @@ val split_str(val str, val sep) const wchar_t *cstr = c_str(str); const wchar_t *csep = c_str(sep); + list_collect_decl (out, iter); + prot1(&str); prot1(&sep); - list_collect_decl (out, iter); - for (;;) { const wchar_t *psep = wcsstr(cstr, csep); size_t span = (psep != 0) ? psep - cstr : wcslen(cstr); @@ -2025,8 +2025,10 @@ val split_str(val str, val sep) } break; } + rel1(&sep); rel1(&str); + return out; } } @@ -2416,8 +2418,8 @@ val make_sym(val name) val gensym(val prefix) { - gensym_counter = plus(gensym_counter, one); - val name = format(nil, lit("~a~,04a"), prefix, gensym_counter, nao); + val name = format(nil, lit("~a~,04a"), prefix, + gensym_counter = plus(gensym_counter, one), nao); return make_sym(name); } @@ -2991,7 +2993,8 @@ val funcall1(val fun, val arg) type_check(fun, FUN); if (fun->f.optargs) { - val args[32] = { arg }; + val args[32]; + args[0] = arg; return generic_funcall(fun, args, 1); } @@ -3028,7 +3031,9 @@ val funcall2(val fun, val arg1, val arg2) type_check(fun, FUN); if (fun->f.optargs) { - val arg[32] = { arg1, arg2 }; + val arg[32]; + arg[0] = arg1; + arg[1] = arg2; return generic_funcall(fun, arg, 2); } @@ -3070,7 +3075,10 @@ val funcall3(val fun, val arg1, val arg2, val arg3) type_check(fun, FUN); if (fun->f.optargs) { - val arg[32] = { arg1, arg2, arg3 }; + val arg[32]; + arg[0] = arg1; + arg[1] = arg2; + arg[2] = arg3; return generic_funcall(fun, arg, 3); } @@ -3116,7 +3124,11 @@ val funcall4(val fun, val arg1, val arg2, val arg3, val arg4) type_check(fun, FUN); if (fun->f.optargs) { - val arg[32] = { arg1, arg2, arg3, arg4 }; + val arg[32]; + arg[0] = arg1; + arg[1] = arg2; + arg[2] = arg3; + arg[3] = arg4; return generic_funcall(fun, arg, 4); } @@ -4646,8 +4658,8 @@ val obj_print(val obj, val out) case STR: { const wchar_t *ptr; - put_char(chr('"'), out); int semi_flag = 0; + put_char(chr('"'), out); for (ptr = c_str(obj); *ptr; ptr++) { if (semi_flag && iswxdigit(*ptr)) @@ -107,7 +107,7 @@ struct func { unsigned optargs : 7; /* fixparam - optargs = required args */ unsigned variadic : 1; unsigned : 1; - functype_t functype : 16; + unsigned functype : 16; val env; union { val interp_fun; @@ -343,8 +343,15 @@ typedef struct { static match_line_ctx ml_all(val bindings, val specline, val dataline, val pos, val data_lineno, val file) { - match_line_ctx c = { bindings, specline, dataline, - zero, pos, data_lineno, file }; + match_line_ctx c; + c.bindings = bindings; + c.specline = specline; + c.dataline = dataline; + c.base = zero; + c.pos = pos; + c.data_lineno = data_lineno; + c.file = file; + return c; } @@ -1394,11 +1401,12 @@ static val subst_vars(val spec, val bindings, val filter) static val do_txeval(val spec, val form, val bindings, val allow_unbound) { val ret = nil; + uw_mark_frame; + uw_catch_begin (cons(query_error_s, nil), exc_sym, exc); if (!form) - return nil; + uw_fast_return(nil); - uw_catch_begin (cons(query_error_s, nil), exc_sym, exc); { if (!form) { ret = form; @@ -1847,7 +1855,12 @@ static void do_output(val bindings, val specs, val filter, val out) static match_files_ctx mf_all(val spec, val files, val bindings, val data, val data_lineno) { - match_files_ctx c = { spec, files, car(files), bindings, data, data_lineno }; + match_files_ctx c; + c.spec = spec; + c.files = files; + c.bindings = bindings; + c.data = data; + c.data_lineno = data_lineno; return c; } @@ -1906,7 +1919,7 @@ typedef val (*v_match_func)(match_files_ctx *cout); #define spec_bind(specline, first_spec, spec) \ val specline = first(spec); \ - val first_spec = first(specline); + val first_spec = first(specline) static val v_skip(match_files_ctx *c) { @@ -2538,8 +2551,8 @@ static val v_gather(match_files_ctx *c) c->bindings = new_bindings; max_data = t; } else if (consp(success) && max_data != t) { - c->bindings = new_bindings; cons_bind (new_data, new_line, success); + c->bindings = new_bindings; if (gt(new_line, max_line)) { max_line = new_line; max_data = new_data; @@ -2647,6 +2660,8 @@ static val v_collect(match_files_ctx *c) cnum ctimes = fixnump(times) ? c_num(times) : 0; cnum clines = fixnump(lines) ? c_num(lines) : 0; val iter; + uw_mark_frame; + uw_block_begin(nil, result); if (gap && (max || min)) sem_error(specline, lit("~s: cannot mix :gap with :mingap or :maxgap"), @@ -2662,9 +2677,7 @@ static val v_collect(match_files_ctx *c) vars = vars_to_bindings(specline, vars, c->bindings); if ((times && ctimes == 0) || (lines && clines == 0)) - return next_spec_k; - - uw_block_begin(nil, result); + uw_fast_return(next_spec_k); result = t; @@ -3748,11 +3761,11 @@ val match_filter(val name, val arg, val other_args) cons(in_arg_sym, cons(out_arg_sym, other_args))), nao), nil); match_files_ctx c = mf_all(spec, nil, bindings, nil, num(0)); + val ret = v_fun(&c); + (void) first_spec; rlcp(car(spec), specline); - val ret = v_fun(&c); - if (ret == nil) sem_error(specline, lit("filter: (~s ~s ~s) failed"), name, arg, out_arg_sym, nao); @@ -187,6 +187,12 @@ void uw_pop_frame(uw_frame_t *fr) } } +void uw_pop_until(uw_frame_t *fr) +{ + while (uw_stack != fr) + uw_pop_frame(uw_stack); +} + uw_frame_t *uw_current_frame(void) { return uw_stack; @@ -110,16 +110,25 @@ void uw_push_debug(uw_frame_t *, val func, val args, val ub_p_a_pairs, val env, val data, val line, val chr); void uw_pop_frame(uw_frame_t *); +void uw_pop_until(uw_frame_t *); uw_frame_t *uw_current_frame(void); uw_frame_t *uw_current_exit_point(void); void uw_init(void); noreturn val type_mismatch(val, ...); +#define uw_mark_frame \ + uw_frame_t *uw_top = uw_current_frame() + +#define uw_fast_return(VAL) \ + do { \ + uw_pop_until(uw_top); \ + return VAL; \ + } while (0) + #define uw_block_begin(TAG, RESULTVAR) \ obj_t *RESULTVAR = nil; \ - do \ - { \ + do { \ uw_frame_t uw_blk; \ uw_push_block(&uw_blk, TAG); \ if (setjmp(uw_blk.bl.jb)) { \ |