diff -Nur -x *~ -x *.Po -x *.[oaP] -x .#* -x .*swp -x CVS -x *.rej -x *.orig -x tags -x config.status -x config.log -x config.cache -x Makefile -x ABOUT-NLS -x aclocal.m4 -x config.guess -x config.h -x config.h.in -x config.sub -x configure -x install-sh findutils-4.1.7-orig/TODO findutils-4.1.7/TODO --- findutils-4.1.7-orig/TODO Sun May 20 18:07:49 2001 +++ findutils-4.1.7/TODO Thu Mar 14 07:07:28 2002 @@ -72,17 +72,6 @@ * Is lib/strcasecmp.c required? -* xargs: allow newline or arbitrary character to separate arguments -Tyler 'Crackerjack' MacDonald suggested that it would be -nice if newlines could separate arguments to xargs. This would allow -a single line to be used as an argument, regardless of white space, -quotes, and backslash. A function similar to read_string in xargs.c -can be written which replaces the line: - - if (c == '\0') - -with the appropriate character. - * investigate _LIBC when used with TOLOWER and TOUPPER _LIBC is used to determine whether TOLOWER should check isupper first. Is there something better to check? Alternatively, can tolower be diff -Nur -x *~ -x *.Po -x *.[oaP] -x .#* -x .*swp -x CVS -x *.rej -x *.orig -x tags -x config.status -x config.log -x config.cache -x Makefile -x ABOUT-NLS -x aclocal.m4 -x config.guess -x config.h -x config.h.in -x config.sub -x configure -x install-sh findutils-4.1.7-orig/xargs/xargs.c findutils-4.1.7/xargs/xargs.c --- findutils-4.1.7-orig/xargs/xargs.c Sun May 20 13:39:38 2001 +++ findutils-4.1.7/xargs/xargs.c Thu Mar 14 06:53:43 2002 @@ -235,6 +235,7 @@ static struct option const longopts[] = { {"null", no_argument, NULL, '0'}, + {"newline", no_argument, NULL, 'N'}, {"eof", optional_argument, NULL, 'e'}, {"replace", optional_argument, NULL, 'i'}, {"max-lines", optional_argument, NULL, 'l'}, @@ -252,6 +253,7 @@ static int read_line PARAMS ((void)); static int read_string PARAMS ((void)); +static int read_string_line PARAMS ((void)); static void do_insert PARAMS ((char *arg, size_t arglen, size_t lblen)); static void push_arg PARAMS ((char *arg, size_t len)); static boolean print_args PARAMS ((boolean ask)); @@ -297,7 +299,7 @@ if (arg_max <= 0) error (1, 0, _("environment is too large for exec")); - while ((optc = getopt_long (argc, argv, "+0e::i::l::n:prs:txP:", + while ((optc = getopt_long (argc, argv, "+0Ne::i::l::n:prs:txP:", longopts, (int *) 0)) != -1) { switch (optc) @@ -306,6 +308,10 @@ read_args = read_string; break; + case 'N': + read_args = read_string_line; + break; + case 'e': if (optarg) eof_str = optarg; @@ -561,6 +567,54 @@ *p++ = c; } } + +/* Read a newline-terminated string from stdin and add it to the list of + arguments to pass to the command. + Return -1 if eof (either physical or logical) is reached, + otherwise the length of the string read (including the null). */ + +static int +read_string_line (void) +{ + static boolean eof = false; + int len; + char *p = linebuf; + /* Including the NUL, the args must not grow past this point. */ + char *endbuf = linebuf + arg_max - initial_argv_chars - 1; + + if (eof) + return -1; + while (1) + { + int c = getc (stdin); + if (c == EOF) + { + eof = true; + if (p == linebuf) + return -1; + *p++ = '\0'; + len = p - linebuf; + if (!replace_pat) + push_arg (linebuf, len); + return len; + } + if (c == '\n' || c == '\r') + { + if (p == linebuf) + continue; /* Blank line. */ + lineno++; /* For -l. */ + *p++ = '\0'; + len = p - linebuf; + if (!replace_pat) + push_arg (linebuf, len); + return len; + } + if (p >= endbuf) + error (1, 0, _("argument line too long")); + *p++ = c; + } +} + /* Read a null-terminated string from stdin and add it to the list of arguments to pass to the command.