RFC: Add a Glob() function

259 views
Skip to first unread message

Benny Siegert

unread,
Oct 5, 2010, 9:15:48 AM10/5/10
to golan...@googlegroups.com
Hi all!

Andrew Gerrand suggested that I bring this up for discussion on this list.

I would like to have a function akin to glob(3) from libc in Go. This
is especially needed under Windows, where the shell does not expand
wildcards in program arguments and the program has to handle them
itself. In Issue 1053, I proposed a small Windows-specific
implementation using GetFirstFile and GetNextFile, but it was
suggested to implement Glob in pure Go.

The C prototype of glob is (from
http://www.mirbsd.org/htman/i386/man3/glob.htm):
int glob(const char *pattern, int flags, const int (*errfunc)(const
char *, int), glob_t *pglob);

I am trying to stay as close as possible to this prototype, however we
do not need the pglob structure in Go, as we can just return a slice
of filenames.
The prototype that I put up at
http://cvs.mirbsd.org/contrib/hosted/bsiegert/go-glob/ contains two
functions:

func Glob(pattern string, flags int, errfunc func(string, os.Error)
bool) ([]string, bool)
func GlobAll(patterns []string, flags int, errfunc func(string,
os.Error) bool) ([]string, bool)

The second one is interesting because it allows, for example, to plug
in something like os.Args[1:]. It just calls Glob with a for loop and
sorts the results once at the end, unless GLOB_NOSORT is given.

As for the flags, the following ones seem interesting:
GLOB_ERR: abort on error
GLOB_MARK: append a path name separator (/ or \) to the matches if
they are directories
GLOB_NOCHECK: if a pattern does not match any pathname, return it unchanged
GLOB_NOESCAPE (not sure)
GLOB_NOSORT: do not sort results

GLOB_BRACE: expand {foo,bar}
GLOB_TILDE: replace ~ by the user's home directory (unix only); as we
do not have getpwnam() and friends, we cannot expand things like
~user.

At the moment, the functions do not work well under Windows, due to
missing support for Windows-style paths in the path package.

There are two things that I am not sure about:

1. Into which package should this function go? os or path?

2. How do we handle the backslash, w.r.t. escape character vs. Windows
path separator?

Comments?

--Benny.

--
The first essential in chemistry is that you should perform practical
work and conduct experiments, for he who performs not practical work
nor makes experiments will never attain the least degree of mastery.
        -- Abu Musa Jabir ibn Hayyan (721-815)

Russ Cox

unread,
Oct 5, 2010, 9:24:03 AM10/5/10
to Benny Siegert, golan...@googlegroups.com
I'm not convinced this is so easy to define.
How would you use it, and when?

Every Unix shell does something a little different.
Unix programs trying to be Windows programs
do need something, but it's not clear what.
Certainly every program shouldn't start by
globbing the arguments: the shell has already
done that in most cases.

It's also noteworthy that Windows programs
don't just glob their inputs either. For example,
the old standby copy lets you write

copy *.txt *.doc

which cannot be explained by globbing.

If we do add some kind of path expander I would
strongly prefer it to do one right thing instead of
having a half dozen flags that everyone must know
about and choose between. Compare path.Match
to the POSIX equivalent, for example.

Russ

Benny Siegert

unread,
Oct 5, 2010, 9:52:34 AM10/5/10
to golan...@googlegroups.com
On Tue, Oct 5, 2010 at 15:24, Russ Cox <r...@golang.org> wrote:
> I'm not convinced this is so easy to define.
> How would you use it, and when?

There have been cases in C programming where I needed to call glob --
for example if you read a config file which contains paths with
wildcards.


> Every Unix shell does something a little different.
> Unix programs trying to be Windows programs
> do need something, but it's not clear what.
> Certainly every program shouldn't start by
> globbing the arguments: the shell has already
> done that in most cases.

Exactly. I am not saying every program needs to call Glob on every
argument. The MinGW runtime does this automatically IIRC, and it
creates problems, for instance when you are trying to pass regexps as
an argument.

But right now, you need to reimplement Glob by hand if you write Go
programs for Windows that accept file name arguments with wildcards. I
just happened to need such a thing for my dayjob.

> It's also noteworthy that Windows programs
> don't just glob their inputs either.  For example,
> the old standby copy lets you write
>
>    copy *.txt *.doc

Right. But this is not an argument against having path.Glob or os.Glob
or something similar.

> If we do add some kind of path expander I would
> strongly prefer it to do one right thing instead of
> having a half dozen flags that everyone must know
> about and choose between.  Compare path.Match
> to the POSIX equivalent, for example.

I am not married to the POSIX-like function prototype, it was just a
proposal in the spirit of the os package, which also stays quite close
to the libc function names and prototypes.

We could do away with most of the flags, I suppose. I don't know if
somebody really needs the error function. Tilde and brace expansion
could just be done by separate functions.

Do you want me to propose something simpler?

Benny Siegert

unread,
Oct 12, 2010, 8:55:06 AM10/12/10
to r...@golang.org, golan...@googlegroups.com
On Tue, Oct 5, 2010 at 15:24, Russ Cox <r...@golang.org> wrote:
> If we do add some kind of path expander I would
> strongly prefer it to do one right thing instead of
> having a half dozen flags that everyone must know
> about and choose between.  Compare path.Match
> to the POSIX equivalent, for example.

Okay, I think I have something minimal but functional. No flags, no
sorting, no multiple patterns. Just:

func Glob(pattern string) []string

The implementation is here:
https://cvs.mirbsd.org/contrib/hosted/bsiegert/go-glob/simpleglob.go

I am convinced that this simplest possible version does exactly what
it is supposed to do for most users.

If you are okay with the general direction, then I will prepare a CL
for adding this to the path package.

Russ Cox

unread,
Oct 12, 2010, 3:18:29 PM10/12/10
to Benny Siegert, golan...@googlegroups.com

rh

unread,
Dec 9, 2010, 9:10:23 AM12/9/10
to golang-dev

roger peppe

unread,
Dec 9, 2010, 9:14:28 AM12/9/10
to rh, golang-dev
are you aware of this, that's been done in the meantime?

http://golang.org/pkg/path/#Glob

peterGo

unread,
Dec 9, 2010, 9:26:27 AM12/9/10
to golang-dev
rh,

It's here.

push by r...@golang.org - path: add Glob... on 2010-11-05 17:47 GMT -
golang-checkins | Google Groups
http://groups.google.com/group/golang-checkins/browse_thread/thread/c6e8346bfd44faac/67bd18708ebea378

Peter

On Dec 9, 9:10 am, rh <robert.hen...@gmail.com> wrote:
> I think I found it at:https://www.mirbsd.org/cvs.cgi/contrib/hosted/bsiegert/go-glob/simple...

rh

unread,
Dec 9, 2010, 9:37:53 AM12/9/10
to golang-dev
I completely missed that. Apologies for the noise. Thanks, both.
Reply all
Reply to author
Forward
0 new messages