diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | awk.h | 1 | ||||
-rw-r--r-- | eval.c | 3 | ||||
-rw-r--r-- | extension/ChangeLog | 3 | ||||
-rw-r--r-- | extension/testext.c | 147 | ||||
-rw-r--r-- | gawkapi.c | 8 | ||||
-rw-r--r-- | gawkapi.h | 5 |
7 files changed, 164 insertions, 8 deletions
@@ -3,6 +3,11 @@ * cint_array.c (tree_print, leaf_print): Add additional casts for printf warnings. + * awk.h (update_ext_api): Add declaration. + * gawkapi.c (update_ext_api): New function. + * eval.c (set_LINT): Call update_ext_api() at the end. + * gawkapi.h: Document that do_XXX could change on the fly. + 2012-06-05 Arnold D. Robbins <arnold@skeeve.com> * ext.c (load_ext): Remove use of RTLD_GLOBAL. Not needed in new @@ -709,6 +709,7 @@ struct break_point; #include "gawkapi.h" extern gawk_api_t api_impl; extern void init_ext_api(void); +extern void update_ext_api(void); extern NODE *awk_value_to_node(const awk_value_t *); #endif @@ -967,6 +967,9 @@ set_LINT() /* explicitly use warning() here, in case lintfunc == r_fatal */ if (old_lint != do_lint && old_lint && ! do_lint) warning(_("turning off `--lint' due to assignment to `LINT'")); + + /* inform plug-in api of change */ + update_ext_api(); #endif /* ! NO_LINT */ } diff --git a/extension/ChangeLog b/extension/ChangeLog index e31a1079..140aea50 100644 --- a/extension/ChangeLog +++ b/extension/ChangeLog @@ -2,6 +2,9 @@ * filefuncs.c (do_stat): Make `type' const char *. + * testext.c: Functions renamed, some of them filled in. Corresponding + awk code for each test added inline. + 2012-05-30 Arnold D. Robbins <arnold@skeeve.com> * testext.c: New file. Outline of tests for extension API. diff --git a/extension/testext.c b/extension/testext.c index 599581c0..5b171e84 100644 --- a/extension/testext.c +++ b/extension/testext.c @@ -41,35 +41,92 @@ static awk_ext_id_t *ext_id; int plugin_is_GPL_compatible; +/* + * The awk code for these tests is embedded in this file and then extracted + * dynamically to create the script that is run together with this extension. + * Extraction requires the format for awk code where test code is enclosed + * in a BEGIN block, with the BEGIN and close brace on lines by themselves + * and at the front of the lines. + */ + +/* +@load testext +BEGIN { + dump_procinfo() +} +*/ static awk_value_t * -do_func1(int nargs, awk_value_t *result) +dump_procinfo(int nargs, awk_value_t *result) { /* get PROCINFO as flat array and print it */ } +/* +BEGIN { + testvar = "One Adam Twelve" + ret = var_test("testvar") + printf "var_test() returned %d, test_var = %s\n", ret, testvar +} +*/ + static awk_value_t * -do_func2(int nargs, awk_value_t *result) +var_test(int nargs, awk_value_t *result) { + awk_value_t value; + + if (nargs != 1 || result == NULL) + return NULL; + /* look up a reserved variable - should fail */ + if (sym_lookup("ARGC", & value, AWK_NUMBER) != NULL) + printf("var_test: sym_lookup of ARGC failed - got a value!\n"); + else + printf("var_test: sym_lookup of ARGC passed\n"); + /* look up variable whose name is passed in, should pass */ /* change the value, should be reflected in awk script */ } +/* +BEGIN { + ERRNO = "" + ret = test_errno() + printf "test_errno() returned %d, ERRNO = %s\n", ret, ERRNO +} +*/ static awk_value_t * -do_func3(int nargs, awk_value_t *result) +test_errno(int nargs, awk_value_t *result) { - /* set ERRNO, should be reflected in awk script */ + update_ERRNO_int(ECHILD); } +/* +BEGIN { + for (i = 1; i <= 10; i++) + test_array[i] = i + 2 + + printf ("length of test_array is %d, should be 10\n", length(test_array) + ret = test_array_size(test_array); + printf "test_array_size() returned %d, length is now %d\n", ret, length(test_array) +} +*/ + static awk_value_t * -do_func4(int nargs, awk_value_t *result) +test_array_size(int nargs, awk_value_t *result) { /* get element count and print it; should match length(array) from awk script */ /* clear array - length(array) should then go to zero in script */ } +/* +BEGIN { + n = split("one two three four five six", test_array2) + ret = test_array_elem(test_array2, "3") + printf "test_array_elem() returned %d, test_array2[3] = %g\n", ret, test_array2[3] +} +*/ static awk_value_t * -do_func5(int nargs, awk_value_t *result) +test_array_elem(int nargs, awk_value_t *result) { /* look up an array element and print the value */ /* change the element */ @@ -77,9 +134,66 @@ do_func5(int nargs, awk_value_t *result) /* change and deletion should be reflected in awk script */ } +/* +BEGIN { + printf "Initial value of LINT is %d\n", LINT + ret = print_do_lint(); + printf "print_do_lint() returned %d\n", ret + LINT = ! LINT + printf "Changed value of LINT is %d\n", LINT + ret = print_do_lint(); + printf "print_do_lint() returned %d\n", ret +} +*/ +static awk_value_t * +print_do_lint(int nargs, awk_value_t *result) +{ + printf("print_do_lint: lint = %d\n", do_lint); +} + +static void at_exit0(void *data, int exit_status) +{ + printf("at_exit0 called (should be third):"); + if (data) + printf(" data = %p,", data); + else + printf(" data = <null>,"); + printf(" exit_status = %d\n", exit_status); +} + + +static int data_for_1 = 0xDeadBeef; +static void at_exit1(void *data, int exit_status) +{ + printf("at_exit1 called (should be second):"); + if (data) { + printf(" data = %p", data); + if (data == & data_for_1) + printf(" (data is & data_for_1),"); + else + printf(" (data is NOT & data_for_1),"); + } else + printf(" data = <null>,"); + printf(" exit_status = %d\n", exit_status); +} + +static void at_exit2(void *data, int exit_status) +{ + printf("at_exit2 called (should be first):"); + if (data) + printf(" data = %p,", data); + else + printf(" data = <null>,"); + printf(" exit_status = %d\n", exit_status); +} static awk_ext_func_t func_table[] = { - { "test_func1", do_func1, 1 }, + { "dump_procinfo", dump_procinfo, 0 }, + { "var_test", var_test, 1 }, + { "test_errno", test_errno, 0 }, + { "test_array_size", test_array_size, 1 }, + { "test_array_elem", test_array_elem, 2 }, + { "print_do_lint", print_do_lint, 0 }, }; @@ -88,6 +202,8 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) { size_t i, j; int errors = 0; + awk_value_t value; + static const char message[] = "hello, world"; /* of course */ api = api_p; ext_id = id; @@ -103,7 +219,7 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) /* load functions */ for (i = 0, j = sizeof(func_table) / sizeof(func_table[0]); i < j; i++) { - if (! add_ext_func(& func_table[i], name_space)) { + if (! add_ext_func(& func_table[i], "")) { warning(ext_id, "testfuncs: could not add %s\n", func_table[i].name); errors++; @@ -111,8 +227,23 @@ int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) } /* add at_exit functions */ + awk_atexit(at_exit0, NULL); + awk_atexit(at_exit1, & data_for_1); + awk_atexit(at_exit2, NULL); + +/* +BEGIN { + printf("answer_num = %g\n", answer_num); + printf("message_string = %s\n", message_string); +} +*/ /* install some variables */ + if (! sym_update("answer_num", make_number(42, & value))) + printf("textext: sym_update(\"answer_num\") failed!\n"); + + if (! sym_update("message_string", dup_string(message, strlen(message), & value))) + printf("textext: sym_update(\"answer_num\") failed!\n"); return (errors == 0); } @@ -479,3 +479,11 @@ init_ext_api() api_impl.do_flags[4] = do_debug; api_impl.do_flags[5] = do_mpfr; } + +/* update_ext_api --- update the variables in the API that can change */ + +void +update_ext_api() +{ + api_impl.do_flags[0] = do_lint; +} @@ -179,6 +179,11 @@ typedef struct gawk_api { int major_version; int minor_version; + /* + * These can change on the fly as things happen within gawk. + * Currently only do_lint is prone to change, but we reserve + * the right to allow the others also. + */ int do_flags[DO_FLAGS_SIZE]; /* Use these as indices into do_flags[] array to check the values */ #define gawk_do_lint 0 |