From e3f20c041c078eacf648af94d9f012e4906359bb Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 6 Nov 2014 14:18:37 -0500 Subject: Enhance get_file API to return info about input and output and to enable extensions to create already-opened files or sockets. --- extension/testext.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'extension/testext.c') diff --git a/extension/testext.c b/extension/testext.c index 7462265b..3ac1f124 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -37,6 +37,7 @@ #include #include +#include #include "gawkapi.h" @@ -710,6 +711,7 @@ BEGIN { ret = test_indirect_vars() # should get correct value of NR printf("test_indirect_var() return %d\n", ret) delete ARGV[1] + print "" } */ @@ -742,6 +744,63 @@ out: return result; } +/* +BEGIN { + outfile = "testexttmp.txt" + alias = ".test.alias" + print "line 1" > outfile + print "line 2" > outfile + print "line 3" > outfile + close(outfile) + ret = test_get_file(outfile, alias) + printf "test_get_file returned %d\n", ret + nr = 0 + while ((getline < alias) > 0) + printf "File [%s] nr [%s]: %s\n", alias, ++nr, $0 + close(alias) + system("rm " outfile) + print "" +} +*/ + +/* test_get_file --- test that we can create a file */ + +static awk_value_t * +test_get_file(int nargs, awk_value_t *result) +{ + awk_value_t filename, alias; + int fd; + const awk_input_buf_t *ibuf; + const awk_output_buf_t *obuf; + + if (nargs != 2) { + printf("%s: nargs not right (%d should be 2)\n", __func__, nargs); + return make_number(-1.0, result); + } + + if (! get_argument(0, AWK_STRING, & filename)) { + printf("%s: cannot get first arg\n", __func__); + return make_number(-1.0, result); + } + if (! get_argument(1, AWK_STRING, & alias)) { + printf("%s: cannot get first arg\n", __func__); + return make_number(-1.0, result); + } + if ((fd = open(filename.str_value.str, O_RDONLY)) < 0) { + printf("%s: open(%s) failed\n", __func__, filename.str_value.str); + return make_number(-1.0, result); + } + if (! get_file(alias.str_value.str, strlen(alias.str_value.str), "<", 1, fd, &ibuf, &obuf)) { + printf("%s: get_file(%s) failed\n", __func__, alias.str_value.str); + return make_number(-1.0, result); + } + if (! ibuf || ibuf->fd != fd) { + printf("%s: get_file(%s) returned fd %d instead of %d\n", __func__, alias.str_value.str, ibuf ? ibuf->fd : -1, fd); + return make_number(-1.0, result); + } + return make_number(0.0, result); +} + /* fill_in_array --- fill in a new array */ static void @@ -837,6 +896,7 @@ static awk_ext_func_t func_table[] = { { "test_scalar", test_scalar, 1 }, { "test_scalar_reserved", test_scalar_reserved, 0 }, { "test_indirect_vars", test_indirect_vars, 0 }, + { "test_get_file", test_get_file, 2 }, }; /* init_testext --- additional initialization function */ -- cgit v1.2.3 From d0299eb46c0f4551d355591a58e88715fee139e7 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Sun, 9 Nov 2014 09:09:57 -0500 Subject: Add new functions input_fd and output_fd to the select extension. --- extension/testext.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'extension/testext.c') diff --git a/extension/testext.c b/extension/testext.c index 3ac1f124..f00ced7d 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -774,28 +774,28 @@ test_get_file(int nargs, awk_value_t *result) const awk_output_buf_t *obuf; if (nargs != 2) { - printf("%s: nargs not right (%d should be 2)\n", __func__, nargs); + printf("%s: nargs not right (%d should be 2)\n", "test_get_file", nargs); return make_number(-1.0, result); } if (! get_argument(0, AWK_STRING, & filename)) { - printf("%s: cannot get first arg\n", __func__); + printf("%s: cannot get first arg\n", "test_get_file"); return make_number(-1.0, result); } if (! get_argument(1, AWK_STRING, & alias)) { - printf("%s: cannot get first arg\n", __func__); + printf("%s: cannot get first arg\n", "test_get_file"); return make_number(-1.0, result); } if ((fd = open(filename.str_value.str, O_RDONLY)) < 0) { - printf("%s: open(%s) failed\n", __func__, filename.str_value.str); + printf("%s: open(%s) failed\n", "test_get_file", filename.str_value.str); return make_number(-1.0, result); } if (! get_file(alias.str_value.str, strlen(alias.str_value.str), "<", 1, fd, &ibuf, &obuf)) { - printf("%s: get_file(%s) failed\n", __func__, alias.str_value.str); + printf("%s: get_file(%s) failed\n", "test_get_file", alias.str_value.str); return make_number(-1.0, result); } if (! ibuf || ibuf->fd != fd) { - printf("%s: get_file(%s) returned fd %d instead of %d\n", __func__, alias.str_value.str, ibuf ? ibuf->fd : -1, fd); + printf("%s: get_file(%s) returned fd %d instead of %d\n", "test_get_file", alias.str_value.str, ibuf ? ibuf->fd : -1, fd); return make_number(-1.0, result); } return make_number(0.0, result); -- cgit v1.2.3 From e36300be4deb7bbdeff17c8e896ac2f727e1477e Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Fri, 2 Jan 2015 16:44:33 -0500 Subject: Remove api_get_file typelen argument. --- extension/testext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'extension/testext.c') diff --git a/extension/testext.c b/extension/testext.c index f00ced7d..a10c9255 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -790,7 +790,7 @@ test_get_file(int nargs, awk_value_t *result) printf("%s: open(%s) failed\n", "test_get_file", filename.str_value.str); return make_number(-1.0, result); } - if (! get_file(alias.str_value.str, strlen(alias.str_value.str), "<", 1, fd, &ibuf, &obuf)) { + if (! get_file(alias.str_value.str, strlen(alias.str_value.str), "<", fd, &ibuf, &obuf)) { printf("%s: get_file(%s) failed\n", "test_get_file", alias.str_value.str); return make_number(-1.0, result); } -- cgit v1.2.3 From a97507159ee06523c9dd6ec809199a0774976498 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Mon, 5 Jan 2015 15:44:28 -0500 Subject: Add low-level access to the get_file API through the testext sample extension to facilitate further testing. --- extension/testext.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) (limited to 'extension/testext.c') diff --git a/extension/testext.c b/extension/testext.c index a10c9255..c931ed39 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -783,7 +783,7 @@ test_get_file(int nargs, awk_value_t *result) return make_number(-1.0, result); } if (! get_argument(1, AWK_STRING, & alias)) { - printf("%s: cannot get first arg\n", "test_get_file"); + printf("%s: cannot get second arg\n", "test_get_file"); return make_number(-1.0, result); } if ((fd = open(filename.str_value.str, O_RDONLY)) < 0) { @@ -801,6 +801,68 @@ test_get_file(int nargs, awk_value_t *result) return make_number(0.0, result); } +/* do_get_file --- provide access to get_file API */ + +static awk_value_t * +do_get_file(int nargs, awk_value_t *result) +{ + awk_value_t filename, filetype, fd, res; + const awk_input_buf_t *ibuf; + const awk_output_buf_t *obuf; + awk_array_t array; + + if (nargs != 4) { + printf("%s: nargs not right (%d should be 4)\n", "get_file", nargs); + return make_number(-1.0, result); + } + + if (! get_argument(0, AWK_STRING, & filename)) { + printf("%s: cannot get first arg\n", "get_file"); + return make_number(-1.0, result); + } + if (! get_argument(1, AWK_STRING, & filetype)) { + printf("%s: cannot get second arg\n", "get_file"); + return make_number(-1.0, result); + } + if (! get_argument(2, AWK_NUMBER, & fd)) { + printf("%s: cannot get third arg\n", "get_file"); + return make_number(-1.0, result); + } + if (! get_argument(3, AWK_ARRAY, & res)) { + printf("%s: cannot get fourth arg\n", "get_file"); + return make_number(-1.0, result); + } + clear_array(res.array_cookie); + + if (! get_file(filename.str_value.str, strlen(filename.str_value.str), filetype.str_value.str, fd.num_value, &ibuf, &obuf)) { + printf("%s: get_file(%s, %s, %d) failed\n", "get_file", filename.str_value.str, filetype.str_value.str, (int)(fd.num_value)); + return make_number(0.0, result); + } + + if (ibuf) { + awk_value_t idx, val; + set_array_element(res.array_cookie, + make_const_string("input", 5, & idx), + make_number(ibuf->fd, & val)); + if (ibuf->name) + set_array_element(res.array_cookie, + make_const_string("input_name", 10, & idx), + make_const_string(ibuf->name, strlen(ibuf->name), & val)); + } + if (obuf) { + awk_value_t idx, val; + set_array_element(res.array_cookie, + make_const_string("output", 6, & idx), + make_number(obuf->fp ? fileno(obuf->fp) : -1, + & val)); + if (obuf->name) + set_array_element(res.array_cookie, + make_const_string("output_name", 11, & idx), + make_const_string(obuf->name, strlen(obuf->name), & val)); + } + return make_number(1.0, result); +} + /* fill_in_array --- fill in a new array */ static void @@ -897,6 +959,7 @@ static awk_ext_func_t func_table[] = { { "test_scalar_reserved", test_scalar_reserved, 0 }, { "test_indirect_vars", test_indirect_vars, 0 }, { "test_get_file", test_get_file, 2 }, + { "get_file", do_get_file, 4 }, }; /* init_testext --- additional initialization function */ @@ -907,6 +970,9 @@ static awk_bool_t init_testext(void) static const char message[] = "hello, world"; /* of course */ static const char message2[] = "i am a scalar"; + if (sym_lookup("TESTEXT_QUIET", AWK_NUMBER, & value)) + return awk_true; + /* add at_exit functions */ awk_atexit(at_exit0, NULL); awk_atexit(at_exit1, & data_for_1); -- cgit v1.2.3 From f38a8f801496ea91cef7a8507e2919f6586d0694 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 6 Jan 2015 20:17:35 -0500 Subject: Fix bug in API deferred variable creation and add a test case. --- extension/testext.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) (limited to 'extension/testext.c') diff --git a/extension/testext.c b/extension/testext.c index c931ed39..7c61bb0d 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -374,6 +374,75 @@ out: return result; } +static awk_value_t * +test_deferred(int nargs, awk_value_t *result) +{ + awk_value_t arr; + awk_value_t index, value; + const struct nval { + const char *name; + double val; + } seed[] = { + { "fubar", 9.0, }, + { "rumpus", -5.0, }, + }; + struct nval sysval[] = { + { "uid", getuid(), }, + { "api_major", GAWK_API_MAJOR_VERSION, }, + }; + size_t i; + + assert(result != NULL); + make_number(0.0, result); + + if (nargs != 0) { + printf("test_deferred: nargs not right (%d should be 0)\n", nargs); + goto out; + } + arr.val_type = AWK_ARRAY; + arr.array_cookie = create_array(); + + for (i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) { + make_const_string(seed[i].name, strlen(seed[i].name), & index); + make_number(seed[i].val, & value); + if (! set_array_element(arr.array_cookie, & index, & value)) { + printf("test_deferred: %d: set_array_element(%s) failed\n", __LINE__, seed[i].name); + goto out; + } + } + + if (! sym_update("PROCINFO", & arr)) { + printf("test_deferred: %d: sym_update failed\n", __LINE__); + goto out; + } + + /* test that it still contains the values we loaded */ + for (i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) { + make_const_string(seed[i].name, strlen(seed[i].name), & index); + make_null_string(& value); + if (! get_array_element(arr.array_cookie, &index, AWK_NUMBER, & value)) { + printf("test_deferred: %d: get_array_element(%s) failed\n", __LINE__, seed[i].name); + goto out; + } + printf("%s = %g\n", seed[i].name, value.num_value); + } + + /* check a few automatically-supplied values */ + for (i = 0; i < sizeof(sysval)/sizeof(sysval[0]); i++) { + make_const_string(sysval[i].name, strlen(sysval[i].name), & index); + make_null_string(& value); + if (! get_array_element(arr.array_cookie, &index, AWK_NUMBER, & value)) { + printf("test_deferred: %d: get_array_element(%s) failed\n", __LINE__, sysval[i].name); + goto out; + } + printf("%s matches %d\n", sysval[i].name, (value.num_value == sysval[i].val)); + } + + make_number(1.0, result); +out: + return result; +} + /* BEGIN { for (i = 1; i <= 10; i++) @@ -809,7 +878,6 @@ do_get_file(int nargs, awk_value_t *result) awk_value_t filename, filetype, fd, res; const awk_input_buf_t *ibuf; const awk_output_buf_t *obuf; - awk_array_t array; if (nargs != 4) { printf("%s: nargs not right (%d should be 4)\n", "get_file", nargs); @@ -950,6 +1018,7 @@ static awk_ext_func_t func_table[] = { { "dump_array_and_delete", dump_array_and_delete, 2 }, { "try_modify_environ", try_modify_environ, 0 }, { "var_test", var_test, 1 }, + { "test_deferred", test_deferred, 0 }, { "test_errno", test_errno, 0 }, { "test_array_size", test_array_size, 1 }, { "test_array_elem", test_array_elem, 2 }, -- cgit v1.2.3 From b1f63ac08d7da89ac7e8af4df5ca835527fc5b24 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Wed, 7 Jan 2015 22:23:19 +0200 Subject: Load PROCINFO and ENVIRON if using extensions. --- extension/testext.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'extension/testext.c') diff --git a/extension/testext.c b/extension/testext.c index 7462265b..4a1e7032 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 2012, 2013, 2014 + * Copyright (C) 2012, 2013, 2014, 2015 * the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the @@ -302,11 +302,11 @@ var_test(int nargs, awk_value_t *result) goto out; } - /* look up PROCINFO - should fail */ + /* look up PROCINFO - should succeed fail */ if (sym_lookup("PROCINFO", AWK_ARRAY, & value)) - printf("var_test: sym_lookup of PROCINFO failed - got a value!\n"); + printf("var_test: sym_lookup of PROCINFO passed - got a value!\n"); else - printf("var_test: sym_lookup of PROCINFO passed - did not get a value\n"); + printf("var_test: sym_lookup of PROCINFO failed - did not get a value\n"); /* look up a reserved variable - should pass */ if (sym_lookup("ARGC", AWK_NUMBER, & value)) -- cgit v1.2.3 From f8fecb69346cbcd774a73a49322aeb8ddea73e44 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 8 Jan 2015 09:41:19 -0500 Subject: When an extension calls sym_lookup on a deferred variable, it should always succeed. --- extension/testext.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'extension/testext.c') diff --git a/extension/testext.c b/extension/testext.c index 7c61bb0d..42ec0915 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -303,11 +303,11 @@ var_test(int nargs, awk_value_t *result) goto out; } - /* look up PROCINFO - should fail */ + /* look up PROCINFO - should succeed */ if (sym_lookup("PROCINFO", AWK_ARRAY, & value)) - printf("var_test: sym_lookup of PROCINFO failed - got a value!\n"); + printf("var_test: sym_lookup of PROCINFO passed - got a value!\n"); else - printf("var_test: sym_lookup of PROCINFO passed - did not get a value\n"); + printf("var_test: sym_lookup of PROCINFO failed - did not get a value\n"); /* look up a reserved variable - should pass */ if (sym_lookup("ARGC", AWK_NUMBER, & value)) @@ -399,8 +399,11 @@ test_deferred(int nargs, awk_value_t *result) printf("test_deferred: nargs not right (%d should be 0)\n", nargs); goto out; } - arr.val_type = AWK_ARRAY; - arr.array_cookie = create_array(); + + if (! sym_lookup("PROCINFO", AWK_ARRAY, & arr)) { + printf("test_deferred: %d: sym_lookup failed\n", __LINE__); + goto out; + } for (i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) { make_const_string(seed[i].name, strlen(seed[i].name), & index); @@ -411,11 +414,6 @@ test_deferred(int nargs, awk_value_t *result) } } - if (! sym_update("PROCINFO", & arr)) { - printf("test_deferred: %d: sym_update failed\n", __LINE__); - goto out; - } - /* test that it still contains the values we loaded */ for (i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) { make_const_string(seed[i].name, strlen(seed[i].name), & index); -- cgit v1.2.3 From 2d3f4ffebcb451da84ceb8a4be58bbb23946ee6e Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Mon, 19 Jan 2015 13:56:58 -0500 Subject: Revert "When an extension calls sym_lookup on a deferred variable, it should always succeed." This reverts commit f8fecb69346cbcd774a73a49322aeb8ddea73e44. --- extension/testext.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'extension/testext.c') diff --git a/extension/testext.c b/extension/testext.c index 42ec0915..7c61bb0d 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -303,11 +303,11 @@ var_test(int nargs, awk_value_t *result) goto out; } - /* look up PROCINFO - should succeed */ + /* look up PROCINFO - should fail */ if (sym_lookup("PROCINFO", AWK_ARRAY, & value)) - printf("var_test: sym_lookup of PROCINFO passed - got a value!\n"); + printf("var_test: sym_lookup of PROCINFO failed - got a value!\n"); else - printf("var_test: sym_lookup of PROCINFO failed - did not get a value\n"); + printf("var_test: sym_lookup of PROCINFO passed - did not get a value\n"); /* look up a reserved variable - should pass */ if (sym_lookup("ARGC", AWK_NUMBER, & value)) @@ -399,11 +399,8 @@ test_deferred(int nargs, awk_value_t *result) printf("test_deferred: nargs not right (%d should be 0)\n", nargs); goto out; } - - if (! sym_lookup("PROCINFO", AWK_ARRAY, & arr)) { - printf("test_deferred: %d: sym_lookup failed\n", __LINE__); - goto out; - } + arr.val_type = AWK_ARRAY; + arr.array_cookie = create_array(); for (i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) { make_const_string(seed[i].name, strlen(seed[i].name), & index); @@ -414,6 +411,11 @@ test_deferred(int nargs, awk_value_t *result) } } + if (! sym_update("PROCINFO", & arr)) { + printf("test_deferred: %d: sym_update failed\n", __LINE__); + goto out; + } + /* test that it still contains the values we loaded */ for (i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) { make_const_string(seed[i].name, strlen(seed[i].name), & index); -- cgit v1.2.3 From 9d43b510f74f63806279ce40f65245ea7e5b0d53 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Fri, 27 Mar 2015 06:32:13 +0300 Subject: Some more cleanups. Ready to merge! --- extension/testext.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'extension/testext.c') diff --git a/extension/testext.c b/extension/testext.c index 8a906c67..e2ddbe87 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -374,6 +374,17 @@ out: return result; } +/* + * 3/2015: This test is no longer strictly necessary, + * since PROCINFO is no longer a deferred variable. + * But we leave it in for safety, anyway. + */ +/* +BEGIN { + print "test_deferred returns", test_deferred() + print "" +} +*/ static awk_value_t * test_deferred(int nargs, awk_value_t *result) { @@ -1037,6 +1048,7 @@ static awk_bool_t init_testext(void) static const char message[] = "hello, world"; /* of course */ static const char message2[] = "i am a scalar"; + /* This is used by the getfile test */ if (sym_lookup("TESTEXT_QUIET", AWK_NUMBER, & value)) return awk_true; -- cgit v1.2.3