diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2014-09-04 09:38:08 +0300 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2014-09-04 09:38:08 +0300 |
commit | 611353597e20081bd0c72617e24fa5ff4c63dac1 (patch) | |
tree | c6099826973ea7f036f5a0c7b7536f17b25576a1 | |
parent | cb92ab7aa657c57446cc9e0087f1364adaac8fee (diff) | |
download | egawk-611353597e20081bd0c72617e24fa5ff4c63dac1.tar.gz egawk-611353597e20081bd0c72617e24fa5ff4c63dac1.tar.bz2 egawk-611353597e20081bd0c72617e24fa5ff4c63dac1.zip |
Make indirect calls work on built-in and extension functions.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | awk.h | 2 | ||||
-rw-r--r-- | awkgram.c | 16 | ||||
-rw-r--r-- | awkgram.y | 16 | ||||
-rw-r--r-- | doc/ChangeLog | 6 | ||||
-rw-r--r-- | doc/gawk.1 | 6 | ||||
-rw-r--r-- | doc/gawk.info | 600 | ||||
-rw-r--r-- | doc/gawk.texi | 21 | ||||
-rw-r--r-- | doc/gawktexi.in | 21 | ||||
-rw-r--r-- | interpret.h | 42 | ||||
-rw-r--r-- | test/ChangeLog | 2 | ||||
-rw-r--r-- | test/functab4.ok | 3 |
13 files changed, 422 insertions, 325 deletions
@@ -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 @@ -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 @@ -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); @@ -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; +} @@ -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. @@ -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 |