* Add configure option to enable dmalloc library.
[make.git] / function.c
blob04b835bffc94f5f1bc2b0081ffc1ad5817ff24d4
1 /* Builtin function expansion for GNU Make.
2 Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc.
3 This file is part of GNU Make.
5 GNU Make is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
10 GNU Make is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNU Make; see the file COPYING. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 #include "make.h"
21 #include "filedef.h"
22 #include "variable.h"
23 #include "dep.h"
24 #include "job.h"
25 #include "commands.h"
27 #ifdef _AMIGA
28 #include "amiga.h"
29 #endif
32 struct function_table_entry
34 const char *name;
35 int len;
36 int required_arguments;
37 int expand_all_arguments;
38 char *(*func_ptr) PARAMS((char *output, char **argv, const char*funcname));
41 static struct function_table_entry function_table[];
44 /* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
45 each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is
46 the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is
47 nonzero, substitutions are done only on matches which are complete
48 whitespace-delimited words. If SUFFIX_ONLY is nonzero, substitutions are
49 done only at the ends of whitespace-delimited words. */
51 char *
52 subst_expand (o, text, subst, replace, slen, rlen, by_word, suffix_only)
53 char *o;
54 char *text;
55 char *subst, *replace;
56 unsigned int slen, rlen;
57 int by_word, suffix_only;
59 register char *t = text;
60 register char *p;
62 if (slen == 0 && !by_word && !suffix_only)
64 /* The first occurrence of "" in any string is its end. */
65 o = variable_buffer_output (o, t, strlen (t));
66 if (rlen > 0)
67 o = variable_buffer_output (o, replace, rlen);
68 return o;
73 if ((by_word | suffix_only) && slen == 0)
74 /* When matching by words, the empty string should match
75 the end of each word, rather than the end of the whole text. */
76 p = end_of_token (next_token (t));
77 else
79 p = sindex (t, 0, subst, slen);
80 if (p == 0)
82 /* No more matches. Output everything left on the end. */
83 o = variable_buffer_output (o, t, strlen (t));
84 return o;
88 /* Output everything before this occurrence of the string to replace. */
89 if (p > t)
90 o = variable_buffer_output (o, t, p - t);
92 /* If we're substituting only by fully matched words,
93 or only at the ends of words, check that this case qualifies. */
94 if ((by_word
95 && ((p > t && !isblank (p[-1]))
96 || (p[slen] != '\0' && !isblank (p[slen]))))
97 || (suffix_only
98 && (p[slen] != '\0' && !isblank (p[slen]))))
99 /* Struck out. Output the rest of the string that is
100 no longer to be replaced. */
101 o = variable_buffer_output (o, subst, slen);
102 else if (rlen > 0)
103 /* Output the replacement string. */
104 o = variable_buffer_output (o, replace, rlen);
106 /* Advance T past the string to be replaced. */
107 t = p + slen;
108 } while (*t != '\0');
110 return o;
114 /* Store into VARIABLE_BUFFER at O the result of scanning TEXT
115 and replacing strings matching PATTERN with REPLACE.
116 If PATTERN_PERCENT is not nil, PATTERN has already been
117 run through find_percent, and PATTERN_PERCENT is the result.
118 If REPLACE_PERCENT is not nil, REPLACE has already been
119 run through find_percent, and REPLACE_PERCENT is the result. */
121 char *
122 patsubst_expand (o, text, pattern, replace, pattern_percent, replace_percent)
123 char *o;
124 char *text;
125 register char *pattern, *replace;
126 register char *pattern_percent, *replace_percent;
128 unsigned int pattern_prepercent_len, pattern_postpercent_len;
129 unsigned int replace_prepercent_len, replace_postpercent_len = 0;
130 char *t;
131 unsigned int len;
132 int doneany = 0;
134 /* We call find_percent on REPLACE before checking PATTERN so that REPLACE
135 will be collapsed before we call subst_expand if PATTERN has no %. */
136 if (replace_percent == 0)
137 replace_percent = find_percent (replace);
138 if (replace_percent != 0)
140 /* Record the length of REPLACE before and after the % so
141 we don't have to compute these lengths more than once. */
142 replace_prepercent_len = replace_percent - replace;
143 replace_postpercent_len = strlen (replace_percent + 1);
145 else
146 /* We store the length of the replacement
147 so we only need to compute it once. */
148 replace_prepercent_len = strlen (replace);
150 if (pattern_percent == 0)
151 pattern_percent = find_percent (pattern);
152 if (pattern_percent == 0)
153 /* With no % in the pattern, this is just a simple substitution. */
154 return subst_expand (o, text, pattern, replace,
155 strlen (pattern), strlen (replace), 1, 0);
157 /* Record the length of PATTERN before and after the %
158 so we don't have to compute it more than once. */
159 pattern_prepercent_len = pattern_percent - pattern;
160 pattern_postpercent_len = strlen (pattern_percent + 1);
162 while ((t = find_next_token (&text, &len)) != 0)
164 int fail = 0;
166 /* Is it big enough to match? */
167 if (len < pattern_prepercent_len + pattern_postpercent_len)
168 fail = 1;
170 /* Does the prefix match? */
171 if (!fail && pattern_prepercent_len > 0
172 && (*t != *pattern
173 || t[pattern_prepercent_len - 1] != pattern_percent[-1]
174 || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1)))
175 fail = 1;
177 /* Does the suffix match? */
178 if (!fail && pattern_postpercent_len > 0
179 && (t[len - 1] != pattern_percent[pattern_postpercent_len]
180 || t[len - pattern_postpercent_len] != pattern_percent[1]
181 || !strneq (&t[len - pattern_postpercent_len],
182 &pattern_percent[1], pattern_postpercent_len - 1)))
183 fail = 1;
185 if (fail)
186 /* It didn't match. Output the string. */
187 o = variable_buffer_output (o, t, len);
188 else
190 /* It matched. Output the replacement. */
192 /* Output the part of the replacement before the %. */
193 o = variable_buffer_output (o, replace, replace_prepercent_len);
195 if (replace_percent != 0)
197 /* Output the part of the matched string that
198 matched the % in the pattern. */
199 o = variable_buffer_output (o, t + pattern_prepercent_len,
200 len - (pattern_prepercent_len
201 + pattern_postpercent_len));
202 /* Output the part of the replacement after the %. */
203 o = variable_buffer_output (o, replace_percent + 1,
204 replace_postpercent_len);
208 /* Output a space, but not if the replacement is "". */
209 if (fail || replace_prepercent_len > 0
210 || (replace_percent != 0 && len + replace_postpercent_len > 0))
212 o = variable_buffer_output (o, " ", 1);
213 doneany = 1;
216 if (doneany)
217 /* Kill the last space. */
218 --o;
220 return o;
224 /* Look up a function by name.
225 The table is currently small enough that it's not really worthwhile to use
226 a fancier lookup algorithm. If it gets larger, maybe...
229 static const struct function_table_entry *
230 lookup_function (table, s)
231 const struct function_table_entry *table;
232 const char *s;
234 int len = strlen(s);
236 for (; table->name != NULL; ++table)
237 if (table->len <= len
238 && (isblank (s[table->len]) || s[table->len] == '\0')
239 && strneq (s, table->name, table->len))
240 return table;
242 return NULL;
246 /* Return 1 if PATTERN matches STR, 0 if not. */
249 pattern_matches (pattern, percent, str)
250 register char *pattern, *percent, *str;
252 unsigned int sfxlen, strlength;
254 if (percent == 0)
256 unsigned int len = strlen (pattern) + 1;
257 char *new_chars = (char *) alloca (len);
258 bcopy (pattern, new_chars, len);
259 pattern = new_chars;
260 percent = find_percent (pattern);
261 if (percent == 0)
262 return streq (pattern, str);
265 sfxlen = strlen (percent + 1);
266 strlength = strlen (str);
268 if (strlength < (percent - pattern) + sfxlen
269 || !strneq (pattern, str, percent - pattern))
270 return 0;
272 return !strcmp (percent + 1, str + (strlength - sfxlen));
276 /* Find the next comma or ENDPAREN (counting nested STARTPAREN and
277 ENDPARENtheses), starting at PTR before END. Return a pointer to
278 next character.
280 If no next argument is found, return NULL.
283 static char *
284 find_next_argument (startparen, endparen, ptr, end)
285 char startparen;
286 char endparen;
287 const char *ptr;
288 const char *end;
290 int count = 0;
292 for (; ptr < end; ++ptr)
293 if (*ptr == startparen)
294 ++count;
296 else if (*ptr == endparen)
298 --count;
299 if (count < 0)
300 return NULL;
303 else if (*ptr == ',' && !count)
304 return (char *)ptr;
306 /* We didn't find anything. */
307 return NULL;
311 static char *
312 expand_builtin_function (o, argc, argv, entry_p)
313 char *o;
314 int argc;
315 char **argv;
316 struct function_table_entry *entry_p;
318 if (argc < entry_p->required_arguments && entry_p->required_arguments >= 0)
319 fatal (reading_file,
320 "Insufficient number of arguments (%d) to function `%s'",
321 argc, entry_p->name);
323 if (!entry_p->func_ptr)
324 fatal (reading_file, "Unimplemented on this platform: function `%s'",
325 entry_p->name);
327 return entry_p->func_ptr (o, argv, entry_p->name);
330 /* Check for a function invocation in *STRINGP. *STRINGP points at the
331 opening ( or { and is not null-terminated. If a function invocation
332 is found, expand it into the buffer at *OP, updating *OP, incrementing
333 *STRINGP past the reference and returning nonzero. If not, return zero. */
336 handle_function (op, stringp)
337 char **op;
338 char **stringp;
340 const struct function_table_entry *entry_p;
341 char openparen = (*stringp)[0];
342 char closeparen = openparen == '(' ? ')' : '}';
343 char *beg = *stringp + 1;
344 char *endref;
345 int count = 0;
346 char *argbeg;
347 register char *p;
348 char **argv, **argvp;
349 int nargs;
351 entry_p = lookup_function (function_table, beg);
353 if (!entry_p)
354 return 0;
356 /* We have found a call to a builtin function. Find the end of the
357 arguments, and do the function. */
359 endref = beg + entry_p->len;
361 /* Space after function name isn't part of the args. */
362 p = next_token (endref);
363 argbeg = p;
365 /* Find the end of the function invocation, counting nested use of
366 whichever kind of parens we use. Since we're looking, count commas
367 to get a rough estimate of how many arguments we might have. The
368 count might be high, but it'll never be low. */
370 for (nargs=1; *p != '\0'; ++p)
371 if (*p == ',')
372 ++nargs;
373 else if (*p == openparen)
374 ++count;
375 else if (*p == closeparen && --count < 0)
376 break;
378 if (count >= 0)
379 fatal (reading_file,
380 "unterminated call to function `%s': missing `%c'",
381 entry_p->name, closeparen);
383 /* Get some memory to store the arg pointers. */
384 argvp = argv = (char **) alloca (sizeof(char *) * (nargs + 2));
386 /* Chop the string into arguments, then store the end pointer and a nul. */
387 *argvp = argbeg;
388 nargs = 1;
389 while (1)
391 char *next = find_next_argument (openparen, closeparen, *argvp, p);
393 if (!next)
394 break;
396 *(++argvp) = next+1;
397 ++nargs;
400 *(++argvp) = p+1;
401 *(++argvp) = 0;
403 /* If we should expand, do it. */
404 if (entry_p->expand_all_arguments)
406 for (argvp=argv; argvp[1] != 0; ++argvp)
407 *argvp = expand_argument (*argvp, argvp[1]-1);
409 /* end pointer doesn't make sense for expanded stuff. */
410 *argvp = 0;
413 /* Finally! Run the function... */
414 *op = expand_builtin_function (*op, nargs, argv, entry_p);
416 /* If we allocated memory for the expanded args, free it again. */
417 if (entry_p->expand_all_arguments)
418 for (argvp=argv; *argvp != 0; ++argvp)
419 free (*argvp);
421 *stringp = p;
423 return 1;
427 /* Glob-expand LINE. The returned pointer is
428 only good until the next call to string_glob. */
430 static char *
431 string_glob (line)
432 char *line;
434 static char *result = 0;
435 static unsigned int length;
436 register struct nameseq *chain;
437 register unsigned int idx;
439 chain = multi_glob (parse_file_seq
440 (&line, '\0', sizeof (struct nameseq),
441 /* We do not want parse_file_seq to strip `./'s.
442 That would break examples like:
443 $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */
445 sizeof (struct nameseq));
447 if (result == 0)
449 length = 100;
450 result = (char *) xmalloc (100);
453 idx = 0;
454 while (chain != 0)
456 register char *name = chain->name;
457 unsigned int len = strlen (name);
459 struct nameseq *next = chain->next;
460 free ((char *) chain);
461 chain = next;
463 /* multi_glob will pass names without globbing metacharacters
464 through as is, but we want only files that actually exist. */
465 if (file_exists_p (name))
467 if (idx + len + 1 > length)
469 length += (len + 1) * 2;
470 result = (char *) xrealloc (result, length);
472 bcopy (name, &result[idx], len);
473 idx += len;
474 result[idx++] = ' ';
477 free (name);
480 /* Kill the last space and terminate the string. */
481 if (idx == 0)
482 result[0] = '\0';
483 else
484 result[idx - 1] = '\0';
486 return result;
490 Builtin functions
493 static char *
494 func_patsubst (o, argv, funcname)
495 char *o;
496 char **argv;
497 const char *funcname;
499 o = patsubst_expand (o, argv[2], argv[0], argv[1], (char *) 0, (char *) 0);
500 return o;
504 static char *
505 func_join(o, argv, funcname)
506 char *o;
507 char **argv;
508 const char *funcname;
510 int doneany = 0;
512 /* Write each word of the first argument directly followed
513 by the corresponding word of the second argument.
514 If the two arguments have a different number of words,
515 the excess words are just output separated by blanks. */
516 register char *tp;
517 register char *pp;
518 char *list1_iterator = argv[0];
519 char *list2_iterator = argv[1];
522 unsigned int len1, len2;
524 tp = find_next_token (&list1_iterator, &len1);
525 if (tp != 0)
526 o = variable_buffer_output (o, tp, len1);
528 pp = find_next_token (&list2_iterator, &len2);
529 if (pp != 0)
530 o = variable_buffer_output (o, pp, len2);
532 if (tp != 0 || pp != 0)
534 o = variable_buffer_output (o, " ", 1);
535 doneany = 1;
538 while (tp != 0 || pp != 0);
539 if (doneany)
540 /* Kill the last blank. */
541 --o;
543 return o;
547 static char *
548 func_origin(o, argv, funcname)
549 char *o;
550 char **argv;
551 const char *funcname;
553 /* Expand the argument. */
554 register struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
555 if (v == 0)
556 o = variable_buffer_output (o, "undefined", 9);
557 else
558 switch (v->origin)
560 default:
561 case o_invalid:
562 abort ();
563 break;
564 case o_default:
565 o = variable_buffer_output (o, "default", 7);
566 break;
567 case o_env:
568 o = variable_buffer_output (o, "environment", 11);
569 break;
570 case o_file:
571 o = variable_buffer_output (o, "file", 4);
572 break;
573 case o_env_override:
574 o = variable_buffer_output (o, "environment override", 20);
575 break;
576 case o_command:
577 o = variable_buffer_output (o, "command line", 12);
578 break;
579 case o_override:
580 o = variable_buffer_output (o, "override", 8);
581 break;
582 case o_automatic:
583 o = variable_buffer_output (o, "automatic", 9);
584 break;
587 return o;
590 #ifdef VMS
591 #define IS_PATHSEP(c) ((c) == ']')
592 #else
593 #ifdef __MSDOS__
594 #define IS_PATHSEP(c) ((c) == '/' || (c) == '\\')
595 #else
596 #define IS_PATHSEP(c) ((c) == '/')
597 #endif
598 #endif
601 static char *
602 func_notdir_suffix(o, argv, funcname)
603 char *o;
604 char **argv;
605 const char *funcname;
607 /* Expand the argument. */
608 char *list_iterator = argv[0];
609 char *p2 =0;
610 int doneany =0;
611 int len=0;
613 int is_suffix = streq(funcname, "suffix");
614 int is_notdir = !is_suffix;
615 while ((p2 = find_next_token (&list_iterator, &len)) != 0)
617 char *p = p2 + len;
620 while (p >= p2 && (!is_suffix || *p != '.'))
622 if (IS_PATHSEP (*p))
623 break;
624 --p;
627 if (p >= p2)
629 if (is_notdir)
630 ++p;
631 else if (*p != '.')
632 continue;
633 o = variable_buffer_output (o, p, len - (p - p2));
635 #if defined(WINDOWS32) || defined(__MSDOS__)
636 /* Handle the case of "d:foo/bar". */
637 else if (streq(funcname, "notdir") && p2[0] && p2[1] == ':')
639 p = p2 + 2;
640 o = variable_buffer_output (o, p, len - (p - p2));
642 #endif
643 else if (is_notdir)
644 o = variable_buffer_output (o, p2, len);
646 if (is_notdir || p >= p2)
648 o = variable_buffer_output (o, " ", 1);
649 doneany = 1;
652 if (doneany)
653 /* Kill last space. */
654 --o;
657 return o;
662 static char *
663 func_basename_dir(o, argv, funcname)
664 char *o;
665 char **argv;
666 const char *funcname;
668 /* Expand the argument. */
669 char *p3 = argv[0];
670 char *p2=0;
671 int doneany=0;
672 int len=0;
673 char *p=0;
674 int is_basename= streq(funcname, "basename");
675 int is_dir= !is_basename;
677 while ((p2 = find_next_token (&p3, &len)) != 0)
679 p = p2 + len;
680 while (p >= p2 && (!is_basename || *p != '.'))
682 if (IS_PATHSEP(*p))
683 break;
684 --p;
687 if (p >= p2 && (is_dir))
688 o = variable_buffer_output (o, p2, ++p - p2);
689 else if (p >= p2 && (*p == '.'))
690 o = variable_buffer_output (o, p2, p - p2);
691 #if defined(WINDOWS32) || defined(__MSDOS__)
692 /* Handle the "d:foobar" case */
693 else if (p2[0] && p2[1] == ':' && is_dir)
694 o = variable_buffer_output (o, p2, 2);
695 #endif
696 else if (is_dir)
697 #ifdef VMS
698 o = variable_buffer_output (o, "[]", 2);
699 #else
700 #ifndef _AMIGA
701 o = variable_buffer_output (o, "./", 2);
702 #else
703 ; /* Just a nop... */
704 #endif /* AMIGA */
705 #endif /* !VMS */
706 else
707 /* The entire name is the basename. */
708 o = variable_buffer_output (o, p2, len);
710 o = variable_buffer_output (o, " ", 1);
711 doneany = 1;
713 if (doneany)
714 /* Kill last space. */
715 --o;
718 return o;
721 static char *
722 func_addsuffix_addprefix(o, argv, funcname)
723 char *o;
724 char **argv;
725 const char *funcname;
727 int fixlen = strlen (argv[0]);
728 char *list_iterator = argv[1];
729 int is_addprefix = streq (funcname, "addprefix");
730 int is_addsuffix = !is_addprefix;
732 int doneany =0;
733 char *p=0;
734 int len =0;
736 while ((p = find_next_token (&list_iterator, &len)) != 0)
738 if (is_addprefix)
739 o = variable_buffer_output (o, argv[0], fixlen);
740 o = variable_buffer_output (o, p, len);
741 if (is_addsuffix)
742 o = variable_buffer_output (o, argv[0], fixlen);
743 o = variable_buffer_output (o, " ", 1);
744 doneany = 1;
747 if (doneany)
748 /* Kill last space. */
749 --o;
751 return o;
754 static char *
755 func_subst(o, argv, funcname)
756 char *o;
757 char **argv;
758 const char *funcname;
760 o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]),
761 strlen (argv[1]), 0, 0);
763 return o;
767 static char *
768 func_firstword(o, argv, funcname)
769 char *o;
770 char **argv;
771 const char *funcname;
773 int i=0;
774 char *words = argv[0];
775 char *p = find_next_token (&words, &i);
777 if (p != 0)
778 o = variable_buffer_output (o, p, i);
780 return o;
784 static char *
785 func_words(o, argv, funcname)
786 char *o;
787 char **argv;
788 const char *funcname;
790 int i = 0;
791 char *word_iterator = argv[0];
792 char buf[20];
794 while (find_next_token (&word_iterator, (unsigned int *) 0) != 0)
795 ++i;
797 sprintf (buf, "%d", i);
798 o = variable_buffer_output (o, buf, strlen (buf));
801 return o;
804 char *
805 strip_whitespace (begpp, endpp)
806 char **begpp;
807 char **endpp;
809 while (isspace (**begpp) && *begpp <= *endpp)
810 (*begpp) ++;
811 while (isspace (**endpp) && *endpp >= *begpp)
812 (*endpp) --;
813 return *begpp;
817 is_numeric (p)
818 char *p;
820 char *end = p + strlen (p) -1;
821 char *beg = p;
822 strip_whitespace (&p, &end);
823 while (p <= end)
825 if (!isdigit (*p))
826 return 0;
828 p++;
831 return (end - beg >= 0);
834 void
835 check_numeric (s, message)
836 char *s;
837 char *message;
839 if (!is_numeric (s))
840 fatal (reading_file, message);
845 static char *
846 func_word(o, argv, funcname)
847 char *o;
848 char **argv;
849 const char *funcname;
851 char *end_p=0;
852 int i=0;
853 char *p=0;
855 /* Check the first argument. */
856 check_numeric (argv[0], "non-numeric first argument to `word' function");
857 i = atoi (argv[0]);
859 if (i == 0)
860 fatal (reading_file, "the `word' function takes a positive index argument");
863 end_p = argv[1];
864 while ((p = find_next_token (&end_p, 0)) != 0)
865 if (--i == 0)
866 break;
868 if (i == 0)
869 o = variable_buffer_output (o, p, end_p - p);
871 return o;
874 static char *
875 func_wordlist (o, argv, funcname)
876 char *o;
877 char **argv;
878 const char *funcname;
880 int i=0;
881 int j=0;
883 /* Check the first argument. */
884 check_numeric (argv[0],
885 "non-numeric first argument to `wordlist' function");
886 i =atoi(argv[0]);
887 check_numeric (argv[1],
888 "non-numeric second argument to `wordlist' function");
890 j = atoi(argv[1]);
894 char *p;
895 char *end_p = argv[2];
897 int start = (i < j) ? i : j;
898 int count = j -i ;
899 if (count < 0)
900 count = - count;
901 count ++;
905 while (((p = find_next_token (&end_p, 0)) != 0) && --start)
907 if (p)
909 while (--count && (find_next_token (&end_p, 0) != 0))
911 o = variable_buffer_output (o, p, end_p - p);
914 return o;
917 static char*
918 func_findstring(o, argv, funcname)
919 char *o;
920 char **argv;
921 const char *funcname;
923 /* Find the first occurrence of the first string in the second. */
924 int i = strlen (argv[0]);
925 if (sindex (argv[1], 0, argv[0], i) != 0)
926 o = variable_buffer_output (o, argv[0], i);
928 return o;
931 static char *
932 func_foreach (o, argv, funcname)
933 char *o;
934 char **argv;
935 const char *funcname;
937 /* expand only the first two. */
938 char *varname = expand_argument (argv[0], argv[1] -1);
939 char *list = expand_argument (argv[1], argv[2] -1);
940 char *body = savestring (argv[2], argv[3] - argv[2] -1 );
942 int len =0;
943 char *list_iterator = list;
944 char *p;
945 register struct variable *var=0;
946 int doneany =0;
948 push_new_variable_scope ();
949 var = define_variable (varname, strlen (varname), "", o_automatic, 0);
951 /* loop through LIST, put the value in VAR and expand BODY */
952 while ((p = find_next_token (&list_iterator, &len)) != 0)
954 char *result = 0;
957 char save = p[len];
959 p[len] = '\0';
960 free (var->value);
961 var->value = (char *) xstrdup ((char*) p);
962 p[len] = save;
965 result = allocated_variable_expand (body);
967 o = variable_buffer_output (o, result, strlen (result));
968 o = variable_buffer_output (o, " ", 1);
969 doneany = 1;
970 free (result);
973 if (doneany)
974 /* Kill the last space. */
975 --o;
977 pop_variable_scope ();
978 free (varname);
979 free (list);
980 free (body);
982 return o;
985 struct a_word
987 struct a_word *next;
988 char *str;
989 int matched;
992 static char *
993 func_filter_filterout (o, argv, funcname)
994 char *o;
995 char **argv;
996 const char *funcname;
998 struct a_word *wordhead =0;
999 struct a_word *wordtail =0;
1001 int is_filter = streq (funcname, "filter");
1002 char *patterns = argv[0];
1005 char *p;
1006 int len;
1007 char *word_iterator = argv[1];
1009 /* Chop ARGV[1] up into words and then run each pattern through. */
1010 while ((p = find_next_token (&word_iterator, &len)) != 0)
1012 struct a_word *w = (struct a_word *)alloca(sizeof(struct a_word));
1013 if (wordhead == 0)
1014 wordhead = w;
1015 else
1016 wordtail->next = w;
1017 wordtail = w;
1019 if (*word_iterator != '\0')
1020 ++word_iterator;
1021 p[len] = '\0';
1022 w->str = p;
1023 w->matched = 0;
1026 if (wordhead != 0)
1028 struct a_word *wp =0;
1029 char *pat_iterator = patterns;
1030 int doneany = 0;
1032 wordtail->next = 0;
1035 /* Run each pattern through the words, killing words. */
1036 while ((p = find_next_token (&pat_iterator, &len)) != 0)
1038 char *percent;
1039 char save = p[len];
1040 p[len] = '\0';
1042 percent = find_percent (p);
1043 for (wp = wordhead; wp != 0; wp = wp->next)
1044 wp->matched |= (percent == 0 ? streq (p, wp->str)
1045 : pattern_matches (p, percent, wp->str));
1047 p[len] = save;
1050 /* Output the words that matched (or didn't, for filter-out). */
1051 for (wp = wordhead; wp != 0; wp = wp->next)
1052 if (is_filter ? wp->matched : !wp->matched)
1054 o = variable_buffer_output (o, wp->str, strlen (wp->str));
1055 o = variable_buffer_output (o, " ", 1);
1056 doneany = 1;
1059 if (doneany)
1060 /* Kill the last space. */
1061 --o;
1064 return o;
1068 static char *
1069 func_strip(o, argv, funcname)
1070 char *o;
1071 char **argv;
1072 const char *funcname;
1074 char *p = argv[0];
1075 int doneany =0;
1077 while (*p != '\0')
1079 int i=0;
1080 char *word_start=0;
1082 while (isspace(*p))
1083 ++p;
1084 word_start = p;
1085 for (i=0; *p != '\0' && !isspace(*p); ++p, ++i)
1087 if (!i)
1088 break;
1089 o = variable_buffer_output (o, word_start, i);
1090 o = variable_buffer_output (o, " ", 1);
1091 doneany = 1;
1094 if (doneany)
1095 /* Kill the last space. */
1096 --o;
1097 return o;
1101 Print a warning or fatal message.
1103 static char *
1104 func_error (o, argv, funcname)
1105 char *o;
1106 char **argv;
1107 const char *funcname;
1109 char **argvp;
1110 char *msg, *p;
1111 int len;
1113 /* The arguments will be broken on commas. Rather than create yet
1114 another special case where function arguments aren't broken up,
1115 just create a format string that puts them back together. */
1116 for (len=0, argvp=argv; *argvp != 0; ++argvp)
1117 len += strlen(*argvp) + 2;
1119 p = msg = alloca (len + 1);
1121 for (argvp=argv; argvp[1] != 0; ++argvp)
1123 strcpy(p, *argvp);
1124 p += strlen(*argvp);
1125 *(p++) = ',';
1126 *(p++) = ' ';
1128 strcpy(p, *argvp);
1130 if (*funcname == 'e')
1131 fatal (reading_file, "%s", msg);
1133 /* The warning function expands to the empty string. */
1134 error (reading_file, "%s", msg);
1136 return o;
1141 chop argv[0] into words, and sort them.
1143 static char *
1144 func_sort (o, argv, funcname)
1145 char *o;
1146 char **argv;
1147 const char *funcname;
1149 char **words = 0;
1150 int nwords = 0;
1151 register int wordi = 0;
1153 /* Chop ARGV[0] into words and put them in WORDS. */
1154 char *t = argv[0];
1155 char *p=0;
1156 int len;
1157 int i;
1159 while ((p = find_next_token (&t, &len)) != 0)
1161 if (wordi >= nwords - 1)
1163 nwords = 2* nwords + 5;
1164 words = (char **) xrealloc ((char *) words,
1165 nwords * sizeof (char *));
1167 words[wordi++] = savestring (p, len);
1170 if (!wordi)
1171 return o;
1173 /* Now sort the list of words. */
1174 qsort ((char *) words, wordi, sizeof (char *), alpha_compare);
1176 /* Now write the sorted list. */
1177 for (i = 0; i < wordi; ++i)
1179 len = strlen (words[i]);
1180 if (i == wordi - 1 || strlen (words[i + 1]) != len
1181 || strcmp (words[i], words[i + 1]))
1183 o = variable_buffer_output (o, words[i], len);
1184 o = variable_buffer_output (o, " ", 1);
1186 free (words[i]);
1188 /* Kill the last space. */
1189 --o;
1191 free (words);
1193 return o;
1196 static char *
1197 func_wildcard(o, argv, funcname)
1198 char *o;
1199 char **argv;
1200 const char *funcname;
1203 #ifdef _AMIGA
1204 o = wildcard_expansion (argv[0], o);
1205 #else
1206 char *p = string_glob (argv[0]);
1207 o = variable_buffer_output (o, p, strlen (p));
1208 #endif
1209 return o;
1213 \r is replaced on UNIX as well. Is this desirable?
1215 void
1216 fold_newlines (buffer, length)
1217 char *buffer;
1218 int *length;
1220 char *dst = buffer;
1221 char *src = buffer;
1222 char *last_nonnl = buffer -1;
1223 src[*length] = 0;
1224 for (; *src != '\0'; ++src)
1226 if (src[0] == '\r' && src[1] == '\n')
1227 continue;
1228 if (*src == '\n')
1230 *dst++ = ' ';
1232 else
1234 last_nonnl = dst;
1235 *dst++ = *src;
1238 *(++last_nonnl) = '\0';
1239 *length = last_nonnl - buffer;
1244 int shell_function_pid = 0, shell_function_completed;
1247 #ifdef WINDOWS32
1248 /*untested*/
1250 #include <windows.h>
1251 #include <io.h>
1252 #include "sub_proc.h"
1255 void
1256 windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
1258 SECURITY_ATTRIBUTES saAttr;
1259 HANDLE hIn;
1260 HANDLE hErr;
1261 HANDLE hChildOutRd;
1262 HANDLE hChildOutWr;
1263 HANDLE hProcess;
1266 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
1267 saAttr.bInheritHandle = TRUE;
1268 saAttr.lpSecurityDescriptor = NULL;
1270 if (DuplicateHandle(GetCurrentProcess(),
1271 GetStdHandle(STD_INPUT_HANDLE),
1272 GetCurrentProcess(),
1273 &hIn,
1275 TRUE,
1276 DUPLICATE_SAME_ACCESS) == FALSE) {
1277 fatal (NILF, "create_child_process: DuplicateHandle(In) failed (e=%d)\n",
1278 GetLastError());
1281 if (DuplicateHandle(GetCurrentProcess(),
1282 GetStdHandle(STD_ERROR_HANDLE),
1283 GetCurrentProcess(),
1284 &hErr,
1286 TRUE,
1287 DUPLICATE_SAME_ACCESS) == FALSE) {
1288 fatal (NILF, "create_child_process: DuplicateHandle(Err) failed (e=%d)\n",
1289 GetLastError());
1292 if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
1293 fatal (NILF, "CreatePipe() failed (e=%d)\n", GetLastError());
1297 hProcess = process_init_fd(hIn, hChildOutWr, hErr);
1299 if (!hProcess)
1300 fatal (NILF, "windows32_openpipe (): process_init_fd() failed\n");
1302 else
1303 process_register(hProcess);
1305 /* make sure that CreateProcess() has Path it needs */
1306 sync_Path_environment();
1308 if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL))
1309 *pid_p = (int) hProcess;
1310 else
1311 fatal (NILF, "windows32_openpipe (): unable to launch process (e=%d)\n",
1312 process_last_err(hProcess));
1314 /* set up to read data from child */
1315 pipedes[0] = _open_osfhandle((long) hChildOutRd, O_RDONLY);
1317 /* this will be closed almost right away */
1318 pipedes[1] = _open_osfhandle((long) hChildOutWr, O_APPEND);
1320 #endif
1323 #ifdef __MSDOS__
1325 untested
1328 msdos_openpipe (int* pipedes, int *pidp, char *text)
1330 FILE *fpipe=0;
1331 /* MSDOS can't fork, but it has `popen'.
1332 (Bwt, why isn't `popen' used in all the versions?) */
1333 struct variable *sh = lookup_variable ("SHELL", 5);
1334 int e;
1335 extern int dos_command_running, dos_status;
1337 /* Make sure not to bother processing an empty line. */
1338 while (isblank (*text))
1339 ++text;
1340 if (*text == '\0')
1341 return 0;
1343 if (sh)
1345 char buf[PATH_MAX + 7];
1346 /* This makes sure $SHELL value is used by $(shell), even
1347 though the target environment is not passed to it. */
1348 sprintf (buf, "SHELL=%s", sh->value);
1349 putenv (buf);
1352 e = errno;
1353 errno = 0;
1354 dos_command_running = 1;
1355 dos_status = 0;
1356 fpipe = popen (text, "rt");
1357 dos_command_running = 0;
1358 if (!fpipe || dos_status)
1360 pipedes[0] = -1;
1361 *pidp = -1;
1362 if (dos_status)
1363 errno = EINTR;
1364 else if (errno == 0)
1365 errno = ENOMEM;
1366 shell_function_completed = -1;
1368 else
1370 pipedes[0] = fileno (fpipe);
1371 *pidp = 42; /* uh? The meaning of Life?*/
1372 errno = e;
1373 shell_function_completed = 1;
1375 return fpipe;
1377 #endif
1380 Do shell spawning, with the naughty bits for different OSes.
1383 #ifdef VMS
1385 /* VMS can't do $(shell ...) */
1386 #define func_shell 0
1388 #else
1389 #ifndef _AMIGA
1390 static char *
1391 func_shell (o, argv, funcname)
1392 char *o;
1393 char **argv;
1394 const char *funcname;
1396 char* batch_filename = NULL;
1397 int i;
1399 #ifdef __MSDOS__
1400 FILE *fpipe;
1401 #endif
1402 char **command_argv;
1403 char *error_prefix;
1404 char **envp;
1405 int pipedes[2];
1406 int pid;
1408 #ifndef __MSDOS__
1409 /* Construct the argument list. */
1410 command_argv = construct_command_argv (argv[0],
1411 (char **) NULL, (struct file *) 0,
1412 &batch_filename);
1413 if (command_argv == 0)
1414 return o;
1415 #endif
1417 /* Using a target environment for `shell' loses in cases like:
1418 export var = $(shell echo foobie)
1419 because target_environment hits a loop trying to expand $(var)
1420 to put it in the environment. This is even more confusing when
1421 var was not explicitly exported, but just appeared in the
1422 calling environment. */
1424 envp = environ;
1426 /* For error messages. */
1427 if (reading_file != 0)
1429 error_prefix = (char *) alloca (strlen(reading_file->filenm)+100);
1431 sprintf (error_prefix,
1432 "%s:%lu: ", reading_file->filenm, reading_file->lineno);
1435 else
1436 error_prefix = "";
1438 #ifdef WINDOWS32
1439 windows32_openpipe (pipedes, &pid, command_argv, envp);
1440 #else /* WINDOWS32 */
1442 # ifdef __MSDOS__
1443 fpipe = msdos_openpipe (pipedes, argv[0], command_argv, envp);
1444 if (!fpipe || pipedes[0] < 0)
1446 perror_with_name (error_prefix, "pipe");
1447 return o;
1449 # else
1450 if (pipe (pipedes) < 0)
1452 perror_with_name (error_prefix, "pipe");
1453 return o;
1456 pid = vfork ();
1457 if (pid < 0)
1458 perror_with_name (error_prefix, "fork");
1459 else if (pid == 0)
1460 child_execute_job (0, pipedes[1], command_argv, envp);
1461 else
1462 # endif /* ! __MSDOS__ */
1464 #endif /* WINDOWS32 */
1466 /* We are the parent. */
1468 char *buffer;
1469 unsigned int maxlen;
1470 int cc;
1472 /* Record the PID for reap_children. */
1473 shell_function_pid = pid;
1474 #ifndef __MSDOS__
1475 shell_function_completed = 0;
1477 /* Free the storage only the child needed. */
1478 free (command_argv[0]);
1479 free ((char *) command_argv);
1481 /* Close the write side of the pipe. */
1482 (void) close (pipedes[1]);
1483 #endif
1485 /* Set up and read from the pipe. */
1487 maxlen = 200;
1488 buffer = (char *) xmalloc (maxlen + 1);
1490 /* Read from the pipe until it gets EOF. */
1491 i = 0;
1494 if (i == maxlen)
1496 maxlen += 512;
1497 buffer = (char *) xrealloc (buffer, maxlen + 1);
1500 errno = 0;
1501 cc = read (pipedes[0], &buffer[i], maxlen - i);
1502 if (cc > 0)
1503 i += cc;
1505 #ifdef EINTR
1506 while (cc > 0 || errno == EINTR);
1507 #else
1508 while (cc > 0);
1509 #endif
1511 /* Close the read side of the pipe. */
1512 #ifdef __MSDOS__
1513 if (fpipe)
1514 (void) pclose (fpipe);
1515 #else
1516 (void) close (pipedes[0]);
1517 #endif
1519 /* Loop until child_handler sets shell_function_completed
1520 to the status of our child shell. */
1521 while (shell_function_completed == 0)
1522 reap_children (1, 0);
1524 if (batch_filename) {
1525 if (debug_flag)
1526 printf("Cleaning up temporary batch file %s\n", batch_filename);
1527 remove(batch_filename);
1528 free(batch_filename);
1530 shell_function_pid = 0;
1532 /* The child_handler function will set shell_function_completed
1533 to 1 when the child dies normally, or to -1 if it
1534 dies with status 127, which is most likely an exec fail. */
1536 if (shell_function_completed == -1)
1538 /* This most likely means that the execvp failed,
1539 so we should just write out the error message
1540 that came in over the pipe from the child. */
1541 fputs (buffer, stderr);
1542 fflush (stderr);
1544 else
1546 /* The child finished normally. Replace all
1547 newlines in its output with spaces, and put
1548 that in the variable output buffer. */
1549 fold_newlines (buffer, &i);
1550 o = variable_buffer_output (o, buffer, i);
1553 free (buffer);
1556 return o;
1559 #else /* _AMIGA */
1561 /* Do the Amiga version of func_shell. */
1563 static char *
1564 func_shell (char *o, char **argv, const char *funcname)
1566 /* Amiga can't fork nor spawn, but I can start a program with
1567 redirection of my choice. However, this means that we
1568 don't have an opportunity to reopen stdout to trap it. Thus,
1569 we save our own stdout onto a new descriptor and dup a temp
1570 file's descriptor onto our stdout temporarily. After we
1571 spawn the shell program, we dup our own stdout back to the
1572 stdout descriptor. The buffer reading is the same as above,
1573 except that we're now reading from a file. */
1575 #include <dos/dos.h>
1576 #include <proto/dos.h>
1578 BPTR child_stdout;
1579 char tmp_output[FILENAME_MAX];
1580 unsigned int maxlen = 200;
1581 int cc, i;
1582 char * buffer, * ptr;
1583 char ** aptr;
1584 int len = 0;
1585 char* batch_filename = NULL;
1587 /* Construct the argument list. */
1588 command_argv = construct_command_argv (argv[0], (char **) NULL,
1589 (struct file *) 0, &batch_filename);
1590 if (command_argv == 0)
1591 return o;
1594 strcpy (tmp_output, "t:MakeshXXXXXXXX");
1595 mktemp (tmp_output);
1596 child_stdout = Open (tmp_output, MODE_NEWFILE);
1598 for (aptr=command_argv; *aptr; aptr++)
1599 len += strlen (*aptr) + 1;
1601 buffer = xmalloc (len + 1);
1602 ptr = buffer;
1604 for (aptr=command_argv; *aptr; aptr++)
1606 strcpy (ptr, *aptr);
1607 ptr += strlen (ptr) + 1;
1608 *ptr ++ = ' ';
1609 *ptr = 0;
1612 ptr[-1] = '\n';
1614 Execute (buffer, NULL, child_stdout);
1615 free (buffer);
1617 Close (child_stdout);
1619 child_stdout = Open (tmp_output, MODE_OLDFILE);
1621 buffer = xmalloc (maxlen);
1622 i = 0;
1625 if (i == maxlen)
1627 maxlen += 512;
1628 buffer = (char *) xrealloc (buffer, maxlen + 1);
1631 cc = Read (child_stdout, &buffer[i], maxlen - i);
1632 if (cc > 0)
1633 i += cc;
1634 } while (cc > 0);
1636 Close (child_stdout);
1638 fold_newlines (buffer, &i);
1639 o = variable_buffer_output (o, buffer, i);
1640 free (buffer);
1641 return o;
1643 #endif /* _AMIGA */
1644 #endif /* !VMS */
1646 #ifdef EXPERIMENTAL
1649 equality. Return is string-boolean, ie, the empty string is false.
1651 static char *
1652 func_eq (char* o, char **argv, char *funcname)
1654 int result = ! strcmp (argv[0], argv[1]);
1655 o = variable_buffer_output (o, result ? "1" : "", result);
1656 return o;
1661 string-boolean not operator.
1663 static char *
1664 func_not (char* o, char **argv, char *funcname)
1666 char * s = argv[0];
1667 int result = 0;
1668 while (isspace (*s))
1669 s++;
1670 result = ! (*s);
1671 o = variable_buffer_output (o, result ? "1" : "", result);
1672 return o;
1678 This is an experimental conditional function.
1680 Syntax:
1682 $(if condition, true-part, false-part)
1684 This is fully not consistent with make's syntax, but more in line
1685 with `normal' programming languages.
1687 Semantics:
1689 - CONDITION is false iff it evaluates to an empty string. White
1690 space before and after condition are stripped before evaluation.
1692 - If CONDITION is true, then TRUE-PART is evaluated, otherwise
1693 FALSE-PART is evaluated. Because only one of the two PARTs is
1694 evaluated, you can use $(if ) to create side-effects with the
1695 $(shell ) function
1698 static char *
1699 func_if (char* o, char **argv, char *funcname)
1701 char *begp = argv[0];
1702 char *endp = argv[1]-2;
1703 char *expansion =0;
1704 int result = 0;
1706 strip_whitespace (&begp, &endp);
1707 if(begp <= endp)
1708 expansion = expand_argument (begp, endp + 1);
1710 result = expansion
1711 ? strlen (expansion)
1712 : 0;
1714 result = !result;
1715 free (expansion);
1717 expansion = expand_argument (argv[1 + result], argv[2+result] -1);
1718 o = variable_buffer_output (o, expansion, strlen (expansion));
1720 return o;
1722 #endif
1724 /* User-defined functions. Expand the first argument as either a builtin
1725 function or a make variable, in the context of the rest of the arguments
1726 assigned to $1, $2, ... $N. $0 is the name of the function. */
1728 char *
1729 func_call (o, argv, funcname)
1730 char *o;
1731 char **argv;
1732 const char *funcname;
1734 char *fname;
1735 int flen;
1736 char *body;
1737 int i;
1738 const struct function_table_entry *entry_p;
1740 /* Calling nothing is a no-op. */
1741 if (*argv[0] == '\0')
1742 return o;
1744 /* There is no way to define a variable with a space in the name, so strip
1745 trailing whitespace as a favor to the user. */
1747 flen = strlen (argv[0]);
1748 fname = argv[0] + flen - 1;
1749 while (isspace (*fname))
1750 --fname;
1751 fname[1] = '\0';
1753 flen = fname - argv[0] + 1;
1754 fname = argv[0];
1756 /* Are we invoking a builtin function? */
1758 entry_p = lookup_function (function_table, fname);
1760 if (entry_p)
1762 for (i=0; argv[i+1]; ++i)
1765 return expand_builtin_function (o, i, argv + 1, entry_p);
1768 /* No, so the first argument is the name of a variable to be expanded and
1769 interpreted as a function. Create the variable reference. */
1770 body = alloca (flen + 4);
1771 body[0]='$';
1772 body[1]='(';
1773 strcpy (body + 2, fname);
1774 body[flen+2]=')';
1775 body[flen+3]= '\0';
1777 /* Set up arguments $(1) .. $(N). $(0) is the function name. */
1779 push_new_variable_scope ();
1781 for (i=0; *argv; ++i, ++argv)
1783 char num[11];
1785 sprintf (num, "%d", i);
1786 define_variable (num, strlen (num), *argv, o_automatic, 0);
1789 /* Expand the body in the context of the arguments, adding the result to
1790 the variable buffer. */
1792 o = variable_expand_string (o, body, flen+3);
1794 pop_variable_scope ();
1796 return o + strlen(o);
1800 #define STRING_SIZE_TUPLE(_s) (_s), (sizeof(_s)-1)
1802 /* Lookup table for builtin functions.
1804 This doesn't have to be sorted; we use a straight lookup. We might gain
1805 some efficiency by moving most often used functions to the start of the
1806 table.
1808 REQUIRED_ARGUMENTS is the minimum number of arguments. A function
1809 can have more, but if they have less an error will be generated.
1811 EXPAND_ALL_ARGUMENTS means that all arguments should be expanded
1812 before invocation. Functions that do namespace tricks (foreach)
1813 don't automatically expand. */
1815 static struct function_table_entry function_table[] =
1817 /* Name/size */ /* ARG EXP? Function */
1818 { STRING_SIZE_TUPLE("addprefix"), 2, 1, func_addsuffix_addprefix},
1819 { STRING_SIZE_TUPLE("addsuffix"), 2, 1, func_addsuffix_addprefix},
1820 { STRING_SIZE_TUPLE("basename"), 1, 1, func_basename_dir},
1821 { STRING_SIZE_TUPLE("dir"), 1, 1, func_basename_dir},
1822 { STRING_SIZE_TUPLE("notdir"), 1, 1, func_notdir_suffix},
1823 { STRING_SIZE_TUPLE("subst"), 3, 1, func_subst},
1824 { STRING_SIZE_TUPLE("suffix"), 1, 1, func_notdir_suffix},
1825 { STRING_SIZE_TUPLE("filter"), 2, 1, func_filter_filterout},
1826 { STRING_SIZE_TUPLE("filter-out"), 2, 1, func_filter_filterout},
1827 { STRING_SIZE_TUPLE("findstring"), 2, 1, func_findstring},
1828 { STRING_SIZE_TUPLE("firstword"), 1, 1, func_firstword},
1829 { STRING_SIZE_TUPLE("join"), 2, 1, func_join},
1830 { STRING_SIZE_TUPLE("patsubst"), 3, 1, func_patsubst},
1831 { STRING_SIZE_TUPLE("shell"), 1, 1, func_shell},
1832 { STRING_SIZE_TUPLE("sort"), 1, 1, func_sort},
1833 { STRING_SIZE_TUPLE("strip"), 1, 1, func_strip},
1834 { STRING_SIZE_TUPLE("wildcard"), 1, 1, func_wildcard},
1835 { STRING_SIZE_TUPLE("word"), 2, 1, func_word},
1836 { STRING_SIZE_TUPLE("wordlist"), 3, 1, func_wordlist},
1837 { STRING_SIZE_TUPLE("words"), 1, 1, func_words},
1838 { STRING_SIZE_TUPLE("origin"), 1, 1, func_origin},
1839 { STRING_SIZE_TUPLE("foreach"), 3, 0, func_foreach},
1840 { STRING_SIZE_TUPLE("call"), 1, 1, func_call},
1841 { STRING_SIZE_TUPLE("error"), 1, 1, func_error},
1842 { STRING_SIZE_TUPLE("warning"), 1, 1, func_error},
1843 #ifdef EXPERIMENTAL
1844 { STRING_SIZE_TUPLE("eq"), 2, 1, func_eq},
1845 { STRING_SIZE_TUPLE("if"), 3, 0, func_if},
1846 { STRING_SIZE_TUPLE("not"), 1, 1, func_not},
1847 #endif
1848 { 0 }