summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-04-21 04:15:01 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-04-21 04:15:01 -0700
commit4f2f300bb835af37b86b8a1239bec6fb469b289f (patch)
tree6f29d6524e747a70a596d11aa5511d8353b7222c
parent2e36e0feae8d1dd75c8410b365d7dc33b30ce66b (diff)
downloadtxr-4f2f300bb835af37b86b8a1239bec6fb469b289f.tar.gz
txr-4f2f300bb835af37b86b8a1239bec6fb469b289f.tar.bz2
txr-4f2f300bb835af37b86b8a1239bec6fb469b289f.zip
bugfix: source lineno off by one under hash bang.
* eval.c (load): When we read and discard a hash bang line, we must set the parser line number to two. * parser.c (parser_set_lineno): New function. * parser.h (parser_set_lineno): Declared. * txr.c (check_hash_bang): New argument, occurs. (txr_main): Track whether hash bang has occurred in a new local variable hb_occurs. Then, before parsing, if hash bang has occurred, set the line number to two.
-rw-r--r--eval.c4
-rw-r--r--parser.c8
-rw-r--r--parser.h1
-rw-r--r--txr.c11
4 files changed, 20 insertions, 4 deletions
diff --git a/eval.c b/eval.c
index ee9ac973..43e499d8 100644
--- a/eval.c
+++ b/eval.c
@@ -4341,7 +4341,9 @@ val load(val target)
open_txr_file(path, &txr_lisp_p, &name, &stream);
- if (!match_str(or2(get_line(stream), lit("")), lit("#!"), nil))
+ if (match_str(or2(get_line(stream), lit("")), lit("#!"), nil))
+ parser_set_lineno(self, stream, two);
+ else
seek_stream(stream, zero, from_start_k);
uw_simple_catch_begin;
diff --git a/parser.c b/parser.c
index fbc2e2ca..7662614e 100644
--- a/parser.c
+++ b/parser.c
@@ -193,6 +193,14 @@ static void pushback_token(parser_t *p, struct yy_token *tok)
p->tok_pushback[p->tok_idx++] = *tok;
}
+val parser_set_lineno(val self, val stream, val lineno)
+{
+ val parser = ensure_parser(stream);
+ parser_t *pi = parser_get_impl(self, parser);
+ pi->lineno = c_num(lineno);
+ return stream;
+}
+
void prime_parser(parser_t *p, val name, enum prime_parser prim)
{
struct yy_token sec_tok = { 0 };
diff --git a/parser.h b/parser.h
index ec694bbb..ccb23d35 100644
--- a/parser.h
+++ b/parser.h
@@ -132,6 +132,7 @@ val parser(val stream, val lineno);
parser_t *parser_get_impl(val self, val parser);
val get_parser(val stream);
val ensure_parser(val stream);
+val parser_set_lineno(val self, val stream, val lineno);
val parser_errors(val parser);
val parser_eof(val parser);
void parse_init(void);
diff --git a/txr.c b/txr.c
index 5c9ce0c6..fccbb89a 100644
--- a/txr.c
+++ b/txr.c
@@ -189,13 +189,14 @@ static void hint(void)
}
#endif
-static val check_hash_bang(val stream, val args)
+static val check_hash_bang(val stream, val args, int *occurs)
{
val line = get_line(stream);
if (line) {
if (match_str(line, lit("#!"), nil)) {
val pos = search_str(line, lit("\xdc00"), nil, nil);
+ *occurs = 1;
if (pos) {
val after_null = sub_str(line, succ(pos), t);
@@ -511,6 +512,7 @@ int txr_main(int argc, char **argv)
val compat_var = lit("TXR_COMPAT");
val compat_val = getenv_wrap(compat_var);
val orig_args = nil, ref_arg_list = nil;
+ int hb_occurs = 0;
list_collect_decl(arg_list, arg_tail);
list_collect_decl(eff_arg_list, eff_arg_tail);
@@ -576,7 +578,7 @@ int txr_main(int argc, char **argv)
simulate_setuid_setgid(parse_stream);
dyn_env = make_env(nil, nil, dyn_env);
env_vbind(dyn_env, load_path_s, spec_file_str);
- arg_list = check_hash_bang(parse_stream, arg_undo);
+ arg_list = check_hash_bang(parse_stream, arg_undo, &hb_occurs);
set(eff_arg_tail, butlastn(one, deref(eff_arg_tail)));
continue;
}
@@ -877,7 +879,7 @@ int txr_main(int argc, char **argv)
simulate_setuid_setgid(parse_stream);
dyn_env = make_env(nil, nil, dyn_env);
env_vbind(dyn_env, load_path_s, spec_file_str);
- arg_list = check_hash_bang(parse_stream, arg_list);
+ arg_list = check_hash_bang(parse_stream, arg_list, &hb_occurs);
} else {
drop_privilege();
spec_file_str = lit("stdin");
@@ -1050,6 +1052,9 @@ int txr_main(int argc, char **argv)
env_vbind(dyn_env, load_recursive_s, t);
+ if (hb_occurs)
+ parser_set_lineno(prog_string, parse_stream, two);
+
if (!txr_lisp_p)
{
int gc = gc_state(0);