diff options
author | Paolo Bonzini <bonzini@gnu.org> | 2012-02-05 11:19:12 +0100 |
---|---|---|
committer | Paolo Bonzini <bonzini@gnu.org> | 2012-03-16 08:50:10 +0100 |
commit | ee2a5bd0faa19f57107a1f3d17a6bc99600436a7 (patch) | |
tree | acfa7a3cad76465324871655aa0bf08841143acd | |
parent | aaf92634aa86655a3e14dd1a3f030fc74abd3a62 (diff) | |
download | sed-ee2a5bd0faa19f57107a1f3d17a6bc99600436a7.tar.gz |
add -z/--null-data
2012-02-05 Paolo Bonzini <bonzini@gnu.org>
Jim Hill <gjthill@gmail.com>
* autoboot.conf: Change getline to getdelim.
* doc/sed-in.texi: Document -z/--null-data.
* doc/sed.texi: Regenerate.
* sed/execute.c: Change '\n' to buffer_delimiter.
* sed/sed.c: Add support for -z/--null-data.
* sed/sed.h: Add buffer_delimiter.
* sed/utils.c: Change ck_getline to ck_getdelim.
* sed/utils.h: Change ck_getline to ck_getdelim.
* NEWS: Document new option.
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | autoboot.conf | 6 | ||||
-rw-r--r-- | doc/sed-in.texi | 10 | ||||
-rw-r--r-- | doc/sed.1 | 10 | ||||
-rw-r--r-- | doc/sed.texi | 10 | ||||
-rw-r--r-- | sed/execute.c | 25 | ||||
-rw-r--r-- | sed/sed.c | 15 | ||||
-rw-r--r-- | sed/sed.h | 3 | ||||
-rw-r--r-- | sed/utils.c | 5 | ||||
-rw-r--r-- | sed/utils.h | 2 |
10 files changed, 77 insertions, 23 deletions
@@ -1,3 +1,17 @@ +2012-02-05 Paolo Bonzini <bonzini@gnu.org> + Jim Hill <gjthill@gmail.com> + + * autoboot.conf: Change getline to getdelim. + * doc/sed-in.texi: Document -z/--null-data. + * doc/sed.texi: Regenerate. + * doc/sed.1: Regenerate. + * sed/execute.c: Change '\n' to buffer_delimiter. + * sed/sed.c: Add support for -z/--null-data. + * sed/sed.h: Add buffer_delimiter. + * sed/utils.c: Change ck_getline to ck_getdelim. + * sed/utils.h: Change ck_getline to ck_getdelim. + * NEWS: Document new option. + 2010-07-18 Paolo Bonzini <bonzini@gnu.org> * sed.c (write_mode): New. diff --git a/autoboot.conf b/autoboot.conf index bdc54bc..2965e22 100644 --- a/autoboot.conf +++ b/autoboot.conf @@ -18,9 +18,9 @@ # gnulib modules used by this package. gnulib_modules=" - acl alloca btowc extensions fwriting getline getopt gettext-h - localcharset mbrlen mbrtowc memchr mbsinit mkostemp obstack pathmax - rename selinux-h snprintf stdbool stat-macros strerror strverscmp ssize_t + acl alloca btowc c-ctype extensions fwriting getdelim getopt gettext-h + localcharset mbrlen mbrtowc memchr mbsinit mkostemp obstack pathmax snprintf + rename selinux-h stdbool stat-macros ssize_t strerror strverscmp unlocked-io vasnprintf verify version-etc-fsf wcrtomb wctob" SKIP_PO=t diff --git a/doc/sed-in.texi b/doc/sed-in.texi index 1c28d66..4f6f864 100644 --- a/doc/sed-in.texi +++ b/doc/sed-in.texi @@ -369,6 +369,16 @@ Buffer both input and output as minimally as practical. the likes of @samp{tail -f}, and you wish to see the transformed output as soon as possible.) +@item -z +@itemx --null-data +@itemx --zero-terminated +@opindex -z +@opindex --null-data +@opindex --zero-terminated +Treat the input as a set of lines, each terminated by a zero byte +(the ASCII @samp{NUL} character) instead of a newline. This option can +be used with commands like @samp{sort -z} and @samp{find -print0} +to process arbitrary file names. @end table If no @option{-e}, @option{-f}, @option{--expression}, or @option{--file} @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.28. -.TH SED "1" "December 2010" "sed (super-sed) 3.63" "User Commands" +.TH SED "1" "February 2012" "sed (super-sed) 3.63" "User Commands" .SH NAME sed \- stream editor for filtering and transforming text .SH SYNOPSIS @@ -38,7 +38,7 @@ follow symlinks when processing in place .HP \fB\-i[SUFFIX]\fR, \fB\-\-in\-place\fR[=\fISUFFIX\fR] .IP -edit files in place (makes backup if extension supplied) +edit files in place (makes backup if SUFFIX supplied) .HP \fB\-l\fR N, \fB\-\-line\-length\fR=\fIN\fR .IP @@ -65,6 +65,10 @@ long stream. .IP load minimal amounts of data from the input files and flush the output buffers more often +.HP +\fB\-z\fR, \fB\-\-null\-data\fR +.IP +separate lines by NUL characters .TP \fB\-\-help\fR display this help and exit @@ -375,7 +379,7 @@ and Paolo Bonzini. E-mail bug reports to: <bonzini@gnu.org>. Be sure to include the word ``ssed'' somewhere in the ``Subject:'' field. .SH COPYRIGHT -Copyright \(co 2010 Free Software Foundation, Inc. +Copyright \(co 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>. .br This is free software: you are free to change and redistribute it. diff --git a/doc/sed.texi b/doc/sed.texi index ff2a559..2f179b3 100644 --- a/doc/sed.texi +++ b/doc/sed.texi @@ -370,6 +370,16 @@ Buffer both input and output as minimally as practical. the likes of @samp{tail -f}, and you wish to see the transformed output as soon as possible.) +@item -z +@itemx --null-data +@itemx --zero-terminated +@opindex -z +@opindex --null-data +@opindex --zero-terminated +Treat the input as a set of lines, each terminated by a zero byte +(the ASCII @samp{NUL} character) instead of a newline. This option can +be used with commands like @samp{sort -z} and @samp{find -print0} +to process arbitrary file names. @end table If no @option{-e}, @option{-f}, @option{--expression}, or @option{--file} diff --git a/sed/execute.c b/sed/execute.c index ccbebd0..34ce920 100644 --- a/sed/execute.c +++ b/sed/execute.c @@ -472,7 +472,7 @@ line_append(from, to, state) struct line *to; int state; { - str_append(to, "\n", 1); + str_append(to, &buffer_delimiter, 1); str_append(to, from->active, from->length); to->chomped = from->chomped; @@ -525,12 +525,12 @@ read_file_line(input) static char *b; static size_t blen; - long result = ck_getline (&b, &blen, input->fp); + long result = ck_getdelim (&b, &blen, buffer_delimiter, input->fp); if (result <= 0) return false; /* Remove the trailing new-line that is left by getline. */ - if (b[result - 1] == '\n') + if (b[result - 1] == buffer_delimiter) --result; else line.chomped = false; @@ -547,7 +547,7 @@ output_missing_newline(outf) { if (outf->missing_newline) { - ck_fwrite("\n", 1, 1, outf->fp); + ck_fwrite(&buffer_delimiter, 1, 1, outf->fp); outf->missing_newline = false; } } @@ -576,7 +576,7 @@ output_line(text, length, nl, outf) if (length) ck_fwrite(text, 1, length, outf->fp); if (nl) - ck_fwrite("\n", 1, 1, outf->fp); + ck_fwrite(&buffer_delimiter, 1, 1, outf->fp); else outf->missing_newline = true; @@ -1301,7 +1301,7 @@ do_subst(sub) for 'g' as to while the third argument is incorrect anyway. */ line_exchange(&line, &s_accum, true); if (line.length && - line.active[line.length - 1] == '\n') + line.active[line.length - 1] == buffer_delimiter) line.length--; } else @@ -1421,7 +1421,7 @@ execute_program(vec, input) case 'D': { - char *p = memchr(line.active, '\n', line.length); + char *p = memchr(line.active, buffer_delimiter, line.length); if (!p) return -1; @@ -1471,7 +1471,7 @@ execute_program(vec, input) { /* Store into pattern space for plain `e' commands */ if (s_accum.length && - s_accum.active[s_accum.length - 1] == '\n') + s_accum.active[s_accum.length - 1] == buffer_delimiter) s_accum.length--; /* Exchange line and s_accum. This can be much @@ -1552,7 +1552,7 @@ execute_program(vec, input) break; case 'N': - str_append(&line, "\n", 1); + str_append(&line, &buffer_delimiter, 1); if (test_eof(input) || !read_pattern_space(input, vec, true)) { @@ -1570,7 +1570,7 @@ execute_program(vec, input) case 'P': { - char *p = memchr(line.active, '\n', line.length); + char *p = memchr(line.active, buffer_delimiter, line.length); output_line(line.active, p ? p - line.active : line.length, p ? true : line.chomped, &output_file); } @@ -1600,7 +1600,8 @@ execute_program(vec, input) char *text = NULL; int result; - result = ck_getline (&text, &buflen, cur_cmd->x.fp); + result = ck_getdelim (&text, &buflen, buffer_delimiter, + cur_cmd->x.fp); if (result != EOF) { aq = next_append_slot(); @@ -1643,7 +1644,7 @@ execute_program(vec, input) case 'W': if (cur_cmd->x.fp) { - char *p = memchr(line.active, '\n', line.length); + char *p = memchr(line.active, buffer_delimiter, line.length); output_line(line.active, p ? p - line.active : line.length, p ? true : line.chomped, cur_cmd->x.outf); } @@ -66,6 +66,9 @@ char *program_name; int extended_regexp_flags = 0; +/* one-byte buffer delimiter */ +char buffer_delimiter = '\n'; + /* If set, fflush(stdout) on every line output. */ bool unbuffered = false; @@ -161,6 +164,8 @@ Usage: %s [OPTION]... {script-only-if-no-other-script} [input-file]...\n\ fprintf(out, _(" -u, --unbuffered\n\ load minimal amounts of data from the input files and flush\n\ the output buffers more often\n")); + fprintf(out, _(" -z, --null-data\n\ + separate lines by NUL characters\n")); fprintf(out, _(" --help display this help and exit\n")); fprintf(out, _(" --version output version information and exit\n")); fprintf(out, _("\n\ @@ -181,9 +186,9 @@ main(argc, argv) char **argv; { #ifdef REG_PERL -#define SHORTOPTS "bsnrRuEe:f:l:i::V:" +#define SHORTOPTS "bsnrzRuEe:f:l:i::V:" #else -#define SHORTOPTS "bsnruEe:f:l:i::V:" +#define SHORTOPTS "bsnrzuEe:f:l:i::V:" #endif static struct option longopts[] = { @@ -196,6 +201,8 @@ main(argc, argv) {"file", 1, NULL, 'f'}, {"in-place", 2, NULL, 'i'}, {"line-length", 1, NULL, 'l'}, + {"null-data", 0, NULL, 'z'}, + {"zero-terminated", 0, NULL, 'z'}, {"quiet", 0, NULL, 'n'}, {"posix", 0, NULL, 'p'}, {"silent", 0, NULL, 'n'}, @@ -259,6 +266,10 @@ main(argc, argv) the_program = compile_file(the_program, optarg); break; + case 'z': + buffer_delimiter = 0; + break; + case 'F': follow_symlinks = true; break; @@ -211,6 +211,9 @@ extern void fmt P_ ((const char *line, const char *line_end, int max_length, FIL extern int extended_regexp_flags; +/* one-byte buffer delimiter */ +extern char buffer_delimiter; + /* If set, fflush(stdout) on every line output, and turn off stream buffering on inputs. */ extern bool unbuffered; diff --git a/sed/utils.c b/sed/utils.c index 7a00f67..cb29b87 100644 --- a/sed/utils.c +++ b/sed/utils.c @@ -259,9 +259,10 @@ ck_fread(ptr, size, nmemb, stream) } size_t -ck_getline(text, buflen, stream) +ck_getdelim(text, buflen, buffer_delimiter, stream) char **text; size_t *buflen; + char buffer_delimiter; FILE *stream; { ssize_t result; @@ -270,7 +271,7 @@ ck_getline(text, buflen, stream) error = ferror (stream); if (!error) { - result = getline (text, buflen, stream); + result = getdelim (text, buflen, buffer_delimiter, stream); error = ferror (stream); } diff --git a/sed/utils.h b/sed/utils.h index aef8e65..9132e3d 100644 --- a/sed/utils.h +++ b/sed/utils.h @@ -29,7 +29,7 @@ size_t ck_fread P_((VOID *ptr, size_t size, size_t nmemb, FILE *stream)); void ck_fflush P_((FILE *stream)); void ck_fclose P_((FILE *stream)); const char *follow_symlink P_((const char *path)); -size_t ck_getline P_((char **text, size_t *buflen, FILE *stream)); +size_t ck_getdelim P_((char **text, size_t *buflen, char buffer_delimiter, FILE *stream)); FILE * ck_mkstemp P_((char **p_filename, const char *tmpdir, const char *base, const char *mode)); void ck_rename P_((const char *from, const char *to, const char *unlink_if_fail)); |