lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Dirk Laurie once stated:
> 
> I don't think lfs functions are left out of the standard libraries because
> the Lua maintainers would find that an extra bother. I think it is because
> the support libraries are not in core C, only in C compilers that support
> for example Posix extensions.
> 
> I am not arguing for the stuff in luaposix, only for basic directory
> awareness. Paths are essential to the package library anyway, so why
> not in the os library where users can access them for another purpose
> than finding modules?

  Paths are incidental to the package library.  All it does is substitute
the name of a module into a string and opens it using the standard C library
routines.  It has no real understanding of "paths".

> > The standard libs are already quite sufficient for a very common set
> > of use cases (manipulation of text files), and serve as an example of
> > good practices for people that want to expand that.
> 
> They are very good for binary files too, now that string.pack/unpack
> is available. Which makes it harder to understand why Lua can't DIR,
> CHDIR, MKDIR, RMDIR. Every device that can read a USB stick
> or SD card needs that functionality.

  I've checked Unix, MS-DOS (on the assumption that Windows is more or less
the same even 30+ years later, and I have way too much documentation about
it) and AmigaOS (because I have a ton of documentation about that, too) and
while all three or or less have similar semantics for MKDIR, RMDIR and
CHDIR, it's DIR where there the differences lie.

  Under Unix, you have opendir()/readdir()/closedir().  You call opendir(),
then repeatedly call readdir(), which returns the successive file names on
the directory.  When done, you call closedir().  This returns the "."
(current directory) and ".." (parent directory).  You also have wordexp()
(it is POSIX), which returns a list of filenames matching a pattern (also
glob() and fnmatch() which are variations on a theme).

  Under MS-DOS, you have FindFirstFile() and FindNextFile().  You have to
first call FindFirstFile() with a given pattern and attributes (hidden,
system, directory)---this returns the first filename; subsequent calls
require FindNextFile().  I don't think the parent and current directory are
returned; but someone more familiar with Windows can answer this.

  Under AmigaOS [3], you have options.  You can call ExAll() (Examine All;
you can return just the name, or name with a selection of other metadata). 
You can call Examine() (think opendir()) then loop with ExNext()
(readdir()).  Or you have MatchFirst()/MatchNext()/MatchEnd(), which works
like MS-DOS.  There are separate calls to get the current directory and
parent directory (these don't have names under AmigaOS).

  The only reason I bring these up is to illustrate that there is more than
one way DIR is handled.  Pass in a pattern, and under Unix you might get
[1]:

> for file in fsys.gexpand("/tmp/*") do print(file) end
/tmp/1
/tmp/2
/tmp/langtranslate.lua
/tmp/md5.c
/tmp/modules
/tmp/rfc1751
/tmp/rfc1751.c
/tmp/signal-test.lua

  But that misses a few files on Unix:

> for file in fsys.gexpand("/tmp/.*") do print(file) end
/tmp/.
/tmp/..
/tmp/.ICE-unix
/tmp/.X0-lock
/tmp/.X11-unix
/tmp/.font-unix

  Assume looping through each issue, you get all the files:

> for file in fsys.dir("/tmp") do print(file) end
.X11-unix
rfc1751.c
rfc1751
md5.c
1
langtranslate.lua
.font-unix
2
modules
.ICE-unix
.X0-lock
signal-test.lua

but you get all the files [2] and any "globbing" must be added by the user
(and in the case of MS-DOS/Windows, duplicating what the operating system
can provide by default).  Or, you somehow provide for both operations (which
for MS-DOS could be the same function under two different names).  The
tricky part is defining the name(s) and what to expect.

  -spc (And for all three systems, renaming a file not only has a similar
	API, but all three have the same restriction that you can't rename
	across a disks)

[1]	fsys is org.conman.fsys

	https://github.com/spc476/lua-conmanorg/blob/master/src/fsys.c

[2]	Except for "." and ".." in this example, since I skip those.  I skip
	those in fsys.dir() because in all the code I've written, I never
	wanted to bother with "." and "..".

[3]	AmigaDOS has the concept of drives like MS-DOS, but instead of just
	a single letter name like A:, it uses a longer name, such as DF0:
	(for floppy drive 0).  Not only can you use physical names like
	DF0:, but volume names like Steve: or MyHardDisk:.  If you specify a
	file like:

		TheGreatGame:config.txt

	AmigaDOS will prompt for TheGreatGame: volume if it isn't mounted.
	You can place TheGreatGame: disk in any drive, and AmigaDOS will
	automatically find it and open the file.

	You can also assign volume names to directories as well.  It's a
	really cool system.