Add $ENV builtin variable to access environment

This commit is contained in:
Nicolas Williams committed 2017-02-26 00:39:24 -06:00
1 parent 1a8a0ae0f5
commit 3504bd9a2a
3 files changed
+60 -5

No files matched your search

+12 -2
View File
@@ -1666,12 +1666,22 @@ sections:
output: output:
- '[{"a":{"b":2}}]' - '[{"a":{"b":2}}]'
- title: "`env`" - title: "`$ENV`, `env`"
body: | body: |
Outputs an object representing jq's environment. `$ENV` is an object representing the environment variables as
set when the jq program started.
`env` outputs an object representing jq's current environment.
At the moment there is no builtin for setting environment
variables.
examples: examples:
- program: '$ENV.PAGER'
input: 'null'
output: ['"less"']
- program: 'env.PAGER' - program: 'env.PAGER'
input: 'null' input: 'null'
output: ['"less"'] output: ['"less"']
+12 -2
View File
@@ -1830,13 +1830,23 @@ jq \'walk( if type == "object" then with_entries( \.key |= sub( "^_+"; "") ) els
. .
.IP "" 0 .IP "" 0
. .
.SS "env" .SS "$ENV, env"
Outputs an object representing jq\'s environment\. \fB$ENV\fR is an object representing the environment variables as set when the jq program started\.
.
.P
\fBenv\fR outputs an object representing jq\'s current environment\.
.
.P
At the moment there is no builtin for setting environment variables\.
. .
.IP "" 4 .IP "" 4
. .
.nf .nf
jq \'$ENV\.PAGER\'
null
=> "less"
jq \'env\.PAGER\' jq \'env\.PAGER\'
null null
=> "less" => "less"
+36 -1
View File
@@ -5,6 +5,7 @@
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include "compile.h" #include "compile.h"
#include "bytecode.h" #include "bytecode.h"
#include "locfile.h" #include "locfile.h"
@@ -997,6 +998,37 @@ static int count_cfunctions(block b) {
return n; return n;
} }
#ifdef WIN32
extern const char **environ;
#endif
static jv env = {JV_KIND_INVALID, 0, 0, 0, {0}};
static void
free_env(void)
{
jv_free(env);
}
static jv
make_env(void)
{
if (jv_is_valid(env))
return jv_copy(env);
jv r = jv_object();
if (environ == NULL)
return r;
for (size_t i = 0; environ[i] != NULL; i++) {
const char *eq;
if ((eq = strchr(environ[i], '=')) == NULL)
r = jv_object_delete(r, jv_string(environ[i]));
else
r = jv_object_set(r, jv_string_sized(environ[i], eq - environ[i]), jv_string(eq + 1));
}
atexit(free_env);
return (env = jv_copy(r));
}
// Expands call instructions into a calling sequence // Expands call instructions into a calling sequence
static int expand_call_arglist(block* b) { static int expand_call_arglist(block* b) {
@@ -1004,7 +1036,10 @@ static int expand_call_arglist(block* b) {
block ret = gen_noop(); block ret = gen_noop();
for (inst* curr; (curr = block_take(b));) { for (inst* curr; (curr = block_take(b));) {
if (opcode_describe(curr->op)->flags & OP_HAS_BINDING) { if (opcode_describe(curr->op)->flags & OP_HAS_BINDING) {
if (!curr->bound_by) { if (!curr->bound_by && curr->op == LOADV && strcmp(curr->symbol, "ENV") == 0) {
curr->op = LOADK;
curr->imm.constant = make_env();
} else if (!curr->bound_by) {
if (curr->symbol[0] == '*' && curr->symbol[1] >= '1' && curr->symbol[1] <= '3' && curr->symbol[2] == '\0') if (curr->symbol[0] == '*' && curr->symbol[1] >= '1' && curr->symbol[1] <= '3' && curr->symbol[2] == '\0')
locfile_locate(curr->locfile, curr->source, "jq: error: break used outside labeled control structure"); locfile_locate(curr->locfile, curr->source, "jq: error: break used outside labeled control structure");
else if (curr->op == LOADV) else if (curr->op == LOADV)