Ok, I'm attaching a patch for gnu cat. It's not finished and still has a lot
of room for improvement, but should be enough as a proof of concept.
Results for stripped binaries on my system are (in bytes):
5396 build.old/src/cat.o
3172 build/src/cat.o
16696 build.old/src/cat
14392 build/src/cat
Some thoughts:
- The code is more readable if we alter the order of command-line options,
so that extra features are displayed together and can be #if'ed out in
one block. I opted to display POSIX features first and then GNU extensions,
any preference on this?
- I believe my "poor man's malloc" hack would be optimal with an "int" on
i386, but I can't tell for other CPUs. Do you want "char" or "int"?
- Looking at the unlinked object I saved more than 2 KBs. But most of the
space seems to be eaten by libfetish when linking it staticaly. Do you
think it's viable to discard parts of libfetich that might not be needed
in our new ripped-down gnu cat?
--
Robert Millan
"[..] but the delight and pride of Aule is in the deed of making, and in the
thing made, and neither in possession nor in his own mastery; wherefore he
gives and hoards not, and is free from care, passing ever on to some new work."
-- J.R.R.T, Ainulindale (Silmarillion)
--- coreutils.old/src/cat.c 2003-10-18 12:05:47.000000000 +0200
+++ coreutils/src/cat.c 2003-11-01 18:21:05.000000000 +0100
@@ -53,6 +59,7 @@
/* Descriptor on which input file is open. */
static int input_desc;
+#if EXTRAS
/* Buffer for line numbers.
An 11 digit counter may overflow within an hour on a P2/466,
an 18 digit counter needs about 1000y */
@@ -76,6 +83,7 @@
/* Preserves the `cat' function's local `newlines' between invocations. */
static int newlines2 = 0;
+#endif /* EXTRAS */
/* Count of non-fatal error conditions. */
static int exit_status = 0;
@@ -95,6 +103,10 @@
fputs (_("\
Concatenate FILE(s), or standard input, to standard output.\n\
\n\
+ -u (ignored)\n\
+"
+#if EXTRAS
+"\
-A, --show-all equivalent to -vET\n\
-b, --number-nonblank number nonblank output lines\n\
-e equivalent to -vE\n\
@@ -105,8 +117,10 @@
fputs (_("\
-t equivalent to -vT\n\
-T, --show-tabs display TAB characters as ^I\n\
- -u (ignored)\n\
-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB\n\
+"
+#endif /* EXTRAS */
+"\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -125,6 +139,7 @@
exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
+#if EXTRAS
/* Compute the next line number. */
static void
@@ -145,6 +160,7 @@
if (line_num_start < line_num_print)
line_num_print--;
}
+#endif /* EXTRAS */
/* Plain cat. Copies the file behind `input_desc' to STDOUT_FILENO. */
@@ -190,6 +206,7 @@
}
}
+#if EXTRAS
/* Cat the file behind INPUT_DESC to the file behind OUTPUT_DESC.
Called if any option more than -u was specified.
@@ -483,6 +500,7 @@
}
}
}
+#endif /* EXTRAS */
/* This is gross, but necessary, because of the way close_stdout
works and because this program closes STDOUT_FILENO directly. */
@@ -498,11 +516,13 @@
int
main (int argc, char **argv)
{
+#if EXTRAS
/* Optimal size of i/o operations of output. */
size_t outsize;
/* Optimal size of i/o operations of input. */
size_t insize;
+#endif /* EXTRAS */
/* Pointer to the input buffer. */
char *inbuf;
@@ -547,6 +567,7 @@
static struct option const long_options[] =
{
+#if EXTRAS
{"number-nonblank", no_argument, NULL, 'b'},
{"number", no_argument, NULL, 'n'},
{"squeeze-blank", no_argument, NULL, 's'},
@@ -557,6 +578,7 @@
#if O_BINARY
{"binary", no_argument, NULL, 'B'},
#endif
+#endif /* EXTRAS */
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -587,6 +609,11 @@
case 0:
break;
+ case 'u':
+ /* We provide the -u feature unconditionally. */
+ break;
+
+#if EXTRAS
case 'b':
++options;
numbers = 1;
@@ -615,10 +642,6 @@
quote = 1;
break;
- case 'u':
- /* We provide the -u feature unconditionally. */
- break;
-
case 'v':
++options;
quote = 1;
@@ -647,6 +670,7 @@
++options;
output_tabs = 0;
break;
+#endif /* EXTRAS */
case_GETOPT_HELP_CHAR;
@@ -665,12 +689,14 @@
if (fstat (STDOUT_FILENO, &stat_buf) < 0)
error (EXIT_FAILURE, errno, _("standard output"));
+#if EXTRAS
outsize = ST_BLKSIZE (stat_buf);
/* Input file can be output file for non-regular files.
fstat on pipes returns S_IFSOCK on some systems, S_IFIFO
on others, so the checking should not be done for those types,
and to allow things like cat < /dev/tty > /dev/tty, checking
is not done for device files either. */
+#endif
if (S_ISREG (stat_buf.st_mode))
{
@@ -783,7 +809,9 @@
exit_status = 1;
goto contin;
}
+#if EXTRAS
insize = ST_BLKSIZE (stat_buf);
+#endif
/* Compare the device and i-node numbers of this input file with
the corresponding values of the (output file associated with)
@@ -799,6 +827,7 @@
goto contin;
}
+#if EXTRAS
/* Select which version of `cat' to use. If any options (more than -u,
--version, or --help) were specified, use `cat', otherwise use
`simple_cat'. */
@@ -807,8 +836,15 @@
{
insize = max (insize, outsize);
inbuf = xmalloc (insize);
+#else
+ /* poor man's malloc */
+ char buf;
+#define insize sizeof(char)
+#define inbuf &buf
+#endif
simple_cat (inbuf, insize);
+#if EXTRAS
}
else
{
@@ -839,6 +875,7 @@
free (outbuf);
}
+#endif /* EXTRAS */
free (inbuf);
_______________________________________________
Bug-coreutils mailing list
[EMAIL PROTECTED]
http://mail.gnu.org/mailman/listinfo/bug-coreutils