Devlog – alanza.xyz
ROBBIE LYMAN
Devlog
250104 – Please clap
Seamstress, until recently, had a pretty simple approach to command-line arguments: if you fed it -v
or --version
or -h
or --help
it would print a short message and exit. I realized the other day that of course Lua's approach to command-line arguments is a detail of the interpreter implementation and not the language's doing. In anticipation of making more of that goodness available from the Seamstress command-line tool, I figured it might be good to get a better parser going.
Here's where we're at today:
Here's what my code does: we declare a bunch of optional things we want to pull out of the arguments. Then we loop through the arguments (using a while
loop so that we can alter the index mid-flight) and attempt to match against the flags we accept. Since the arguments are strings, the way to match is just a bunch of if
statements. Obviously something like Rust's match
would feel nicer to write, but I appreciate the honesty of the if
statement, since it's not like there's an a priori obvious way to magic up a jump table in assembly out of these conditions. If none of the flags match, we treat the argument as a filename. Since we declared our arguments as optionals, we know that if the optional is already populated, there's a duplicate arguent, so we can fail in that case. Finally we package all of what we got up into our Args
type and return that.
Processing command line arguments appears to be a common place where people shell out to a package for the actual parsing code. I frankly haven't the foggiest idea why.
250103 – Seamstress for Windows?
A month or so ago I was talking with Jeremy about how there really are only so many kinds of programs. I’ve forgotten the list we made of them, and I think part of the fun of it is that every program is a little bit many of them anyway.
Anyway the point of this post is that the Zig compiler and standard library is a great resource for learning the basics of how to interact with a computer when you don’t have that kind of computer ready to play with.
I realized the other day that in its current state, with Lua itself being the only “external” (which is to say, non-Zig) dependency, attempting building Seamstress for Windows is surely much easier than it would be later on.
Anyway, compiling turned out to not be so difficult. Here are some things I learned: It turns out Windows (at least, the GitHub CI machine I was interacting with) does not have a $HOME
environment variable. Creating /tmp/seamstress.log
won’t work because a Unix-style absolute path is no good. Under POSIX (apparently), environment variables are present in a memory structure whose type in Zig is [*:null]?[*:0]u8
, which is to say, an array of pointers, each of which is a C-style string (that is, a pointer to bytes; you know when you’re at the end of the string because you’ll hit a character with ASCII value 0
.) This memory structure is available at the global (extern) variable environ
when linking against POSIX libc.
In order for Seamstress to find and access luarocks
modules, in particular busted
, which I’m using for Lua unit tests, it needs to set some environment variables that result from running luarocks path
. (It’s not enough to use Zig’s cross-platform EnvMap
abstraction, though, because ultimately it is Lua code that will need to access these environment variables.) It occurred to me that because the Zig Build system needs to be able to spawn child processes and exposes the ability to set their environment variables that of course the Zig standard library must contain a solution for getting and setting environment variables on Windows.
Indeed it does: std.process.createWindowsEnvBlock
creates such an environment from a std.process.EnvMap
. It returns a slice of type []u16
(really [:0]u16
). In Zig code at least, to set the environment one interacts (apparently) with the variable std.os.windows.peb().ProcessParameters.Environment
. It’s not clear to me how successful or correct this understanding is, since currently my GitHub CI machine neither crashes nor completes on Windows, just hangs, but I’m pretty excited nonetheless.