svn commit: trunk/busybox: docs editors

vda at busybox.net vda at busybox.net
Mon Mar 26 20:48:47 UTC 2007


Author: vda
Date: 2007-03-26 13:48:46 -0700 (Mon, 26 Mar 2007)
New Revision: 18251

Log:
sed: a communal variable managed to slip past 'size'
('size' happily displays 0 bytes in data and bss,
but in reality sed.o used 180 bytes of it). Oh well.
function                                             old     new   delta
pipe_putc                                             67      76      +9
sed_main                                             627     633      +6
get_next_line                                        161     166      +5
bbg                                                  180       -    -180
(add/remove: 0/1 grow/shrink: 3/0 up/down: 20/-180)          Total: -160 bytes

sed: also make sed -i failure message less cryptic


Modified:
   trunk/busybox/docs/keep_data_small.txt
   trunk/busybox/editors/sed.c


Changeset:
Modified: trunk/busybox/docs/keep_data_small.txt
===================================================================
--- trunk/busybox/docs/keep_data_small.txt	2007-03-26 20:15:40 UTC (rev 18250)
+++ trunk/busybox/docs/keep_data_small.txt	2007-03-26 20:48:46 UTC (rev 18251)
@@ -112,7 +112,7 @@
 Since bb_common_bufsiz1 is BUFSIZ + 1 bytes long and BUFSIZ can change
 from one libc to another, you have to add compile-time check for it:
 
-if(sizeof(struct globals) > sizeof(bb_common_bufsiz1))
+if (sizeof(struct globals) > sizeof(bb_common_bufsiz1))
 	BUG_<applet>_globals_too_big();
 
 

Modified: trunk/busybox/editors/sed.c
===================================================================
--- trunk/busybox/editors/sed.c	2007-03-26 20:15:40 UTC (rev 18250)
+++ trunk/busybox/editors/sed.c	2007-03-26 20:48:46 UTC (rev 18251)
@@ -21,7 +21,7 @@
   add_cmd() is called on each line of sed command text (from a file or from
   the command line).  It calls get_address() and parse_cmd_args().  The
   resulting sed_cmd_t structures are appended to a linked list
-  (bbg.sed_cmd_head/bbg.sed_cmd_tail).
+  (G.sed_cmd_head/G.sed_cmd_tail).
 
   add_input_file() adds a FILE * to the list of input files.  We need to
   know all input sources ahead of time to find the last line for the $ match.
@@ -91,7 +91,7 @@
 
 static const char semicolon_whitespace[] = "; \n\r\t\v";
 
-struct sed_globals {
+struct globals {
 	/* options */
 	int be_quiet, regex_type;
 	FILE *nonstdout;
@@ -117,15 +117,16 @@
 		int idx;	/* Space used */
 		int len;	/* Space allocated */
 	} pipeline;
-} bbg;
+};
 
+#define G (*(struct globals*)&bb_common_bufsiz1)
 
 #if ENABLE_FEATURE_CLEAN_UP
 static void sed_free_and_close_stuff(void)
 {
-	sed_cmd_t *sed_cmd = bbg.sed_cmd_head.next;
+	sed_cmd_t *sed_cmd = G.sed_cmd_head.next;
 
-	llist_free(bbg.append_head, free);
+	llist_free(G.append_head, free);
 
 	while (sed_cmd) {
 		sed_cmd_t *sed_cmd_next = sed_cmd->next;
@@ -150,10 +151,10 @@
 		sed_cmd = sed_cmd_next;
 	}
 
-	if (bbg.hold_space) free(bbg.hold_space);
+	if (G.hold_space) free(G.hold_space);
 
-	while (bbg.current_input_file < bbg.input_file_count)
-		fclose(bbg.input_file_list[bbg.current_input_file++]);
+	while (G.current_input_file < G.input_file_count)
+		fclose(G.input_file_list[G.current_input_file++]);
 }
 #else
 void sed_free_and_close_stuff(void);
@@ -163,7 +164,7 @@
 
 static void cleanup_outname(void)
 {
-	if (bbg.outname) unlink(bbg.outname);
+	if (G.outname) unlink(G.outname);
 }
 
 /* strdup, replacing "\n" with '\n', and "\delimiter" with 'delimiter' */
@@ -282,7 +283,7 @@
 		next = index_of_next_unescaped_regexp_delim(delimiter, ++pos);
 		temp = copy_parsing_escapes(pos, next);
 		*regex = xmalloc(sizeof(regex_t));
-		xregcomp(*regex, temp, bbg.regex_type|REG_NEWLINE);
+		xregcomp(*regex, temp, G.regex_type|REG_NEWLINE);
 		free(temp);
 		/* Move position to next character after last delimiter */
 		pos += (next+1);
@@ -316,7 +317,7 @@
 
 static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr)
 {
-	int cflags = bbg.regex_type;
+	int cflags = G.regex_type;
 	char *match;
 	int idx;
 
@@ -478,18 +479,18 @@
 	int temp;
 
 	/* Append this line to any unfinished line from last time. */
-	if (bbg.add_cmd_line) {
-		char *tp = xasprintf("%s\n%s", bbg.add_cmd_line, cmdstr);
-		free(bbg.add_cmd_line);
-		bbg.add_cmd_line = tp;
+	if (G.add_cmd_line) {
+		char *tp = xasprintf("%s\n%s", G.add_cmd_line, cmdstr);
+		free(G.add_cmd_line);
+		G.add_cmd_line = tp;
 	}
 
 	/* If this line ends with backslash, request next line. */
 	temp = strlen(cmdstr);
 	if (temp && cmdstr[temp-1] == '\\') {
-		if (!bbg.add_cmd_line)
-			bbg.add_cmd_line = xstrdup(cmdstr);
-		bbg.add_cmd_line[temp-1] = 0;
+		if (!G.add_cmd_line)
+			G.add_cmd_line = xstrdup(cmdstr);
+		G.add_cmd_line[temp-1] = 0;
 		return;
 	}
 
@@ -505,7 +506,7 @@
 		if (*cmdstr == '#') {
 			/* "#n" is the same as using -n on the command line */
 			if (cmdstr[1] == 'n')
-				bbg.be_quiet++;
+				G.be_quiet++;
 			cmdstr = strpbrk(cmdstr, "\n\r");
 			if (!cmdstr) break;
 			continue;
@@ -552,13 +553,13 @@
 		cmdstr = parse_cmd_args(sed_cmd, cmdstr);
 
 		/* Add the command to the command array */
-		bbg.sed_cmd_tail->next = sed_cmd;
-		bbg.sed_cmd_tail = bbg.sed_cmd_tail->next;
+		G.sed_cmd_tail->next = sed_cmd;
+		G.sed_cmd_tail = G.sed_cmd_tail->next;
 	}
 
 	/* If we glued multiple lines together, free the memory. */
-	free(bbg.add_cmd_line);
-	bbg.add_cmd_line = NULL;
+	free(G.add_cmd_line);
+	G.add_cmd_line = NULL;
 }
 
 /* Append to a string, reallocating memory as necessary. */
@@ -567,12 +568,12 @@
 
 static void pipe_putc(char c)
 {
-	if (bbg.pipeline.idx == bbg.pipeline.len) {
-		bbg.pipeline.buf = xrealloc(bbg.pipeline.buf,
-				bbg.pipeline.len + PIPE_GROW);
-		bbg.pipeline.len += PIPE_GROW;
+	if (G.pipeline.idx == G.pipeline.len) {
+		G.pipeline.buf = xrealloc(G.pipeline.buf,
+				G.pipeline.len + PIPE_GROW);
+		G.pipeline.len += PIPE_GROW;
 	}
-	bbg.pipeline.buf[bbg.pipeline.idx++] = c;
+	G.pipeline.buf[G.pipeline.idx++] = c;
 }
 
 static void do_subst_w_backrefs(char *line, char *replace)
@@ -585,10 +586,10 @@
 		if (replace[i] == '\\') {
 			unsigned backref = replace[++i] - '0';
 			if (backref <= 9) {
-				/* print out the text held in bbg.regmatch[backref] */
-				if (bbg.regmatch[backref].rm_so != -1) {
-					j = bbg.regmatch[backref].rm_so;
-					while (j < bbg.regmatch[backref].rm_eo)
+				/* print out the text held in G.regmatch[backref] */
+				if (G.regmatch[backref].rm_so != -1) {
+					j = G.regmatch[backref].rm_so;
+					while (j < G.regmatch[backref].rm_eo)
 						pipe_putc(line[j++]);
 				}
 				continue;
@@ -602,8 +603,8 @@
 		}
 		/* if we find an unescaped '&' print out the whole matched text. */
 		if (replace[i] == '&') {
-			j = bbg.regmatch[0].rm_so;
-			while (j < bbg.regmatch[0].rm_eo)
+			j = G.regmatch[0].rm_so;
+			while (j < G.regmatch[0].rm_eo)
 				pipe_putc(line[j++]);
 			continue;
 		}
@@ -621,20 +622,20 @@
 
 	/* Handle empty regex. */
 	if (sed_cmd->sub_match == NULL) {
-		current_regex = bbg.previous_regex_ptr;
+		current_regex = G.previous_regex_ptr;
 		if (!current_regex)
 			bb_error_msg_and_die("no previous regexp");
 	} else
-		bbg.previous_regex_ptr = current_regex = sed_cmd->sub_match;
+		G.previous_regex_ptr = current_regex = sed_cmd->sub_match;
 
 	/* Find the first match */
-	if (REG_NOMATCH == regexec(current_regex, oldline, 10, bbg.regmatch, 0))
+	if (REG_NOMATCH == regexec(current_regex, oldline, 10, G.regmatch, 0))
 		return 0;
 
 	/* Initialize temporary output buffer. */
-	bbg.pipeline.buf = xmalloc(PIPE_GROW);
-	bbg.pipeline.len = PIPE_GROW;
-	bbg.pipeline.idx = 0;
+	G.pipeline.buf = xmalloc(PIPE_GROW);
+	G.pipeline.len = PIPE_GROW;
+	G.pipeline.idx = 0;
 
 	/* Now loop through, substituting for matches */
 	do {
@@ -644,7 +645,7 @@
 		   echo " a.b" | busybox sed 's [^ .]* x g'
 		   The match_count check is so not to break
 		   echo "hi" | busybox sed 's/^/!/g' */
-		if (!bbg.regmatch[0].rm_so && !bbg.regmatch[0].rm_eo && match_count) {
+		if (!G.regmatch[0].rm_so && !G.regmatch[0].rm_eo && match_count) {
 			pipe_putc(*oldline++);
 			continue;
 		}
@@ -654,26 +655,26 @@
 		/* If we aren't interested in this match, output old line to
 		   end of match and continue */
 		if (sed_cmd->which_match && sed_cmd->which_match != match_count) {
-			for (i = 0; i < bbg.regmatch[0].rm_eo; i++)
+			for (i = 0; i < G.regmatch[0].rm_eo; i++)
 				pipe_putc(*oldline++);
 			continue;
 		}
 
 		/* print everything before the match */
-		for (i = 0; i < bbg.regmatch[0].rm_so; i++)
+		for (i = 0; i < G.regmatch[0].rm_so; i++)
 			pipe_putc(oldline[i]);
 
 		/* then print the substitution string */
 		do_subst_w_backrefs(oldline, sed_cmd->string);
 
 		/* advance past the match */
-		oldline += bbg.regmatch[0].rm_eo;
+		oldline += G.regmatch[0].rm_eo;
 		/* flag that something has changed */
 		altered++;
 
 		/* if we're not doing this globally, get out now */
 		if (sed_cmd->which_match) break;
-	} while (*oldline && (regexec(current_regex, oldline, 10, bbg.regmatch, 0) != REG_NOMATCH));
+	} while (*oldline && (regexec(current_regex, oldline, 10, G.regmatch, 0) != REG_NOMATCH));
 
 	/* Copy rest of string into output pipeline */
 
@@ -682,7 +683,7 @@
 	pipe_putc(0);
 
 	free(*line);
-	*line = bbg.pipeline.buf;
+	*line = G.pipeline.buf;
 	return altered;
 }
 
@@ -691,7 +692,7 @@
 {
 	sed_cmd_t *sed_cmd;
 
-	for (sed_cmd = bbg.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) {
+	for (sed_cmd = G.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) {
 		if (sed_cmd->cmd == ':' && sed_cmd->string && !strcmp(sed_cmd->string, label)) {
 			return sed_cmd;
 		}
@@ -701,7 +702,7 @@
 
 static void append(char *s)
 {
-	llist_add_to_end(&bbg.append_head, xstrdup(s));
+	llist_add_to_end(&G.append_head, xstrdup(s));
 }
 
 static void flush_append(void)
@@ -709,20 +710,20 @@
 	char *data;
 
 	/* Output appended lines. */
-	while ((data = (char *)llist_pop(&bbg.append_head))) {
-		fprintf(bbg.nonstdout, "%s\n", data);
+	while ((data = (char *)llist_pop(&G.append_head))) {
+		fprintf(G.nonstdout, "%s\n", data);
 		free(data);
 	}
 }
 
 static void add_input_file(FILE *file)
 {
-	bbg.input_file_list = xrealloc(bbg.input_file_list,
-			(bbg.input_file_count + 1) * sizeof(FILE *));
-	bbg.input_file_list[bbg.input_file_count++] = file;
+	G.input_file_list = xrealloc(G.input_file_list,
+			(G.input_file_count + 1) * sizeof(FILE *));
+	G.input_file_list[G.input_file_count++] = file;
 }
 
-/* Get next line of input from bbg.input_file_list, flushing append buffer and
+/* Get next line of input from G.input_file_list, flushing append buffer and
  * noting if we ran out of files without a newline on the last line we read.
  */
 enum {
@@ -740,8 +741,8 @@
 	/* will be returned if last line in the file
 	 * doesn't end with either '\n' or '\0' */
 	gc = NO_EOL_CHAR;
-	while (bbg.current_input_file < bbg.input_file_count) {
-		FILE *fp = bbg.input_file_list[bbg.current_input_file];
+	while (G.current_input_file < G.input_file_count) {
+		FILE *fp = G.input_file_list[G.current_input_file];
 		/* Read line up to a newline or NUL byte, inclusive,
 		 * return malloc'ed char[]. length of the chunk read
 		 * is stored in len. NULL if EOF/error */
@@ -773,7 +774,7 @@
 		}
 		/* Close this file and advance to next one */
 		fclose(fp);
-		bbg.current_input_file++;
+		G.current_input_file++;
 	}
 	*gets_char = gc;
 	return temp;
@@ -827,7 +828,7 @@
 	*last_puts_char = lpc;
 }
 
-#define sed_puts(s, n) (puts_maybe_newline(s, bbg.nonstdout, &last_puts_char, n))
+#define sed_puts(s, n) (puts_maybe_newline(s, G.nonstdout, &last_puts_char, n))
 
 /* Process all the lines in all the files */
 
@@ -858,7 +859,7 @@
 	linenum++;
 restart:
 	/* for every line, go through all the commands */
-	for (sed_cmd = bbg.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) {
+	for (sed_cmd = G.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) {
 		int old_matched, matched;
 
 		old_matched = sed_cmd->in_match;
@@ -916,7 +917,7 @@
 		if (sed_cmd->invert ? !matched : matched) {
 			/* Update last used regex in case a blank substitute BRE is found */
 			if (sed_cmd->beg_match) {
-				bbg.previous_regex_ptr = sed_cmd->beg_match;
+				G.previous_regex_ptr = sed_cmd->beg_match;
 			}
 
 			/* actual sedding */
@@ -924,7 +925,7 @@
 
 			/* Print line number */
 			case '=':
-				fprintf(bbg.nonstdout, "%d\n", linenum);
+				fprintf(G.nonstdout, "%d\n", linenum);
 				break;
 
 			/* Write the current pattern space up to the first newline */
@@ -1026,7 +1027,7 @@
 
 			/* Read next line from input */
 			case 'n':
-				if (!bbg.be_quiet)
+				if (!G.be_quiet)
 					sed_puts(pattern_space, last_gets_char);
 				if (next_line) {
 					free(pattern_space);
@@ -1099,7 +1100,7 @@
 			}
 			case 'g':	/* Replace pattern space with hold space */
 				free(pattern_space);
-				pattern_space = xstrdup(bbg.hold_space ? bbg.hold_space : "");
+				pattern_space = xstrdup(G.hold_space ? G.hold_space : "");
 				break;
 			case 'G':	/* Append newline and hold space to pattern space */
 			{
@@ -1108,49 +1109,49 @@
 
 				if (pattern_space)
 					pattern_space_size += strlen(pattern_space);
-				if (bbg.hold_space)
-					hold_space_size = strlen(bbg.hold_space);
+				if (G.hold_space)
+					hold_space_size = strlen(G.hold_space);
 				pattern_space = xrealloc(pattern_space,
 						pattern_space_size + hold_space_size);
 				if (pattern_space_size == 2)
 					pattern_space[0] = 0;
 				strcat(pattern_space, "\n");
-				if (bbg.hold_space)
-					strcat(pattern_space, bbg.hold_space);
+				if (G.hold_space)
+					strcat(pattern_space, G.hold_space);
 				last_gets_char = '\n';
 
 				break;
 			}
 			case 'h':	/* Replace hold space with pattern space */
-				free(bbg.hold_space);
-				bbg.hold_space = xstrdup(pattern_space);
+				free(G.hold_space);
+				G.hold_space = xstrdup(pattern_space);
 				break;
 			case 'H':	/* Append newline and pattern space to hold space */
 			{
 				int hold_space_size = 2;
 				int pattern_space_size = 0;
 
-				if (bbg.hold_space)
-					hold_space_size += strlen(bbg.hold_space);
+				if (G.hold_space)
+					hold_space_size += strlen(G.hold_space);
 				if (pattern_space)
 					pattern_space_size = strlen(pattern_space);
-				bbg.hold_space = xrealloc(bbg.hold_space,
+				G.hold_space = xrealloc(G.hold_space,
 						hold_space_size + pattern_space_size);
 
 				if (hold_space_size == 2)
-					*bbg.hold_space = 0;
-				strcat(bbg.hold_space, "\n");
+					*G.hold_space = 0;
+				strcat(G.hold_space, "\n");
 				if (pattern_space)
-					strcat(bbg.hold_space, pattern_space);
+					strcat(G.hold_space, pattern_space);
 
 				break;
 			}
 			case 'x': /* Exchange hold and pattern space */
 			{
 				char *tmp = pattern_space;
-				pattern_space = bbg.hold_space ? : xzalloc(1);
+				pattern_space = G.hold_space ? : xzalloc(1);
 				last_gets_char = '\n';
-				bbg.hold_space = tmp;
+				G.hold_space = tmp;
 				break;
 			}
 			}
@@ -1163,7 +1164,7 @@
  discard_commands:
 	/* we will print the line unless we were told to be quiet ('-n')
 	   or if the line was suppressed (ala 'd'elete) */
-	if (!bbg.be_quiet)
+	if (!G.be_quiet)
 		sed_puts(pattern_space, last_gets_char);
 
 	/* Delete and such jump here. */
@@ -1232,6 +1233,8 @@
 	free(opt_f);
 }
 
+void BUG_sed_globals_too_big(void);
+
 int sed_main(int argc, char **argv);
 int sed_main(int argc, char **argv)
 {
@@ -1242,8 +1245,11 @@
 	llist_t *opt_e, *opt_f;
 	int status = EXIT_SUCCESS;
 
-	bbg.sed_cmd_tail = &bbg.sed_cmd_head;
+	if (sizeof(struct globals) > sizeof(bb_common_bufsiz1))
+	        BUG_sed_globals_too_big();
 
+	G.sed_cmd_tail = &G.sed_cmd_head;
+
 	/* destroy command strings on exit */
 	if (ENABLE_FEATURE_CLEAN_UP) atexit(sed_free_and_close_stuff);
 
@@ -1258,14 +1264,14 @@
 	opt_complementary = "e::f::" /* can occur multiple times */
 	                    "nn"; /* count -n */
 	opt = getopt32(argc, argv, "irne:f:", &opt_e, &opt_f,
-			    &bbg.be_quiet); /* counter for -n */
+			    &G.be_quiet); /* counter for -n */
 	argc -= optind;
 	argv += optind;
 	if (opt & OPT_in_place) { // -i
 		atexit(cleanup_outname);
 	}
-	if (opt & 0x2) bbg.regex_type |= REG_EXTENDED; // -r
-	//if (opt & 0x4) bbg.be_quiet++; // -n
+	if (opt & 0x2) G.regex_type |= REG_EXTENDED; // -r
+	//if (opt & 0x4) G.be_quiet++; // -n
 	if (opt & 0x8) { // -e
 		/* getopt32 reverses order of arguments, handle it */
 		add_cmds_link(opt_e);
@@ -1285,7 +1291,7 @@
 	add_cmd("");
 
 	/* By default, we write to stdout */
-	bbg.nonstdout = stdout;
+	G.nonstdout = stdout;
 
 	/* argv[0..(argc-1)] should be names of file to process. If no
 	 * files were specified or '-' was specified, take input from stdin.
@@ -1318,11 +1324,11 @@
 				continue;
 			}
 
-			bbg.outname = xasprintf("%sXXXXXX", argv[i]);
-			nonstdoutfd = mkstemp(bbg.outname);
+			G.outname = xasprintf("%sXXXXXX", argv[i]);
+			nonstdoutfd = mkstemp(G.outname);
 			if (-1 == nonstdoutfd)
-				bb_error_msg_and_die("no temp file");
-			bbg.nonstdout = fdopen(nonstdoutfd, "w");
+				bb_perror_msg_and_die("cannot create temp file %s", G.outname);
+			G.nonstdout = fdopen(nonstdoutfd, "w");
 
 			/* Set permissions of output file */
 
@@ -1330,16 +1336,16 @@
 			fchmod(nonstdoutfd, statbuf.st_mode);
 			add_input_file(file);
 			process_files();
-			fclose(bbg.nonstdout);
+			fclose(G.nonstdout);
 
-			bbg.nonstdout = stdout;
+			G.nonstdout = stdout;
 			/* unlink(argv[i]); */
 			// FIXME: error check / message?
-			rename(bbg.outname, argv[i]);
-			free(bbg.outname);
-			bbg.outname = 0;
+			rename(G.outname, argv[i]);
+			free(G.outname);
+			G.outname = 0;
 		}
-		if (bbg.input_file_count > bbg.current_input_file)
+		if (G.input_file_count > G.current_input_file)
 			process_files();
 	}
 




More information about the busybox-cvs mailing list