Hi,
this is a first attempt to implement a stripped down version of expand.
This version is only little tested so it may contain all sort of bugs.
Hints, critics and help in testing and improving it is welcome. 

bloat-o-meter (after make defconfig and enabling the expand applet) says:
function                                             old     new   delta
expand_main                                            -     437    +437
.rodata                                           121357  121485    +128
packed_usage                                       22558   22660    +102
applets                                             3108    3120     +12
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 3/0 up/down: 679/0)             Total: 679 bytes

Usage is: expand  [-i] [-t NUM] [FILE | -]

 *  Options:
 *  -t num              Convert tabs to num spaces (default 8 spaces).
 *
 *              Caveat: this version doesn't accept tab lists and
 *              therefore isn't conform to The Open Group Base 
 *              Specifications Issue 6.
 *
 *  -i                  Only convert initial tabs on each line to spaces.

Ciao,
Tito
--- busybox.orig/include/applets.h	2007-08-03 14:17:54.000000000 +0200
+++ busybox/include/applets.h	2007-08-05 20:57:48.000000000 +0200
@@ -134,6 +134,7 @@
 USE_ENVDIR(APPLET_ODDNAME(envdir, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, envdir))
 USE_ENVUIDGID(APPLET_ODDNAME(envuidgid, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, envuidgid))
 USE_ETHER_WAKE(APPLET_ODDNAME(ether-wake, ether_wake, _BB_DIR_USR_BIN, _BB_SUID_NEVER, ether_wake))
+USE_EXPAND(APPLET(expand, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
 USE_EXPR(APPLET(expr, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
 USE_FAKEIDENTD(APPLET(fakeidentd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER))
 USE_FALSE(APPLET_NOFORK(false, false, _BB_DIR_BIN, _BB_SUID_NEVER, false))
--- busybox.orig/include/usage.h	2007-08-03 14:17:54.000000000 +0200
+++ busybox/include/usage.h	2007-08-06 22:36:50.000000000 +0200
@@ -843,6 +843,15 @@
        "	-i iface	Use interface ifname instead of the default \"eth0\"\n" \
        "	-p pass		Append the four or six byte password PW to the packet"
 
+#define expand_trivial_usage \
+       "[-i] [-t NUM] [FILE|-]"
+#define expand_full_usage \
+       "Convert tabs in each FILE to spaces, writing to standard output.\n" \
+       "With no FILE, or when FILE is -, read standard input" \
+       "\n\nOptions:\n" \
+       "	-i, --initial       do not convert tabs after non blanks\n" \
+       "	-t, --tabs=NUMBER   have tabs NUMBER characters apart, not 8"
+
 #define expr_trivial_usage \
        "EXPRESSION"
 #define expr_full_usage \
--- busybox.orig/scripts/defconfig	2007-07-21 00:28:41.000000000 +0200
+++ busybox/scripts/defconfig	2007-08-05 21:03:05.000000000 +0200
@@ -152,6 +152,7 @@
 CONFIG_FEATURE_FANCY_ECHO=y
 CONFIG_ENV=y
 CONFIG_FEATURE_ENV_LONG_OPTIONS=y
+CONFIG_EXPAND=y
 CONFIG_EXPR=y
 CONFIG_EXPR_MATH_SUPPORT_64=y
 CONFIG_FALSE=y
--- busybox.orig/coreutils/Config.in	2007-06-12 15:32:54.000000000 +0200
+++ busybox/coreutils/Config.in	2007-08-05 20:56:08.000000000 +0200
@@ -200,6 +200,12 @@
 	help
 	  Support long options for the env applet.
 
+config EXPAND
+	bool "expand"
+	default n
+	help
+	  By default, convert all tabs to spaces.
+
 config EXPR
 	bool "expr"
 	default n
--- busybox.orig/coreutils/Kbuild	2007-06-12 15:32:54.000000000 +0200
+++ busybox/coreutils/Kbuild	2007-08-05 20:56:32.000000000 +0200
@@ -31,6 +31,7 @@
 lib-$(CONFIG_ASH)       += echo.o # used by ash
 lib-$(CONFIG_ENV)       += env.o
 lib-$(CONFIG_EXPR)      += expr.o
+lib-$(CONFIG_EXPR)      += expand.o
 lib-$(CONFIG_FALSE)     += false.o
 lib-$(CONFIG_FOLD)      += fold.o
 lib-$(CONFIG_HEAD)      += head.o
--- busybox.orig/coreutils/expand.c	1970-01-01 01:00:00.000000000 +0100
+++ busybox/coreutils/expand.c	2007-08-06 22:46:54.000000000 +0200
@@ -0,0 +1,99 @@
+/* expand - convert tabs to spaces
+ * Copyright (C) 89, 91, 1995-2006 Free Software Foundation, Inc.
+ * 
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ * 
+ * By default, convert all tabs to spaces.
+ *
+ *  Options:
+ *  -t num		Convert tabs to num spaces (default 8 spaces).
+ *
+ *              Caveat: this version doesn't accept tab lists and
+ *              therefore isn't conform to The Open Group Base 
+ *              Specifications Issue 6.
+ *
+ *  -i			Only convert initial tabs on each line to spaces.
+ *
+ *  David MacKenzie <[EMAIL PROTECTED]>
+ * 
+ *  Adapted for busybox by Tito Ragusa <[EMAIL PROTECTED]>.
+ */
+
+#include "libbb.h"
+
+enum {
+
+OPT_INITIAL     = 1 << 0,
+OPT_TABS        = 1 << 1,
+
+};
+
+int expand_main (int argc, char **argv);
+int expand_main (int argc, char **argv)
+{
+	unsigned opt;
+	/* Default 8 spaces for 1 tab */
+	const char *opt_t = "8";
+	FILE *file;
+	int i;
+	int convert = 1;
+	int have_read_stdin = 0;
+	int exit_status = EXIT_SUCCESS;
+	unsigned int tab_size;
+	char *line;
+	char *ptr;
+
+	opt = getopt32(argc, argv, "it:", &opt_t);
+	tab_size = xatou_range(opt_t, 1, UINT_MAX);
+
+	argv += optind;
+
+	if (!*argv)
+		*--argv = (char *) "-";
+
+	do {
+		if (LONE_CHAR(*argv, '-')) {
+			file = stdin;
+			have_read_stdin = 1;
+		} else {
+			file = fopen_or_warn(*argv, "r");
+		}
+		if (!file) {
+			exit_status = EXIT_FAILURE;
+			continue;
+		}
+		while ((line = xmalloc_fgets(file)) != NULL) {
+			convert = 1;
+			ptr = line;
+			while (*line) {
+				if (*line == '\t' && convert) {
+					for (i = 0; i < tab_size; i++) {
+						if (putchar(' ') < 0)
+							goto write_error;
+					}
+				} else {
+					if ((opt & OPT_INITIAL) && !isblank(*line)) convert = 0;
+					if (putchar(*line) < 0)
+ write_error:
+						bb_error_msg_and_die(bb_msg_write_error);
+				}
+				line++;
+			}
+			free(ptr);
+		}
+		if (ferror(file) || fclose_if_not_stdin(file)) {
+			bb_perror_msg("%s", *argv);
+			exit_status = EXIT_FAILURE;
+		}
+		/* If stdin also clear EOF.  */
+		if (file == stdin)
+			clearerr (file);
+	} while (*++argv);
+
+	if (have_read_stdin && fclose (stdin) != 0)
+		bb_perror_msg_and_die(bb_msg_standard_input);
+	if (fclose (stdout) != 0)
+		bb_perror_msg_and_die("stdout");	
+
+	exit (exit_status);
+}
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to