summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog34
-rwxr-xr-xconfigure2
-rw-r--r--lib.c30
-rw-r--r--lib.h2
-rw-r--r--match.c37
-rw-r--r--unwind.c6
-rw-r--r--unwind.h13
7 files changed, 99 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 8ab1f112..201468f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/configure b/configure
index 571762d3..dece3572 100755
--- a/configure
+++ b/configure
@@ -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=
diff --git a/lib.c b/lib.c
index 2b90b60a..35c8296b 100644
--- a/lib.c
+++ b/lib.c
@@ -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))
diff --git a/lib.h b/lib.h
index c29eaa6d..231d830b 100644
--- a/lib.h
+++ b/lib.h
@@ -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;
diff --git a/match.c b/match.c
index 0cd4da50..070303cf 100644
--- a/match.c
+++ b/match.c
@@ -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);
diff --git a/unwind.c b/unwind.c
index e76ace02..35084a81 100644
--- a/unwind.c
+++ b/unwind.c
@@ -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;
diff --git a/unwind.h b/unwind.h
index db8a53fa..9d584a2a 100644
--- a/unwind.h
+++ b/unwind.h
@@ -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)) { \