aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--NEWS3
-rw-r--r--awk.h2
-rw-r--r--awkgram.c16
-rw-r--r--awkgram.y16
-rw-r--r--doc/ChangeLog6
-rw-r--r--doc/gawk.16
-rw-r--r--doc/gawk.info600
-rw-r--r--doc/gawk.texi21
-rw-r--r--doc/gawktexi.in21
-rw-r--r--interpret.h42
-rw-r--r--test/ChangeLog2
-rw-r--r--test/functab4.ok3
13 files changed, 422 insertions, 325 deletions
diff --git a/ChangeLog b/ChangeLog
index 81631787..12ea2778 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,15 @@
* profile.c (pprint): Case Op_K_for: Improve printing of
empty for loop header.
+ Unrelated: Make indirect function calls work for built-in and
+ extension functions.
+
+ * awkgram.y (lookup_builtin): New function.
+ * awk.h (builtin_func_t): New typedef.
+ (lookup_builtin): Declare it.
+ * interpret.h (r_interpret): For indirect calls, add code to
+ find and call builtin functions, and call extension functions.
+
2014-09-01 Arnold D. Robbins <arnold@skeeve.com>
* builtin.c (do_substr): Return "" instead of null string in case
diff --git a/NEWS b/NEWS
index 047c8e2a..6664a2a0 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,9 @@ Changes from 4.1.1 to 4.1.2
4. A number of bugs have been fixed in the MPFR code.
+5. Indirect function calls now work for both built-in and
+ extension functions.
+
XX. A number of bugs have been fixed. See the ChangeLog.
Changes from 4.1.0 to 4.1.1
diff --git a/awk.h b/awk.h
index a232e7a0..60e40d11 100644
--- a/awk.h
+++ b/awk.h
@@ -1377,6 +1377,8 @@ extern void register_deferred_variable(const char *name, NODE *(*load_func)(void
extern int files_are_same(char *path, SRCFILE *src);
extern void valinfo(NODE *n, Func_print print_func, FILE *fp);
extern void negate_num(NODE *n);
+typedef NODE *(*builtin_func_t)(int); /* function that implements a built-in */
+extern builtin_func_t lookup_builtin(const char *name);
/* builtin.c */
extern double double_to_int(double d);
extern NODE *do_exp(int nargs);
diff --git a/awkgram.c b/awkgram.c
index be852dfa..4bb2fc17 100644
--- a/awkgram.c
+++ b/awkgram.c
@@ -8044,3 +8044,19 @@ one_line_close(int fd)
}
+/* lookup_builtin --- find a builtin function or return NULL */
+
+builtin_func_t
+lookup_builtin(const char *name)
+{
+ int mid = check_special(name);
+
+ if (mid == -1 || tokentab[mid].class != LEX_BUILTIN)
+ return NULL;
+#ifdef HAVE_MPFR
+ if (do_mpfr)
+ return tokentab[mid].ptr2;
+#endif
+
+ return tokentab[mid].ptr;
+}
diff --git a/awkgram.y b/awkgram.y
index 53a218a2..a0dfc550 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -5705,3 +5705,19 @@ one_line_close(int fd)
}
+/* lookup_builtin --- find a builtin function or return NULL */
+
+builtin_func_t
+lookup_builtin(const char *name)
+{
+ int mid = check_special(name);
+
+ if (mid == -1 || tokentab[mid].class != LEX_BUILTIN)
+ return NULL;
+#ifdef HAVE_MPFR
+ if (do_mpfr)
+ return tokentab[mid].ptr2;
+#endif
+
+ return tokentab[mid].ptr;
+}
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 2ea9bbc7..457ac8ed 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,9 @@
+2014-09-04 Arnold D. Robbins <arnold@skeeve.com>
+
+ * gawktexi.in: Document that indirect calls now work on built-in
+ and extension functions.
+ * gawk.1: Same.
+
2014-09-03 Arnold D. Robbins <arnold@skeeve.com>
* gawktexi.in: Further fixes from reviews and bug reports.
diff --git a/doc/gawk.1 b/doc/gawk.1
index c7646557..4a70c2ed 100644
--- a/doc/gawk.1
+++ b/doc/gawk.1
@@ -13,7 +13,7 @@
. if \w'\(rq' .ds rq "\(rq
. \}
.\}
-.TH GAWK 1 "Apr 17 2014" "Free Software Foundation" "Utility Commands"
+.TH GAWK 1 "Aug 03 2014" "Free Software Foundation" "Utility Commands"
.SH NAME
gawk \- pattern scanning and processing language
.SH SYNOPSIS
@@ -3264,7 +3264,7 @@ sign, like so:
.RS
.ft B
.nf
-function myfunc()
+function myfunc()
{
print "myfunc called"
\&.\|.\|.
@@ -3278,6 +3278,8 @@ function myfunc()
.fi
.ft R
.RE
+As of version 4.1.2, this works with user-defined functions,
+built-in functions, and extension functions.
.PP
If
.B \-\^\-lint
diff --git a/doc/gawk.info b/doc/gawk.info
index 1e6e93f5..f008ecfa 100644
--- a/doc/gawk.info
+++ b/doc/gawk.info
@@ -13853,7 +13853,7 @@ File: gawk.info, Node: Indirect Calls, Next: Functions Summary, Prev: User-de
9.3 Indirect Function Calls
===========================
-This section describes a `gawk'-specific extension.
+This section describes an advanced, `gawk'-specific extension.
Often, you may wish to defer the choice of function to call until
runtime. For example, you may have different kinds of records, each of
@@ -13892,7 +13892,7 @@ your test scores:
This style of programming works, but can be awkward. With "indirect"
function calls, you tell `gawk' to use the _value_ of a variable as the
-name of the function to call.
+_name_ of the function to call.
The syntax is similar to that of a regular function call: an
identifier immediately followed by a left parenthesis, any arguments,
@@ -13934,7 +13934,6 @@ using indirect function calls.
Otherwise they perform the expected computations and are not unusual.
# For each record, print the class name and the requested statistics
-
{
class_name = $1
gsub(/_/, " ", class_name) # Replace _ with spaces
@@ -14121,11 +14120,11 @@ names of the two comparison functions:
Remember that you must supply a leading `@' in front of an indirect
function call.
- Unfortunately, indirect function calls cannot be used with the
-built-in functions. However, you can generally write "wrapper"
-functions which call the built-in ones, and those can be called
-indirectly. (Other than, perhaps, the mathematical functions, there is
-not a lot of reason to try to call the built-in functions indirectly.)
+ Starting with version 4.1.2 of `gawk', indirect function calls may
+also be used with built-in functions and with extension functions
+(*note Dynamic Extensions::). The only thing you cannot do is pass a
+regular expression constant to a built-in function through an indirect
+function call.(1)
`gawk' does its best to make indirect function calls efficient. For
example, in the following case:
@@ -14133,7 +14132,12 @@ example, in the following case:
for (i = 1; i <= n; i++)
@the_func()
-`gawk' will look up the actual function to call only once.
+`gawk' looks up the actual function to call only once.
+
+ ---------- Footnotes ----------
+
+ (1) This may change in a future version; recheck the documentation
+that comes with your version of `gawk' to see if it has.

File: gawk.info, Node: Functions Summary, Prev: Indirect Calls, Up: Functions
@@ -14170,7 +14174,9 @@ File: gawk.info, Node: Functions Summary, Prev: Indirect Calls, Up: Functions
* User-defined functions may call other user-defined (and built-in)
functions and may call themselves recursively. Function parameters
- "hide" any global variables of the same names.
+ "hide" any global variables of the same names. You cannot use the
+ name of a reserved variable (such as `ARGC') as the name of a
+ parameter in user-defined functions.
* Scalar values are passed to user-defined functions by value. Array
parameters are passed by reference; any changes made by the
@@ -14186,10 +14192,9 @@ File: gawk.info, Node: Functions Summary, Prev: Indirect Calls, Up: Functions
either scalar or array.
* `gawk' provides indirect function calls using a special syntax.
- By setting a variable to the name of a user-defined function, you
- can determine at runtime what function will be called at that
- point in the program. This is equivalent to function pointers in C
- and C++.
+ By setting a variable to the name of a function, you can determine
+ at runtime what function will be called at that point in the
+ program. This is equivalent to function pointers in C and C++.

@@ -34292,288 +34297,289 @@ Node: Pass By Value/Reference571978
Node: Return Statement575488
Node: Dynamic Typing578472
Node: Indirect Calls579401
-Node: Functions Summary589114
-Node: Library Functions591653
-Ref: Library Functions-Footnote-1595271
-Ref: Library Functions-Footnote-2595414
-Node: Library Names595585
-Ref: Library Names-Footnote-1599058
-Ref: Library Names-Footnote-2599278
-Node: General Functions599364
-Node: Strtonum Function600392
-Node: Assert Function603266
-Node: Round Function606592
-Node: Cliff Random Function608133
-Node: Ordinal Functions609149
-Ref: Ordinal Functions-Footnote-1612214
-Ref: Ordinal Functions-Footnote-2612466
-Node: Join Function612677
-Ref: Join Function-Footnote-1614448
-Node: Getlocaltime Function614648
-Node: Readfile Function618384
-Node: Data File Management620223
-Node: Filetrans Function620855
-Node: Rewind Function624924
-Node: File Checking626482
-Ref: File Checking-Footnote-1627614
-Node: Empty Files627815
-Node: Ignoring Assigns629794
-Node: Getopt Function631348
-Ref: Getopt Function-Footnote-1642612
-Node: Passwd Functions642815
-Ref: Passwd Functions-Footnote-1651794
-Node: Group Functions651882
-Ref: Group Functions-Footnote-1659813
-Node: Walking Arrays660026
-Node: Library Functions Summary661629
-Node: Library Exercises663017
-Node: Sample Programs664297
-Node: Running Examples665067
-Node: Clones665795
-Node: Cut Program667019
-Node: Egrep Program676877
-Ref: Egrep Program-Footnote-1684464
-Node: Id Program684574
-Node: Split Program688228
-Ref: Split Program-Footnote-1691766
-Node: Tee Program691894
-Node: Uniq Program694681
-Node: Wc Program702104
-Ref: Wc Program-Footnote-1706369
-Node: Miscellaneous Programs706461
-Node: Dupword Program707674
-Node: Alarm Program709705
-Node: Translate Program714509
-Ref: Translate Program-Footnote-1718900
-Ref: Translate Program-Footnote-2719170
-Node: Labels Program719309
-Ref: Labels Program-Footnote-1722670
-Node: Word Sorting722754
-Node: History Sorting726797
-Node: Extract Program728633
-Node: Simple Sed736169
-Node: Igawk Program739231
-Ref: Igawk Program-Footnote-1753535
-Ref: Igawk Program-Footnote-2753736
-Node: Anagram Program753874
-Node: Signature Program756942
-Node: Programs Summary758189
-Node: Programs Exercises759404
-Ref: Programs Exercises-Footnote-1763791
-Node: Advanced Features763882
-Node: Nondecimal Data765830
-Node: Array Sorting767407
-Node: Controlling Array Traversal768104
-Node: Array Sorting Functions776384
-Ref: Array Sorting Functions-Footnote-1780291
-Node: Two-way I/O780485
-Ref: Two-way I/O-Footnote-1785429
-Ref: Two-way I/O-Footnote-2785608
-Node: TCP/IP Networking785690
-Node: Profiling788535
-Node: Advanced Features Summary796077
-Node: Internationalization797941
-Node: I18N and L10N799421
-Node: Explaining gettext800107
-Ref: Explaining gettext-Footnote-1805133
-Ref: Explaining gettext-Footnote-2805317
-Node: Programmer i18n805482
-Ref: Programmer i18n-Footnote-1810276
-Node: Translator i18n810325
-Node: String Extraction811119
-Ref: String Extraction-Footnote-1812252
-Node: Printf Ordering812338
-Ref: Printf Ordering-Footnote-1815120
-Node: I18N Portability815184
-Ref: I18N Portability-Footnote-1817633
-Node: I18N Example817696
-Ref: I18N Example-Footnote-1820402
-Node: Gawk I18N820474
-Node: I18N Summary821112
-Node: Debugger822451
-Node: Debugging823473
-Node: Debugging Concepts823914
-Node: Debugging Terms825770
-Node: Awk Debugging828367
-Node: Sample Debugging Session829259
-Node: Debugger Invocation829779
-Node: Finding The Bug831115
-Node: List of Debugger Commands837594
-Node: Breakpoint Control838926
-Node: Debugger Execution Control842590
-Node: Viewing And Changing Data845950
-Node: Execution Stack849308
-Node: Debugger Info850821
-Node: Miscellaneous Debugger Commands854815
-Node: Readline Support859999
-Node: Limitations860891
-Node: Debugging Summary863164
-Node: Arbitrary Precision Arithmetic864332
-Node: Computer Arithmetic865819
-Ref: Computer Arithmetic-Footnote-1870206
-Node: Math Definitions870263
-Ref: table-ieee-formats873552
-Ref: Math Definitions-Footnote-1874092
-Node: MPFR features874195
-Node: FP Math Caution875812
-Ref: FP Math Caution-Footnote-1876862
-Node: Inexactness of computations877231
-Node: Inexact representation878179
-Node: Comparing FP Values879534
-Node: Errors accumulate880498
-Node: Getting Accuracy881931
-Node: Try To Round884590
-Node: Setting precision885489
-Ref: table-predefined-precision-strings886171
-Node: Setting the rounding mode887964
-Ref: table-gawk-rounding-modes888328
-Ref: Setting the rounding mode-Footnote-1891782
-Node: Arbitrary Precision Integers891961
-Ref: Arbitrary Precision Integers-Footnote-1894942
-Node: POSIX Floating Point Problems895091
-Ref: POSIX Floating Point Problems-Footnote-1898967
-Node: Floating point summary899005
-Node: Dynamic Extensions901209
-Node: Extension Intro902761
-Node: Plugin License904026
-Node: Extension Mechanism Outline904711
-Ref: figure-load-extension905135
-Ref: figure-load-new-function906620
-Ref: figure-call-new-function907622
-Node: Extension API Description909606
-Node: Extension API Functions Introduction911056
-Node: General Data Types915923
-Ref: General Data Types-Footnote-1921616
-Node: Requesting Values921915
-Ref: table-value-types-returned922652
-Node: Memory Allocation Functions923610
-Ref: Memory Allocation Functions-Footnote-1926357
-Node: Constructor Functions926453
-Node: Registration Functions928211
-Node: Extension Functions928896
-Node: Exit Callback Functions931198
-Node: Extension Version String932446
-Node: Input Parsers933096
-Node: Output Wrappers942910
-Node: Two-way processors947426
-Node: Printing Messages949630
-Ref: Printing Messages-Footnote-1950707
-Node: Updating `ERRNO'950859
-Node: Accessing Parameters951598
-Node: Symbol Table Access952828
-Node: Symbol table by name953342
-Node: Symbol table by cookie955318
-Ref: Symbol table by cookie-Footnote-1959451
-Node: Cached values959514
-Ref: Cached values-Footnote-1963018
-Node: Array Manipulation963109
-Ref: Array Manipulation-Footnote-1964207
-Node: Array Data Types964246
-Ref: Array Data Types-Footnote-1966949
-Node: Array Functions967041
-Node: Flattening Arrays970915
-Node: Creating Arrays977767
-Node: Extension API Variables982498
-Node: Extension Versioning983134
-Node: Extension API Informational Variables985035
-Node: Extension API Boilerplate986121
-Node: Finding Extensions989925
-Node: Extension Example990485
-Node: Internal File Description991215
-Node: Internal File Ops995306
-Ref: Internal File Ops-Footnote-11006738
-Node: Using Internal File Ops1006878
-Ref: Using Internal File Ops-Footnote-11009225
-Node: Extension Samples1009493
-Node: Extension Sample File Functions1011017
-Node: Extension Sample Fnmatch1018585
-Node: Extension Sample Fork1020067
-Node: Extension Sample Inplace1021280
-Node: Extension Sample Ord1022955
-Node: Extension Sample Readdir1023791
-Ref: table-readdir-file-types1024647
-Node: Extension Sample Revout1025446
-Node: Extension Sample Rev2way1026037
-Node: Extension Sample Read write array1026778
-Node: Extension Sample Readfile1028657
-Node: Extension Sample API Tests1029757
-Node: Extension Sample Time1030282
-Node: gawkextlib1031597
-Node: Extension summary1034410
-Node: Extension Exercises1038103
-Node: Language History1038825
-Node: V7/SVR3.11040468
-Node: SVR41042788
-Node: POSIX1044230
-Node: BTL1045616
-Node: POSIX/GNU1046350
-Node: Feature History1052066
-Node: Common Extensions1065157
-Node: Ranges and Locales1066469
-Ref: Ranges and Locales-Footnote-11071086
-Ref: Ranges and Locales-Footnote-21071113
-Ref: Ranges and Locales-Footnote-31071347
-Node: Contributors1071568
-Node: History summary1076993
-Node: Installation1078362
-Node: Gawk Distribution1079313
-Node: Getting1079797
-Node: Extracting1080621
-Node: Distribution contents1082263
-Node: Unix Installation1087980
-Node: Quick Installation1088597
-Node: Additional Configuration Options1091039
-Node: Configuration Philosophy1092777
-Node: Non-Unix Installation1095128
-Node: PC Installation1095586
-Node: PC Binary Installation1096897
-Node: PC Compiling1098745
-Ref: PC Compiling-Footnote-11101744
-Node: PC Testing1101849
-Node: PC Using1103025
-Node: Cygwin1107177
-Node: MSYS1107986
-Node: VMS Installation1108500
-Node: VMS Compilation1109296
-Ref: VMS Compilation-Footnote-11110518
-Node: VMS Dynamic Extensions1110576
-Node: VMS Installation Details1111949
-Node: VMS Running1114201
-Node: VMS GNV1117035
-Node: VMS Old Gawk1117758
-Node: Bugs1118228
-Node: Other Versions1122232
-Node: Installation summary1128459
-Node: Notes1129515
-Node: Compatibility Mode1130380
-Node: Additions1131162
-Node: Accessing The Source1132087
-Node: Adding Code1133523
-Node: New Ports1139701
-Node: Derived Files1144182
-Ref: Derived Files-Footnote-11149263
-Ref: Derived Files-Footnote-21149297
-Ref: Derived Files-Footnote-31149893
-Node: Future Extensions1150007
-Node: Implementation Limitations1150613
-Node: Extension Design1151861
-Node: Old Extension Problems1153015
-Ref: Old Extension Problems-Footnote-11154532
-Node: Extension New Mechanism Goals1154589
-Ref: Extension New Mechanism Goals-Footnote-11157949
-Node: Extension Other Design Decisions1158138
-Node: Extension Future Growth1160244
-Node: Old Extension Mechanism1161080
-Node: Notes summary1162842
-Node: Basic Concepts1164028
-Node: Basic High Level1164709
-Ref: figure-general-flow1164981
-Ref: figure-process-flow1165580
-Ref: Basic High Level-Footnote-11168809
-Node: Basic Data Typing1168994
-Node: Glossary1172322
-Node: Copying1197474
-Node: GNU Free Documentation License1235030
-Node: Index1260166
+Ref: Indirect Calls-Footnote-1589117
+Node: Functions Summary589245
+Node: Library Functions591895
+Ref: Library Functions-Footnote-1595513
+Ref: Library Functions-Footnote-2595656
+Node: Library Names595827
+Ref: Library Names-Footnote-1599300
+Ref: Library Names-Footnote-2599520
+Node: General Functions599606
+Node: Strtonum Function600634
+Node: Assert Function603508
+Node: Round Function606834
+Node: Cliff Random Function608375
+Node: Ordinal Functions609391
+Ref: Ordinal Functions-Footnote-1612456
+Ref: Ordinal Functions-Footnote-2612708
+Node: Join Function612919
+Ref: Join Function-Footnote-1614690
+Node: Getlocaltime Function614890
+Node: Readfile Function618626
+Node: Data File Management620465
+Node: Filetrans Function621097
+Node: Rewind Function625166
+Node: File Checking626724
+Ref: File Checking-Footnote-1627856
+Node: Empty Files628057
+Node: Ignoring Assigns630036
+Node: Getopt Function631590
+Ref: Getopt Function-Footnote-1642854
+Node: Passwd Functions643057
+Ref: Passwd Functions-Footnote-1652036
+Node: Group Functions652124
+Ref: Group Functions-Footnote-1660055
+Node: Walking Arrays660268
+Node: Library Functions Summary661871
+Node: Library Exercises663259
+Node: Sample Programs664539
+Node: Running Examples665309
+Node: Clones666037
+Node: Cut Program667261
+Node: Egrep Program677119
+Ref: Egrep Program-Footnote-1684706
+Node: Id Program684816
+Node: Split Program688470
+Ref: Split Program-Footnote-1692008
+Node: Tee Program692136
+Node: Uniq Program694923
+Node: Wc Program702346
+Ref: Wc Program-Footnote-1706611
+Node: Miscellaneous Programs706703
+Node: Dupword Program707916
+Node: Alarm Program709947
+Node: Translate Program714751
+Ref: Translate Program-Footnote-1719142
+Ref: Translate Program-Footnote-2719412
+Node: Labels Program719551
+Ref: Labels Program-Footnote-1722912
+Node: Word Sorting722996
+Node: History Sorting727039
+Node: Extract Program728875
+Node: Simple Sed736411
+Node: Igawk Program739473
+Ref: Igawk Program-Footnote-1753777
+Ref: Igawk Program-Footnote-2753978
+Node: Anagram Program754116
+Node: Signature Program757184
+Node: Programs Summary758431
+Node: Programs Exercises759646
+Ref: Programs Exercises-Footnote-1764033
+Node: Advanced Features764124
+Node: Nondecimal Data766072
+Node: Array Sorting767649
+Node: Controlling Array Traversal768346
+Node: Array Sorting Functions776626
+Ref: Array Sorting Functions-Footnote-1780533
+Node: Two-way I/O780727
+Ref: Two-way I/O-Footnote-1785671
+Ref: Two-way I/O-Footnote-2785850
+Node: TCP/IP Networking785932
+Node: Profiling788777
+Node: Advanced Features Summary796319
+Node: Internationalization798183
+Node: I18N and L10N799663
+Node: Explaining gettext800349
+Ref: Explaining gettext-Footnote-1805375
+Ref: Explaining gettext-Footnote-2805559
+Node: Programmer i18n805724
+Ref: Programmer i18n-Footnote-1810518
+Node: Translator i18n810567
+Node: String Extraction811361
+Ref: String Extraction-Footnote-1812494
+Node: Printf Ordering812580
+Ref: Printf Ordering-Footnote-1815362
+Node: I18N Portability815426
+Ref: I18N Portability-Footnote-1817875
+Node: I18N Example817938
+Ref: I18N Example-Footnote-1820644
+Node: Gawk I18N820716
+Node: I18N Summary821354
+Node: Debugger822693
+Node: Debugging823715
+Node: Debugging Concepts824156
+Node: Debugging Terms826012
+Node: Awk Debugging828609
+Node: Sample Debugging Session829501
+Node: Debugger Invocation830021
+Node: Finding The Bug831357
+Node: List of Debugger Commands837836
+Node: Breakpoint Control839168
+Node: Debugger Execution Control842832
+Node: Viewing And Changing Data846192
+Node: Execution Stack849550
+Node: Debugger Info851063
+Node: Miscellaneous Debugger Commands855057
+Node: Readline Support860241
+Node: Limitations861133
+Node: Debugging Summary863406
+Node: Arbitrary Precision Arithmetic864574
+Node: Computer Arithmetic866061
+Ref: Computer Arithmetic-Footnote-1870448
+Node: Math Definitions870505
+Ref: table-ieee-formats873794
+Ref: Math Definitions-Footnote-1874334
+Node: MPFR features874437
+Node: FP Math Caution876054
+Ref: FP Math Caution-Footnote-1877104
+Node: Inexactness of computations877473
+Node: Inexact representation878421
+Node: Comparing FP Values879776
+Node: Errors accumulate880740
+Node: Getting Accuracy882173
+Node: Try To Round884832
+Node: Setting precision885731
+Ref: table-predefined-precision-strings886413
+Node: Setting the rounding mode888206
+Ref: table-gawk-rounding-modes888570
+Ref: Setting the rounding mode-Footnote-1892024
+Node: Arbitrary Precision Integers892203
+Ref: Arbitrary Precision Integers-Footnote-1895184
+Node: POSIX Floating Point Problems895333
+Ref: POSIX Floating Point Problems-Footnote-1899209
+Node: Floating point summary899247
+Node: Dynamic Extensions901451
+Node: Extension Intro903003
+Node: Plugin License904268
+Node: Extension Mechanism Outline904953
+Ref: figure-load-extension905377
+Ref: figure-load-new-function906862
+Ref: figure-call-new-function907864
+Node: Extension API Description909848
+Node: Extension API Functions Introduction911298
+Node: General Data Types916165
+Ref: General Data Types-Footnote-1921858
+Node: Requesting Values922157
+Ref: table-value-types-returned922894
+Node: Memory Allocation Functions923852
+Ref: Memory Allocation Functions-Footnote-1926599
+Node: Constructor Functions926695
+Node: Registration Functions928453
+Node: Extension Functions929138
+Node: Exit Callback Functions931440
+Node: Extension Version String932688
+Node: Input Parsers933338
+Node: Output Wrappers943152
+Node: Two-way processors947668
+Node: Printing Messages949872
+Ref: Printing Messages-Footnote-1950949
+Node: Updating `ERRNO'951101
+Node: Accessing Parameters951840
+Node: Symbol Table Access953070
+Node: Symbol table by name953584
+Node: Symbol table by cookie955560
+Ref: Symbol table by cookie-Footnote-1959693
+Node: Cached values959756
+Ref: Cached values-Footnote-1963260
+Node: Array Manipulation963351
+Ref: Array Manipulation-Footnote-1964449
+Node: Array Data Types964488
+Ref: Array Data Types-Footnote-1967191
+Node: Array Functions967283
+Node: Flattening Arrays971157
+Node: Creating Arrays978009
+Node: Extension API Variables982740
+Node: Extension Versioning983376
+Node: Extension API Informational Variables985277
+Node: Extension API Boilerplate986363
+Node: Finding Extensions990167
+Node: Extension Example990727
+Node: Internal File Description991457
+Node: Internal File Ops995548
+Ref: Internal File Ops-Footnote-11006980
+Node: Using Internal File Ops1007120
+Ref: Using Internal File Ops-Footnote-11009467
+Node: Extension Samples1009735
+Node: Extension Sample File Functions1011259
+Node: Extension Sample Fnmatch1018827
+Node: Extension Sample Fork1020309
+Node: Extension Sample Inplace1021522
+Node: Extension Sample Ord1023197
+Node: Extension Sample Readdir1024033
+Ref: table-readdir-file-types1024889
+Node: Extension Sample Revout1025688
+Node: Extension Sample Rev2way1026279
+Node: Extension Sample Read write array1027020
+Node: Extension Sample Readfile1028899
+Node: Extension Sample API Tests1029999
+Node: Extension Sample Time1030524
+Node: gawkextlib1031839
+Node: Extension summary1034652
+Node: Extension Exercises1038345
+Node: Language History1039067
+Node: V7/SVR3.11040710
+Node: SVR41043030
+Node: POSIX1044472
+Node: BTL1045858
+Node: POSIX/GNU1046592
+Node: Feature History1052308
+Node: Common Extensions1065399
+Node: Ranges and Locales1066711
+Ref: Ranges and Locales-Footnote-11071328
+Ref: Ranges and Locales-Footnote-21071355
+Ref: Ranges and Locales-Footnote-31071589
+Node: Contributors1071810
+Node: History summary1077235
+Node: Installation1078604
+Node: Gawk Distribution1079555
+Node: Getting1080039
+Node: Extracting1080863
+Node: Distribution contents1082505
+Node: Unix Installation1088222
+Node: Quick Installation1088839
+Node: Additional Configuration Options1091281
+Node: Configuration Philosophy1093019
+Node: Non-Unix Installation1095370
+Node: PC Installation1095828
+Node: PC Binary Installation1097139
+Node: PC Compiling1098987
+Ref: PC Compiling-Footnote-11101986
+Node: PC Testing1102091
+Node: PC Using1103267
+Node: Cygwin1107419
+Node: MSYS1108228
+Node: VMS Installation1108742
+Node: VMS Compilation1109538
+Ref: VMS Compilation-Footnote-11110760
+Node: VMS Dynamic Extensions1110818
+Node: VMS Installation Details1112191
+Node: VMS Running1114443
+Node: VMS GNV1117277
+Node: VMS Old Gawk1118000
+Node: Bugs1118470
+Node: Other Versions1122474
+Node: Installation summary1128701
+Node: Notes1129757
+Node: Compatibility Mode1130622
+Node: Additions1131404
+Node: Accessing The Source1132329
+Node: Adding Code1133765
+Node: New Ports1139943
+Node: Derived Files1144424
+Ref: Derived Files-Footnote-11149505
+Ref: Derived Files-Footnote-21149539
+Ref: Derived Files-Footnote-31150135
+Node: Future Extensions1150249
+Node: Implementation Limitations1150855
+Node: Extension Design1152103
+Node: Old Extension Problems1153257
+Ref: Old Extension Problems-Footnote-11154774
+Node: Extension New Mechanism Goals1154831
+Ref: Extension New Mechanism Goals-Footnote-11158191
+Node: Extension Other Design Decisions1158380
+Node: Extension Future Growth1160486
+Node: Old Extension Mechanism1161322
+Node: Notes summary1163084
+Node: Basic Concepts1164270
+Node: Basic High Level1164951
+Ref: figure-general-flow1165223
+Ref: figure-process-flow1165822
+Ref: Basic High Level-Footnote-11169051
+Node: Basic Data Typing1169236
+Node: Glossary1172564
+Node: Copying1197716
+Node: GNU Free Documentation License1235272
+Node: Index1260408

End Tag Table
diff --git a/doc/gawk.texi b/doc/gawk.texi
index 0257a828..6e917e44 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -19813,7 +19813,7 @@ being aware of them.
@cindex pointers to functions
@cindex differences in @command{awk} and @command{gawk}, indirect function calls
-This section describes a @command{gawk}-specific extension.
+This section describes an advanced, @command{gawk}-specific extension.
Often, you may wish to defer the choice of function to call until runtime.
For example, you may have different kinds of records, each of which
@@ -19859,7 +19859,7 @@ To process the data, you might write initially:
@noindent
This style of programming works, but can be awkward. With @dfn{indirect}
function calls, you tell @command{gawk} to use the @emph{value} of a
-variable as the name of the function to call.
+variable as the @emph{name} of the function to call.
@cindex @code{@@}-notation for indirect function calls
@cindex indirect function calls, @code{@@}-notation
@@ -19921,7 +19921,6 @@ Otherwise they perform the expected computations and are not unusual.
@example
@c file eg/prog/indirectcall.awk
# For each record, print the class name and the requested statistics
-
@{
class_name = $1
gsub(/_/, " ", class_name) # Replace _ with spaces
@@ -20150,10 +20149,12 @@ $ @kbd{gawk -f quicksort.awk -f indirectcall.awk class_data2}
Remember that you must supply a leading @samp{@@} in front of an indirect function call.
-Unfortunately, indirect function calls cannot be used with the built-in functions. However,
-you can generally write ``wrapper'' functions which call the built-in ones, and those can
-be called indirectly. (Other than, perhaps, the mathematical functions, there is not a lot
-of reason to try to call the built-in functions indirectly.)
+Starting with @value{PVERSION} 4.1.2 of @command{gawk}, indirect function
+calls may also be used with built-in functions and with extension functions
+(@pxref{Dynamic Extensions}). The only thing you cannot do is pass a regular
+expression constant to a built-in function through an indirect function
+call.@footnote{This may change in a future version; recheck the documentation that
+comes with your version of @command{gawk} to see if it has.}
@command{gawk} does its best to make indirect function calls efficient.
For example, in the following case:
@@ -20164,7 +20165,7 @@ for (i = 1; i <= n; i++)
@end example
@noindent
-@code{gawk} will look up the actual function to call only once.
+@code{gawk} looks up the actual function to call only once.
@node Functions Summary
@section Summary
@@ -20204,6 +20205,8 @@ from the real parameters by extra whitespace.
User-defined functions may call other user-defined (and built-in)
functions and may call themselves recursively. Function parameters
``hide'' any global variables of the same names.
+You cannot use the name of a reserved variable (such as @code{ARGC})
+as the name of a parameter in user-defined functions.
@item
Scalar values are passed to user-defined functions by value. Array
@@ -20222,7 +20225,7 @@ either scalar or array.
@item
@command{gawk} provides indirect function calls using a special syntax.
-By setting a variable to the name of a user-defined function, you can
+By setting a variable to the name of a function, you can
determine at runtime what function will be called at that point in the
program. This is equivalent to function pointers in C and C++.
diff --git a/doc/gawktexi.in b/doc/gawktexi.in
index 002f5ec5..a6ece064 100644
--- a/doc/gawktexi.in
+++ b/doc/gawktexi.in
@@ -18940,7 +18940,7 @@ being aware of them.
@cindex pointers to functions
@cindex differences in @command{awk} and @command{gawk}, indirect function calls
-This section describes a @command{gawk}-specific extension.
+This section describes an advanced, @command{gawk}-specific extension.
Often, you may wish to defer the choice of function to call until runtime.
For example, you may have different kinds of records, each of which
@@ -18986,7 +18986,7 @@ To process the data, you might write initially:
@noindent
This style of programming works, but can be awkward. With @dfn{indirect}
function calls, you tell @command{gawk} to use the @emph{value} of a
-variable as the name of the function to call.
+variable as the @emph{name} of the function to call.
@cindex @code{@@}-notation for indirect function calls
@cindex indirect function calls, @code{@@}-notation
@@ -19048,7 +19048,6 @@ Otherwise they perform the expected computations and are not unusual.
@example
@c file eg/prog/indirectcall.awk
# For each record, print the class name and the requested statistics
-
@{
class_name = $1
gsub(/_/, " ", class_name) # Replace _ with spaces
@@ -19277,10 +19276,12 @@ $ @kbd{gawk -f quicksort.awk -f indirectcall.awk class_data2}
Remember that you must supply a leading @samp{@@} in front of an indirect function call.
-Unfortunately, indirect function calls cannot be used with the built-in functions. However,
-you can generally write ``wrapper'' functions which call the built-in ones, and those can
-be called indirectly. (Other than, perhaps, the mathematical functions, there is not a lot
-of reason to try to call the built-in functions indirectly.)
+Starting with @value{PVERSION} 4.1.2 of @command{gawk}, indirect function
+calls may also be used with built-in functions and with extension functions
+(@pxref{Dynamic Extensions}). The only thing you cannot do is pass a regular
+expression constant to a built-in function through an indirect function
+call.@footnote{This may change in a future version; recheck the documentation that
+comes with your version of @command{gawk} to see if it has.}
@command{gawk} does its best to make indirect function calls efficient.
For example, in the following case:
@@ -19291,7 +19292,7 @@ for (i = 1; i <= n; i++)
@end example
@noindent
-@code{gawk} will look up the actual function to call only once.
+@code{gawk} looks up the actual function to call only once.
@node Functions Summary
@section Summary
@@ -19331,6 +19332,8 @@ from the real parameters by extra whitespace.
User-defined functions may call other user-defined (and built-in)
functions and may call themselves recursively. Function parameters
``hide'' any global variables of the same names.
+You cannot use the name of a reserved variable (such as @code{ARGC})
+as the name of a parameter in user-defined functions.
@item
Scalar values are passed to user-defined functions by value. Array
@@ -19349,7 +19352,7 @@ either scalar or array.
@item
@command{gawk} provides indirect function calls using a special syntax.
-By setting a variable to the name of a user-defined function, you can
+By setting a variable to the name of a function, you can
determine at runtime what function will be called at that point in the
program. This is equivalent to function pointers in C and C++.
diff --git a/interpret.h b/interpret.h
index be017355..fee8136e 100644
--- a/interpret.h
+++ b/interpret.h
@@ -1039,13 +1039,42 @@ match_re:
}
if (f == NULL) {
- /* FIXME: See if function is a built-in and try to call it */
- fatal(_("`%s' is not a user-defined function, so it cannot be called indirectly"),
+ int arg_count = (pc + 1)->expr_count;
+ builtin_func_t the_func = lookup_builtin(t1->stptr);
+
+ if (the_func == NULL)
+ fatal(_("`%s' is not a user-defined function, so it cannot be called indirectly"),
t1->stptr);
- } else if(f->type != Node_func) {
- if (f->type == Node_ext_func || f->type == Node_old_ext_func)
- fatal(_("cannot (yet) call extension functions indirectly"));
- else
+
+ /* call it */
+ r = the_func(arg_count);
+ PUSH(r);
+ break;
+ } else if (f->type != Node_func) {
+ if ( f->type == Node_ext_func
+ || f->type == Node_old_ext_func) {
+ /* code copied from below, keep in sync */
+ INSTRUCTION *bc;
+ char *fname = pc->func_name;
+ int arg_count = (pc + 1)->expr_count;
+ static INSTRUCTION npc[2];
+
+ npc[0] = *pc;
+
+ bc = f->code_ptr;
+ assert(bc->opcode == Op_symbol);
+ if (f->type == Node_ext_func)
+ npc[0].opcode = Op_ext_builtin; /* self modifying code */
+ else
+ npc[0].opcode = Op_old_ext_builtin; /* self modifying code */
+ npc[0].extfunc = bc->extfunc;
+ npc[0].expr_count = arg_count; /* actual argument count */
+ npc[1] = pc[1];
+ npc[1].func_name = fname; /* name of the builtin */
+ npc[1].expr_count = bc->expr_count; /* defined max # of arguments */
+ ni = npc;
+ JUMPTO(ni);
+ } else
fatal(_("function called indirectly through `%s' does not exist"),
pc->func_name);
}
@@ -1069,6 +1098,7 @@ match_re:
}
if (f->type == Node_ext_func || f->type == Node_old_ext_func) {
+ /* keep in sync with indirect call code */
INSTRUCTION *bc;
char *fname = pc->func_name;
int arg_count = (pc + 1)->expr_count;
diff --git a/test/ChangeLog b/test/ChangeLog
index c6a102b4..3d20eaac 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,6 +1,8 @@
2014-09-04 Arnold D. Robbins <arnold@skeeve.com>
* profile2.ok: Update after code improvement in profiler.
+ * functab4.ok: Update after making indirect calls of
+ extension functions work. :-)
2014-08-15 Arnold D. Robbins <arnold@skeeve.com>
diff --git a/test/functab4.ok b/test/functab4.ok
index 70a520b7..8eaab508 100644
--- a/test/functab4.ok
+++ b/test/functab4.ok
@@ -1,3 +1,2 @@
x = chdir
-gawk: functab4.awk:11: fatal: cannot (yet) call extension functions indirectly
-EXIT CODE: 2
+we are now in --> /tmp