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

Reply via email to