bug-gawk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [bug-gawk] built-in variables in extensions


From: Aharon Robbins
Subject: Re: [bug-gawk] built-in variables in extensions
Date: Wed, 19 Dec 2012 15:01:46 +0200
User-agent: Heirloom mailx 12.5 6/20/10

Hi Assaf.

> Trying to write my own extension, I've encountered the following case:
> If my extension tries to access a built-in variable that isn't used in
> the code (e.g. "NR" or "NF") - the value is not properly returned.

As mentioned, this is a bug.  The following patch seems to fix it for
me.  Please try it out for you.

The following works for me, also:

        BEGIN {
                file = "testit.txt"
                for (i = 1; i <= 3; i++)
                        print("line", i) > file
                close(file)

                ARGV[1] = file
                ARGC = 2

                for (i = 1; i <= 3; i++)
                        getline

                printf "NR should be 3, is %d\n", SYMTAB["NR"]
                system("rm testit.txt")
        }

Thanks,

Arnold
---------------------------------------
diff --git a/extension/testext.c b/extension/testext.c
index 9367da7..8f6735c 100644
--- a/extension/testext.c
+++ b/extension/testext.c
@@ -686,6 +686,52 @@ out:
        return result;
 }
 
+/*
+BEGIN {
+       print "line 1" > "testexttmp.txt"
+       print "line 2" > "testexttmp.txt"
+       print "line 3" > "testexttmp.txt"
+       close("testexttmp.txt")
+       ARGV[1] = "testexttmp.txt"
+       ARGC = 2
+       getline
+       getline
+       getline         # now NR should be 3
+#      system("rm testexttmp.txt")
+       ret = test_indirect_vars()      # should get correct value of NR
+       printf("test_indirect_var() return %d\n", ret)
+       delete ARGV[1]
+}
+*/
+
+/* test_indirect_vars --- test that access to NR, NF, get correct vales */
+
+static awk_value_t *
+test_indirect_vars(int nargs, awk_value_t *result)
+{
+       awk_value_t value;
+       char *name = "NR";
+
+       assert(result != NULL);
+       make_number(0.0, result);
+
+       /* system("rm testexttmp.txt") */
+       (void) unlink("testexttmp.txt");
+
+       if (sym_lookup(name, AWK_NUMBER, & value))
+               printf("test_indirect_var: sym_lookup of %s passed\n", name);
+       else {
+               printf("test_indirect_var: sym_lookup of %s failed\n", name);
+               goto out;
+       }
+
+       printf("test_indirect_var: value of NR is %g\n", value.num_value);
+
+       make_number(1.0, result);
+out:
+       return result;
+}
+
 /* fill_in_array --- fill in a new array */
 
 static void
@@ -780,6 +826,7 @@ static awk_ext_func_t func_table[] = {
        { "print_do_lint", print_do_lint, 0 },
        { "test_scalar", test_scalar, 1 },
        { "test_scalar_reserved", test_scalar_reserved, 0 },
+       { "test_indirect_vars", test_indirect_vars, 0 },
 };
 
 /* init_testext --- additional initialization function */
diff --git a/gawkapi.c b/gawkapi.c
index cd09cdd..b89bdbc 100644
--- a/gawkapi.c
+++ b/gawkapi.c
@@ -505,6 +505,8 @@ api_sym_lookup(awk_ext_id_t id,
 {
        NODE *node;
 
+       update_global_values();         /* make sure stuff like NF, NR, are up 
to date */
+
        if (   name == NULL
            || *name == '\0'
            || result == NULL
@@ -532,6 +534,8 @@ api_sym_lookup_scalar(awk_ext_id_t id,
            || node->type != Node_var)
                return false;
 
+       update_global_values(); /* make sure stuff like NF, NR, are up to date 
*/
+
        return node_to_awk_value(node, result, wanted);
 }
 
diff --git a/interpret.h b/interpret.h
index 228a3f3..c652624 100644
--- a/interpret.h
+++ b/interpret.h
@@ -225,6 +225,10 @@ top:
                                }
                                r = t2;
                        } else {
+                               /* make sure stuff like NF, NR, are up to date 
*/
+                               if (t1 == symbol_table)
+                                       update_global_values();
+
                                r = *assoc_lookup(t1, t2);
                        }
                        DEREF(t2);
@@ -308,6 +312,7 @@ top:
                        else if (   t1 == symbol_table
                                 && (   (*lhs)->type == Node_var
                                     || (*lhs)->type == Node_var_new)) {
+                               update_global_values();         /* make sure 
stuff like NF, NR, are up to date */
                                (*lhs)->type = Node_var;        /* in case was 
Node_var_new */
                                lhs = & ((*lhs)->var_value);    /* extra level 
of indirection */
                        }
diff --git a/main.c b/main.c
index d054ec1..d55d1b6 100644
--- a/main.c
+++ b/main.c
@@ -1561,6 +1561,8 @@ save_argv(int argc, char **argv)
 /*
  * update_global_values --- make sure the symbol table has correct values.
  * Called from the grammar before dumping values.
+ *
+ * Also called when accessing through SYMTAB.
  */
 
 void



reply via email to

[Prev in Thread] Current Thread [Next in Thread]