2
2
* gawkapi.h -- Definitions for use by extension functions calling into gawk.
6
* copyright (c) 2012-2019, 2021-2024, the free software foundation, inc.
6
* Copyright (C) 2012-2014 the Free Software Foundation, Inc.
8
8
* This file is part of GAWK, the GNU implementation of the
9
9
* AWK Programming Language.
11
11
* GAWK is free software; you can redistribute it and/or modify
12
12
* it under the terms of the GNU General Public License as published by
13
13
* the Free Software Foundation; either version 3 of the License, or
14
14
* (at your option) any later version.
16
16
* GAWK is distributed in the hope that it will be useful,
17
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
19
* GNU General Public License for more details.
21
21
* You should have received a copy of the GNU General Public License
22
22
* along with this program; if not, write to the Free Software
23
23
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
98
98
* for arrays that will have subarrays as elements; however it is
99
99
* a good idea to always do this. This restriction may be relaxed
100
100
* in a subsequent revision of the API.
102
* 3. While each routine in the API has a few lines of summary for it
103
* in this header, said summaries are not standalone, adequate documentation. You
104
* should read the chapter in the gawk manual on writing extensions. Find it online
105
* at https://www.gnu.org/software/gawk/manual/html_node/Dynamic-Extensions.html,
106
* or in the Info files distributed with gawk.
109
103
/* Allow use in C++ code. */
124
118
} awk_bool_t; /* we don't use <stdbool.h> on purpose */
127
* If an input parser would like to specify the field positions in the input
128
* record, it may populate an awk_fieldwidth_info_t structure to indicate
129
* the location of each field. The use_chars boolean controls whether the
130
* field lengths are specified in terms of bytes or potentially multi-byte
131
* characters. Performance will be better if the values are supplied in
132
* terms of bytes. The fields[0].skip value indicates how many bytes (or
133
* characters) to skip before $1, and fields[0].len is the length of $1, etc.
137
awk_bool_t use_chars; /* false ==> use bytes */
139
struct awk_field_info {
140
size_t skip; /* amount to skip before field starts */
141
size_t len; /* length of field */
142
} fields[1]; /* actual dimension should be nf */
143
} awk_fieldwidth_info_t;
146
* This macro calculates the total struct size needed. This is useful when
147
* calling malloc or realloc.
149
#define awk_fieldwidth_info_size(NF) (sizeof(awk_fieldwidth_info_t) + \
150
(((NF)-1) * sizeof(struct awk_field_info)))
152
120
/* The information about input files that input parsers need to know: */
153
121
typedef struct awk_input {
154
122
const char *name; /* filename */
155
123
int fd; /* file descriptor */
156
124
#define INVALID_HANDLE (-1)
157
125
void *opaque; /* private data for input parsers */
160
127
* The get_record function is called to read the next record of data.
169
136
* parser is responsible for managing its own memory buffer.
170
137
* Similarly, gawk will make its own copy of RT, so the parser
171
138
* is also responsible for managing this memory.
173
140
* It is guaranteed that errcode is a valid pointer, so there is
174
141
* no need to test for a NULL value. Gawk sets *errcode to 0,
175
142
* so there is no need to set it unless an error occurs.
177
144
* If an error does occur, the function should return EOF and set
178
* *errcode to a positive value. In that case, if *errcode is greater
179
* than zero, gawk will automatically update the ERRNO variable based
145
* *errcode to a non-zero value. In that case, if *errcode does not
146
* equal -1, gawk will automatically update the ERRNO variable based
180
147
* on the value of *errcode (e.g., setting *errcode = errno should do
181
148
* the right thing).
183
* If field_width is non-NULL, then *field_width will be initialized
184
* to NULL, and the function may set it to point to a structure
185
* supplying field width information to override the default
186
* gawk field parsing mechanism. Note that this structure will not
187
* be copied by gawk; it must persist at least until the next call
188
* to get_record or close_func. Note also that field_width will
189
* be NULL when getline is assigning the results to a variable, thus
190
* field parsing is not needed.
192
150
int (*get_record)(char **out, struct awk_input *iobuf, int *errcode,
193
char **rt_start, size_t *rt_len,
194
const awk_fieldwidth_info_t **field_width);
151
char **rt_start, size_t *rt_len);
197
* This replaces the POSIX read() system call. Use it if you want to
198
* manage reading raw bytes yourself, and let gawk parse the record.
154
* No argument prototype on read_func to allow for older systems
155
* whose headers are not up to date.
200
ssize_t (*read_func)(int, void *, size_t);
157
ssize_t (*read_func)();
203
160
* The close_func is called to allow the parser to free private data.
303
260
awk_const struct awk_two_way_processor *awk_const next; /* for use by gawk */
304
261
} awk_two_way_processor_t;
306
#define gawk_api_major_version 4
307
#define gawk_api_minor_version 0
309
263
/* Current version of the API. */
311
GAWK_API_MAJOR_VERSION = gawk_api_major_version,
312
GAWK_API_MINOR_VERSION = gawk_api_minor_version
265
GAWK_API_MAJOR_VERSION = 1,
266
GAWK_API_MINOR_VERSION = 1
315
269
/* A number of typedefs related to different types of values. */
321
275
* The API deals exclusively with regular chars; these strings may
322
276
* be multibyte encoded in the current locale's encoding and character
323
277
* set. Gawk will convert internally to wide characters if necessary.
325
* Note that a string provided by gawk will always be terminated
326
* with a '\0' character.
328
279
typedef struct awk_string {
329
280
char *str; /* data */
330
281
size_t len; /* length thereof, in chars */
333
enum AWK_NUMBER_TYPE {
334
AWK_NUMBER_TYPE_DOUBLE,
335
AWK_NUMBER_TYPE_MPFR,
340
* When type is AWK_NUMBER_MPFR or AWK_NUMBER_MPZ, the memory pointed to
341
* by the ptr member belongs to gawk if it came from gawk. Otherwise the
342
* memory belongs to the extension and gawk copies it when its received.
343
* See the manual for further discussion.
346
typedef struct awk_number {
347
double d; /* always populated in data received from gawk */
348
enum AWK_NUMBER_TYPE type;
349
void *ptr; /* either NULL or mpfr_ptr or mpz_ptr */
352
284
/* Arrays are represented as an opaque type. */
353
285
typedef void *awk_array_t;
448
371
* Each extension function may decide what to do if the number of
449
372
* arguments isn't what it expected. Following awk functions, it
450
373
* is likely OK to ignore extra arguments.
452
* 'min_required_args' indicates how many arguments MUST be passed.
453
* The API will throw a fatal error if not enough are passed.
455
* 'max_expected_args' is more benign; if more than that are passed,
456
* the API prints a lint message (IFF lint is enabled, of course).
458
* In any case, the extension function itself need not compare the
459
* actual number of arguments passed to those two values if it does
462
375
typedef struct awk_ext_func {
463
376
const char *name;
464
awk_value_t *(*const function)(int num_actual_args,
466
struct awk_ext_func *finfo);
467
const size_t max_expected_args;
468
const size_t min_required_args;
469
awk_bool_t suppress_lint;
470
void *data; /* opaque pointer to any extra state */
377
awk_value_t *(*function)(int num_actual_args, awk_value_t *result);
378
size_t num_expected_args;
471
379
} awk_ext_func_t;
473
381
typedef void *awk_ext_id_t; /* opaque type for extension id */
486
391
awk_const int major_version;
487
392
awk_const int minor_version;
489
/* GMP/MPFR versions, if extended-precision is available */
490
awk_const int gmp_major_version;
491
awk_const int gmp_minor_version;
492
awk_const int mpfr_major_version;
493
awk_const int mpfr_minor_version;
496
395
* These can change on the fly as things happen within gawk.
497
396
* Currently only do_lint is prone to change, but we reserve
498
397
* the right to allow the others to do so also.
500
* N.B. If we ever again need to add an additional do_flags value,
501
* it would be wise to convert this from an array to a bitmask. If
502
* we add a new do_flags value and bump DO_FLAGS_SIZE, then it requires
503
* us to increment the ABI version. If we use a bitmask instead, then
504
* we will be free to add new flags without breaking ABI compatibility.
506
#define DO_FLAGS_SIZE 7
399
#define DO_FLAGS_SIZE 6
507
400
awk_const int do_flags[DO_FLAGS_SIZE];
508
401
/* Use these as indices into do_flags[] array to check the values */
509
402
#define gawk_do_lint 0
512
405
#define gawk_do_sandbox 3
513
406
#define gawk_do_debug 4
514
407
#define gawk_do_mpfr 5
515
#define gawk_do_csv 6
517
409
/* Next, registration functions: */
520
* Add a function to the interpreter, returns true upon success.
521
* Gawk does not modify what func points to, but the extension
522
* function itself receives this pointer and can modify what it
523
* points to, thus it's not const.
525
awk_bool_t (*api_add_ext_func)(awk_ext_id_t id, const char *name_space,
526
awk_ext_func_t *func);
411
/* Add a function to the interpreter, returns true upon success */
412
awk_bool_t (*api_add_ext_func)(awk_ext_id_t id, const char *namespace,
413
const awk_ext_func_t *func);
528
415
/* Register an input parser; for opening files read-only */
529
416
void (*api_register_input_parser)(awk_ext_id_t id,
570
456
* behave in the same way.
572
458
* For a function parameter, the return is false if the argument
573
* count is out of range, or if the actual parameter does not match
459
* count is out of range, or if actual paramater does not match
574
460
* what is specified in wanted. In that case, result->val_type
575
461
* will hold the actual type of what was passed.
577
463
* Similarly for symbol table access to variables and array elements,
578
464
* the return is false if the actual variable or array element does
579
* not match what was requested, and result->val_type will hold
465
* not match what was requested, and the result->val_type will hold
580
466
* the actual type.
582
468
Table entry is type returned:
585
+----------------------------------------------------------------+
586
| Type of Actual Value: |
587
+--------+--------+--------+--------+--------+-------+-----------+
588
| String | Strnum | Number | Regex | Bool | Array | Undefined |
589
+-----------+-----------+--------+--------+--------+--------+--------+-------+-----------+
590
| | String | String | String | String | String | String | false | false |
591
| +-----------+--------+--------+--------+--------+--------+-------+-----------+
592
| | Strnum | false | Strnum | Strnum | false | false | false | false |
593
| +-----------+--------+--------+--------+--------+--------+-------+-----------+
594
| | Number | Number | Number | Number | false | Number | false | false |
595
| +-----------+--------+--------+--------+--------+--------+-------+-----------+
596
| | Regex | false | false | false | Regex | false | false | false |
597
| +-----------+--------+--------+--------+--------+--------+-------+-----------+
598
| Type | Bool | false | false | false | false | Bool | false | false |
599
| Requested +-----------+--------+--------+--------+--------+--------+-------+-----------+
600
| | Array | false | false | false | false | false | Array | false |
601
| +-----------+--------+--------+--------+--------+--------+-------+-----------+
602
| | Scalar | Scalar | Scalar | Scalar | Scalar | Scalar | false | false |
603
| +-----------+--------+--------+--------+--------+--------+-------+-----------+
604
| | Undefined | String | Strnum | Number | Regex | Bool | Array | Undefined |
605
| +-----------+--------+--------+--------+--------+--------+-------+-----------+
606
| | Value | false | false | false | false | false | false | false |
607
| | Cookie | | | | | | | |
608
+-----------+-----------+--------+--------+--------+--------+--------+-------+-----------+
471
+-------------------------------------------------+
472
| Type of Actual Value: |
473
+------------+------------+-----------+-----------+
474
| String | Number | Array | Undefined |
475
+-----------+-----------+------------+------------+-----------+-----------+
476
| | String | String | String | false | false |
477
| |-----------+------------+------------+-----------+-----------+
478
| | Number | Number if | Number | false | false |
480
| | | converted, | | | |
481
| | | else false | | | |
482
| |-----------+------------+------------+-----------+-----------+
483
| Type | Array | false | false | Array | false |
484
| Requested |-----------+------------+------------+-----------+-----------+
485
| | Scalar | Scalar | Scalar | false | false |
486
| |-----------+------------+------------+-----------+-----------+
487
| | Undefined | String | Number | Array | Undefined |
488
| |-----------+------------+------------+-----------+-----------+
489
| | Value | false | false | false | false |
491
+-----------+-----------+------------+------------+-----------+-----------+
611
494
/* Functions to handle parameters passed to the extension. */
614
* Get the count'th parameter, zero-based.
615
* Returns false if count is out of range, or if actual parameter
497
* Get the count'th paramater, zero-based.
498
* Returns false if count is out of range, or if actual paramater
616
499
* does not match what is specified in wanted. In that case,
617
500
* result->val_type is as described above.
635
518
* - Read-only access to special variables (NF, etc.)
636
519
* - One special exception: PROCINFO.
637
520
* - Use sym_update() to change a value, including from UNDEFINED
638
* to scalar or array.
521
* to scalar or array.
641
524
* Lookup a variable, fill in value. No messing with the value
643
* Returns false if the variable doesn't exist or if the wrong type
526
* Returns false if the variable doesn't exist* or if the wrong type
644
527
* was requested. In the latter case, vaule->val_type will have
645
528
* the real type, as described above.
714
595
/* Cached values */
717
* Create a cached string,regex, or numeric value for efficient later
598
* Create a cached string or numeric value for efficient later
718
599
* assignment. This improves performance when you want to assign
719
600
* the same value to one or more variables repeatedly. Only
720
* AWK_NUMBER, AWK_STRING, AWK_REGEX and AWK_STRNUM values are allowed.
721
* Any other type is rejected. We disallow AWK_UNDEFINED since that
722
* case would result in inferior performance.
601
* AWK_NUMBER and AWK_STRING values are allowed. Any other type
602
* is rejected. We disallow AWK_UNDEFINED since that case would
603
* result in inferior performance.
724
605
awk_bool_t (*api_create_value)(awk_ext_id_t id, awk_value_t *value,
725
606
awk_value_cookie_t *result);
765
646
* Remove the element with the given index.
766
* Returns true if removed or false if element did not exist.
647
* Returns success if removed or false if element did not exist.
768
649
awk_bool_t (*api_del_array_element)(awk_ext_id_t id,
769
650
awk_array_t a_cookie, const awk_value_t* const index);
771
/* Create a new array cookie to which elements may be added. */
652
/* Create a new array cookie to which elements may be added */
772
653
awk_array_t (*api_create_array)(awk_ext_id_t id);
774
/* Clear out an array. */
655
/* Clear out an array */
775
656
awk_bool_t (*api_clear_array)(awk_ext_id_t id, awk_array_t a_cookie);
778
* Flatten out an array with type conversions as requested.
779
* This supersedes the earlier api_flatten_array function that
780
* did not allow the caller to specify the requested types.
781
* (That API is still available as a macro, defined below.)
783
awk_bool_t (*api_flatten_array_typed)(awk_ext_id_t id,
658
/* Flatten out an array so that it can be looped over easily. */
659
awk_bool_t (*api_flatten_array)(awk_ext_id_t id,
784
660
awk_array_t a_cookie,
785
awk_flat_array_t **data,
786
awk_valtype_t index_type, awk_valtype_t value_type);
661
awk_flat_array_t **data);
788
663
/* When done, delete any marked elements, release the memory. */
789
664
awk_bool_t (*api_release_flattened_array)(awk_ext_id_t id,
799
674
void *(*api_calloc)(size_t nmemb, size_t size);
800
675
void *(*api_realloc)(void *ptr, size_t size);
801
676
void (*api_free)(void *ptr);
804
* Obsolete function, should not be used. It remains only
805
* for binary compatibility. Any value it returns should be
806
* freed via api_free.
808
void *(*api_get_mpfr)(awk_ext_id_t id);
811
* Obsolete function, should not be used. It remains only
812
* for binary compatibility. Any value it returns should be
813
* freed via api_free.
815
void *(*api_get_mpz)(awk_ext_id_t id);
818
* Look up a file. If the name is NULL or name_len is 0, it returns
819
* data for the currently open input file corresponding to FILENAME
820
* (and it will not access the filetype argument, so that may be
823
* If the file is not already open, try to open it.
825
* The "filetype" argument should be one of:
827
* ">", ">>", "<", "|>", "|<", and "|&"
829
* If the file is not already open, and the fd argument is non-negative,
830
* gawk will use that file descriptor instead of opening the file
833
* If the fd is non-negative, but the file exists already, gawk
834
* ignores the fd and returns the existing file. It is the caller's
835
* responsibility to notice that the fd in the returned
836
* awk_input_buf_t does not match the requested value.
838
* Note that supplying a file descriptor is currently NOT supported
839
* for pipes. It should work for input, output, append, and two-way
840
* (coprocess) sockets. If the filetype is two-way, we assume that
843
* Note that in the two-way case, the input and output file descriptors
844
* may differ. To check for success, one must check that either of
847
* ibufp and obufp point at gawk's internal copies of the
848
* awk_input_buf_t and awk_output_t associated with the open
849
* file. Treat these data structures as read-only!
851
awk_bool_t (*api_get_file)(awk_ext_id_t id,
854
const char *filetype,
857
* Return values (on success, one or both should
860
const awk_input_buf_t **ibufp,
861
const awk_output_buf_t **obufp);
863
/* Destroy an array. */
864
awk_bool_t (*api_destroy_array)(awk_ext_id_t id, awk_array_t a_cookie);
867
679
#ifndef GAWK /* these are not for the gawk code itself! */
902
712
#define awk_atexit(funcp, arg0) (api->api_awk_atexit(ext_id, funcp, arg0))
904
714
#define sym_lookup(name, wanted, result) \
905
sym_lookup_ns("", name, wanted, result)
906
#define sym_update(name, value) \
907
sym_update_ns("", name, value)
909
#define sym_lookup_ns(name_space, name, wanted, result) \
910
(api->api_sym_lookup(ext_id, name_space, name, wanted, result))
911
#define sym_update_ns(name_space, name, value) \
912
(api->api_sym_update(ext_id, name_space, name, value))
715
(api->api_sym_lookup(ext_id, name, wanted, result))
914
716
#define sym_lookup_scalar(scalar_cookie, wanted, result) \
915
717
(api->api_sym_lookup_scalar(ext_id, scalar_cookie, wanted, result))
718
#define sym_update(name, value) \
719
(api->api_sym_update(ext_id, name, value))
916
720
#define sym_update_scalar(scalar_cookie, value) \
917
721
(api->api_sym_update_scalar)(ext_id, scalar_cookie, value)
934
738
#define create_array() (api->api_create_array(ext_id))
936
#define destroy_array(array) (api->api_destroy_array(ext_id, array))
938
740
#define clear_array(array) (api->api_clear_array(ext_id, array))
940
#define flatten_array_typed(array, data, index_type, value_type) \
941
(api->api_flatten_array_typed(ext_id, array, data, index_type, value_type))
943
742
#define flatten_array(array, data) \
944
flatten_array_typed(array, data, AWK_STRING, AWK_UNDEFINED)
743
(api->api_flatten_array(ext_id, array, data))
946
745
#define release_flattened_array(array, data) \
947
746
(api->api_release_flattened_array(ext_id, array, data))
957
756
#define release_value(value) \
958
757
(api->api_release_value(ext_id, value))
960
#define get_file(name, namelen, filetype, fd, ibuf, obuf) \
961
(api->api_get_file(ext_id, name, namelen, filetype, fd, ibuf, obuf))
963
/* These two are obsolete and should not be used. */
964
#define get_mpfr_ptr() (api->api_get_mpfr(ext_id))
965
#define get_mpz_ptr() (api->api_get_mpz(ext_id))
967
759
#define register_ext_version(version) \
968
760
(api->api_register_ext_version(ext_id, version))
970
762
#define emalloc(pointer, type, size, message) \
972
764
if ((pointer = (type) gawk_malloc(size)) == 0) \
973
fatal(ext_id, "%s: malloc of %d bytes failed", message, size); \
976
#define ezalloc(pointer, type, size, message) \
978
if ((pointer = (type) gawk_calloc(1, size)) == 0) \
979
fatal(ext_id, "%s: calloc of %d bytes failed", message, size); \
765
fatal(ext_id, "%s: malloc of %d bytes failed\n", message, size); \
982
768
#define erealloc(pointer, type, size, message) \
984
770
if ((pointer = (type) gawk_realloc(pointer, size)) == 0) \
985
fatal(ext_id, "%s: realloc of %d bytes failed", message, size); \
771
fatal(ext_id, "%s: realloc of %d bytes failed\n", message, size); \
988
774
/* Constructor functions */
990
/* r_make_string_type --- make a string or strnum or regexp value in result from the passed-in string */
776
/* r_make_string --- make a string value in result from the passed-in string */
992
778
static inline awk_value_t *
993
r_make_string_type(const gawk_api_t *api, /* needed for emalloc */
994
awk_ext_id_t ext_id, /* ditto */
997
awk_bool_t duplicate,
999
awk_valtype_t val_type)
779
r_make_string(const gawk_api_t *api, /* needed for emalloc */
780
awk_ext_id_t *ext_id, /* ditto */
783
awk_bool_t duplicate,
1001
786
char *cp = NULL;
1003
788
memset(result, 0, sizeof(*result));
1005
result->val_type = val_type;
790
result->val_type = AWK_STRING;
1006
791
result->str_value.len = length;
1008
793
if (duplicate) {
1009
emalloc(cp, char *, length + 1, "r_make_string");
794
emalloc(cp, char *, length + 2, "r_make_string");
1010
795
memcpy(cp, string, length);
1011
796
cp[length] = '\0';
1012
797
result->str_value.str = cp;
1020
/* r_make_string --- make a string value in result from the passed-in string */
1022
static inline awk_value_t *
1023
r_make_string(const gawk_api_t *api, /* needed for emalloc */
1024
awk_ext_id_t ext_id, /* ditto */
1027
awk_bool_t duplicate,
1028
awk_value_t *result)
1030
return r_make_string_type(api, ext_id, string, length, duplicate, result, AWK_STRING);
1033
#define make_const_string(str, len, result) r_make_string(api, ext_id, str, len, awk_true, result)
1034
#define make_malloced_string(str, len, result) r_make_string(api, ext_id, str, len, awk_false, result)
1036
#define make_const_regex(str, len, result) r_make_string_type(api, ext_id, str, len, awk_true, result, AWK_REGEX)
1037
#define make_malloced_regex(str, len, result) r_make_string_type(api, ext_id, str, len, awk_false, result, AWK_REGEX)
1040
* Note: The caller may not create a STRNUM, but it can create a string that is
1041
* flagged as user input that MAY be a STRNUM. Gawk will decide whether it's a
1042
* STRNUM or a string by checking whether the string is numeric.
1044
#define make_const_user_input(str, len, result) r_make_string_type(api, ext_id, str, len, 1, result, AWK_STRNUM)
1045
#define make_malloced_user_input(str, len, result) r_make_string_type(api, ext_id, str, len, 0, result, AWK_STRNUM)
805
#define make_const_string(str, len, result) r_make_string(api, ext_id, str, len, 1, result)
806
#define make_malloced_string(str, len, result) r_make_string(api, ext_id, str, len, 0, result)
1047
808
/* make_null_string --- make a null string value */
1060
821
static inline awk_value_t *
1061
822
make_number(double num, awk_value_t *result)
824
memset(result, 0, sizeof(*result));
1063
826
result->val_type = AWK_NUMBER;
1064
827
result->num_value = num;
1065
result->num_type = AWK_NUMBER_TYPE_DOUBLE;
1070
* make_number_mpz --- make an mpz number value in result.
1071
* The mpz_ptr must be from a call to get_mpz_ptr.
1074
static inline awk_value_t *
1075
make_number_mpz(void *mpz_ptr, awk_value_t *result)
1077
result->val_type = AWK_NUMBER;
1078
result->num_type = AWK_NUMBER_TYPE_MPZ;
1079
result->num_ptr = mpz_ptr;
1084
* make_number_mpfr --- make an mpfr number value in result.
1085
* The mpfr_ptr must be from a call to get_mpfr_ptr.
1088
static inline awk_value_t *
1089
make_number_mpfr(void *mpfr_ptr, awk_value_t *result)
1091
result->val_type = AWK_NUMBER;
1092
result->num_type = AWK_NUMBER_TYPE_MPFR;
1093
result->num_ptr = mpfr_ptr;
1097
/* make_bool --- make a bool value in result */
1099
static inline awk_value_t *
1100
make_bool(awk_bool_t boolval, awk_value_t *result)
1102
result->val_type = AWK_BOOL;
1103
result->bool_value = boolval;
1109
833
* Each extension must define a function with this prototype:
1143
867
static awk_bool_t
1144
init_my_extension(void)
1149
static awk_bool_t (*init_func)(void) = init_my_extension;
873
static awk_bool_t (*init_func)(void) = init_my_module;
1151
875
dl_load_func(func_table, some_name, "name_space_in_quotes")
1154
#define dl_load_func(func_table, extension, name_space) \
878
#define dl_load_func(func_table, module, name_space) \
1155
879
int dl_load(const gawk_api_t *const api_p, awk_ext_id_t id) \
1158
882
int errors = 0; \
1161
ext_id = (void **) id; \
1163
887
if (api->major_version != GAWK_API_MAJOR_VERSION \
1164
888
|| api->minor_version < GAWK_API_MINOR_VERSION) { \
1165
fprintf(stderr, #extension ": version mismatch with gawk!\n"); \
1166
fprintf(stderr, "\tmy version (API %d.%d), gawk version (API %d.%d)\n", \
889
fprintf(stderr, #module ": version mismatch with gawk!\n"); \
890
fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n", \
1167
891
GAWK_API_MAJOR_VERSION, GAWK_API_MINOR_VERSION, \
1168
892
api->major_version, api->minor_version); \
1172
check_mpfr_version(extension); \
1174
896
/* load functions */ \
1175
897
for (i = 0, j = sizeof(func_table) / sizeof(func_table[0]); i < j; i++) { \
1176
898
if (func_table[i].name == NULL) \
1178
900
if (! add_ext_func(name_space, & func_table[i])) { \
1179
warning(ext_id, #extension ": could not add %s", \
901
warning(ext_id, #module ": could not add %s\n", \
1180
902
func_table[i].name); \
1195
917
return (errors == 0); \
1198
#if defined __GNU_MP_VERSION && defined MPFR_VERSION_MAJOR
1199
#define check_mpfr_version(extension) do { \
1200
if (api->gmp_major_version != __GNU_MP_VERSION \
1201
|| api->gmp_minor_version < __GNU_MP_VERSION_MINOR) { \
1202
fprintf(stderr, #extension ": GMP version mismatch with gawk!\n"); \
1203
fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n", \
1204
__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, \
1205
api->gmp_major_version, api->gmp_minor_version); \
1208
if (api->mpfr_major_version != MPFR_VERSION_MAJOR \
1209
|| api->mpfr_minor_version < MPFR_VERSION_MINOR) { \
1210
fprintf(stderr, #extension ": MPFR version mismatch with gawk!\n"); \
1211
fprintf(stderr, "\tmy version (%d, %d), gawk version (%d, %d)\n", \
1212
MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR, \
1213
api->mpfr_major_version, api->mpfr_minor_version); \
1218
#define check_mpfr_version(extension) /* nothing */
1221
920
#endif /* GAWK */
1223
922
#ifdef __cplusplus