[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: Re: Sigh... Bumping the sed nul fix to 1.1.2.
From: "Roberto A. Foglietta" <me () roberto ! foglietta ! name>
Date: 2006-02-28 11:04:56
Message-ID: 44042E58.2010300 () roberto ! foglietta ! name
[Download RAW message or body]
Martijn de Gouw wrote:
>
> Why don't post two patches,
> 1) bug fix
> 2) name changes
>
Yes you are right, probably I am lazy... but I supposed that divide
renameing from patch was pretty simple (using sed on the patch itself):
svn co ...
cp -af busybox busybox.orig
cat sed_4-svn14360.patch | \
sed -e "s/lastchar/no_newline/g" >sed_4-svn14360_tmp.patch
patch -p0 <sed_3-svn14360_tmp.patch
mv busybox busybox_sed4
cp -a busybox.orig busybox
diff -pru busybox busybox_sed4 >sed_4-svn14360_norename.patch
In this way the patch size is resized to an half than before but a lot
of that patch is someting like that
-sed_puts(sed_cmd->string,0);
+sed_puts(sed_cmd->string,'\n');
-sed_puts(sed_cmd->string,1);
+sed_puts(sed_cmd->string,NONE);
Which is pretty simple to understand but could not stripped away by
sed in order to reduce patch. The patch concept is pretty simple: in
reading I save at the end of buffer, after ending \0 the "lastchar" and
depending of the nature of this "lastchar" I will put in the destination
file or ignore it. Obviously the reading/buffer are modified a little
bit to read and contain that "lastchar"
I found also that patch does not apply at svn so I attached new one at
the end of this mail. To test them:
dd if=/dev/zero bs=1k count=1 >/tmp/test
echo ciao>>/tmp/test
dd if=/dev/zero bs=1k count=1 >>/tmp/test
cat /tmp/test | ./busybox sed -e "s/ciao/miao/g" >/tmp/test2
wc -l /tmp/test*
du -b /tmp/test*
I am going to put them in the bugs system.
Cheers,
--
Roberto A. Foglietta
http://roberto.foglietta.name
http://lugge.net
["sed_4-svn14360.patch" (text/x-patch)]
diff -pru busybox/editors/sed.c busybox.14360_sed4a/editors/sed.c
--- busybox/editors/sed.c 2006-02-28 09:51:07.000000000 +0100
+++ busybox.14360_sed4a/editors/sed.c 2006-02-28 11:34:18.000000000 +0100
@@ -67,6 +67,8 @@
#include "busybox.h"
#include "xregex.h"
+#define NONE EOF
+#define sed_cmd_t_null {0,0,0, 0,0, 0,0, 0, 0,0,EOF,0, 0,0}
typedef struct sed_cmd_s {
/* Ordered by alignment requirements: currently 36 bytes on x86 */
@@ -85,7 +87,7 @@ typedef struct sed_cmd_s {
/* Bitfields (gcc won't group them if we don't) */
unsigned int invert:1; /* the '!' after the address */
unsigned int in_match:1; /* Next line also included in match? */
- unsigned int no_newline:1; /* Last line written by (sw) had no '\n' */
+ unsigned int lastchar:1; /* Last line written by (sw) had no '\n' */
unsigned int sub_p:1; /* (s) print option */
@@ -112,7 +114,7 @@ static regmatch_t regmatch[10];
static regex_t *previous_regex_ptr;
/* linked list of sed commands */
-static sed_cmd_t sed_cmd_head;
+static sed_cmd_t sed_cmd_head = sed_cmd_t_null;
static sed_cmd_t *sed_cmd_tail = &sed_cmd_head;
/* Linked list of append lines */
@@ -726,20 +728,23 @@ static void add_input_file(FILE *file)
/* Get next line of input from input_file_list, flushing append buffer and
* noting if we ran out of files without a newline on the last line we read.
*/
-static char *get_next_line(int *no_newline)
+static char *get_next_line(int *lastchar)
{
char *temp=NULL;
int len;
flush_append();
while (current_input_file<input_file_count) {
- temp = bb_get_chunk_from_file(input_file_list[current_input_file],&len);
+ temp = bb_get_chunk_from_file(input_file_list[current_input_file],NULL);
if (temp) {
- *no_newline = !(len && temp[len-1]=='\n');
- if (!*no_newline) temp[len-1] = 0;
+ len = 0; while(temp[len]) len++;
+ *lastchar = *(int *)&temp[len+1];
break;
// Close this file and advance to next one
- } else fclose(input_file_list[current_input_file++]);
+ } else {
+ fclose(input_file_list[current_input_file++]);
+ *lastchar=NONE;
+ }
}
return temp;
@@ -749,18 +754,18 @@ static char *get_next_line(int *no_newli
end with a newline. no_newline means this line does not end with a
newline. */
-static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int \
no_newline) +static int puts_maybe_newline(char *s, FILE *file, int missing, int \
lastchar) {
- if(missing_newline) fputc('\n',file);
- fputs(s,file);
- if(!no_newline) fputc('\n',file);
- if(ferror(file)) {
- fprintf(stderr,"Write failed.\n");
- exit(4); /* It's what gnu sed exits with... */
- }
+ if(missing==NONE) //missing to do not miss the '\n' between two streams!
+ fputc('\n',file);
+ fputs(s,file);
+ if(lastchar!=NONE)
+ fputc(lastchar,file);
+ if(ferror(file))
+ bb_perror_msg_and_die("Write failed");
- return no_newline;
+ return lastchar;
}
#define sed_puts(s,n) \
missing_newline=puts_maybe_newline(s,nonstdout,missing_newline,n) @@ -771,10 +776,10 \
@@ static void process_files(void) {
char *pattern_space, *next_line;
int linenum = 0, missing_newline=0;
- int no_newline,next_no_newline=0;
+ int next_lastchar=NONE, lastchar=NONE;
/* Prime the pump */
- next_line = get_next_line(&next_no_newline);
+ next_line = get_next_line(&next_lastchar);
/* go through every line in each file */
for(;;) {
@@ -783,11 +788,11 @@ static void process_files(void)
/* Advance to next line. Stop if out of lines. */
if(!(pattern_space=next_line)) break;
- no_newline=next_no_newline;
+ lastchar=next_lastchar;
/* Read one line in advance so we can act on the last line,
* the '$' address */
- next_line = get_next_line(&next_no_newline);
+ next_line = get_next_line(&next_lastchar);
linenum++;
restart:
/* for every line, go through all the commands */
@@ -865,7 +870,7 @@ restart:
if (tmp) {
*tmp = '\0';
- sed_puts(pattern_space,1);
+ sed_puts(pattern_space,NONE);
*tmp = '\n';
break;
}
@@ -874,7 +879,7 @@ restart:
/* Write the current pattern space to output */
case 'p':
- sed_puts(pattern_space,no_newline);
+ sed_puts(pattern_space,lastchar);
break;
/* Delete up through first newline */
case 'D':
@@ -899,11 +904,10 @@ restart:
/* handle p option */
if(sed_cmd->sub_p)
- sed_puts(pattern_space,no_newline);
+ sed_puts(pattern_space,lastchar);
/* handle w option */
if(sed_cmd->file)
- sed_cmd->no_newline=puts_maybe_newline(pattern_space, sed_cmd->file, \
sed_cmd->no_newline, no_newline);
-
+ sed_cmd->lastchar=puts_maybe_newline(pattern_space, sed_cmd->file, \
sed_cmd->lastchar, lastchar); }
break;
@@ -916,13 +920,13 @@ restart:
/* Insert text before this line */
case 'i':
- sed_puts(sed_cmd->string,1);
+ sed_puts(sed_cmd->string,NONE);
break;
/* Cut and paste text (replace) */
case 'c':
/* Only triggers on last line of a matching range. */
- if (!sed_cmd->in_match) sed_puts(sed_cmd->string,0);
+ if (!sed_cmd->in_match) sed_puts(sed_cmd->string,'\n');
goto discard_line;
/* Read file, append contents to output */
@@ -945,18 +949,18 @@ restart:
/* Write pattern space to file. */
case 'w':
- sed_cmd->no_newline=puts_maybe_newline(pattern_space,sed_cmd->file, \
sed_cmd->no_newline,no_newline); \
+ sed_cmd->lastchar=puts_maybe_newline(pattern_space,sed_cmd->file, \
sed_cmd->lastchar,lastchar); break;
/* Read next line from input */
case 'n':
if (!be_quiet)
- sed_puts(pattern_space,no_newline);
+ sed_puts(pattern_space,lastchar);
if (next_line) {
free(pattern_space);
pattern_space = next_line;
- no_newline=next_no_newline;
- next_line = get_next_line(&next_no_newline);
+ lastchar=next_lastchar;
+ next_line = get_next_line(&next_lastchar);
linenum++;
break;
}
@@ -985,8 +989,8 @@ restart:
pattern_space = realloc(pattern_space, len + strlen(next_line) + 2);
pattern_space[len]='\n';
strcpy(pattern_space+len+1, next_line);
- no_newline=next_no_newline;
- next_line = get_next_line(&next_no_newline);
+ lastchar=next_lastchar;
+ next_line = get_next_line(&next_lastchar);
linenum++;
}
break;
@@ -1040,8 +1044,7 @@ restart:
if (pattern_space_size == 2) pattern_space[0]=0;
strcat(pattern_space, "\n");
if (hold_space) strcat(pattern_space, hold_space);
- no_newline=0;
-
+ lastchar='\n';
break;
}
case 'h': /* Replace hold space with pattern space */
@@ -1069,7 +1072,7 @@ restart:
{
char *tmp = pattern_space;
pattern_space = hold_space;
- no_newline=0;
+ lastchar='\n';
hold_space = tmp;
break;
}
@@ -1083,7 +1086,7 @@ restart:
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 (!be_quiet) sed_puts(pattern_space,no_newline);
+ if (!be_quiet) sed_puts(pattern_space,lastchar);
/* Delete and such jump here. */
discard_line:
diff -pru busybox/libbb/get_line_from_file.c \
busybox.14360_sed4a/libbb/get_line_from_file.c
--- busybox/libbb/get_line_from_file.c 2006-02-28 09:50:35.000000000 +0100
+++ busybox.14360_sed4a/libbb/get_line_from_file.c 2006-02-28 11:30:42.000000000 \
+0100 @@ -16,7 +16,7 @@
/* get_line_from_file() - This function reads an entire line from a text file,
* up to a newline or NUL byte. It returns a malloc'ed char * which must be
* stored and free'ed by the caller. If end is null '\n' isn't considered
- * and of line. If end isn't null, length of the chunk read is stored in it. */
+ * end of line. If end isn't null, length of the chunk read is stored in it. */
char *bb_get_chunk_from_file(FILE *file, int *end)
{
@@ -27,11 +27,15 @@ char *bb_get_chunk_from_file(FILE *file,
while ((ch = getc(file)) != EOF) {
/* grow the line buffer as necessary */
- if (idx > linebufsz - 2) {
+ if (idx > linebufsz - 6) {
linebuf = xrealloc(linebuf, linebufsz += 80);
}
+ if(!ch) break;
linebuf[idx++] = (char)ch;
- if (!ch || (end && ch == '\n')) break;
+ if (ch == '\n') {
+ if(!end) --idx;
+ break;
+ }
}
if (end) *end = idx;
if (linebuf) {
@@ -39,7 +43,8 @@ char *bb_get_chunk_from_file(FILE *file,
free(linebuf);
return NULL;
}
- linebuf[idx] = 0;
+ linebuf[idx++] = 0;
+ *(int *)&linebuf[idx] = ch;
}
return linebuf;
}
@@ -54,9 +59,5 @@ extern char *bb_get_line_from_file(FILE
/* Get line. Remove trailing /n */
extern char *bb_get_chomped_line_from_file(FILE *file)
{
- int i;
- char *c=bb_get_chunk_from_file(file, &i);
- if(i) c[--i]=0;
-
- return c;
+ return bb_get_chunk_from_file(file, NULL);
}
["sed_4-svn14360_norename.patch" (text/x-patch)]
diff -pru busybox/editors/sed.c busybox_sed4/editors/sed.c
--- busybox/editors/sed.c 2006-02-28 09:51:07.000000000 +0100
+++ busybox_sed4/editors/sed.c 2006-02-28 11:59:43.000000000 +0100
@@ -67,6 +67,8 @@
#include "busybox.h"
#include "xregex.h"
+#define NONE EOF
+#define sed_cmd_t_null {0,0,0, 0,0, 0,0, 0, 0,0,EOF,0, 0,0}
typedef struct sed_cmd_s {
/* Ordered by alignment requirements: currently 36 bytes on x86 */
@@ -112,7 +114,7 @@ static regmatch_t regmatch[10];
static regex_t *previous_regex_ptr;
/* linked list of sed commands */
-static sed_cmd_t sed_cmd_head;
+static sed_cmd_t sed_cmd_head = sed_cmd_t_null;
static sed_cmd_t *sed_cmd_tail = &sed_cmd_head;
/* Linked list of append lines */
@@ -733,13 +735,16 @@ static char *get_next_line(int *no_newli
flush_append();
while (current_input_file<input_file_count) {
- temp = bb_get_chunk_from_file(input_file_list[current_input_file],&len);
+ temp = bb_get_chunk_from_file(input_file_list[current_input_file],NULL);
if (temp) {
- *no_newline = !(len && temp[len-1]=='\n');
- if (!*no_newline) temp[len-1] = 0;
+ len = 0; while(temp[len]) len++;
+ *no_newline = *(int *)&temp[len+1];
break;
// Close this file and advance to next one
- } else fclose(input_file_list[current_input_file++]);
+ } else {
+ fclose(input_file_list[current_input_file++]);
+ *no_newline=NONE;
+ }
}
return temp;
@@ -749,16 +754,16 @@ static char *get_next_line(int *no_newli
end with a newline. no_newline means this line does not end with a
newline. */
-static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int \
no_newline) +static int puts_maybe_newline(char *s, FILE *file, int missing, int \
no_newline) {
- if(missing_newline) fputc('\n',file);
- fputs(s,file);
- if(!no_newline) fputc('\n',file);
- if(ferror(file)) {
- fprintf(stderr,"Write failed.\n");
- exit(4); /* It's what gnu sed exits with... */
- }
+ if(missing==NONE) //missing to do not miss the '\n' between two streams!
+ fputc('\n',file);
+ fputs(s,file);
+ if(no_newline!=NONE)
+ fputc(no_newline,file);
+ if(ferror(file))
+ bb_perror_msg_and_die("Write failed");
return no_newline;
}
@@ -771,7 +776,7 @@ static void process_files(void)
{
char *pattern_space, *next_line;
int linenum = 0, missing_newline=0;
- int no_newline,next_no_newline=0;
+ int next_no_newline=NONE, no_newline=NONE;
/* Prime the pump */
next_line = get_next_line(&next_no_newline);
@@ -865,7 +870,7 @@ restart:
if (tmp) {
*tmp = '\0';
- sed_puts(pattern_space,1);
+ sed_puts(pattern_space,NONE);
*tmp = '\n';
break;
}
@@ -903,7 +908,6 @@ restart:
/* handle w option */
if(sed_cmd->file)
sed_cmd->no_newline=puts_maybe_newline(pattern_space, sed_cmd->file, \
sed_cmd->no_newline, no_newline);
-
}
break;
@@ -916,13 +920,13 @@ restart:
/* Insert text before this line */
case 'i':
- sed_puts(sed_cmd->string,1);
+ sed_puts(sed_cmd->string,NONE);
break;
/* Cut and paste text (replace) */
case 'c':
/* Only triggers on last line of a matching range. */
- if (!sed_cmd->in_match) sed_puts(sed_cmd->string,0);
+ if (!sed_cmd->in_match) sed_puts(sed_cmd->string,'\n');
goto discard_line;
/* Read file, append contents to output */
@@ -1040,8 +1044,7 @@ restart:
if (pattern_space_size == 2) pattern_space[0]=0;
strcat(pattern_space, "\n");
if (hold_space) strcat(pattern_space, hold_space);
- no_newline=0;
-
+ no_newline='\n';
break;
}
case 'h': /* Replace hold space with pattern space */
@@ -1069,7 +1072,7 @@ restart:
{
char *tmp = pattern_space;
pattern_space = hold_space;
- no_newline=0;
+ no_newline='\n';
hold_space = tmp;
break;
}
diff -pru busybox/libbb/get_line_from_file.c busybox_sed4/libbb/get_line_from_file.c
--- busybox/libbb/get_line_from_file.c 2006-02-28 09:50:35.000000000 +0100
+++ busybox_sed4/libbb/get_line_from_file.c 2006-02-28 11:59:43.000000000 +0100
@@ -16,7 +16,7 @@
/* get_line_from_file() - This function reads an entire line from a text file,
* up to a newline or NUL byte. It returns a malloc'ed char * which must be
* stored and free'ed by the caller. If end is null '\n' isn't considered
- * and of line. If end isn't null, length of the chunk read is stored in it. */
+ * end of line. If end isn't null, length of the chunk read is stored in it. */
char *bb_get_chunk_from_file(FILE *file, int *end)
{
@@ -27,11 +27,15 @@ char *bb_get_chunk_from_file(FILE *file,
while ((ch = getc(file)) != EOF) {
/* grow the line buffer as necessary */
- if (idx > linebufsz - 2) {
+ if (idx > linebufsz - 6) {
linebuf = xrealloc(linebuf, linebufsz += 80);
}
+ if(!ch) break;
linebuf[idx++] = (char)ch;
- if (!ch || (end && ch == '\n')) break;
+ if (ch == '\n') {
+ if(!end) --idx;
+ break;
+ }
}
if (end) *end = idx;
if (linebuf) {
@@ -39,7 +43,8 @@ char *bb_get_chunk_from_file(FILE *file,
free(linebuf);
return NULL;
}
- linebuf[idx] = 0;
+ linebuf[idx++] = 0;
+ *(int *)&linebuf[idx] = ch;
}
return linebuf;
}
@@ -54,9 +59,5 @@ extern char *bb_get_line_from_file(FILE
/* Get line. Remove trailing /n */
extern char *bb_get_chomped_line_from_file(FILE *file)
{
- int i;
- char *c=bb_get_chunk_from_file(file, &i);
- if(i) c[--i]=0;
-
- return c;
+ return bb_get_chunk_from_file(file, NULL);
}
_______________________________________________
busybox mailing list
busybox@busybox.net
http://busybox.net/cgi-bin/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic