From 6e373942e52ae13742bc1dd75f645244b805670c Mon Sep 17 00:00:00 2001 From: Brendan Macmillan Date: Fri, 17 May 2013 03:03:42 +1000 Subject: [PATCH] Load library from ~/.jq --- .gitignore | 2 ++ builtin.c | 48 +++++++++++++++++++++++++++++++++++++++--------- builtin.h | 2 +- execute.c | 6 ++++-- main.c | 2 +- main.h | 9 +++++++++ 6 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 main.h diff --git a/.gitignore b/.gitignore index ba354c6..eab159d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ *.o *~ +.*.sw[a-p] +tags jq jq.1 diff --git a/builtin.c b/builtin.c index 071cb56..e6cfa4d 100644 --- a/builtin.c +++ b/builtin.c @@ -1,3 +1,4 @@ +#include #include #include "builtin.h" #include "compile.h" @@ -5,6 +6,7 @@ #include "locfile.h" #include "jv_aux.h" #include "jv_unicode.h" +#include "main.h" @@ -566,16 +568,44 @@ static const char* const jq_builtins[] = { }; -block builtins_bind(block b) { +int builtins_bind_one(block* bb, const char* code) { + struct locfile src; + locfile_init(&src, code, strlen(code)); + block funcs; + int nerrors = jq_parse_library(&src, &funcs); + if (nerrors == 0) { + *bb = block_bind_referenced(funcs, *bb, OP_IS_CALL_PSEUDO); + } + locfile_free(&src); + return nerrors; +} + +int slurp_lib(block* bb) { + int nerrors = 0; + char* home = getenv("HOME"); + if (home) { // silently ignore no $HOME + jv filename = jv_string_append_str(jv_string(home), "/.jq"); + jv data = slurp_file(jv_string_value(filename), 1); + if (jv_is_valid(data)) { + nerrors = builtins_bind_one(bb, jv_string_value(data) ); + } + jv_free(filename); + jv_free(data); + } + return nerrors; +} + +int builtins_bind(block* bb) { + int nerrors = slurp_lib(bb); + if (nerrors) { + block_free(*bb); + return nerrors; + } for (int i=(int)(sizeof(jq_builtins)/sizeof(jq_builtins[0]))-1; i>=0; i--) { - struct locfile src; - locfile_init(&src, jq_builtins[i], strlen(jq_builtins[i])); - block funcs; - int nerrors = jq_parse_library(&src, &funcs); + nerrors = builtins_bind_one(bb, jq_builtins[i]); assert(!nerrors); - b = block_bind_referenced(funcs, b, OP_IS_CALL_PSEUDO); - locfile_free(&src); } - b = bind_bytecoded_builtins(b); - return gen_cbinding(function_list, sizeof(function_list)/sizeof(function_list[0]), b); + *bb = bind_bytecoded_builtins(*bb); + *bb = gen_cbinding(function_list, sizeof(function_list)/sizeof(function_list[0]), *bb); + return nerrors; } diff --git a/builtin.h b/builtin.h index 538a139..fdbce92 100644 --- a/builtin.h +++ b/builtin.h @@ -3,7 +3,7 @@ #include "compile.h" -block builtins_bind(block); +int builtins_bind(block*); typedef void (*cfunction_ptr)(void); diff --git a/execute.c b/execute.c index fe8e698..44cf2ba 100644 --- a/execute.c +++ b/execute.c @@ -611,8 +611,10 @@ struct bytecode* jq_compile_args(const char* str, jv args) { jv_free(name); } jv_free(args); - program = builtins_bind(program); - nerrors = block_compile(program, &locations, &bc); + nerrors = builtins_bind(&program); + if (nerrors == 0) { + nerrors = block_compile(program, &locations, &bc); + } } if (nerrors) { fprintf(stderr, "%d compile %s\n", nerrors, nerrors > 1 ? "errors" : "error"); diff --git a/main.c b/main.c index 1e95184..72ffbc1 100644 --- a/main.c +++ b/main.c @@ -93,7 +93,7 @@ static void process(jv value, int flags) { jq_teardown(&jq); } -static jv slurp_file(const char* filename, int raw) { +jv slurp_file(const char* filename, int raw) { FILE* file = fopen(filename, "r"); struct jv_parser parser; jv data; diff --git a/main.h b/main.h new file mode 100644 index 0000000..ec60039 --- /dev/null +++ b/main.h @@ -0,0 +1,9 @@ +#ifndef MAIN_H +#define MAIN_H + +#include "compile.h" + +jv slurp_file(const char*, int); + + +#endif -- 2.40.0