Re: [RFC]: --format=FORMAT option for ls

2008-02-12 Thread Bauke Jan Douma

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

2008-02-12 Thread James Youngman
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

2008-02-12 Thread Jim Meyering
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

2008-02-12 Thread Jim Meyering
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

2008-02-12 Thread Steven Schubiger
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

2008-02-12 Thread James Youngman
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

2008-02-12 Thread Jim Meyering
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

2008-02-12 Thread Steven Schubiger
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