diff options
author | Rob Landley <rob@landley.net> | 2006-02-24 05:30:39 +0300 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2006-02-24 05:30:39 +0300 |
commit | 2b26fd5570ebd6efb395aac4773051a5f3ed4dcd (patch) | |
tree | 432c38fd4819faa22fb61c5f5a7114774a97493b | |
parent | 5c22c11de2dacac3c024a70ae01ee7afb64dddb8 (diff) |
A few changes falling out from the effort to make sed handle embedded NUL bytes.
Checking in to reduce the diff between my tree and svn...
-rw-r--r-- | coreutils/sort.c | 18 | ||||
-rw-r--r-- | editors/sed.c | 44 | ||||
-rw-r--r-- | libbb/get_line_from_file.c | 66 |
3 files changed, 50 insertions, 78 deletions
diff --git a/coreutils/sort.c b/coreutils/sort.c index b56a5abb8..98cea7cd7 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c @@ -4,19 +4,9 @@ * * Copyright (C) 2004 by Rob Landley <rob@landley.net> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * MAINTAINER: Rob Landley <rob@landley.net> + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. * * See SuS3 sort standard at: * http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html @@ -142,7 +132,7 @@ static struct sort_key *add_key(void) return *pkey=xcalloc(1,sizeof(struct sort_key)); } -#define GET_LINE(fp) (global_flags&FLAG_z) ? bb_get_chunk_from_file(fp) \ +#define GET_LINE(fp) (global_flags&FLAG_z) ? bb_get_chunk_from_file(fp,NULL) \ : bb_get_chomped_line_from_file(fp) #else #define GET_LINE(fp) bb_get_chomped_line_from_file(fp) diff --git a/editors/sed.c b/editors/sed.c index dcc2ca06b..b08eae4dc 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -8,6 +8,8 @@ * Copyright (C) 2003 by Glenn McGrath <bug1@iinet.net.au> * Copyright (C) 2003,2004 by Rob Landley <rob@landley.net> * + * MAINTAINER: Rob Landley <rob@landley.net> + * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ @@ -74,8 +76,8 @@ typedef struct sed_cmd_s { regex_t *sub_match; /* For 's/sub_match/string/' */ int beg_line; /* 'sed 1p' 0 == apply commands to all lines */ int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($) */ - - FILE *file; /* File (sr) command writes to, -1 for none. */ + + FILE *file; /* File (sw) command writes to, -1 for none. */ char *string; /* Data string for (saicytb) commands. */ unsigned short which_match; /* (s) Which match to replace (0 for all) */ @@ -83,7 +85,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 (sr) had no '\n' */ + unsigned int no_newline:1; /* Last line written by (sw) had no '\n' */ unsigned int sub_p:1; /* (s) print option */ @@ -120,6 +122,7 @@ struct append_list { }; static struct append_list *append_head=NULL, *append_tail=NULL; +void free_and_close_stuff(void); #ifdef CONFIG_FEATURE_CLEAN_UP static void free_and_close_stuff(void) { @@ -729,13 +732,13 @@ static char *get_next_line(int *no_newline) int len; flush_append(); - while(current_input_file<input_file_count) { - temp=bb_get_line_from_file(input_file_list[current_input_file]); - if(temp) { - len=strlen(temp); - *no_newline=!(len && temp[len-1]=='\n'); - if(!*no_newline) temp[len-1]=0; + while (current_input_file<input_file_count) { + temp = bb_get_chunk_from_file(input_file_list[current_input_file],&len); + if (temp) { + *no_newline = !(len && temp[len-1]=='\n'); + if (!*no_newline) temp[len-1] = 0; break; + // Close this file and advance to next one } else fclose(input_file_list[current_input_file++]); } @@ -762,12 +765,15 @@ static int puts_maybe_newline(char *s, FILE *file, int missing_newline, int no_n #define sed_puts(s,n) missing_newline=puts_maybe_newline(s,nonstdout,missing_newline,n) +/* Process all the lines in all the files */ + static void process_files(void) { char *pattern_space, *next_line; int linenum = 0, missing_newline=0; int no_newline,next_no_newline=0; + /* Prime the pump */ next_line = get_next_line(&next_no_newline); /* go through every line in each file */ @@ -779,7 +785,8 @@ static void process_files(void) if(!(pattern_space=next_line)) break; no_newline=next_no_newline; - /* Read one line in advance so we can act on the last line, the '$' address */ + /* Read one line in advance so we can act on the last line, + * the '$' address */ next_line = get_next_line(&next_no_newline); linenum++; restart: @@ -921,16 +928,16 @@ restart: /* Read file, append contents to output */ case 'r': { - FILE *outfile; + FILE *rfile; - outfile = fopen(sed_cmd->string, "r"); - if (outfile) { + rfile = fopen(sed_cmd->string, "r"); + if (rfile) { char *line; - while ((line = bb_get_chomped_line_from_file(outfile)) + while ((line = bb_get_chomped_line_from_file(rfile)) != NULL) append(line); - bb_xprint_and_close_file(outfile); + bb_xprint_and_close_file(rfile); } break; @@ -1107,11 +1114,9 @@ extern int sed_main(int argc, char **argv) { int status = EXIT_SUCCESS, opt, getpat = 1; -#ifdef CONFIG_FEATURE_CLEAN_UP /* destroy command strings on exit */ - if (atexit(free_and_close_stuff) == -1) + if (ENABLE_FEATURE_CLEAN_UP && atexit(free_and_close_stuff) == -1) bb_perror_msg_and_die("atexit"); -#endif /* Lie to autoconf when it starts asking stupid questions. */ if(argc==2 && !strcmp(argv[1],"--version")) { @@ -1197,12 +1202,15 @@ extern int sed_main(int argc, char **argv) if(-1==(nonstdoutfd=mkstemp(outname))) bb_error_msg_and_die("no temp file"); nonstdout=fdopen(nonstdoutfd,"w"); + /* Set permissions of output file */ + fstat(fileno(file),&statbuf); fchmod(nonstdoutfd,statbuf.st_mode); add_input_file(file); process_files(); fclose(nonstdout); + nonstdout=stdout; unlink(argv[i]); rename(outname,argv[i]); diff --git a/libbb/get_line_from_file.c b/libbb/get_line_from_file.c index a27edc3bd..5ad497ffa 100644 --- a/libbb/get_line_from_file.c +++ b/libbb/get_line_from_file.c @@ -2,22 +2,11 @@ /* * Utility routines. * - * Copyright (C) many different people. - * If you wrote this, please acknowledge your work. + * Copyright (C) 2005, 2006 Rob Landley <rob@landley.net> + * Copyright (C) 2004 Erik Andersen <andersen@codepoet.org> + * Copyright (C) 2001 Matt Krai * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ #include <stdio.h> @@ -25,14 +14,12 @@ #include "libbb.h" /* get_line_from_file() - This function reads an entire line from a text file, - * up to a newline. It returns a malloc'ed char * which must be stored and - * free'ed by the caller. If 'c' is nonzero, the trailing '\n' (if any) - * is removed. In event of a read error or EOF, NULL is returned. */ + * 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. */ -static char *private_get_line_from_file(FILE *file, int c) +char *bb_get_chunk_from_file(FILE *file, int *end) { -#define GROWBY (80) /* how large we will grow strings by */ - int ch; int idx = 0; char *linebuf = NULL; @@ -41,17 +28,12 @@ static char *private_get_line_from_file(FILE *file, int c) while ((ch = getc(file)) != EOF) { /* grow the line buffer as necessary */ if (idx > linebufsz - 2) { - linebuf = xrealloc(linebuf, linebufsz += GROWBY); + linebuf = xrealloc(linebuf, linebufsz += 80); } linebuf[idx++] = (char)ch; - if (!ch) return linebuf; - if (c<2 && ch == '\n') { - if (c) { - --idx; - } - break; - } + if (!ch || (end && ch == '\n')) break; } + if (end) *end = idx; if (linebuf) { if (ferror(file)) { free(linebuf); @@ -62,27 +44,19 @@ static char *private_get_line_from_file(FILE *file, int c) return linebuf; } +/* Get line, including trailing /n if any */ extern char *bb_get_line_from_file(FILE *file) { - return private_get_line_from_file(file, 0); + int i; + return bb_get_chunk_from_file(file, &i); } +/* Get line. Remove trailing /n */ extern char *bb_get_chomped_line_from_file(FILE *file) { - return private_get_line_from_file(file, 1); -} - -extern char *bb_get_chunk_from_file(FILE *file) -{ - return private_get_line_from_file(file, 2); + int i; + char *c=bb_get_chunk_from_file(file, &i); + if(i) c[--i]=0; + + return c; } - - -/* END CODE */ -/* -Local Variables: -c-file-style: "linux" -c-basic-offset: 4 -tab-width: 4 -End: -*/ |