1 | /*
|
---|
2 | * awk.h -- Definitions for gawk.
|
---|
3 | */
|
---|
4 |
|
---|
5 | /*
|
---|
6 | * Copyright (C) 1986, 1988, 1989, 1991-2005 the Free Software Foundation, Inc.
|
---|
7 | *
|
---|
8 | * This file is part of GAWK, the GNU implementation of the
|
---|
9 | * AWK Programming Language.
|
---|
10 | *
|
---|
11 | * GAWK is free software; you can redistribute it and/or modify
|
---|
12 | * it under the terms of the GNU General Public License as published by
|
---|
13 | * the Free Software Foundation; either version 2 of the License, or
|
---|
14 | * (at your option) any later version.
|
---|
15 | *
|
---|
16 | * GAWK is distributed in the hope that it will be useful,
|
---|
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
19 | * GNU General Public License for more details.
|
---|
20 | *
|
---|
21 | * You should have received a copy of the GNU General Public License
|
---|
22 | * along with this program; if not, write to the Free Software
|
---|
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
---|
24 | */
|
---|
25 |
|
---|
26 | /* ------------------------------ Includes ------------------------------ */
|
---|
27 |
|
---|
28 | /*
|
---|
29 | * config.h absolutely, positively, *M*U*S*T* be included before
|
---|
30 | * any system headers. Otherwise, extreme death, destruction
|
---|
31 | * and loss of life results.
|
---|
32 | *
|
---|
33 | * Well, OK, gawk just won't work on systems using egcs and LFS. But
|
---|
34 | * that's almost as bad.
|
---|
35 | */
|
---|
36 | #ifdef HAVE_CONFIG_H
|
---|
37 | #include <config.h>
|
---|
38 | #endif
|
---|
39 |
|
---|
40 | #ifndef _GNU_SOURCE
|
---|
41 | #define _GNU_SOURCE 1 /* enable GNU extensions */
|
---|
42 | #endif /* _GNU_SOURCE */
|
---|
43 |
|
---|
44 | #include <stdio.h>
|
---|
45 | #include <assert.h>
|
---|
46 | #ifdef HAVE_LIMITS_H
|
---|
47 | #include <limits.h>
|
---|
48 | #endif /* HAVE_LIMITS_H */
|
---|
49 | #include <ctype.h>
|
---|
50 | #include <setjmp.h>
|
---|
51 |
|
---|
52 | #include "gettext.h"
|
---|
53 | #define _(msgid) gettext(msgid)
|
---|
54 | #define N_(msgid) msgid
|
---|
55 |
|
---|
56 | #if ! (defined(HAVE_LIBINTL_H) && defined(ENABLE_NLS) && ENABLE_NLS > 0)
|
---|
57 | #ifndef LOCALEDIR
|
---|
58 | #define LOCALEDIR NULL
|
---|
59 | #endif /* LOCALEDIR */
|
---|
60 | #endif
|
---|
61 |
|
---|
62 | #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
|
---|
63 | #include <stdarg.h>
|
---|
64 | #else
|
---|
65 | #include <varargs.h>
|
---|
66 | #endif
|
---|
67 | #include <signal.h>
|
---|
68 | #include <time.h>
|
---|
69 | #include <errno.h>
|
---|
70 | #if ! defined(errno) && ! defined(MSDOS) && ! defined(OS2)
|
---|
71 | extern int errno;
|
---|
72 | #endif
|
---|
73 | #ifdef HAVE_SIGNUM_H
|
---|
74 | #include <signum.h>
|
---|
75 | #endif
|
---|
76 |
|
---|
77 | #ifndef NO_MBSUPPORT
|
---|
78 | #include "mbsupport.h" /* defines MBS_SUPPORT */
|
---|
79 | #endif
|
---|
80 |
|
---|
81 | #if defined(MBS_SUPPORT)
|
---|
82 | /* We can handle multibyte strings. */
|
---|
83 | #include <wchar.h>
|
---|
84 | #include <wctype.h>
|
---|
85 | #endif
|
---|
86 |
|
---|
87 | #ifdef STDC_HEADERS
|
---|
88 | #include <float.h>
|
---|
89 | #endif
|
---|
90 |
|
---|
91 | /* ----------------- System dependencies (with more includes) -----------*/
|
---|
92 |
|
---|
93 | /* This section is the messiest one in the file, not a lot that can be done */
|
---|
94 |
|
---|
95 | /* First, get the ctype stuff right; from Jim Meyering */
|
---|
96 | #if defined(STDC_HEADERS) || (!defined(isascii) && !defined(HAVE_ISASCII))
|
---|
97 | #define IN_CTYPE_DOMAIN(c) 1
|
---|
98 | #else
|
---|
99 | #define IN_CTYPE_DOMAIN(c) isascii((unsigned char) c)
|
---|
100 | #endif
|
---|
101 |
|
---|
102 | #ifdef isblank
|
---|
103 | #define ISBLANK(c) (IN_CTYPE_DOMAIN(c) && isblank((unsigned char) c))
|
---|
104 | #else
|
---|
105 | #define ISBLANK(c) ((c) == ' ' || (c) == '\t')
|
---|
106 | #endif
|
---|
107 | #ifdef isgraph
|
---|
108 | #define ISGRAPH(c) (IN_CTYPE_DOMAIN(c) && isgraph((unsigned char) c))
|
---|
109 | #else
|
---|
110 | #define ISGRAPH(c) (IN_CTYPE_DOMAIN(c) && isprint((unsigned char) c) && !isspace((unsigned char) c))
|
---|
111 | #endif
|
---|
112 |
|
---|
113 | #define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint ((unsigned char) c))
|
---|
114 | #define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit ((unsigned char) c))
|
---|
115 | #define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum ((unsigned char) c))
|
---|
116 | #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha ((unsigned char) c))
|
---|
117 | #define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl ((unsigned char) c))
|
---|
118 | #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower ((unsigned char) c))
|
---|
119 | #define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct (unsigned char) (c))
|
---|
120 | #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace ((unsigned char) c))
|
---|
121 | #define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper ((unsigned char) c))
|
---|
122 | #define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit ((unsigned char) c))
|
---|
123 |
|
---|
124 | #ifndef TOUPPER
|
---|
125 | #define TOUPPER(c) toupper((unsigned char) c)
|
---|
126 | #endif
|
---|
127 | #ifndef TOLOWER
|
---|
128 | #define TOLOWER(c) tolower((unsigned char) c)
|
---|
129 | #endif
|
---|
130 |
|
---|
131 | #ifdef __STDC__
|
---|
132 | #define P(s) s
|
---|
133 | #define MALLOC_ARG_T size_t
|
---|
134 | #else /* not __STDC__ */
|
---|
135 | #define P(s) ()
|
---|
136 | #define MALLOC_ARG_T unsigned
|
---|
137 | #define volatile
|
---|
138 | #endif /* not __STDC__ */
|
---|
139 |
|
---|
140 | #ifndef VMS
|
---|
141 | #include <sys/types.h>
|
---|
142 | #include <sys/stat.h>
|
---|
143 | #else /* VMS */
|
---|
144 | #include <stddef.h>
|
---|
145 | #include <stat.h>
|
---|
146 | #include <file.h> /* avoid <fcntl.h> in io.c */
|
---|
147 | #endif /* VMS */
|
---|
148 |
|
---|
149 | #if ! defined(S_ISREG) && defined(S_IFREG)
|
---|
150 | #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
---|
151 | #endif
|
---|
152 |
|
---|
153 | #ifdef STDC_HEADERS
|
---|
154 | #include <stdlib.h>
|
---|
155 | #else /* not STDC_HEADERS */
|
---|
156 | #include "protos.h"
|
---|
157 | #endif /* not STDC_HEADERS */
|
---|
158 |
|
---|
159 | #ifdef HAVE_STRING_H
|
---|
160 | #include <string.h>
|
---|
161 | #ifdef NEED_MEMORY_H
|
---|
162 | #include <memory.h>
|
---|
163 | #endif /* NEED_MEMORY_H */
|
---|
164 | #else /* not HAVE_STRING_H */
|
---|
165 | #ifdef HAVE_STRINGS_H
|
---|
166 | #include <strings.h>
|
---|
167 | #endif /* HAVE_STRINGS_H */
|
---|
168 | #endif /* not HAVE_STRING_H */
|
---|
169 |
|
---|
170 | #ifdef NeXT
|
---|
171 | #if __GNUC__ < 2 || __GNUC_MINOR__ < 7
|
---|
172 | #include <libc.h>
|
---|
173 | #endif
|
---|
174 | #undef atof
|
---|
175 | #define getopt GNU_getopt
|
---|
176 | #define GFMT_WORKAROUND
|
---|
177 | #endif /* NeXT */
|
---|
178 |
|
---|
179 | #if defined(atarist) || defined(VMS)
|
---|
180 | #include <unixlib.h>
|
---|
181 | #endif /* atarist || VMS */
|
---|
182 |
|
---|
183 | #if ! defined(MSDOS) && ! defined(OS2) && ! defined(WIN32) && ! defined(__EMX__) && ! defined(__CYGWIN__) && ! defined(O_BINARY) /*duh*/
|
---|
184 | #define O_BINARY 0
|
---|
185 | #endif
|
---|
186 |
|
---|
187 | #if defined(TANDEM)
|
---|
188 | #define variable variabl
|
---|
189 | #define open(name, how, mode) open(name, how) /* !!! ANSI C !!! */
|
---|
190 | #endif
|
---|
191 |
|
---|
192 | #if HAVE_UNISTD_H
|
---|
193 | #include <unistd.h>
|
---|
194 | #endif /* HAVE_UNISTD_H */
|
---|
195 |
|
---|
196 | #ifndef HAVE_VPRINTF
|
---|
197 | /* if you don't have vprintf, try this and cross your fingers. */
|
---|
198 | #ifdef HAVE_DOPRNT
|
---|
199 | #define vfprintf(fp,fmt,arg) _doprnt((fmt), (arg), (fp))
|
---|
200 | #else /* not HAVE_DOPRNT */
|
---|
201 | you
|
---|
202 | lose
|
---|
203 | #endif /* not HAVE_DOPRNT */
|
---|
204 | #endif /* HAVE_VPRINTF */
|
---|
205 |
|
---|
206 | #ifndef HAVE_SETLOCALE
|
---|
207 | #define setlocale(locale, val) /* nothing */
|
---|
208 | #endif /* HAVE_SETLOCALE */
|
---|
209 |
|
---|
210 | /* use this as lintwarn("...")
|
---|
211 | this is a hack but it gives us the right semantics */
|
---|
212 | #define lintwarn (*(set_loc(__FILE__, __LINE__),lintfunc))
|
---|
213 |
|
---|
214 | #ifdef VMS
|
---|
215 | #include "vms/redirect.h"
|
---|
216 | #endif /*VMS*/
|
---|
217 |
|
---|
218 | #ifdef atarist
|
---|
219 | #include "unsupported/atari/redirect.h"
|
---|
220 | #endif
|
---|
221 |
|
---|
222 | #define GNU_REGEX
|
---|
223 | #ifdef GNU_REGEX
|
---|
224 | #include "regex.h"
|
---|
225 | #include "dfa.h"
|
---|
226 | typedef struct Regexp {
|
---|
227 | struct re_pattern_buffer pat;
|
---|
228 | struct re_registers regs;
|
---|
229 | struct dfa dfareg;
|
---|
230 | short dfa;
|
---|
231 | short has_anchor; /* speed up of avoid_dfa kludge, temporary */
|
---|
232 | } Regexp;
|
---|
233 | #define RESTART(rp,s) (rp)->regs.start[0]
|
---|
234 | #define REEND(rp,s) (rp)->regs.end[0]
|
---|
235 | #define SUBPATSTART(rp,s,n) (rp)->regs.start[n]
|
---|
236 | #define SUBPATEND(rp,s,n) (rp)->regs.end[n]
|
---|
237 | #define NUMSUBPATS(rp,s) (rp)->regs.num_regs
|
---|
238 | #endif /* GNU_REGEX */
|
---|
239 | /* regexp matching flags: */
|
---|
240 | #define RE_NEED_START 1 /* need to know start/end of match */
|
---|
241 | #define RE_NO_BOL 2 /* for RS, not allowed to match ^ in regexp */
|
---|
242 |
|
---|
243 | /* Stuff for losing systems. */
|
---|
244 | #ifdef STRTOD_NOT_C89
|
---|
245 | extern double gawk_strtod();
|
---|
246 | #define strtod gawk_strtod
|
---|
247 | #endif
|
---|
248 |
|
---|
249 | #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
|
---|
250 | # define __attribute__(x)
|
---|
251 | #endif
|
---|
252 |
|
---|
253 | #ifndef ATTRIBUTE_UNUSED
|
---|
254 | #define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
---|
255 | #endif /* ATTRIBUTE_UNUSED */
|
---|
256 |
|
---|
257 | #ifndef ATTRIBUTE_NORETURN
|
---|
258 | #define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
---|
259 | #endif /* ATTRIBUTE_NORETURN */
|
---|
260 |
|
---|
261 | #ifndef ATTRIBUTE_PRINTF
|
---|
262 | #define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
|
---|
263 | #define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
|
---|
264 | #endif /* ATTRIBUTE_PRINTF */
|
---|
265 |
|
---|
266 | /* We use __extension__ in some places to suppress -pedantic warnings
|
---|
267 | about GCC extensions. This feature didn't work properly before
|
---|
268 | gcc 2.8. */
|
---|
269 | #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
|
---|
270 | #define __extension__
|
---|
271 | #endif
|
---|
272 |
|
---|
273 | /* this is defined by Windows32 extension libraries. It must be added to
|
---|
274 | * every variable which is exported (including function pointers) */
|
---|
275 | #if defined(WIN32_EXTENSION) && !defined(ATTRIBUTE_EXPORTED)
|
---|
276 | # define ATTRIBUTE_EXPORTED __declspec(dllimport)
|
---|
277 | #else
|
---|
278 | # define ATTRIBUTE_EXPORTED
|
---|
279 | #endif
|
---|
280 |
|
---|
281 |
|
---|
282 | /* ------------------ Constants, Structures, Typedefs ------------------ */
|
---|
283 |
|
---|
284 | #if 0
|
---|
285 | /* This isn't right. Figure it out the right way for the next release */
|
---|
286 | #ifndef AWKNUM
|
---|
287 | #ifdef LDBL_MANT_DIG
|
---|
288 | #define AWKNUM long double
|
---|
289 | #else
|
---|
290 | #endif
|
---|
291 | #endif
|
---|
292 | #endif
|
---|
293 |
|
---|
294 | #define AWKNUM double
|
---|
295 |
|
---|
296 | #ifndef TRUE
|
---|
297 | /* a bit hackneyed, but what the heck */
|
---|
298 | #define TRUE 1
|
---|
299 | #define FALSE 0
|
---|
300 | #endif
|
---|
301 |
|
---|
302 | #define LINT_INVALID 1 /* only warn about invalid */
|
---|
303 | #define LINT_ALL 2 /* warn about all things */
|
---|
304 |
|
---|
305 | /* Figure out what '\a' really is. */
|
---|
306 | #ifdef __STDC__
|
---|
307 | #define BELL '\a' /* sure makes life easy, don't it? */
|
---|
308 | #else
|
---|
309 | # if 'z' - 'a' == 25 /* ascii */
|
---|
310 | # if 'a' != 97 /* machine is dumb enough to use mark parity */
|
---|
311 | # define BELL '\207'
|
---|
312 | # else
|
---|
313 | # define BELL '\07'
|
---|
314 | # endif
|
---|
315 | # else
|
---|
316 | # define BELL '\057'
|
---|
317 | # endif
|
---|
318 | #endif
|
---|
319 |
|
---|
320 | typedef enum nodevals {
|
---|
321 | /* illegal entry == 0 */
|
---|
322 | Node_illegal,
|
---|
323 |
|
---|
324 | /* binary operators lnode and rnode are the expressions to work on */
|
---|
325 | Node_times,
|
---|
326 | Node_quotient,
|
---|
327 | Node_mod,
|
---|
328 | Node_plus,
|
---|
329 | Node_minus,
|
---|
330 | Node_cond_pair, /* conditional pair (see Node_line_range) */
|
---|
331 | Node_subscript,
|
---|
332 | Node_concat,
|
---|
333 | Node_exp,
|
---|
334 |
|
---|
335 | /* unary operators subnode is the expression to work on */
|
---|
336 | Node_preincrement,
|
---|
337 | Node_predecrement,
|
---|
338 | Node_postincrement,
|
---|
339 | Node_postdecrement,
|
---|
340 | Node_unary_minus,
|
---|
341 | Node_field_spec,
|
---|
342 |
|
---|
343 | /* assignments lnode is the var to assign to, rnode is the exp */
|
---|
344 | Node_assign,
|
---|
345 | Node_assign_times,
|
---|
346 | Node_assign_quotient,
|
---|
347 | Node_assign_mod,
|
---|
348 | Node_assign_plus,
|
---|
349 | Node_assign_minus,
|
---|
350 | Node_assign_exp,
|
---|
351 | Node_assign_concat,
|
---|
352 |
|
---|
353 | /* boolean binaries lnode and rnode are expressions */
|
---|
354 | Node_and,
|
---|
355 | Node_or,
|
---|
356 |
|
---|
357 | /* binary relationals compares lnode and rnode */
|
---|
358 | Node_equal,
|
---|
359 | Node_notequal,
|
---|
360 | Node_less,
|
---|
361 | Node_greater,
|
---|
362 | Node_leq,
|
---|
363 | Node_geq,
|
---|
364 | Node_match,
|
---|
365 | Node_nomatch,
|
---|
366 |
|
---|
367 | /* unary relationals works on subnode */
|
---|
368 | Node_not,
|
---|
369 |
|
---|
370 | /* program structures */
|
---|
371 | Node_rule_list, /* lnode is a rule, rnode is rest of list */
|
---|
372 | Node_rule_node, /* lnode is pattern, rnode is statement */
|
---|
373 | Node_statement_list, /* lnode is statement, rnode is more list */
|
---|
374 | Node_switch_body, /* lnode is the case list, rnode is default list */
|
---|
375 | Node_case_list, /* lnode is the case, rnode is a statement list */
|
---|
376 | Node_if_branches, /* lnode is to run on true, rnode on false */
|
---|
377 | Node_expression_list, /* lnode is an exp, rnode is more list */
|
---|
378 | Node_param_list, /* lnode is a variable, rnode is more list */
|
---|
379 |
|
---|
380 | /* keywords */
|
---|
381 | Node_K_if, /* lnode is conditonal, rnode is if_branches */
|
---|
382 | Node_K_switch, /* lnode is switch value, rnode is body of case statements */
|
---|
383 | Node_K_case, /* lnode is case value, rnode is stuff to run */
|
---|
384 | Node_K_default, /* lnode is empty, rnode is stuff to run */
|
---|
385 | Node_K_while, /* lnode is condtional, rnode is stuff to run */
|
---|
386 | Node_K_for, /* lnode is for_struct, rnode is stuff to run */
|
---|
387 | Node_K_arrayfor, /* lnode is for_struct, rnode is stuff to run */
|
---|
388 | Node_K_break, /* no subs */
|
---|
389 | Node_K_continue, /* no subs */
|
---|
390 | Node_K_print, /* lnode is exp_list, rnode is redirect */
|
---|
391 | Node_K_print_rec, /* lnode is NULL, rnode is redirect */
|
---|
392 | Node_K_printf, /* lnode is exp_list, rnode is redirect */
|
---|
393 | Node_K_next, /* no subs */
|
---|
394 | Node_K_exit, /* subnode is return value, or NULL */
|
---|
395 | Node_K_do, /* lnode is conditional, rnode stuff to run */
|
---|
396 | Node_K_return, /* lnode is return value */
|
---|
397 | Node_K_delete, /* lnode is array, rnode is subscript */
|
---|
398 | Node_K_delete_loop, /* lnode is array, rnode is subscript */
|
---|
399 | Node_K_getline, /* lnode is opt var, rnode is redirection */
|
---|
400 | Node_K_function, /* lnode is statement list, rnode is params */
|
---|
401 | Node_K_nextfile, /* no subs */
|
---|
402 |
|
---|
403 | /* I/O redirection for print statements */
|
---|
404 | Node_redirect_output, /* subnode is where to redirect */
|
---|
405 | Node_redirect_append, /* subnode is where to redirect */
|
---|
406 | Node_redirect_pipe, /* subnode is where to redirect */
|
---|
407 | Node_redirect_pipein, /* subnode is where to redirect */
|
---|
408 | Node_redirect_input, /* subnode is where to redirect */
|
---|
409 | Node_redirect_twoway, /* subnode is where to redirect */
|
---|
410 |
|
---|
411 | /* Variables */
|
---|
412 | Node_var_new, /* newly created variable, may become an array */
|
---|
413 | Node_var, /* scalar variable, lnode is value */
|
---|
414 | Node_var_array, /* array is ptr to elements, table_size num of eles */
|
---|
415 | Node_val, /* node is a value - type in flags */
|
---|
416 |
|
---|
417 | /* Builtins subnode is explist to work on, builtin is func to call */
|
---|
418 | Node_builtin,
|
---|
419 |
|
---|
420 | /*
|
---|
421 | * pattern: conditional ',' conditional ; lnode of Node_line_range
|
---|
422 | * is the two conditionals (Node_cond_pair), other word (rnode place)
|
---|
423 | * is a flag indicating whether or not this range has been entered.
|
---|
424 | */
|
---|
425 | Node_line_range,
|
---|
426 |
|
---|
427 | /*
|
---|
428 | * boolean test of membership in array
|
---|
429 | * lnode is string-valued, expression rnode is array name
|
---|
430 | */
|
---|
431 | Node_in_array,
|
---|
432 |
|
---|
433 | Node_func, /* lnode is param. list, rnode is body */
|
---|
434 | Node_func_call, /* lnode is name, rnode is argument list */
|
---|
435 |
|
---|
436 | Node_cond_exp, /* lnode is conditonal, rnode is if_branches */
|
---|
437 | Node_regex, /* a regexp, text, compiled, flags, etc */
|
---|
438 | Node_dynregex, /* a dynamic regexp */
|
---|
439 | Node_hashnode, /* an identifier in the symbol table */
|
---|
440 | Node_ahash, /* an array element */
|
---|
441 | Node_array_ref, /* array passed by ref as parameter */
|
---|
442 |
|
---|
443 | Node_BINMODE, /* variables recognized in the grammar */
|
---|
444 | Node_CONVFMT,
|
---|
445 | Node_FIELDWIDTHS,
|
---|
446 | Node_FNR,
|
---|
447 | Node_FS,
|
---|
448 | Node_IGNORECASE,
|
---|
449 | Node_LINT,
|
---|
450 | Node_NF,
|
---|
451 | Node_NR,
|
---|
452 | Node_OFMT,
|
---|
453 | Node_OFS,
|
---|
454 | Node_ORS,
|
---|
455 | Node_RS,
|
---|
456 | Node_TEXTDOMAIN,
|
---|
457 | Node_SUBSEP,
|
---|
458 | Node_final /* sentry value, not legal */
|
---|
459 | } NODETYPE;
|
---|
460 |
|
---|
461 | /*
|
---|
462 | * NOTE - this struct is a rather kludgey -- it is packed to minimize
|
---|
463 | * space usage, at the expense of cleanliness. Alter at own risk.
|
---|
464 | */
|
---|
465 | typedef struct exp_node {
|
---|
466 | union {
|
---|
467 | struct {
|
---|
468 | union {
|
---|
469 | struct exp_node *lptr;
|
---|
470 | char *param_name;
|
---|
471 | long ll;
|
---|
472 | } l;
|
---|
473 | union {
|
---|
474 | struct exp_node *rptr;
|
---|
475 | struct exp_node *(*pptr) P((struct exp_node *));
|
---|
476 | Regexp *preg;
|
---|
477 | struct for_loop_header *hd;
|
---|
478 | struct exp_node **av;
|
---|
479 | int r_ent; /* range entered */
|
---|
480 | } r;
|
---|
481 | union {
|
---|
482 | struct exp_node *extra;
|
---|
483 | long xl;
|
---|
484 | char **param_list;
|
---|
485 | } x;
|
---|
486 | char *name;
|
---|
487 | short number;
|
---|
488 | unsigned long reflags;
|
---|
489 | # define CASE 1
|
---|
490 | # define CONST 2
|
---|
491 | # define FS_DFLT 4
|
---|
492 | } nodep;
|
---|
493 | struct {
|
---|
494 | AWKNUM fltnum; /* this is here for optimal packing of
|
---|
495 | * the structure on many machines
|
---|
496 | */
|
---|
497 | char *sp;
|
---|
498 | size_t slen;
|
---|
499 | long sref;
|
---|
500 | int idx;
|
---|
501 | #ifdef MBS_SUPPORT
|
---|
502 | wchar_t *wsp;
|
---|
503 | size_t wslen;
|
---|
504 | #endif
|
---|
505 | } val;
|
---|
506 | struct {
|
---|
507 | struct exp_node *next;
|
---|
508 | char *name;
|
---|
509 | size_t length;
|
---|
510 | struct exp_node *value;
|
---|
511 | long ref;
|
---|
512 | } hash;
|
---|
513 | #define hnext sub.hash.next
|
---|
514 | #define hname sub.hash.name
|
---|
515 | #define hlength sub.hash.length
|
---|
516 | #define hvalue sub.hash.value
|
---|
517 |
|
---|
518 | #define ahnext sub.hash.next
|
---|
519 | #define ahname_str sub.hash.name
|
---|
520 | #define ahname_len sub.hash.length
|
---|
521 | #define ahvalue sub.hash.value
|
---|
522 | #define ahname_ref sub.hash.ref
|
---|
523 | } sub;
|
---|
524 | NODETYPE type;
|
---|
525 | unsigned short flags;
|
---|
526 | # define MALLOC 1 /* can be free'd */
|
---|
527 | # define TEMP 2 /* should be free'd */
|
---|
528 | # define PERM 4 /* can't be free'd */
|
---|
529 | # define STRING 8 /* assigned as string */
|
---|
530 | # define STRCUR 16 /* string value is current */
|
---|
531 | # define NUMCUR 32 /* numeric value is current */
|
---|
532 | # define NUMBER 64 /* assigned as number */
|
---|
533 | # define MAYBE_NUM 128 /* user input: if NUMERIC then
|
---|
534 | * a NUMBER */
|
---|
535 | # define ARRAYMAXED 256 /* array is at max size */
|
---|
536 | # define FUNC 512 /* this parameter is really a
|
---|
537 | * function name; see awkgram.y */
|
---|
538 | # define FIELD 1024 /* this is a field */
|
---|
539 | # define INTLSTR 2048 /* use localized version */
|
---|
540 | #ifdef MBS_SUPPORT
|
---|
541 | # define WSTRCUR 4096 /* wide str value is current */
|
---|
542 | #endif
|
---|
543 | } NODE;
|
---|
544 |
|
---|
545 | #define vname sub.nodep.name
|
---|
546 | #define exec_count sub.nodep.reflags
|
---|
547 |
|
---|
548 | #define lnode sub.nodep.l.lptr
|
---|
549 | #define nextp sub.nodep.l.lptr
|
---|
550 | #define rnode sub.nodep.r.rptr
|
---|
551 | #define source_file sub.nodep.name
|
---|
552 | #define source_line sub.nodep.number
|
---|
553 | #define param_cnt sub.nodep.number
|
---|
554 | #define param sub.nodep.l.param_name
|
---|
555 | #define parmlist sub.nodep.x.param_list
|
---|
556 |
|
---|
557 | #define subnode lnode
|
---|
558 | #define builtin sub.nodep.r.pptr
|
---|
559 | #define callresult sub.nodep.x.extra
|
---|
560 | #define funcbody sub.nodep.x.extra
|
---|
561 |
|
---|
562 | #define re_reg sub.nodep.r.preg
|
---|
563 | #define re_flags sub.nodep.reflags
|
---|
564 | #define re_text lnode
|
---|
565 | #define re_exp sub.nodep.x.extra
|
---|
566 | #define re_cnt sub.nodep.number
|
---|
567 |
|
---|
568 | #define forloop rnode->sub.nodep.r.hd
|
---|
569 |
|
---|
570 | #define stptr sub.val.sp
|
---|
571 | #define stlen sub.val.slen
|
---|
572 | #define stref sub.val.sref
|
---|
573 | #define stfmt sub.val.idx
|
---|
574 |
|
---|
575 | #define wstptr sub.val.wsp
|
---|
576 | #define wstlen sub.val.wslen
|
---|
577 |
|
---|
578 | #define numbr sub.val.fltnum
|
---|
579 |
|
---|
580 | /* Node_var: */
|
---|
581 | #define var_value lnode
|
---|
582 |
|
---|
583 | /* Node_var_array: */
|
---|
584 | #define var_array sub.nodep.r.av
|
---|
585 | #define array_size sub.nodep.l.ll
|
---|
586 | #define table_size sub.nodep.x.xl
|
---|
587 |
|
---|
588 | /* Node_array_ref: */
|
---|
589 | #define orig_array sub.nodep.x.extra
|
---|
590 | #define prev_array rnode
|
---|
591 |
|
---|
592 | #define printf_count sub.nodep.x.xl
|
---|
593 |
|
---|
594 | #define condpair lnode
|
---|
595 | #define triggered sub.nodep.r.r_ent
|
---|
596 |
|
---|
597 | /* a regular for loop */
|
---|
598 | typedef struct for_loop_header {
|
---|
599 | NODE *init;
|
---|
600 | NODE *cond;
|
---|
601 | NODE *incr;
|
---|
602 | } FOR_LOOP_HEADER;
|
---|
603 |
|
---|
604 | typedef struct iobuf {
|
---|
605 | const char *name; /* filename */
|
---|
606 | int fd; /* file descriptor */
|
---|
607 | struct stat sbuf; /* stat buf */
|
---|
608 | char *buf; /* start data buffer */
|
---|
609 | char *off; /* start of current record in buffer */
|
---|
610 | char *dataend; /* first byte in buffer to hold new data,
|
---|
611 | NULL if not read yet */
|
---|
612 | char *end; /* end of buffer */
|
---|
613 | size_t readsize; /* set from fstat call */
|
---|
614 | size_t size; /* buffer size */
|
---|
615 | ssize_t count; /* amount read last time */
|
---|
616 | size_t scanoff; /* where we were in the buffer when we had
|
---|
617 | to regrow/refill */
|
---|
618 |
|
---|
619 | void *opaque; /* private data for open hooks */
|
---|
620 | int (*get_record) P((char **out, struct iobuf *, int *errcode));
|
---|
621 | void (*close_func) P((struct iobuf *)); /* open and close hooks */
|
---|
622 |
|
---|
623 | int flag;
|
---|
624 | # define IOP_IS_TTY 1
|
---|
625 | # define IOP_IS_INTERNAL 2
|
---|
626 | # define IOP_NO_FREE 4
|
---|
627 | # define IOP_NOFREE_OBJ 8
|
---|
628 | # define IOP_AT_EOF 16
|
---|
629 | # define IOP_CLOSED 32
|
---|
630 | # define IOP_AT_START 64
|
---|
631 | } IOBUF;
|
---|
632 |
|
---|
633 | typedef void (*Func_ptr) P((void));
|
---|
634 |
|
---|
635 | /* structure used to dynamically maintain a linked-list of open files/pipes */
|
---|
636 | struct redirect {
|
---|
637 | unsigned int flag;
|
---|
638 | # define RED_FILE 1
|
---|
639 | # define RED_PIPE 2
|
---|
640 | # define RED_READ 4
|
---|
641 | # define RED_WRITE 8
|
---|
642 | # define RED_APPEND 16
|
---|
643 | # define RED_NOBUF 32
|
---|
644 | # define RED_USED 64 /* closed temporarily to reuse fd */
|
---|
645 | # define RED_EOF 128
|
---|
646 | # define RED_TWOWAY 256
|
---|
647 | # define RED_PTY 512
|
---|
648 | # define RED_SOCKET 1024
|
---|
649 | # define RED_TCP 2048
|
---|
650 | char *value;
|
---|
651 | FILE *fp;
|
---|
652 | FILE *ifp; /* input fp, needed for PIPES_SIMULATED */
|
---|
653 | IOBUF *iop;
|
---|
654 | int pid;
|
---|
655 | int status;
|
---|
656 | struct redirect *prev;
|
---|
657 | struct redirect *next;
|
---|
658 | const char *mode;
|
---|
659 | };
|
---|
660 |
|
---|
661 | /*
|
---|
662 | * structure for our source, either a command line string or a source file.
|
---|
663 | * the same structure is used to remember variable pre-assignments.
|
---|
664 | */
|
---|
665 | struct src {
|
---|
666 | enum srctype { CMDLINE = 1, SOURCEFILE,
|
---|
667 | PRE_ASSIGN, PRE_ASSIGN_FS } stype;
|
---|
668 | char *val;
|
---|
669 | };
|
---|
670 |
|
---|
671 | /* for debugging purposes */
|
---|
672 | struct flagtab {
|
---|
673 | int val;
|
---|
674 | const char *name;
|
---|
675 | };
|
---|
676 |
|
---|
677 | /* longjmp return codes, must be nonzero */
|
---|
678 | /* Continue means either for loop/while continue, or next input record */
|
---|
679 | #define TAG_CONTINUE 1
|
---|
680 | /* Break means either for/while break, or stop reading input */
|
---|
681 | #define TAG_BREAK 2
|
---|
682 | /* Return means return from a function call; leave value in ret_node */
|
---|
683 | #define TAG_RETURN 3
|
---|
684 |
|
---|
685 | #ifndef LONG_MAX
|
---|
686 | #define LONG_MAX ((long)(~(1L << (sizeof (long) * 8 - 1))))
|
---|
687 | #endif
|
---|
688 | #ifndef ULONG_MAX
|
---|
689 | #define ULONG_MAX (~(unsigned long)0)
|
---|
690 | #endif
|
---|
691 | #ifndef LONG_MIN
|
---|
692 | #define LONG_MIN ((long)(-LONG_MAX - 1L))
|
---|
693 | #endif
|
---|
694 | #define UNLIMITED LONG_MAX
|
---|
695 |
|
---|
696 | /* -------------------------- External variables -------------------------- */
|
---|
697 | /* gawk builtin variables */
|
---|
698 | extern long NF;
|
---|
699 | extern long NR;
|
---|
700 | extern long FNR;
|
---|
701 | extern int BINMODE;
|
---|
702 | extern int IGNORECASE;
|
---|
703 | extern int RS_is_null;
|
---|
704 | extern char *OFS;
|
---|
705 | extern int OFSlen;
|
---|
706 | extern char *ORS;
|
---|
707 | extern int ORSlen;
|
---|
708 | extern char *OFMT;
|
---|
709 | extern char *CONVFMT;
|
---|
710 | ATTRIBUTE_EXPORTED extern int CONVFMTidx;
|
---|
711 | extern int OFMTidx;
|
---|
712 | extern char *TEXTDOMAIN;
|
---|
713 | extern NODE *BINMODE_node, *CONVFMT_node, *FIELDWIDTHS_node, *FILENAME_node;
|
---|
714 | extern NODE *FNR_node, *FS_node, *IGNORECASE_node, *NF_node;
|
---|
715 | extern NODE *NR_node, *OFMT_node, *OFS_node, *ORS_node, *RLENGTH_node;
|
---|
716 | extern NODE *RSTART_node, *RS_node, *RT_node, *SUBSEP_node, *PROCINFO_node;
|
---|
717 | extern NODE *LINT_node, *ERRNO_node, *TEXTDOMAIN_node;
|
---|
718 | ATTRIBUTE_EXPORTED extern NODE **stack_ptr;
|
---|
719 | extern NODE *Nnull_string;
|
---|
720 | extern NODE *Null_field;
|
---|
721 | extern NODE **fields_arr;
|
---|
722 | extern int sourceline;
|
---|
723 | extern char *source;
|
---|
724 | extern NODE *expression_value;
|
---|
725 |
|
---|
726 | #if __GNUC__ < 2
|
---|
727 | # if defined(WIN32_EXTENSION)
|
---|
728 | static
|
---|
729 | # else
|
---|
730 | extern
|
---|
731 | #endif
|
---|
732 | NODE *_t; /* used as temporary in tree_eval */
|
---|
733 | #endif
|
---|
734 |
|
---|
735 | extern NODE *nextfree;
|
---|
736 | extern int field0_valid;
|
---|
737 | extern int do_traditional;
|
---|
738 | extern int do_posix;
|
---|
739 | extern int do_intervals;
|
---|
740 | extern int do_intl;
|
---|
741 | extern int do_non_decimal_data;
|
---|
742 | extern int do_dump_vars;
|
---|
743 | extern int do_tidy_mem;
|
---|
744 | extern int in_begin_rule;
|
---|
745 | extern int in_end_rule;
|
---|
746 | extern int whiny_users;
|
---|
747 | #ifdef NO_LINT
|
---|
748 | #define do_lint 0
|
---|
749 | #define do_lint_old 0
|
---|
750 | #else
|
---|
751 | ATTRIBUTE_EXPORTED extern int do_lint;
|
---|
752 | extern int do_lint_old;
|
---|
753 | #endif
|
---|
754 | #ifdef MBS_SUPPORT
|
---|
755 | extern int gawk_mb_cur_max;
|
---|
756 | #else
|
---|
757 | extern const int gawk_mb_cur_max;
|
---|
758 | #endif
|
---|
759 |
|
---|
760 | #if defined (HAVE_GETGROUPS) && defined(NGROUPS_MAX) && NGROUPS_MAX > 0
|
---|
761 | extern GETGROUPS_T *groupset;
|
---|
762 | extern int ngroups;
|
---|
763 | #endif
|
---|
764 |
|
---|
765 | #ifdef HAVE_LOCALE_H
|
---|
766 | extern struct lconv loc;
|
---|
767 | #endif /* HAVE_LOCALE_H */
|
---|
768 |
|
---|
769 | extern const char *myname;
|
---|
770 |
|
---|
771 | extern char quote;
|
---|
772 | extern char *defpath;
|
---|
773 | extern char envsep;
|
---|
774 |
|
---|
775 | extern char casetable[]; /* for case-independent regexp matching */
|
---|
776 |
|
---|
777 | /* ------------------------- Pseudo-functions ------------------------- */
|
---|
778 |
|
---|
779 | #define is_identchar(c) (isalnum(c) || (c) == '_')
|
---|
780 |
|
---|
781 | #define var_uninitialized(n) ((n)->var_value == Nnull_string)
|
---|
782 |
|
---|
783 | #ifdef MPROF
|
---|
784 | #define getnode(n) emalloc((n), NODE *, sizeof(NODE), "getnode"), (n)->flags = 0, (n)-exec_count = 0;
|
---|
785 | #define freenode(n) free(n)
|
---|
786 | #else /* not MPROF */
|
---|
787 | #define getnode(n) if (nextfree) n = nextfree, nextfree = nextfree->nextp;\
|
---|
788 | else n = more_nodes()
|
---|
789 | #ifndef NO_PROFILING
|
---|
790 | #define freenode(n) ((n)->flags = 0,\
|
---|
791 | (n)->exec_count = 0, (n)->nextp = nextfree, nextfree = (n))
|
---|
792 | #else /* not PROFILING */
|
---|
793 | #define freenode(n) ((n)->flags = 0,\
|
---|
794 | (n)->nextp = nextfree, nextfree = (n))
|
---|
795 | #endif /* not PROFILING */
|
---|
796 | #endif /* not MPROF */
|
---|
797 |
|
---|
798 | #ifndef GAWKDEBUG
|
---|
799 | #define DUPNODE_MACRO 1
|
---|
800 | /*
|
---|
801 | * Speed up the path leading to r_dupnode, as well as duplicating TEMP nodes,
|
---|
802 | * on expense of slowing down the access to PERM nodes (by two instructions).
|
---|
803 | * This is right since PERM nodes are realtively rare.
|
---|
804 | *
|
---|
805 | * The code also sets MALLOC flag for PERM nodes, which should not matter.
|
---|
806 | */
|
---|
807 | #define DUPNODE_COMMON (_t->flags & (TEMP|PERM)) != 0 ? \
|
---|
808 | (_t->flags &= ~TEMP, _t->flags |= MALLOC, _t) : \
|
---|
809 | r_dupnode(_t)
|
---|
810 | #if __GNUC__ >= 2
|
---|
811 | #define dupnode(n) ({NODE * _t = (n); DUPNODE_COMMON;})
|
---|
812 | #else
|
---|
813 | #define dupnode(n) (_t = (n), DUPNODE_COMMON)
|
---|
814 | #endif
|
---|
815 | #else /* GAWKDEBUG */
|
---|
816 | #define dupnode(n) r_dupnode(n)
|
---|
817 | #endif /* GAWKDEBUG */
|
---|
818 |
|
---|
819 | #define get_array(t) get_actual(t, TRUE) /* allowed to die fatally */
|
---|
820 | #define get_param(t) get_actual(t, FALSE) /* not allowed */
|
---|
821 |
|
---|
822 | #ifdef MEMDEBUG
|
---|
823 | #undef freenode
|
---|
824 | #define get_lhs(p, a, r) r_get_lhs((p), (a), (r))
|
---|
825 | #define m_tree_eval(t, iscond) r_tree_eval(t, iscond)
|
---|
826 | #else
|
---|
827 | #define get_lhs(p, a, r) ((p)->type == Node_var && \
|
---|
828 | ! var_uninitialized(p) ? \
|
---|
829 | (&(p)->var_value) : \
|
---|
830 | r_get_lhs((p), (a), (r)))
|
---|
831 | #define TREE_EVAL_MACRO 1
|
---|
832 | #if __GNUC__ >= 2
|
---|
833 | #define m_tree_eval(t, iscond) __extension__ \
|
---|
834 | ({NODE * _t = (t); \
|
---|
835 | if (_t == (NODE*)NULL) \
|
---|
836 | cant_happen(); \
|
---|
837 | switch(_t->type) { \
|
---|
838 | case Node_val: \
|
---|
839 | if (_t->flags&INTLSTR) \
|
---|
840 | _t = r_force_string(_t); \
|
---|
841 | break; \
|
---|
842 | case Node_var: \
|
---|
843 | if (! var_uninitialized(_t)) { \
|
---|
844 | _t = _t->var_value; \
|
---|
845 | break; \
|
---|
846 | } \
|
---|
847 | /*FALLTHROUGH*/ \
|
---|
848 | default: \
|
---|
849 | _t = r_tree_eval(_t, iscond);\
|
---|
850 | break; \
|
---|
851 | } \
|
---|
852 | _t;})
|
---|
853 | #else
|
---|
854 | #define m_tree_eval(t, iscond) (_t = (t), _t == (NODE*)NULL ? (cant_happen(), (NODE*)NULL) : \
|
---|
855 | (_t->type == Node_param_list ? \
|
---|
856 | r_tree_eval(_t, iscond) : \
|
---|
857 | ((_t->type == Node_val && (_t->flags&INTLSTR)) ? \
|
---|
858 | r_force_string(_t) : \
|
---|
859 | (_t->type == Node_val ? _t : \
|
---|
860 | (_t->type == Node_var && \
|
---|
861 | ! var_uninitialized(_t) ? _t->var_value : \
|
---|
862 | r_tree_eval(_t, iscond))))))
|
---|
863 | #endif /* __GNUC__ */
|
---|
864 | #endif /* not MEMDEBUG */
|
---|
865 | #define tree_eval(t) m_tree_eval(t, FALSE)
|
---|
866 |
|
---|
867 | #define make_number(x) mk_number((x), (unsigned int)(MALLOC|NUMCUR|NUMBER))
|
---|
868 | #define tmp_number(x) mk_number((x), (unsigned int)(MALLOC|TEMP|NUMCUR|NUMBER))
|
---|
869 |
|
---|
870 | #define free_temp(n) do { NODE *_n = (n); if (_n->flags&TEMP) unref(_n);} \
|
---|
871 | while (FALSE)
|
---|
872 |
|
---|
873 | #define make_string(s, l) make_str_node((s), (size_t) (l), 0)
|
---|
874 | #define SCAN 1
|
---|
875 | #define ALREADY_MALLOCED 2
|
---|
876 |
|
---|
877 | #define cant_happen() r_fatal("internal error line %d, file: %s", \
|
---|
878 | __LINE__, __FILE__)
|
---|
879 |
|
---|
880 | /*
|
---|
881 | * For SunOS 4.1.x which is pre-Standard C, `realloc' doesn't
|
---|
882 | * accept NULL. Sigh. The check must be done for both cases,
|
---|
883 | * since could be using GCC but with stock C library. Sigh, again.
|
---|
884 | */
|
---|
885 | #ifdef HAVE_STRINGIZE
|
---|
886 | #define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
|
---|
887 | (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
|
---|
888 | (str), #var, (long) (x), strerror(errno)),0))
|
---|
889 | #define erealloc(var,ty,x,str) (void)((var = ((var == NULL) \
|
---|
890 | ? (ty)malloc((MALLOC_ARG_T)(x)) \
|
---|
891 | : (ty)realloc((char *)var, (MALLOC_ARG_T)(x))) ) \
|
---|
892 | ||\
|
---|
893 | (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
|
---|
894 | (str), #var, (long) (x), strerror(errno)),0))
|
---|
895 | #else /* HAVE_STRINGIZE */
|
---|
896 | #define emalloc(var,ty,x,str) (void)((var=(ty)malloc((MALLOC_ARG_T)(x))) ||\
|
---|
897 | (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
|
---|
898 | (str), "var", (long) (x), strerror(errno)),0))
|
---|
899 | #define erealloc(var,ty,x,str) (void)((var = ((var == NULL) \
|
---|
900 | ? (ty)malloc((MALLOC_ARG_T)(x)) \
|
---|
901 | : (ty)realloc((char *)var, (MALLOC_ARG_T)(x))) ) \
|
---|
902 | ||\
|
---|
903 | (fatal(_("%s: %s: can't allocate %ld bytes of memory (%s)"),\
|
---|
904 | (str), "var", (long) (x), strerror(errno)),0))
|
---|
905 | #endif /* HAVE_STRINGIZE */
|
---|
906 |
|
---|
907 | #ifdef GAWKDEBUG
|
---|
908 | #define force_number r_force_number
|
---|
909 | #define force_string r_force_string
|
---|
910 | #else /* not GAWKDEBUG */
|
---|
911 | #ifdef lint
|
---|
912 | extern AWKNUM force_number();
|
---|
913 | #endif
|
---|
914 | #if __GNUC__ >= 2
|
---|
915 | #define force_number(n) __extension__ ({NODE *_tn = (n);\
|
---|
916 | (_tn->flags & NUMCUR) ?_tn->numbr : r_force_number(_tn);})
|
---|
917 | #define force_string(s) __extension__ ({NODE *_ts = (s);\
|
---|
918 | ((_ts->flags & INTLSTR) ? \
|
---|
919 | r_force_string(_ts) : \
|
---|
920 | ((_ts->flags & STRCUR) && \
|
---|
921 | (_ts->stfmt == -1 || _ts->stfmt == CONVFMTidx)) ?\
|
---|
922 | _ts : r_force_string(_ts));})
|
---|
923 | #else
|
---|
924 | #ifdef MSDOS
|
---|
925 | extern double _msc51bug;
|
---|
926 | #define force_number(n) (_msc51bug=(_t = (n),\
|
---|
927 | (_t->flags & NUMCUR) ? _t->numbr : r_force_number(_t)))
|
---|
928 | #else /* not MSDOS */
|
---|
929 | #define force_number(n) (_t = (n),\
|
---|
930 | (_t->flags & NUMCUR) ? _t->numbr : r_force_number(_t))
|
---|
931 | #endif /* not MSDOS */
|
---|
932 | #define force_string(s) (_t = (s),(_t->flags & INTLSTR) ? \
|
---|
933 | r_force_string(_t) :\
|
---|
934 | ((_t->flags & STRCUR) && \
|
---|
935 | (_t->stfmt == -1 || \
|
---|
936 | _t->stfmt == CONVFMTidx))? \
|
---|
937 | _t : r_force_string(_t))
|
---|
938 |
|
---|
939 | #endif /* not __GNUC__ */
|
---|
940 | #endif /* not GAWKDEBUG */
|
---|
941 |
|
---|
942 | #define STREQ(a,b) (*(a) == *(b) && strcmp((a), (b)) == 0)
|
---|
943 | #define STREQN(a,b,n) ((n) && *(a)== *(b) && \
|
---|
944 | strncmp((a), (b), (size_t) (n)) == 0)
|
---|
945 |
|
---|
946 | #define fatal set_loc(__FILE__, __LINE__), r_fatal
|
---|
947 |
|
---|
948 | /* ------------- Function prototypes or defs (as appropriate) ------------- */
|
---|
949 |
|
---|
950 | /* array.c */
|
---|
951 | extern NODE *get_actual P((NODE *symbol, int canfatal));
|
---|
952 | extern char *array_vname P((const NODE *symbol));
|
---|
953 | extern void array_init P((void));
|
---|
954 | extern NODE *concat_exp P((NODE *tree));
|
---|
955 | extern void assoc_clear P((NODE *symbol));
|
---|
956 | extern NODE *in_array P((NODE *symbol, NODE *subs));
|
---|
957 | extern NODE **assoc_lookup P((NODE *symbol, NODE *subs, int reference));
|
---|
958 | extern void do_delete P((NODE *symbol, NODE *tree));
|
---|
959 | extern void do_delete_loop P((NODE *symbol, NODE *tree));
|
---|
960 | extern void set_SUBSEP P((void));
|
---|
961 | extern NODE *assoc_dump P((NODE *symbol));
|
---|
962 | extern NODE *do_adump P((NODE *tree));
|
---|
963 | extern NODE *do_asort P((NODE *tree));
|
---|
964 | extern NODE *do_asorti P((NODE *tree));
|
---|
965 | extern unsigned long (*hash)P((const char *s, size_t len, unsigned long hsize));
|
---|
966 | /* awkgram.c */
|
---|
967 | extern char *tokexpand P((void));
|
---|
968 | extern NODE *node P((NODE *left, NODETYPE op, NODE *right));
|
---|
969 | extern NODE *install P((char *name, NODE *value));
|
---|
970 | extern NODE *lookup P((const char *name));
|
---|
971 | extern NODE *variable P((char *name, int can_free, NODETYPE type));
|
---|
972 | extern int yyparse P((void));
|
---|
973 | extern void dump_funcs P((void));
|
---|
974 | extern void dump_vars P((const char *fname));
|
---|
975 | extern void release_all_vars P((void));
|
---|
976 | extern const char *getfname P((NODE *(*)(NODE *)));
|
---|
977 | extern NODE *stopme P((NODE *tree));
|
---|
978 | extern void shadow_funcs P((void));
|
---|
979 | extern int check_special P((const char *name));
|
---|
980 | extern void register_deferred_variable P((const char *name,
|
---|
981 | NODE *(*load_func)(void)));
|
---|
982 | /* builtin.c */
|
---|
983 | extern double double_to_int P((double d));
|
---|
984 | extern NODE *do_exp P((NODE *tree));
|
---|
985 | extern NODE *do_fflush P((NODE *tree));
|
---|
986 | extern NODE *do_index P((NODE *tree));
|
---|
987 | extern NODE *do_int P((NODE *tree));
|
---|
988 | extern NODE *do_length P((NODE *tree));
|
---|
989 | extern NODE *do_log P((NODE *tree));
|
---|
990 | extern NODE *do_mktime P((NODE *tree));
|
---|
991 | extern NODE *do_sprintf P((NODE *tree));
|
---|
992 | extern void do_printf P((NODE *tree));
|
---|
993 | extern void print_simple P((NODE *tree, FILE *fp));
|
---|
994 | extern NODE *do_sqrt P((NODE *tree));
|
---|
995 | extern NODE *do_substr P((NODE *tree));
|
---|
996 | extern NODE *do_strftime P((NODE *tree));
|
---|
997 | extern NODE *do_systime P((NODE *tree));
|
---|
998 | extern NODE *do_system P((NODE *tree));
|
---|
999 | extern void do_print P((NODE *tree));
|
---|
1000 | extern void do_print_rec P((NODE *tree));
|
---|
1001 | extern NODE *do_tolower P((NODE *tree));
|
---|
1002 | extern NODE *do_toupper P((NODE *tree));
|
---|
1003 | extern NODE *do_atan2 P((NODE *tree));
|
---|
1004 | extern NODE *do_sin P((NODE *tree));
|
---|
1005 | extern NODE *do_cos P((NODE *tree));
|
---|
1006 | extern NODE *do_rand P((NODE *tree));
|
---|
1007 | extern NODE *do_srand P((NODE *tree));
|
---|
1008 | extern NODE *do_match P((NODE *tree));
|
---|
1009 | extern NODE *do_gsub P((NODE *tree));
|
---|
1010 | extern NODE *do_sub P((NODE *tree));
|
---|
1011 | extern NODE *do_gensub P((NODE *tree));
|
---|
1012 | extern NODE *format_tree P((const char *, size_t, NODE *, long));
|
---|
1013 | extern NODE *do_lshift P((NODE *tree));
|
---|
1014 | extern NODE *do_rshift P((NODE *tree));
|
---|
1015 | extern NODE *do_and P((NODE *tree));
|
---|
1016 | extern NODE *do_or P((NODE *tree));
|
---|
1017 | extern NODE *do_xor P((NODE *tree));
|
---|
1018 | extern NODE *do_compl P((NODE *tree));
|
---|
1019 | extern NODE *do_strtonum P((NODE *tree));
|
---|
1020 | extern AWKNUM nondec2awknum P((char *str, size_t len));
|
---|
1021 | extern NODE *do_dcgettext P((NODE *tree));
|
---|
1022 | extern NODE *do_dcngettext P((NODE *tree));
|
---|
1023 | extern NODE *do_bindtextdomain P((NODE *tree));
|
---|
1024 | #ifdef MBS_SUPPORT
|
---|
1025 | extern int strncasecmpmbs P((const char *, mbstate_t, const char *,
|
---|
1026 | mbstate_t, size_t));
|
---|
1027 | #endif
|
---|
1028 | /* eval.c */
|
---|
1029 | extern int interpret P((NODE *volatile tree));
|
---|
1030 | extern NODE *r_tree_eval P((NODE *tree, int iscond));
|
---|
1031 | extern int cmp_nodes P((NODE *t1, NODE *t2));
|
---|
1032 | extern NODE **r_get_lhs P((NODE *ptr, Func_ptr *assign, int reference));
|
---|
1033 | extern void set_IGNORECASE P((void));
|
---|
1034 | extern void set_OFS P((void));
|
---|
1035 | extern void set_ORS P((void));
|
---|
1036 | extern void set_OFMT P((void));
|
---|
1037 | extern void set_CONVFMT P((void));
|
---|
1038 | extern void set_BINMODE P((void));
|
---|
1039 | extern void set_LINT P((void));
|
---|
1040 | extern void set_TEXTDOMAIN P((void));
|
---|
1041 | extern void update_ERRNO P((void));
|
---|
1042 | extern void update_ERRNO_saved P((int));
|
---|
1043 | extern const char *redflags2str P((int));
|
---|
1044 | extern const char *flags2str P((int));
|
---|
1045 | extern const char *genflags2str P((int flagval, const struct flagtab *tab));
|
---|
1046 | extern const char *nodetype2str P((NODETYPE type));
|
---|
1047 | extern NODE *assign_val P((NODE **lhs_p, NODE *rhs));
|
---|
1048 | extern void load_casetable P((void));
|
---|
1049 | extern size_t get_curfunc_arg_count P((void));
|
---|
1050 | #ifdef PROFILING
|
---|
1051 | extern void dump_fcall_stack P((FILE *fp));
|
---|
1052 | #endif
|
---|
1053 | /* ext.c */
|
---|
1054 | NODE *do_ext P((NODE *));
|
---|
1055 | #ifdef DYNAMIC
|
---|
1056 | void make_builtin P((char *, NODE *(*)(NODE *), int));
|
---|
1057 | NODE *get_argument P((NODE *, int));
|
---|
1058 | NODE *get_actual_argument P((NODE *, unsigned int, int, int));
|
---|
1059 | #define get_scalar_argument(t, i, opt) get_actual_argument((t), (i), (opt), FALSE)
|
---|
1060 | #define get_array_argument(t, i, opt) get_actual_argument((t), (i), (opt), TRUE)
|
---|
1061 | void set_value P((NODE *));
|
---|
1062 | #endif
|
---|
1063 | /* field.c */
|
---|
1064 | extern void init_fields P((void));
|
---|
1065 | extern void set_record P((const char *buf, int cnt));
|
---|
1066 | extern void reset_record P((void));
|
---|
1067 | extern void set_NF P((void));
|
---|
1068 | extern NODE **get_field P((long num, Func_ptr *assign));
|
---|
1069 | extern NODE *do_split P((NODE *tree));
|
---|
1070 | extern void set_FS P((void));
|
---|
1071 | extern void set_RS P((void));
|
---|
1072 | extern void set_FIELDWIDTHS P((void));
|
---|
1073 | extern int using_fieldwidths P((void));
|
---|
1074 | /* gawkmisc.c */
|
---|
1075 | extern char *gawk_name P((const char *filespec));
|
---|
1076 | extern void os_arg_fixup P((int *argcp, char ***argvp));
|
---|
1077 | extern int os_devopen P((const char *name, int flag));
|
---|
1078 | extern void os_close_on_exec P((int fd, const char *name, const char *what,
|
---|
1079 | const char *dir));
|
---|
1080 | extern int os_isdir P((int fd));
|
---|
1081 | extern int os_is_setuid P((void));
|
---|
1082 | extern int os_setbinmode P((int fd, int mode));
|
---|
1083 | extern void os_restore_mode P((int fd));
|
---|
1084 | extern size_t optimal_bufsize P((int fd, struct stat *sbuf));
|
---|
1085 | extern int ispath P((const char *file));
|
---|
1086 | extern int isdirpunct P((int c));
|
---|
1087 | #if defined(_MSC_VER) && !defined(_WIN32)
|
---|
1088 | extern char *memcpy_ulong P((char *dest, const char *src, unsigned long l));
|
---|
1089 | extern void *memset_ulong P((void *dest, int val, unsigned long l));
|
---|
1090 | #define memcpy memcpy_ulong
|
---|
1091 | #define memset memset_ulong
|
---|
1092 | #endif
|
---|
1093 | /* io.c */
|
---|
1094 | extern void register_open_hook P((void *(*open_func)(IOBUF *)));
|
---|
1095 | extern void set_FNR P((void));
|
---|
1096 | extern void set_NR P((void));
|
---|
1097 | extern void do_input P((void));
|
---|
1098 | extern struct redirect *redirect P((NODE *tree, int *errflg));
|
---|
1099 | extern NODE *do_close P((NODE *tree));
|
---|
1100 | extern int flush_io P((void));
|
---|
1101 | extern int close_io P((int *stdio_problem));
|
---|
1102 | extern int devopen P((const char *name, const char *mode));
|
---|
1103 | extern int pathopen P((const char *file));
|
---|
1104 | extern NODE *do_getline P((NODE *tree));
|
---|
1105 | extern void do_nextfile P((void)) ATTRIBUTE_NORETURN;
|
---|
1106 | extern struct redirect *getredirect P((const char *str, int len));
|
---|
1107 | /* main.c */
|
---|
1108 | extern int main P((int argc, char **argv));
|
---|
1109 | extern int arg_assign P((char *arg, int initing));
|
---|
1110 | /* msg.c */
|
---|
1111 | extern void err P((const char *s, const char *emsg, va_list argp)) ATTRIBUTE_PRINTF(2, 0);
|
---|
1112 | #if _MSC_VER == 510
|
---|
1113 | extern void msg P((va_list va_alist, ...));
|
---|
1114 | extern void error P((va_list va_alist, ...));
|
---|
1115 | extern void warning P((va_list va_alist, ...));
|
---|
1116 | extern void set_loc P((const char *file, int line));
|
---|
1117 | extern void r_fatal P((va_list va_alist, ...));
|
---|
1118 | extern void (*lintfunc) P((va_list va_alist, ...));
|
---|
1119 | #else
|
---|
1120 | #if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
|
---|
1121 | extern void msg (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
|
---|
1122 | extern void error (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
|
---|
1123 | extern void warning (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
|
---|
1124 | extern void set_loc (const char *file, int line);
|
---|
1125 | extern void r_fatal (const char *mesg, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
|
---|
1126 | ATTRIBUTE_EXPORTED
|
---|
1127 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
|
---|
1128 | extern void (*lintfunc) (const char *mesg, ...) ATTRIBUTE_PRINTF_1;
|
---|
1129 | #else
|
---|
1130 | extern void (*lintfunc) (const char *mesg, ...);
|
---|
1131 | #endif
|
---|
1132 | #else
|
---|
1133 | extern void msg ();
|
---|
1134 | extern void error ();
|
---|
1135 | extern void warning ();
|
---|
1136 | extern void set_loc ();
|
---|
1137 | extern void r_fatal ();
|
---|
1138 | extern void (*lintfunc) ();
|
---|
1139 | #endif
|
---|
1140 | #endif
|
---|
1141 | /* profile.c */
|
---|
1142 | extern void init_profiling P((int *flag, const char *def_file));
|
---|
1143 | extern void init_profiling_signals P((void));
|
---|
1144 | extern void set_prof_file P((const char *filename));
|
---|
1145 | extern void dump_prog P((NODE *begin, NODE *prog, NODE *end));
|
---|
1146 | extern void pp_func P((const char *name, size_t namelen, NODE *f));
|
---|
1147 | extern void pp_string_fp P((FILE *fp, const char *str, size_t namelen,
|
---|
1148 | int delim, int breaklines));
|
---|
1149 | /* node.c */
|
---|
1150 | extern AWKNUM r_force_number P((NODE *n));
|
---|
1151 | extern NODE *format_val P((const char *format, int index, NODE *s));
|
---|
1152 | extern NODE *r_force_string P((NODE *s));
|
---|
1153 | extern NODE *r_dupnode P((NODE *n));
|
---|
1154 | extern NODE *copynode P((NODE *n));
|
---|
1155 | extern NODE *mk_number P((AWKNUM x, unsigned int flags));
|
---|
1156 | extern NODE *make_str_node P((char *s, unsigned long len, int scan ));
|
---|
1157 | extern NODE *tmp_string P((char *s, size_t len ));
|
---|
1158 | extern NODE *more_nodes P((void));
|
---|
1159 | #ifdef MEMDEBUG
|
---|
1160 | extern void freenode P((NODE *it));
|
---|
1161 | #endif
|
---|
1162 | extern void unref P((NODE *tmp));
|
---|
1163 | extern int parse_escape P((const char **string_ptr));
|
---|
1164 | #ifdef MBS_SUPPORT
|
---|
1165 | extern NODE *str2wstr P((NODE *n, size_t **ptr));
|
---|
1166 | #define force_wstring(n) str2wstr(n, NULL)
|
---|
1167 | extern const wchar_t *wstrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len));
|
---|
1168 | extern const wchar_t *wcasestrstr P((const wchar_t *haystack, size_t hs_len, const wchar_t *needle, size_t needle_len));
|
---|
1169 | #endif
|
---|
1170 | /* re.c */
|
---|
1171 | extern Regexp *make_regexp P((const char *s, size_t len, int ignorecase, int dfa));
|
---|
1172 | extern int research P((Regexp *rp, char *str, int start,
|
---|
1173 | size_t len, int flags));
|
---|
1174 | extern void refree P((Regexp *rp));
|
---|
1175 | extern void reg_error P((const char *s));
|
---|
1176 | extern Regexp *re_update P((NODE *t));
|
---|
1177 | extern void resyntax P((int syntax));
|
---|
1178 | extern void resetup P((void));
|
---|
1179 | extern int avoid_dfa P((NODE *re, char *str, size_t len)); /* temporary */
|
---|
1180 | extern int reisstring P((const char *text, size_t len, Regexp *re, const char *buf));
|
---|
1181 | extern int remaybelong P((const char *text, size_t len));
|
---|
1182 | extern int isnondecimal P((const char *str, int use_locale));
|
---|
1183 |
|
---|
1184 | /* strncasecmp.c */
|
---|
1185 | #ifndef BROKEN_STRNCASECMP
|
---|
1186 | extern int strcasecmp P((const char *s1, const char *s2));
|
---|
1187 | extern int strncasecmp P((const char *s1, const char *s2, register size_t n));
|
---|
1188 | #endif
|
---|
1189 |
|
---|
1190 | #if defined(atarist)
|
---|
1191 | #if defined(PIPES_SIMULATED)
|
---|
1192 | /* unsupported/atari/tmpnam.c */
|
---|
1193 | extern char *tmpnam P((char *buf));
|
---|
1194 | extern char *tempnam P((const char *path, const char *base));
|
---|
1195 | #else
|
---|
1196 | #include <wait.h>
|
---|
1197 | #endif
|
---|
1198 | #include <fcntl.h>
|
---|
1199 | #define INVALID_HANDLE (__SMALLEST_VALID_HANDLE - 1)
|
---|
1200 | #else
|
---|
1201 | #define INVALID_HANDLE (-1)
|
---|
1202 | #endif /* atarist */
|
---|
1203 |
|
---|
1204 | #ifdef HAVE_SYS_WAIT_H
|
---|
1205 | #include <sys/wait.h>
|
---|
1206 | #endif
|
---|
1207 | #ifndef WEXITSTATUS
|
---|
1208 | #define WEXITSTATUS(stat_val) ((((unsigned) (stat_val)) >> 8) & 0xFF)
|
---|
1209 | #endif
|
---|
1210 |
|
---|
1211 | #ifndef STATIC
|
---|
1212 | #define STATIC static
|
---|
1213 | #endif
|
---|