svn commit: trunk/busybox: coreutils

vda at busybox.net vda at busybox.net
Fri Jun 13 11:16:10 UTC 2008


Author: vda
Date: 2008-06-13 04:16:09 -0700 (Fri, 13 Jun 2008)
New Revision: 22317

Log:
build system: introduce FEATURE_ASSUME_UNICODE
ls: use it. also do G trick. with UNICODE off:

function                                             old     new   delta
ls_main                                              843     871     +28
show_color                                             1       -      -1
showdirs                                             500     497      -3
my_stat                                              100      97      -3
terminal_width                                         4       -      -4
tabstops                                               4       -      -4
status                                               122     118      -4
static.dotdir                                          4       -      -4
current_time_t                                         4       -      -4
all_fmt                                                4       -      -4
------------------------------------------------------------------------------
(add/remove: 0/6 grow/shrink: 1/3 up/down: 28/-31)             Total: -3 bytes

Also was tested with UNICODE on with glibc.



Modified:
   trunk/busybox/Config.in
   trunk/busybox/coreutils/ls.c


Changeset:
Modified: trunk/busybox/Config.in
===================================================================
--- trunk/busybox/Config.in	2008-06-13 10:01:03 UTC (rev 22316)
+++ trunk/busybox/Config.in	2008-06-13 11:16:09 UTC (rev 22317)
@@ -21,6 +21,18 @@
 	  Select this only if you plan to use busybox on full-blown
 	  desktop machine with common Linux distro, not on an embedded box.
 
+config FEATURE_ASSUME_UNICODE
+	bool "Assume that 1:1 char/glyph correspondence is not true"
+	default n
+	help
+	  This makes various applets aware that one byte is not
+	  one character on screen.
+
+	  Busybox aims to eventually work correctly with Unicode displays.
+	  Any older encodings are not guaranteed to work.
+	  Probably by the time when busybox will be fully Unicode-clean,
+	  other encodings will be mainly of historic interest.
+
 choice
 	prompt "Buffer allocation policy"
 	default FEATURE_BUFFERS_USE_MALLOC

Modified: trunk/busybox/coreutils/ls.c
===================================================================
--- trunk/busybox/coreutils/ls.c	2008-06-13 10:01:03 UTC (rev 22316)
+++ trunk/busybox/coreutils/ls.c	2008-06-13 11:16:09 UTC (rev 22317)
@@ -31,6 +31,10 @@
 
 #include "libbb.h"
 
+#if ENABLE_FEATURE_ASSUME_UNICODE
+#include <wchar.h>
+#endif
+
 /* This is a NOEXEC applet. Be very careful! */
 
 
@@ -114,18 +118,6 @@
 #define ATTR(mode)	("\00\00\01\00\01\00\01\00"\
 			 "\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)])
 
-/* colored LS support by JaWi, janwillem.janssen at lxtreme.nl */
-#if ENABLE_FEATURE_LS_COLOR
-static smallint show_color;
-/* long option entry used only for --color, which has no short option
- * equivalent */
-static const char ls_color_opt[] ALIGN1 =
-	"color\0" Optional_argument "\xff" /* no short equivalent */
-	;
-#else
-enum { show_color = 0 };
-#endif
-
 /*
  * a directory entry and its stat info are stored here
  */
@@ -137,26 +129,69 @@
 	USE_SELINUX(security_context_t sid;)
 	struct dnode *next;     /* point at the next node */
 };
-typedef struct dnode dnode_t;
 
 static struct dnode **list_dir(const char *);
 static struct dnode **dnalloc(int);
-static int list_single(struct dnode *);
+static int list_single(const struct dnode *);
 
-static unsigned all_fmt;
 
+struct globals {
+#if ENABLE_FEATURE_LS_COLOR
+	smallint show_color;
+#endif
+	smallint exit_failure;
+	unsigned all_fmt;
 #if ENABLE_FEATURE_AUTOWIDTH
-static unsigned tabstops = COLUMN_GAP;
-static unsigned terminal_width = TERMINAL_WIDTH;
+	unsigned tabstops; // = COLUMN_GAP;
+	unsigned terminal_width; // = TERMINAL_WIDTH;
+#endif
+#if ENABLE_FEATURE_LS_TIMESTAMPS
+	/* Do time() just once. Saves one syscall per file for "ls -l" */
+	time_t current_time_t;
+#endif
+};
+#define G (*(struct globals*)&bb_common_bufsiz1)
+#if ENABLE_FEATURE_LS_COLOR
+#define show_color     (G.show_color    )
 #else
+enum { show_color = 0 };
+#endif
+#define exit_failure   (G.exit_failure  )
+#define all_fmt        (G.all_fmt       )
+#if ENABLE_FEATURE_AUTOWIDTH
+#define tabstops       (G.tabstops      )
+#define terminal_width (G.terminal_width)
+#else
 enum {
 	tabstops = COLUMN_GAP,
 	terminal_width = TERMINAL_WIDTH,
 };
 #endif
+#define current_time_t (G.current_time_t)
+/* memset: we have to zero it out because of NOEXEC */
+#define INIT_G() { \
+	memset(&G, 0, sizeof(G)); \
+	tabstops = COLUMN_GAP; \
+	terminal_width = TERMINAL_WIDTH; \
+	USE_FEATURE_LS_TIMESTAMPS(time(&current_time_t);) \
+}
 
-static int status = EXIT_SUCCESS;
 
+#if ENABLE_FEATURE_ASSUME_UNICODE
+/* libbb candidate */
+static size_t mbstrlen(const char *string)
+{
+	size_t width = mbsrtowcs(NULL /*dest*/, &string,
+				MAXINT(size_t) /*len*/, NULL /*state*/);
+	if (width == (size_t)-1)
+		return strlen(string);
+	return width;
+}
+#else
+#define mbstrlen(string) strlen(string)
+#endif
+
+
 static struct dnode *my_stat(const char *fullname, const char *name, int force_follow)
 {
 	struct stat dstat;
@@ -171,7 +206,7 @@
 #endif
 		if (stat(fullname, &dstat)) {
 			bb_simple_perror_msg(fullname);
-			status = EXIT_FAILURE;
+			exit_failure = 1;
 			return 0;
 		}
 	} else {
@@ -182,7 +217,7 @@
 #endif
 		if (lstat(fullname, &dstat)) {
 			bb_simple_perror_msg(fullname);
-			status = EXIT_FAILURE;
+			exit_failure = 1;
 			return 0;
 		}
 	}
@@ -395,7 +430,7 @@
 	} else {
 		/* find the longest file name, use that as the column width */
 		for (i = 0; i < nfiles; i++) {
-			int len = strlen(dn[i]->name);
+			int len = mbstrlen(dn[i]->name);
 			if (column_width < len)
 				column_width = len;
 		}
@@ -494,7 +529,7 @@
 	nfiles = 0;
 	dir = warn_opendir(path);
 	if (dir == NULL) {
-		status = EXIT_FAILURE;
+		exit_failure = 1;
 		return NULL;	/* could not open the dir */
 	}
 	while ((entry = readdir(dir)) != NULL) {
@@ -538,13 +573,7 @@
 }
 
 
-#if ENABLE_FEATURE_LS_TIMESTAMPS
-/* Do time() just once. Saves one syscall per file for "ls -l" */
-/* Initialized in main() */
-static time_t current_time_t;
-#endif
-
-static int list_single(struct dnode *dn)
+static int list_single(const struct dnode *dn)
 {
 	int i, column = 0;
 
@@ -658,7 +687,12 @@
 						fgcolor(info.st_mode));
 			}
 #endif
+#if ENABLE_FEATURE_ASSUME_UNICODE
+			printf("%s", dn->name);
+			column += mbstrlen(dn->name);
+#else
 			column += printf("%s", dn->name);
+#endif
 			if (show_color) {
 				printf("\033[0m");
 			}
@@ -701,6 +735,7 @@
 	return column;
 }
 
+
 /* "[-]Cadil1", POSIX mandated options, busybox always supports */
 /* "[-]gnsx", POSIX non-mandated options, busybox always supports */
 /* "[-]Ak" GNU options, busybox always supports */
@@ -779,11 +814,18 @@
 };
 
 
-/* THIS IS A "SAFE" APPLET, main() MAY BE CALLED INTERNALLY FROM SHELL */
-/* BE CAREFUL! */
+/* colored LS support by JaWi, janwillem.janssen at lxtreme.nl */
+#if ENABLE_FEATURE_LS_COLOR
+/* long option entry used only for --color, which has no short option
+ * equivalent */
+static const char ls_color_opt[] ALIGN1 =
+	"color\0" Optional_argument "\xff" /* no short equivalent */
+	;
+#endif
 
+
 int ls_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-int ls_main(int argc, char **argv)
+int ls_main(int argc ATTRIBUTE_UNUSED, char **argv)
 {
 	struct dnode **dnd;
 	struct dnode **dnf;
@@ -791,18 +833,13 @@
 	struct dnode *dn;
 	struct dnode *cur;
 	unsigned opt;
-	int nfiles = 0;
+	int nfiles;
 	int dnfiles;
 	int dndirs;
-	int oi;
-	int ac;
 	int i;
-	char **av;
 	USE_FEATURE_LS_COLOR(char *color_opt;)
 
-#if ENABLE_FEATURE_LS_TIMESTAMPS
-	time(&current_time_t);
-#endif
+	INIT_G();
 
 	all_fmt = LIST_SHORT |
 		(ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_FORWARD));
@@ -883,39 +920,27 @@
 	if (!(all_fmt & STYLE_MASK))
 		all_fmt |= (isatty(STDOUT_FILENO) ? STYLE_COLUMNS : STYLE_SINGLE);
 
-	/*
-	 * when there are no cmd line args we have to supply a default "." arg.
-	 * we will create a second argv array, "av" that will hold either
-	 * our created "." arg, or the real cmd line args.  The av array
-	 * just holds the pointers- we don't move the date the pointers
-	 * point to.
-	 */
-	ac = argc - optind;	/* how many cmd line args are left */
-	if (ac < 1) {
-		static const char *const dotdir[] = { "." };
+	argv += optind;
+	if (!argv[0])
+		*--argv = (char*)".";
 
-		av = (char **) dotdir;
-		ac = 1;
-	} else {
-		av = argv + optind;
-	}
+	if (argv[1])
+		all_fmt |= DISP_DIRNAME; /* 2 or more items? label directories */
 
-	/* now, everything is in the av array */
-	if (ac > 1)
-		all_fmt |= DISP_DIRNAME;	/* 2 or more items? label directories */
-
 	/* stuff the command line file names into a dnode array */
 	dn = NULL;
-	for (oi = 0; oi < ac; oi++) {
+	nfiles = 0;
+	do {
 		/* ls w/o -l follows links on command line */
-		cur = my_stat(av[oi], av[oi], !(all_fmt & STYLE_LONG));
+		cur = my_stat(*argv, *argv, !(all_fmt & STYLE_LONG));
+		argv++;
 		if (!cur)
 			continue;
 		cur->allocated = 0;
 		cur->next = dn;
 		dn = cur;
 		nfiles++;
-	}
+	} while (*argv);
 
 	/* now that we know how many files there are
 	 * allocate memory for an array to hold dnode pointers
@@ -950,5 +975,5 @@
 	}
 	if (ENABLE_FEATURE_CLEAN_UP)
 		dfree(dnp, nfiles);
-	return status;
+	return (exit_failure == 0);
 }




More information about the busybox-cvs mailing list