Greetings Denys,
> Sent: Monday, January 15, 2018 at 1:16 PM
> From: "Denys Vlasenko" <vda.li...@googlemail.com>
> To: daggs <da...@gmx.com>
> Cc: busybox <busybox@busybox.net>
> Subject: Re: adding lineno implementation
>
> On Mon, Jan 15, 2018 at 10:52 AM, daggs <da...@gmx.com> wrote:
> > Greetings,
> >
> > I'm trying to add LINENO implementation to hush, I've decided to check for
> > new lines in i_getch calls and it seems to work but with one bug, in loops,
> > the value gets updated wrongly.
> >
> > here is my test output:
> > #!/bin/bash
> >
> > t=0
> >
> > echo "at line ${LINENO}"
> > while [ ${t} -lt 10 ]; do
> > echo "at line ${LINENO}"
> > t=$((t+1))
> > done
> > echo "at line ${LINENO}"
> >
> > echo "hello world ${t}"
> >
> > bash output:
> > at line 5
> > at line 7
> > at line 7
> > at line 7
> > at line 7
> > at line 7
> > at line 7
> > at line 7
> > at line 7
> > at line 7
> > at line 7
> > at line 10
> > hello world 10
> >
> > hush output:
> > at line 5
> > at line 9
> > at line 9
> > at line 9
> > at line 9
> > at line 9
> > at line 9
> > at line 9
> > at line 9
> > at line 9
> > at line 9
> > at line 10
> > hello world 10
> >
> > all the line 9 prints are the print within the loop.
> >
> > any ideas why?
>
> Care to send the patch?
>
sure, see attached.
Dagg,
--- shell/hush.c.orig 2018-01-14 20:28:56.309864201 +0200
+++ shell/hush.c 2018-01-15 11:31:01.796334005 +0200
@@ -2535,7 +2535,9 @@ static inline int fgetc_interactive(stru
}
#endif /* INTERACTIVE */
-static int i_getch(struct in_str *i)
+#define i_getch(_i_) i_getch_extended((_i_), NULL)
+
+static int i_getch_extended(struct in_str *i, int *lineno)
{
int ch;
@@ -2574,6 +2576,11 @@ static int i_getch(struct in_str *i)
out:
debug_printf("file_get: got '%c' %d\n", ch, ch);
i->last_char = ch;
+ if (lineno && (ch == '\n')) {
+ set_local_var(xasprintf("LINENO=%d", *lineno), SETFLAG_EXPORT);
+ (*lineno)++;
+ }
+
return ch;
}
@@ -4158,20 +4165,20 @@ static int fetch_heredocs(int heredoc_cn
static int run_list(struct pipe *pi);
#if BB_MMU
-#define parse_stream(pstring, input, end_trigger) \
- parse_stream(input, end_trigger)
+#define parse_stream(pstring, input, end_trigger, _lineno_) \
+ parse_stream(input, end_trigger, _lineno_)
#endif
static struct pipe *parse_stream(char **pstring,
struct in_str *input,
- int end_trigger);
+ int end_trigger, int *lineno);
#if !ENABLE_HUSH_FUNCTIONS
-#define parse_group(dest, ctx, input, ch) \
- parse_group(ctx, input, ch)
+#define parse_group(dest, ctx, input, ch, _lineno_) \
+ parse_group(ctx, input, ch, _lineno_)
#endif
static int parse_group(o_string *dest, struct parse_context *ctx,
- struct in_str *input, int ch)
+ struct in_str *input, int ch, int *lineno)
{
/* dest contains characters seen prior to ( or {.
* Typically it's empty, but for function defs,
@@ -4194,7 +4201,7 @@ static int parse_group(o_string *dest, s
}
/* it is "word(..." or "word (..." */
do
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
while (ch == ' ' || ch == '\t');
if (ch != ')') {
syntax_error_unexpected_ch(ch);
@@ -4202,7 +4209,7 @@ static int parse_group(o_string *dest, s
}
nommu_addchr(&ctx->as_string, ch);
do
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
while (ch == ' ' || ch == '\t' || ch == '\n');
if (ch != '{') {
syntax_error_unexpected_ch(ch);
@@ -4243,7 +4250,7 @@ static int parse_group(o_string *dest, s
return 1;
}
if (ch != '(') {
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
nommu_addchr(&ctx->as_string, ch);
}
}
@@ -4254,7 +4261,7 @@ static int parse_group(o_string *dest, s
#else
char *as_string = NULL;
#endif
- pipe_list = parse_stream(&as_string, input, endch);
+ pipe_list = parse_stream(&as_string, input, endch, lineno);
#if !BB_MMU
if (as_string)
o_addstr(&ctx->as_string, as_string);
@@ -4827,7 +4834,7 @@ static int encode_string(o_string *as_st
*/
static struct pipe *parse_stream(char **pstring,
struct in_str *input,
- int end_trigger)
+ int end_trigger, int *lineno)
{
struct parse_context ctx;
o_string dest = NULL_O_STRING;
@@ -4862,7 +4869,7 @@ static struct pipe *parse_stream(char **
int redir_fd;
redir_type redir_style;
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
debug_printf_parse(": ch=%c (%d) escape=%d\n",
ch, ch, !!(dest.o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
if (ch == EOF) {
@@ -5099,7 +5106,7 @@ static struct pipe *parse_stream(char **
redir_style = REDIRECT_OVERWRITE;
if (next == '>') {
redir_style = REDIRECT_APPEND;
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
nommu_addchr(&ctx.as_string, ch);
}
#if 0
@@ -5121,11 +5128,11 @@ static struct pipe *parse_stream(char **
redir_style = REDIRECT_HEREDOC;
heredoc_cnt++;
debug_printf_parse("++heredoc_cnt=%d\n", heredoc_cnt);
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
nommu_addchr(&ctx.as_string, ch);
} else if (next == '>') {
redir_style = REDIRECT_IO;
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
nommu_addchr(&ctx.as_string, ch);
}
#if 0
@@ -5153,7 +5160,7 @@ static struct pipe *parse_stream(char **
nommu_addchr(&ctx.as_string, '\n');
break;
}
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
if (ch == EOF)
break;
}
@@ -5167,7 +5174,7 @@ static struct pipe *parse_stream(char **
/* Remove trailing '\' from ctx.as_string */
ctx.as_string.data[--ctx.as_string.length] = '\0';
#endif
- ch = i_getch(input); /* eat it */
+ ch = i_getch_extended(input, lineno); /* eat it */
continue; /* back to top of while (1) */
}
break;
@@ -5194,7 +5201,7 @@ static struct pipe *parse_stream(char **
syntax_error("\\<eof>");
xfunc_die();
}
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
/* note: ch != '\n' (that case does not reach this place) */
o_addchr(&dest, '\\');
/*nommu_addchr(&ctx.as_string, '\\'); - already done */
@@ -5216,12 +5223,12 @@ static struct pipe *parse_stream(char **
if (next == '\'' && !ctx.pending_redirect) {
insert_empty_quoted_str_marker:
nommu_addchr(&ctx.as_string, next);
- i_getch(input); /* eat second ' */
+ i_getch_extended(input, lineno); /* eat second ' */
o_addchr(&dest, SPECIAL_VAR_SYMBOL);
o_addchr(&dest, SPECIAL_VAR_SYMBOL);
} else {
while (1) {
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
if (ch == EOF) {
syntax_error_unterm_ch('\'');
goto parse_error;
@@ -5276,7 +5283,7 @@ static struct pipe *parse_stream(char **
ch = i_peek(input);
if (ch != ';')
break;
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
nommu_addchr(&ctx.as_string, ch);
if (ctx.ctx_res_w == RES_CASE_BODY) {
ctx.ctx_dsemicolon = 1;
@@ -5296,7 +5303,7 @@ static struct pipe *parse_stream(char **
goto parse_error;
}
if (next == '&') {
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
nommu_addchr(&ctx.as_string, ch);
done_pipe(&ctx, PIPE_AND);
} else {
@@ -5312,7 +5319,7 @@ static struct pipe *parse_stream(char **
break; /* we are in case's "word | word)" */
#endif
if (next == '|') { /* || */
- ch = i_getch(input);
+ ch = i_getch_extended(input, lineno);
nommu_addchr(&ctx.as_string, ch);
done_pipe(&ctx, PIPE_OR);
} else {
@@ -5334,7 +5341,7 @@ static struct pipe *parse_stream(char **
}
#endif
case '{':
- if (parse_group(&dest, &ctx, input, ch) != 0) {
+ if (parse_group(&dest, &ctx, input, ch, lineno) != 0) {
goto parse_error;
}
goto new_cmd;
@@ -6456,7 +6463,7 @@ static int run_and_free_list(struct pipe
* NUL: parse all, execute, return
* ';': parse till ';' or newline, execute, repeat till EOF
*/
-static void parse_and_run_stream(struct in_str *inp, int end_trigger)
+static void parse_and_run_stream(struct in_str *inp, int end_trigger, int *lineno)
{
/* Why we need empty flag?
* An obscure corner case "false; ``; echo $?":
@@ -6472,7 +6479,7 @@ static void parse_and_run_stream(struct
if (end_trigger == ';')
inp->promptmode = 0; /* PS1 */
#endif
- pipe_list = parse_stream(NULL, inp, end_trigger);
+ pipe_list = parse_stream(NULL, inp, end_trigger, lineno);
if (!pipe_list || pipe_list == ERR_PTR) { /* EOF/error */
/* If we are in "big" script
* (not in `cmd` or something similar)...
@@ -6482,7 +6489,7 @@ static void parse_and_run_stream(struct
int ch = inp->last_char;
while (ch != EOF && ch != '\n') {
//bb_error_msg("Discarded:'%c'", ch);
- ch = i_getch(inp);
+ ch = i_getch_extended(inp, lineno);
}
/* Force prompt */
inp->p = NULL;
@@ -6506,15 +6513,21 @@ static void parse_and_run_stream(struct
static void parse_and_run_string(const char *s)
{
struct in_str input;
+ int lineno = 1;
+
setup_string_in_str(&input, s);
- parse_and_run_stream(&input, '\0');
+ parse_and_run_stream(&input, '\0', &lineno);
+ unset_local_var("LINENO");
}
static void parse_and_run_file(FILE *f)
{
struct in_str input;
+ int lineno = 1;
+
setup_file_in_str(&input, f);
- parse_and_run_stream(&input, ';');
+ parse_and_run_stream(&input, ';', &lineno);
+ unset_local_var("LINENO");
}
#if ENABLE_HUSH_TICK
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox