Re: [RFC]: --format=FORMAT option for ls
Jim Meyering wrote on 12-02-08 15:50: Pádraig Brady [EMAIL PROTECTED] wrote: I can't think of any reason I would use `ls --format` over `find -printf` Ha! Good point. Nor can I. I'll remove the TODO item. Actually, from the perspective of modularity that is (justifiably) hammered on so often, wouldn't a format/printf option have been somewhat more at home with 'ls' than with 'find'? bjd ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: [RFC]: --format=FORMAT option for ls
On Feb 12, 2008 1:22 PM, Jim Meyering [EMAIL PROTECTED] wrote: Steven Schubiger [EMAIL PROTECTED] wrote: I hacked up a prototype of ls with the possibility of specifying a format string that currently solely defines the order of items. Thanks for working on this. However, before you invest more time in it, please look at how GNU find handles its -printf predicate and see if it is feasible to share parts of that code. If this functionality is useful to coreutils, I'm happy to refactor the findutils code so that it's reusable. However, there are a small number of format directives that don't seem to be usefully sharable. For example, %d, %P, and %H. The existing find code is also running out of format specifiers; I've been considering a keyword-oriented variant like %(hardlinkcount)d for a while. That at least would be a little more extensible. On the other hand, refactoring the code would probably only be worthwhile if the result would not be reused. James. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: [RFC]: --format=FORMAT option for ls
Pádraig Brady [EMAIL PROTECTED] wrote: I can't think of any reason I would use `ls --format` over `find -printf` Ha! Good point. Nor can I. I'll remove the TODO item. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: [RFC]: --format=FORMAT option for ls
Steven Schubiger [EMAIL PROTECTED] wrote: Jim Meyering [EMAIL PROTECTED] wrote: However, before you invest more time in it, please look at how GNU find handles its -printf predicate and see if it is feasible to share parts of that code. As far as I can tell, most of the logic boils down to insert_fprintf() in findutils' parser.c. Concerning the feasibility of sharing parts, I don't know offhand (it doesn't look easy though). Albeit I searched through the coreutils mailing list archive and found some according threads regarding extending ls, I'm not exactly sure what format functionality is needed (unless we want a working find -printf resembling behavior). If you're going to implement it, then you should propose what you think is right. IMHO, that would include most if not all of what find's printf predicate does. Then there'd have to be a few new format specifiers so that in the end we can say that by default, ls acts as if it had been given the --format=... option. Of course, implementing such a feature properly will not be quick or easy. If it were so easy, it would have been done long ago. Don't underestimate the value of reusing find's code. Not only do you get stable and well-tested code, but you get the well-written documentation that goes with it. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: [RFC]: --format=FORMAT option for ls
Jim Meyering [EMAIL PROTECTED] wrote: However, before you invest more time in it, please look at how GNU find handles its -printf predicate and see if it is feasible to share parts of that code. As far as I can tell, most of the logic boils down to insert_fprintf() in findutils' parser.c. Concerning the feasibility of sharing parts, I don't know offhand (it doesn't look easy though). Albeit I searched through the coreutils mailing list archive and found some according threads regarding extending ls, I'm not exactly sure what format functionality is needed (unless we want a working find -printf resembling behavior). Steven Schubiger ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: [RFC]: --format=FORMAT option for ls
On Feb 12, 2008 2:59 PM, James Youngman [EMAIL PROTECTED] wrote: On the other hand, refactoring the code would probably only be worthwhile if the result would not be reused. Obviously the not there should be removed. James. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
Re: [RFC]: --format=FORMAT option for ls
Steven Schubiger [EMAIL PROTECTED] wrote: I hacked up a prototype of ls with the possibility of specifying a format string that currently solely defines the order of items. Thanks for working on this. However, before you invest more time in it, please look at how GNU find handles its -printf predicate and see if it is feasible to share parts of that code. ___ Bug-coreutils mailing list Bug-coreutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-coreutils
[RFC]: --format=FORMAT option for ls
I hacked up a prototype of ls with the possibility of specifying a format string that currently solely defines the order of items. I had to change quite a bit of the underlying code to make it work, as in, moving most of the routines called by print_long_format() to functions, that are both used by the user-defined and default format code. Right now only a column is buffered at once (the majority is '\0' terminated) and then written by DIRED_FPUTS(). It probably would be better to buffer the entire row and have it then printed to the output stream (as it mostly was before). How it works: /your/custom/ls --printf=%M %O %G %S %T %f -l should be roughly equivalent to a bare /bin/ls -l I've chosen --printf, because it was easier to add and I didn't want to possibly pollute the --format code (at least not, for now). The patch is not complete at all, but merely an approximation. Ideas, opinions and critique are welcome. Steven Schubiger diff --git a/src/ls.c b/src/ls.c index 46713f2..b15042b 100644 --- a/src/ls.c +++ b/src/ls.c @@ -584,6 +584,12 @@ static bool immediate_dirs; static bool directories_first; +static bool print_formatted_line; + +#define FORMAT_TYPES_NUM 10 + +static char format_specifier[FORMAT_TYPES_NUM]; + /* Which files to ignore. */ static enum @@ -765,6 +771,7 @@ static struct option const long_options[] = {indicator-style, required_argument, NULL, INDICATOR_STYLE_OPTION}, {dereference, no_argument, NULL, 'L'}, {literal, no_argument, NULL, 'N'}, + {printf, required_argument, NULL, 'P'}, {quote-name, no_argument, NULL, 'Q'}, {quoting-style, required_argument, NULL, QUOTING_STYLE_OPTION}, {recursive, no_argument, NULL, 'R'}, @@ -1368,6 +1375,79 @@ main (int argc, char **argv) exit (exit_status); } +static void +extract_formatstring_specifiers (const char *fmt) +{ + const char *fmt_start; + int cnt, i = 0; + + if (!strlen (fmt)) +error (EXIT_FAILURE, 0, _(format string must not be empty)); + + fmt_start = fmt; + + while (*fmt) { +cnt = 0; +while (cnt 2) { + switch (cnt) +{ + case 0: +if (*fmt != '%') + error (EXIT_FAILURE, 0, _(format specifier must begin with %%)); + break; + case 1: +if (isalpha(*fmt)) + { +char ch; +ch = *fmt; +if (i = FORMAT_TYPES_NUM) + goto end; +if (ch == 'f' (fmt - fmt_start != strlen (fmt_start) - 1)) + error (EXIT_FAILURE, 0, _(file format specifier %%f must be at end)); +if (islower(ch) (ch != 'f' ch != 's')) + format_specifier[i] = toupper(ch); +else + format_specifier[i] = ch; +i++; + } +else + error (EXIT_FAILURE, 0, _(format character must be a valid character)); +break; + /* never reached */ + default: + abort (); +} + cnt++; + fmt++; +} +while (*fmt == ' ') + fmt++; + } + + end: + + for (i = 0; isalpha(format_specifier[i]); i++) +{ + switch (format_specifier[i]) +{ + case 'f': + case 's': + case 'A': + case 'B': + case 'G': + case 'I': + case 'M': + case 'O': + case 'S': + case 'T': +break; + default: +error (EXIT_FAILURE, 0, _(format specifier %%%c is unsupported), format_specifier[i]); +break; +} +} +} + /* Set all the option flags according to the switches specified. Return the index of the first non-option argument. */ @@ -1508,7 +1588,7 @@ decode_switches (int argc, char **argv) { int oi = -1; int c = getopt_long (argc, argv, - abcdfghiklmnopqrstuvw:xABCDFGHI:LNQRST:UXZ1, + abcdfghiklmnopqrstuvw:xABCDFGHI:LNPQRST:UXZ1, long_options, oi); if (c == -1) break; @@ -1675,6 +1755,11 @@ decode_switches (int argc, char **argv) set_quoting_style (NULL, literal_quoting_style); break; +case 'P': + print_formatted_line = true; + extract_formatstring_specifiers (optarg); + break; + case 'Q': set_quoting_style (NULL, c_quoting_style); break; @@ -3345,20 +3430,25 @@ get_current_time (void) /* Print the user or group name NAME, with numeric id ID, using a print width of WIDTH columns. */ -static void -format_user_or_group (char const *name, unsigned long int id, int width) +static char * +format_user_or_group (char *p, char *name, unsigned long int id, int width) { size_t len; + char *iter; if (name) { int width_gap = width - mbswidth (name, 0); int pad = MAX (0, width_gap); - fputs (name, stdout); + + iter = name; + while