[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC] linecut addition
From: |
Steven Schubiger |
Subject: |
Re: [RFC] linecut addition |
Date: |
Fri, 14 Sep 2007 17:32:49 +0200 |
User-agent: |
Mutt/1.5.13 (2006-08-11) |
>From a conversation with Jim:
On Fri, Aug 24, 2007 at 02:27:34PM +0200, Jim Meyering wrote:
> If you end up adding a program to coreutils,
> it may make more sense to add a tiny bit of code to "head",
> to make it work the way you want, and then to arrange for that code
> to be enabled in a different incarnation of the same .c file.
> For an example of this approach, look at the vdir, ls, dir triple
> of programs. See src/ls-ls.c, ls-vdir.c, ls-dir.c, and ls.c, and
> the trivial rules in Makefile.am.
Attached is a first (not complete) "approach" open to peer review.
--- head.c.orig 2007-09-14 00:11:56.000000000 +0200
+++ head.c 2007-09-14 16:58:39.000000000 +0200
@@ -62,6 +62,8 @@
multiple_files, always, never
};
+static bool range_mode = false;
+
/* The name this program was run with. */
char *program_name;
@@ -91,6 +93,7 @@
PRESUME_INPUT_PIPE_OPTION}, /* do not document */
{"quiet", no_argument, NULL, 'q'},
{"silent", no_argument, NULL, 'q'},
+ {"range", required_argument, NULL, 'r'},
{"verbose", no_argument, NULL, 'v'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
@@ -803,11 +806,73 @@
}
static bool
+range_lines (const char *filename, int fd)
+{
+ char buffer[BUFSIZ];
+ int line_current, line_from, line_to;
+ int range_iter, range_from, range_to;
+ int ranges[4] = { 3,4,7,10 }; /* XXX (testing) */
+
+ size_t bytes_read = safe_read (fd, buffer, BUFSIZ);
+ size_t byte_offset = 0;
+
+ if (bytes_read == SAFE_READ_ERROR)
+ {
+ error (0, errno, _("error reading %s"), quote (filename));
+ return false;
+ }
+ if (bytes_read == 0)
+ return true;
+
+ line_current = 1;
+ for (range_iter = 0; range_iter < 4; range_iter += 2)
+ {
+ line_from = ranges[range_iter];
+ line_to = ranges[range_iter + 1];
+
+ while (1)
+ {
+ size_t bytes_line_to_write = 0;
+ size_t byte_offset_iter;
+
+ if (byte_offset < bytes_read)
+ {
+ byte_offset_iter = byte_offset;
+ while (buffer[byte_offset_iter++] != '\n')
+ bytes_line_to_write++;
+ bytes_line_to_write++;
+
+ if (line_current >= line_from && line_current <= line_to)
+ {
+ if (fwrite ((buffer + byte_offset), 1,
+ bytes_line_to_write, stdout) < bytes_line_to_write)
+ error (EXIT_FAILURE, errno, _("write error"));
+ }
+
+ line_current++;
+ byte_offset = byte_offset_iter;
+ }
+ else
+ return true;
+
+ if (line_current > line_to)
+ break;
+ }
+ }
+ return true;
+}
+
+static bool
head (const char *filename, int fd, uintmax_t n_units, bool count_lines,
bool elide_from_end)
{
if (print_headers)
write_header (filename);
+
+ if (range_mode)
+ {
+ return range_lines (filename, fd);
+ }
if (elide_from_end)
{
@@ -993,7 +1058,7 @@
argc--;
}
- while ((c = getopt_long (argc, argv, "c:n:qv0123456789", long_options, NULL))
+ while ((c = getopt_long (argc, argv, "c:n:r:qv0123456789", long_options,
NULL))
!= -1)
{
switch (c)
@@ -1022,6 +1087,10 @@
header_mode = never;
break;
+ case 'r':
+ range_mode = true;
+ break;
+
case 'v':
header_mode = always;
break;
- Re: [RFC] linecut addition,
Steven Schubiger <=