[GRASS-dev] r.colors: rules file list unsorted

Hi,

may I kindly ask to get add a qsort() function to the
rules_files() function in main.c of r.colors? Not sure
how to do that.

Currently the rules files are sorted by file time stamp
(I am testing some new rules here):

r.colors help
...
  rules Name of predefined rules file
          options: aspect,bcyr,byg,byr,elevation,evi,etopo2,grey,gyr,ndvi,
                   population,rainbow,ramp,ryg,slope,srtm,terrain,wave,ryb,
                   aspectcolr,curvature,differences

thanks,
Markus

Hi Markus,

You mean sorting by name in the rules file listing when using help,
don't you? r.colors -l should give a sorted list.

Daniel.

On 1/28/07, Markus Neteler <neteler@itc.it> wrote:

Hi,

may I kindly ask to get add a qsort() function to the
rules_files() function in main.c of r.colors? Not sure
how to do that.

Currently the rules files are sorted by file time stamp
(I am testing some new rules here):

r.colors help
...
  rules Name of predefined rules file
          options: aspect,bcyr,byg,byr,elevation,evi,etopo2,grey,gyr,ndvi,
                   population,rainbow,ramp,ryg,slope,srtm,terrain,wave,ryb,
                   aspectcolr,curvature,differences

thanks,
Markus

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

--
-- Daniel Calvelo Aros

Hi Daniel,

that's true. But it would be cool to have the same effect
in
r.colors help

in particular, because the tcl GUI depends in that (and
XML and HTML output). Currently the order there can be wrong,
too.

Markus

On Sun, Jan 28, 2007 at 03:03:29PM -0500, Daniel Calvelo wrote:

Hi Markus,

You mean sorting by name in the rules file listing when using help,
don't you? r.colors -l should give a sorted list.

Daniel.

On 1/28/07, Markus Neteler <neteler@itc.it> wrote:
>Hi,
>
>may I kindly ask to get add a qsort() function to the
>rules_files() function in main.c of r.colors? Not sure
>how to do that.
>
>Currently the rules files are sorted by file time stamp
>(I am testing some new rules here):
>
>r.colors help
>...
> rules Name of predefined rules file
> options: aspect,bcyr,byg,byr,elevation,evi,etopo2,grey,gyr,ndvi,
> population,rainbow,ramp,ryg,slope,srtm,terrain,wave,ryb,
> aspectcolr,curvature,differences
>
>thanks,
>Markus
>
>_______________________________________________
>grass-dev mailing list
>grass-dev@grass.itc.it
>http://grass.itc.it/mailman/listinfo/grass-dev
>

--
-- Daniel Calvelo Aros

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

Rats, I'm compiling my fix to test now... :slight_smile: We seem to be pretty
active for a sunday. Very sunny here, BTW.

Daniel.

On 1/28/07, Wolf Bergenheim <wolf@bergenheim.net> wrote:

Markus Neteler wrote:
> Hi Daniel,
>
> that's true. But it would be cool to have the same effect
> in
> r.colors help
>
> in particular, because the tcl GUI depends in that (and
> XML and HTML output). Currently the order there can be wrong,
> too.
>

I'm almost done with a fix (:

--Wolf

--

<:3 )---- Wolf Bergenheim ----( 8:>

--
-- Daniel Calvelo Aros

Markus Neteler wrote:

Hi Wolf,

wow, high speed programming! I cannot tell you anything,
most likely Glynn will have a comment or Brad.

thanks anyway, please submit if Glynn doesn't object
(maybe give him 24 hours...) :slight_smile:

Yeah, I'm eagerly waiting their comments. Daniel what is your approach?

--Wolf

--

<:3 )---- Wolf Bergenheim ----( 8:>

I'm debugging this patch now. Only to show you the idea; it's not
working currently.

BTW has anybody here experimented with extreme programming techniques?
I've always been intrigued by the approach, and this kind of on-line
concurrent patching weems to be rather along their principles...

On 1/28/07, Wolf Bergenheim <wolf+grass@bergenheim.net> wrote:

Markus Neteler wrote:
> Hi Wolf,
>
> wow, high speed programming! I cannot tell you anything,
> most likely Glynn will have a comment or Brad.
>
> thanks anyway, please submit if Glynn doesn't object
> (maybe give him 24 hours...) :slight_smile:

Yeah, I'm eagerly waiting their comments. Daniel what is your approach?

--Wolf

--

<:3 )---- Wolf Bergenheim ----( 8:>

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

--
-- Daniel Calvelo Aros

(attachments)

r.colors.sortpatch (2.84 KB)

Ok, It's working now. Attached.

Cheers,

Daniel.

On 1/28/07, Daniel Calvelo <dca.gis@gmail.com> wrote:

I'm debugging this patch now. Only to show you the idea; it's not
working currently.

BTW has anybody here experimented with extreme programming techniques?
I've always been intrigued by the approach, and this kind of on-line
concurrent patching weems to be rather along their principles...

On 1/28/07, Wolf Bergenheim <wolf+grass@bergenheim.net> wrote:
> Markus Neteler wrote:
> > Hi Wolf,
> >
> > wow, high speed programming! I cannot tell you anything,
> > most likely Glynn will have a comment or Brad.
> >
> > thanks anyway, please submit if Glynn doesn't object
> > (maybe give him 24 hours...) :slight_smile:
>
> Yeah, I'm eagerly waiting their comments. Daniel what is your approach?
>
> --Wolf
>
> --
>
> <:3 )---- Wolf Bergenheim ----( 8:>
>
> _______________________________________________
> grass-dev mailing list
> grass-dev@grass.itc.it
> http://grass.itc.it/mailman/listinfo/grass-dev
>

--
-- Daniel Calvelo Aros

--
-- Daniel Calvelo Aros

(attachments)

r.colors.sortpatch (2.81 KB)

On Sun, 28 Jan 2007, Daniel Calvelo wrote:

Ok, It's working now. Attached.

What about a library function that does the same thing as system("ls") or system("ls -C"). I can think of several places where it would be useful. It could accept the directory as an argument, also the stream to output too (e.g. stdout or stderr) and perhaps a flag to do a column-wise listing (a la "ls -C"). I think this would be the hardest part to do; not sure how ls does it - unless there is something easy we could do with format conversion strings?

Paul

Paul Kelly wrote:

What about a library function that does the same thing as system("ls") or
system("ls -C"). I can think of several places where it would be useful.
It could accept the directory as an argument, also the stream to output
too (e.g. stdout or stderr) and perhaps a flag to do a column-wise listing
(a la "ls -C"). I think this would be the hardest part to do; not sure how
ls does it - unless there is something easy we could do with format
conversion strings?

see-
http://thread.gmane.org/gmane.comp.gis.grass.devel/17252/focus=17271
http://thread.gmane.org/gmane.comp.gis.grass.devel/17252/focus=17267
http://article.gmane.org/gmane.comp.gis.grass.devel/17443
http://thread.gmane.org/gmane.comp.gis.grass.devel/16041/focus=16223

[yes, please; system("ls") isn't portable]

Hamish

Paul Kelly wrote:

> Ok, It's working now. Attached.

What about a library function that does the same thing as system("ls") or
system("ls -C"). I can think of several places where it would be useful.
It could accept the directory as an argument, also the stream to output
too (e.g. stdout or stderr)

A library function should probably return the entries as an array of
strings (char **) rather than write them to a stream. The caller can
deal with writing them, if that's desired.

and perhaps a flag to do a column-wise listing
(a la "ls -C"). I think this would be the hardest part to do; not sure how
ls does it - unless there is something easy we could do with format
conversion strings?

Read all of the names, find the longest name to determine the column
widths, divide the width of the terminal[1] by the column width to
determine the number of columns, write out all of the strings padded
to a fixed width.

For the last part, you can either use "%*s" or explicitly add with
"columns + 1 - strlen(name)" spaces.

[1] This is the hardest part, as there are several different ways to
get the terminal width, and they may return different results. E.g.

1. tigetnum("cols")
2. tgetnum("co")
3. getenv("COLUMNS")
4. ioctl(TIOCGWINSZ)
5. The "columns" macro from <term.h> (in conjuction with [n]curses).
6. A hardcoded default of 80 columns

#1 requires terminfo, #2 requires termcap, #3 requires that COLUMNS is
set, #4 may not work on all platforms (although I don't know of any
where it doesn't work), #5 requires [n]curses.

If #4 works, it should be the most reliable, as it handles the case of
an xterm (etc) which has been resized by the user. Depending upon the
curses implementation #5 may also use #4 if it works, or it may use #3
(unless use_env(FALSE) has been called).

--
Glynn Clements <glynn@gclements.plus.com>

On 1/28/07, Glynn Clements <glynn@gclements.plus.com> wrote:

Paul Kelly wrote:
>
> What about a library function that does the same thing as system("ls") or
> system("ls -C"). I can think of several places where it would be useful.
> It could accept the directory as an argument, also the stream to output
> too (e.g. stdout or stderr)

A library function should probably return the entries as an array of
strings (char **) rather than write them to a stream. The caller can
deal with writing them, if that's desired.

That's how it's done in the patched r.colors. If it must be turned
into a library function, where would it go? What would its name be?
I'm willing to do it (and also change any system("ls")'s remaining).

> and perhaps a flag to do a column-wise listing
> (a la "ls -C"). I think this would be the hardest part to do; not sure how
> ls does it - unless there is something easy we could do with format
> conversion strings?

Read all of the names, find the longest name to determine the column
widths, divide the width of the terminal[1] by the column width to
determine the number of columns, write out all of the strings padded
to a fixed width.

The parser uses column break with a hardcoded value. We certainly
could use a global function for determining column width.

[snip]

Daniel.

--
-- Daniel Calvelo Aros

Hello Daniel

On Sun, 28 Jan 2007, Daniel Calvelo wrote:

On 1/28/07, Glynn Clements <glynn@gclements.plus.com> wrote:

A library function should probably return the entries as an array of
strings (char **) rather than write them to a stream. The caller can
deal with writing them, if that's desired.

That's how it's done in the patched r.colors. If it must be turned
into a library function, where would it go? What would its name be?
I'm willing to do it (and also change any system("ls")'s remaining).

I've just finished it - see attached - planning on committing it as lib/gis/ls.c tomorrow after some more polishing if no objections.

The way I've done it there are 3 functions:

G__ls() reads the directory and stores the entries in an array.
G_ls() prints the listing to a specified stream, one entry per line.
G_ls_columns() prints the listing to a specified stream in column format.

> and perhaps a flag to do a column-wise listing
> (a la "ls -C"). I think this would be the hardest part to do; not sure how
> ls does it - unless there is something easy we could do with format
> conversion strings?

Read all of the names, find the longest name to determine the column
widths, divide the width of the terminal[1] by the column width to
determine the number of columns, write out all of the strings padded
to a fixed width.

The parser uses column break with a hardcoded value. We certainly
could use a global function for determining column width.

I used the ioctl method. Works for me on Linux but not on Windows - have disabled the functionality there and it just uses hard-coded 80 characters for now. But it does work nicely on Linux as far as I can see. The GetConsoleScreenBufferInfo() function might be worth looking at on Windows.

Paul

(attachments)

ls.c (3.66 KB)

Glynn Clements wrote:

the width of the terminal[1]

..

[1] This is the hardest part, as there are several different ways to
get the terminal width, and they may return different results. E.g.

1. tigetnum("cols")
2. tgetnum("co")
3. getenv("COLUMNS")
4. ioctl(TIOCGWINSZ)
5. The "columns" macro from <term.h> (in conjuction with [n]curses).
6. A hardcoded default of 80 columns

#1 requires terminfo, #2 requires termcap, #3 requires that COLUMNS is
set, #4 may not work on all platforms (although I don't know of any
where it doesn't work), #5 requires [n]curses.

If #4 works, it should be the most reliable, as it handles the case of
an xterm (etc) which has been resized by the user. Depending upon the
curses implementation #5 may also use #4 if it works, or it may use #3
(unless use_env(FALSE) has been called).

see also bug # 1107
  http://intevation.de/rt/webrt?serial_num=1107

"[grass5's] v.digit locks if the terminal is too small"

Hamish

Paul Kelly wrote:

>> A library function should probably return the entries as an array of
>> strings (char **) rather than write them to a stream. The caller can
>> deal with writing them, if that's desired.
>
> That's how it's done in the patched r.colors. If it must be turned
> into a library function, where would it go? What would its name be?
> I'm willing to do it (and also change any system("ls")'s remaining).

I've just finished it - see attached - planning on committing it as
lib/gis/ls.c tomorrow after some more polishing if no objections.

The way I've done it there are 3 functions:

G__ls() reads the directory and stores the entries in an array.

G_ls() prints the listing to a specified stream, one entry per line.

Do we really need a library function for a for/fprintf loop?

> The parser uses column break with a hardcoded value. We certainly
> could use a global function for determining column width.

I used the ioctl method. Works for me on Linux but not on Windows - have
disabled the functionality there and it just uses hard-coded 80 characters
for now. But it does work nicely on Linux as far as I can see.

#ifndef __MINGW32__
# include <sys/ioctl.h>
#endif

This should use HAVE_SYS_IOCTL_H from <grass/config.h>.

#ifndef __MINGW32__
    if (isatty(fileno(stream)))
    {
        /* Determine screen_width if output is a terminal */
  struct winsize size;

  ioctl(fileno(stream), TIOCGWINSZ, (char *) &size);
  screen_width = size.ws_col;
    }
#endif

The code should be conditionalised upon "#ifdef TIOCGWINSZ". That
should ensure that we don't try to use it if it isn't defined. Even if
the platform has it, it might not be defined in <sys/ioctl.h>. FWIW,
SUSv2 only specifies ioctl() with regard to STREAMS (which is an
optional feature).

Also, the return value from ioctl() should be checked. Having done
that, you can dispense with the isatty() check; call ioctl()
unconditionally and only use the result if it succeeds.

However, I'm still unsure whether we might have problems due to
requiring some unspecified header in order to get "struct winsize".
Bear in mind that this is libgis, and if libgis fails to compile so
does everything else. Personally, I'd be inclined to just hard-code a
setting of 80 columns.

--
Glynn Clements <glynn@gclements.plus.com>

On Mon, 29 Jan 2007, Glynn Clements wrote:

Paul Kelly wrote:

A library function should probably return the entries as an array of
strings (char **) rather than write them to a stream. The caller can
deal with writing them, if that's desired.

That's how it's done in the patched r.colors. If it must be turned
into a library function, where would it go? What would its name be?
I'm willing to do it (and also change any system("ls")'s remaining).

I've just finished it - see attached - planning on committing it as
lib/gis/ls.c tomorrow after some more polishing if no objections.

The way I've done it there are 3 functions:

G__ls() reads the directory and stores the entries in an array.

G_ls() prints the listing to a specified stream, one entry per line.

Do we really need a library function for a for/fprintf loop?

Probably not. I was including it for the sake of completeness really, but actually I haven't yet seen anywhere it would be useful. Most modules that call system("ls") appear to rely on column output. Maybe I will make G_ls() do the column output and get rid of the one-file-per-line version.

The parser uses column break with a hardcoded value. We certainly
could use a global function for determining column width.

I used the ioctl method. Works for me on Linux but not on Windows - have
disabled the functionality there and it just uses hard-coded 80 characters
for now. But it does work nicely on Linux as far as I can see.

#ifndef __MINGW32__
# include <sys/ioctl.h>
#endif

This should use HAVE_SYS_IOCTL_H from <grass/config.h>.

Right - didn't know about that, have changed it.

#ifndef __MINGW32__
    if (isatty(fileno(stream)))
    {
        /* Determine screen_width if output is a terminal */
  struct winsize size;

  ioctl(fileno(stream), TIOCGWINSZ, (char *) &size);
  screen_width = size.ws_col;
    }
#endif

The code should be conditionalised upon "#ifdef TIOCGWINSZ". That
should ensure that we don't try to use it if it isn't defined. Even if
the platform has it, it might not be defined in <sys/ioctl.h>. FWIW,
SUSv2 only specifies ioctl() with regard to STREAMS (which is an
optional feature).

OK, have done that.

Also, the return value from ioctl() should be checked. Having done
that, you can dispense with the isatty() check; call ioctl()
unconditionally and only use the result if it succeeds.

Yes, had already changed that in my local version (the check for the return value of ioctl) BUT, my idea was keep the isatty check there
as I thought other platform-specific versions of the terminal width check could be included in the future within the isatty if-construct. Not sure though now if it's worth bothering with. I suppose 80 is a good default.

However, I'm still unsure whether we might have problems due to
requiring some unspecified header in order to get "struct winsize".
Bear in mind that this is libgis, and if libgis fails to compile so
does everything else. Personally, I'd be inclined to just hard-code a
setting of 80 columns.

Hmmm, everywhere I've seen on the web seems to suggest struct winsize is defined in sys/ioctl.h. And the mention of winsize is already conditionalised on TIOCGWINSZ being defined; I should think we're pretty safe, no?

I've added the updated version to CVS now. There are two new functions:
G_ls() prints a directory listing in column format to the specified stream.
G__ls() stores a list of the files in a directory in an array. (It is a lower level function used by G_ls().)

I've also updated lib/init/set_data.c to use these two new functions for listing locations and mapsets during the text-based startup. Hopefully they will be useful in many other places too, both to replace usage of system("ls") etc. and also to reduce cloned code for directory listing.

On Mon, 29 Jan 2007, Paul Kelly wrote:

On Mon, 29 Jan 2007, Glynn Clements wrote:

Paul Kelly wrote:

A library function should probably return the entries as an array of
strings (char **) rather than write them to a stream. The caller can
deal with writing them, if that's desired.

That's how it's done in the patched r.colors. If it must be turned
into a library function, where would it go? What would its name be?
I'm willing to do it (and also change any system("ls")'s remaining).

I've just finished it - see attached - planning on committing it as
lib/gis/ls.c tomorrow after some more polishing if no objections.

The way I've done it there are 3 functions:

G__ls() reads the directory and stores the entries in an array.

G_ls() prints the listing to a specified stream, one entry per line.

Do we really need a library function for a for/fprintf loop?

Probably not. I was including it for the sake of completeness really, but actually I haven't yet seen anywhere it would be useful. Most modules that call system("ls") appear to rely on column output. Maybe I will make G_ls() do the column output and get rid of the one-file-per-line version.

The parser uses column break with a hardcoded value. We certainly
could use a global function for determining column width.

I used the ioctl method. Works for me on Linux but not on Windows - have
disabled the functionality there and it just uses hard-coded 80 characters
for now. But it does work nicely on Linux as far as I can see.

#ifndef __MINGW32__
# include <sys/ioctl.h>
#endif

This should use HAVE_SYS_IOCTL_H from <grass/config.h>.

Right - didn't know about that, have changed it.

#ifndef __MINGW32__
    if (isatty(fileno(stream)))
    {
        /* Determine screen_width if output is a terminal */
  struct winsize size;

  ioctl(fileno(stream), TIOCGWINSZ, (char *) &size);
  screen_width = size.ws_col;
    }
#endif

The code should be conditionalised upon "#ifdef TIOCGWINSZ". That
should ensure that we don't try to use it if it isn't defined. Even if
the platform has it, it might not be defined in <sys/ioctl.h>. FWIW,
SUSv2 only specifies ioctl() with regard to STREAMS (which is an
optional feature).

OK, have done that.

Also, the return value from ioctl() should be checked. Having done
that, you can dispense with the isatty() check; call ioctl()
unconditionally and only use the result if it succeeds.

Yes, had already changed that in my local version (the check for the return value of ioctl) BUT, my idea was keep the isatty check there
as I thought other platform-specific versions of the terminal width check could be included in the future within the isatty if-construct. Not sure though now if it's worth bothering with. I suppose 80 is a good default.

However, I'm still unsure whether we might have problems due to
requiring some unspecified header in order to get "struct winsize".
Bear in mind that this is libgis, and if libgis fails to compile so
does everything else. Personally, I'd be inclined to just hard-code a
setting of 80 columns.

Hmmm, everywhere I've seen on the web seems to suggest struct winsize is defined in sys/ioctl.h. And the mention of winsize is already conditionalised on TIOCGWINSZ being defined; I should think we're pretty safe, no?

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

And for the sake of it, here's yet another proposed patch! Using the new G__ls function.

On Sun, 28 Jan 2007, Daniel Calvelo wrote:

Ok, It's working now. Attached.

Cheers,

Daniel.

On 1/28/07, Daniel Calvelo <dca.gis@gmail.com> wrote:

I'm debugging this patch now. Only to show you the idea; it's not
working currently.

BTW has anybody here experimented with extreme programming techniques?
I've always been intrigued by the approach, and this kind of on-line
concurrent patching weems to be rather along their principles...

On 1/28/07, Wolf Bergenheim <wolf+grass@bergenheim.net> wrote:
> Markus Neteler wrote:
> > Hi Wolf,
> >
> > wow, high speed programming! I cannot tell you anything,
> > most likely Glynn will have a comment or Brad.
> >
> > thanks anyway, please submit if Glynn doesn't object
> > (maybe give him 24 hours...) :slight_smile:
>
> Yeah, I'm eagerly waiting their comments. Daniel what is your approach?
>
> --Wolf
>
> --
>
> <:3 )---- Wolf Bergenheim ----( 8:>
>
> _______________________________________________
> grass-dev mailing list
> grass-dev@grass.itc.it
> http://grass.itc.it/mailman/listinfo/grass-dev
>

--
-- Daniel Calvelo Aros

--
-- Daniel Calvelo Aros

(attachments)

diff.txt (2.5 KB)

Paul Kelly wrote:

> However, I'm still unsure whether we might have problems due to
> requiring some unspecified header in order to get "struct winsize".
> Bear in mind that this is libgis, and if libgis fails to compile so
> does everything else. Personally, I'd be inclined to just hard-code a
> setting of 80 columns.

Hmmm, everywhere I've seen on the web seems to suggest struct winsize is
defined in sys/ioctl.h.

That's the case on Linux, but (AFAICT) none of this is specified by
any of the formal Unix standards. In general, ioctl() commands are
specific to a particular type of device; some platforms have each
device's command macros in a header for that particular device.

On Linux, <sys/ioctl.h> includes <bits/ioctls.h>, which defines the
networking commands (SIOC*) directly, and also includes
<asm/ioctls.h>, which defines the TTY commands (TC* and TIOC*) plus
the generic commands (FIO*). Commands for other devices are defined in
device-specific headers (e.g. <linux/cdrom.h> for commands related to
CD drives). It isn't beyond the bounds of possibility that other
platforms may put the TTY commands in a separate header.

And the mention of winsize is already conditionalised on TIOCGWINSZ
being defined;

But do we actually *know* that "struct winsize" will be defined in the
same header as TIOCGWINSZ?

I should think we're pretty safe, no?

It's safe in the sense that the new code *probably* won't result in
GRASS completely failing to compile. To be truly safe, we need a
configure check, e.g. (untested):

  AC_CHECK_MEMBER([struct winsize.ws_col],
    [AC_DEFINE(HAVE_STRUCT_WINSIZE)],,
    [#include <sys/ioctl.h>])

--
Glynn Clements <glynn@gclements.plus.com>

Paul Kelly wrote:

I've added the updated version to CVS now. There are two new
functions: G_ls() prints a directory listing in column format to the
specified stream.
G__ls() stores a list of the files in a directory in an array. (It is
a lower level function used by G_ls().)

I've also updated lib/init/set_data.c to use these two new functions
for listing locations and mapsets during the text-based startup.
Hopefully they will be useful in many other places too, both to
replace usage of system("ls") etc. and also to reduce cloned code for
directory listing.

what about:

  void G_ls(const char *dir, FILE *stream, int singlecolumn)

where singlecolumn is boolean: 0 prints column output, 1 prints one file
per line.

I can think of one place it might be useful, "i.group -g".

I don't like "int multicolumn" as it might be mistaken to mean number
of columns, not a boolean switch. (which is another idea, -1,0 means
auto, otherwise as specified)

Hamish

On Wed, 31 Jan 2007, Hamish wrote:

what about:

void G_ls(const char *dir, FILE *stream, int singlecolumn)

where singlecolumn is boolean: 0 prints column output, 1 prints one file
per line.

That's actually exactly how my original idea worked, then for some reason I thought I would split it into two functions. I'm happy to change it to that if it's generally agreed it's a good idea.

Paul

I can think of one place it might be useful, "i.group -g".

I don't like "int multicolumn" as it might be mistaken to mean number
of columns, not a boolean switch. (which is another idea, -1,0 means
auto, otherwise as specified)

I was originally doing that when I wasn't sure how to automatically determine the column width, but didn't think it was necessary any more after I got the automatic column width working.

Paul