Pádraig Brady <[email protected]> writes:
> This patch set adds --env0-from to the env(1) command.
>
> https://github.com/pixelb/coreutils/compare/env0-from
>
> This supports efficient round tripping from the output of `env -0`,
> which may contain non standard environment entries without '=' etc.
>
> Note the naming was chosen to be descriptive and consistent form
> with the existing --files0-from option in various commands.
>
> The trigger for doing this now was the request to support regex filtering
> of environment entries, which can now be achieved more generally
> and robustly with something like:
>
> env -i --env0-from=<( env -0 | sed -z ... )
>
> For textual environment files, one can leverage sh to parse and exec,
> which gives support for comments, interpolation etc. which there
> is no need for env(1) to re-implement, though a subset of that
> functionality is available through the -S option if required.
Nice, it works well with more environment variables than you could ever need:
$ for i in {0..50000}; do export ENV$i=$i; done
$ env -0 > .env
$ time ./src/env -i --env0-from=<(cat $(yes .env | head -n 1000)) \
>/dev/null
real 0m15.132s
user 0m14.314s
sys 0m1.159s
Some minor things:
+/* Return true if ENTRY is an assignment whose name is NAME. */
+static bool
+entry_has_name (char const *entry, char const *name, idx_t name_length)
+{
+ char const *eq = strchr (entry, '=');
+ return (eq && eq - entry == name_length
+ && memcmp (entry, name, name_length) == 0);
+}
It's probably better to use memeq for consistency:
$ git grep --perl-regexp 'memcmp *\(\S+?, *\S+?, *\S+?\) == 0' | wc -l
1
$ git grep --perl-regexp 'memeq *\(\S+?, *\S+?, *\S+?\)' | wc -l
11
+/* Hash an environment vector slot by the name in its assignment. */
+static size_t
+env_vector_slot_hash (void const *x, size_t table_size)
+{
+ char *const *slot = x;
+ char const *entry = *slot;
+ char const *eq = strchr (entry, '=');
+ size_t value = 0;
+ for (char const *p = entry; p < eq; ++p)
+ value = value * 31 + (unsigned char) *p;
+ return value % table_size;
+}
I was going to say we could just use lib/hashcode-string1.c, but I guess
Gnulib doesn't have a function for hashing N bytes of memory instead of
NUL terminated strings. I would have thought we had a need for it
somewhere.
Collin