1 /* Copyright (C) 1991-1993, 1996-2000, 2001 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 /* Match STRING against the filename pattern PATTERN, returning zero if
21 it matches, nonzero if not. */
22 static int FCT (const CHAR *pattern, const CHAR *string,
23 const CHAR *string_end, int no_leading_period, int flags)
25 static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
26 const CHAR *string_end, int no_leading_period, int flags)
28 static const CHAR *END (const CHAR *patternp) internal_function;
31 #define __builtin_expect(op,val) ((op) == (val))
36 FCT (pattern, string, string_end, no_leading_period, flags)
39 const CHAR *string_end;
40 int no_leading_period;
43 register const CHAR *p = pattern, *n = string;
46 # if WIDE_CHAR_VERSION
47 const char *collseq = (const char *)
48 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQWC);
50 const UCHAR *collseq = (const UCHAR *)
51 _NL_CURRENT(LC_COLLATE, _NL_COLLATE_COLLSEQMB);
55 while ((c = *p++) != L('\0'))
57 int new_no_leading_period = 0;
63 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
67 res = EXT (c, p, n, string_end, no_leading_period,
75 else if (*n == L('/') && (flags & FNM_FILE_NAME))
77 else if (*n == L('.') && no_leading_period)
82 if (!(flags & FNM_NOESCAPE))
86 /* Trailing \ loses. */
90 if (n == string_end || FOLD ((UCHAR) *n) != c)
95 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
99 res = EXT (c, p, n, string_end, no_leading_period,
105 if (n != string_end && *n == L('.') && no_leading_period)
108 for (c = *p++; c == L('?') || c == L('*'); c = *p++)
110 if (*p == L('(') && (flags & FNM_EXTMATCH) != 0)
112 const CHAR *endp = END (p);
115 /* This is a pattern. Skip over it. */
123 /* A ? needs to match one character. */
125 /* There isn't another character; no match. */
127 else if (*n == L('/')
128 && __builtin_expect (flags & FNM_FILE_NAME, 0))
129 /* A slash does not match a wildcard under
133 /* One character of the string is consumed in matching
134 this ? wildcard, so *??? won't match if there are
135 less than three characters. */
141 /* The wildcard(s) is/are the last element of the pattern.
142 If the name is a file name and contains another slash
143 this means it cannot match, unless the FNM_LEADING_DIR
146 int result = (flags & FNM_FILE_NAME) == 0 ? 0 : FNM_NOMATCH;
148 if (flags & FNM_FILE_NAME)
150 if (flags & FNM_LEADING_DIR)
154 if (MEMCHR (n, L('/'), string_end - n) == NULL)
165 endp = MEMCHR (n, (flags & FNM_FILE_NAME) ? L('/') : L('\0'),
171 || (__builtin_expect (flags & FNM_EXTMATCH, 0) != 0
172 && (c == L('@') || c == L('+') || c == L('!'))
175 int flags2 = ((flags & FNM_FILE_NAME)
176 ? flags : (flags & ~FNM_PERIOD));
177 int no_leading_period2 = no_leading_period;
179 for (--p; n < endp; ++n, no_leading_period2 = 0)
180 if (FCT (p, n, string_end, no_leading_period2, flags2)
184 else if (c == L('/') && (flags & FNM_FILE_NAME))
186 while (n < string_end && *n != L('/'))
188 if (n < string_end && *n == L('/')
189 && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags)
195 int flags2 = ((flags & FNM_FILE_NAME)
196 ? flags : (flags & ~FNM_PERIOD));
197 int no_leading_period2 = no_leading_period;
199 if (c == L('\\') && !(flags & FNM_NOESCAPE))
202 for (--p; n < endp; ++n, no_leading_period2 = 0)
203 if (FOLD ((UCHAR) *n) == c
204 && (FCT (p, n, string_end, no_leading_period2, flags2)
210 /* If we come here no match is possible with the wildcard. */
215 /* Nonzero if the sense of the character class is inverted. */
220 if (posixly_correct == 0)
221 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
226 if (*n == L('.') && no_leading_period)
229 if (*n == L('/') && (flags & FNM_FILE_NAME))
230 /* `/' cannot be matched. */
233 not = (*p == L('!') || (posixly_correct < 0 && *p == L('^')));
237 fn = FOLD ((UCHAR) *n);
242 if (!(flags & FNM_NOESCAPE) && c == L('\\'))
246 c = FOLD ((UCHAR) *p);
252 else if (c == L('[') && *p == L(':'))
254 /* Leave room for the null. */
255 CHAR str[CHAR_CLASS_MAX_LENGTH + 1];
257 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
260 const CHAR *startp = p;
264 if (c1 == CHAR_CLASS_MAX_LENGTH)
265 /* The name is too long and therefore the pattern
270 if (c == L(':') && p[1] == L(']'))
275 if (c < L('a') || c >= L('z'))
277 /* This cannot possibly be a character class name.
278 Match it as a normal range. */
287 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
288 wt = IS_CHAR_CLASS (str);
290 /* Invalid character class name. */
293 # if defined _LIBC && ! WIDE_CHAR_VERSION
294 /* The following code is glibc specific but does
295 there a good job in speeding up the code since
296 we can avoid the btowc() call. */
297 if (_ISCTYPE ((UCHAR) *n, wt))
300 if (ISWCTYPE (BTOWC ((UCHAR) *n), wt))
304 if ((STREQ (str, L("alnum")) && ISALNUM ((UCHAR) *n))
305 || (STREQ (str, L("alpha")) && ISALPHA ((UCHAR) *n))
306 || (STREQ (str, L("blank")) && ISBLANK ((UCHAR) *n))
307 || (STREQ (str, L("cntrl")) && ISCNTRL ((UCHAR) *n))
308 || (STREQ (str, L("digit")) && ISDIGIT ((UCHAR) *n))
309 || (STREQ (str, L("graph")) && ISGRAPH ((UCHAR) *n))
310 || (STREQ (str, L("lower")) && ISLOWER ((UCHAR) *n))
311 || (STREQ (str, L("print")) && ISPRINT ((UCHAR) *n))
312 || (STREQ (str, L("punct")) && ISPUNCT ((UCHAR) *n))
313 || (STREQ (str, L("space")) && ISSPACE ((UCHAR) *n))
314 || (STREQ (str, L("upper")) && ISUPPER ((UCHAR) *n))
315 || (STREQ (str, L("xdigit")) && ISXDIGIT ((UCHAR) *n)))
321 else if (c == L('[') && *p == L('='))
325 _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
326 const CHAR *startp = p;
338 if (c != L('=') || p[1] != L(']'))
348 if ((UCHAR) *n == str[0])
353 const int32_t *table;
354 # if WIDE_CHAR_VERSION
355 const int32_t *weights;
356 const int32_t *extra;
358 const unsigned char *weights;
359 const unsigned char *extra;
361 const int32_t *indirect;
363 const UCHAR *cp = (const UCHAR *) str;
365 /* This #include defines a local function! */
366 # if WIDE_CHAR_VERSION
367 # include <locale/weightwc.h>
369 # include <locale/weight.h>
372 # if WIDE_CHAR_VERSION
373 table = (const int32_t *)
374 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEWC);
375 weights = (const int32_t *)
376 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTWC);
377 extra = (const int32_t *)
378 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAWC);
379 indirect = (const int32_t *)
380 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTWC);
382 table = (const int32_t *)
383 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
384 weights = (const unsigned char *)
385 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
386 extra = (const unsigned char *)
387 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
388 indirect = (const int32_t *)
389 _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
395 /* We found a table entry. Now see whether the
396 character we are currently at has the same
397 equivalance class value. */
398 int len = weights[idx];
400 const UCHAR *np = (const UCHAR *) n;
402 idx2 = findidx (&np);
403 if (idx2 != 0 && len == weights[idx2])
408 && (weights[idx + 1 + cnt]
409 == weights[idx2 + 1 + cnt]))
421 else if (c == L('\0'))
422 /* [ (unterminated) loses. */
431 if (c == L('[') && *p == L('.'))
434 _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
435 const CHAR *startp = p;
441 if (c == L('.') && p[1] == L(']'))
451 /* We have to handling the symbols differently in
452 ranges since then the collation sequence is
454 is_range = *p == L('-') && p[1] != L('\0');
458 /* There are no names defined in the collation
459 data. Therefore we only accept the trivial
460 names consisting of the character itself. */
464 if (!is_range && *n == startp[1])
473 const int32_t *symb_table;
474 # ifdef WIDE_CHAR_VERSION
478 # define str (startp + 1)
480 const unsigned char *extra;
486 # ifdef WIDE_CHAR_VERSION
487 /* We have to convert the name to a single-byte
488 string. This is possible since the names
489 consist of ASCII characters and the internal
490 representation is UCS4. */
491 for (strcnt = 0; strcnt < c1; ++strcnt)
492 str[strcnt] = startp[1 + strcnt];
496 _NL_CURRENT_WORD (LC_COLLATE,
497 _NL_COLLATE_SYMB_HASH_SIZEMB);
498 symb_table = (const int32_t *)
499 _NL_CURRENT (LC_COLLATE,
500 _NL_COLLATE_SYMB_TABLEMB);
501 extra = (const unsigned char *)
502 _NL_CURRENT (LC_COLLATE,
503 _NL_COLLATE_SYMB_EXTRAMB);
505 /* Locate the character in the hashing table. */
506 hash = elem_hash (str, c1);
509 elem = hash % table_size;
510 second = hash % (table_size - 2);
511 while (symb_table[2 * elem] != 0)
513 /* First compare the hashing value. */
514 if (symb_table[2 * elem] == hash
515 && c1 == extra[symb_table[2 * elem + 1]]
517 &extra[symb_table[2 * elem + 1]
520 /* Yep, this is the entry. */
521 idx = symb_table[2 * elem + 1];
522 idx += 1 + extra[idx];
530 if (symb_table[2 * elem] != 0)
532 /* Compare the byte sequence but only if
533 this is not part of a range. */
534 # ifdef WIDE_CHAR_VERSION
537 idx += 1 + extra[idx];
538 /* Adjust for the alignment. */
539 idx = (idx + 3) & ~3;
541 wextra = (int32_t *) &extra[idx + 4];
546 # ifdef WIDE_CHAR_VERSION
547 for (c1 = 0; c1 < wextra[idx]; ++c1)
548 if (n[c1] != wextra[1 + c1])
551 if (c1 == wextra[idx])
554 for (c1 = 0; c1 < extra[idx]; ++c1)
555 if (n[c1] != extra[1 + c1])
558 if (c1 == extra[idx])
563 /* Get the collation sequence value. */
565 # ifdef WIDE_CHAR_VERSION
566 cold = wextra[1 + wextra[idx]];
568 /* Adjust for the alignment. */
569 idx += 1 + extra[idx];
570 idx = (idx + 3) & ~4;
571 cold = *((int32_t *) &extra[idx]);
578 /* No valid character. Match it as a
580 if (!is_range && *n == str[0])
597 /* We have to handling the symbols differently in
598 ranges since then the collation sequence is
600 is_range = *p == L('-') && p[1] != L('\0');
602 if (!is_range && c == fn)
609 if (c == L('-') && *p != L(']'))
612 /* We have to find the collation sequence
613 value for C. Collation sequence is nothing
614 we can regularly access. The sequence
615 value is defined by the order in which the
616 definitions of the collation values for the
617 various characters appear in the source
618 file. A strange concept, nowhere
624 # ifdef WIDE_CHAR_VERSION
625 /* Search in the `names' array for the characters. */
626 fcollseq = collseq_table_lookup (collseq, fn);
627 if (fcollseq == ~((uint32_t) 0))
628 /* XXX We don't know anything about the character
629 we are supposed to match. This means we are
631 goto range_not_matched;
636 lcollseq = collseq_table_lookup (collseq, cold);
638 fcollseq = collseq[fn];
639 lcollseq = is_seqval ? cold : collseq[(UCHAR) cold];
643 if (cend == L('[') && *p == L('.'))
646 _NL_CURRENT_WORD (LC_COLLATE,
648 const CHAR *startp = p;
654 if (c == L('.') && p[1] == L(']'))
666 /* There are no names defined in the
667 collation data. Therefore we only
668 accept the trivial names consisting
669 of the character itself. */
678 const int32_t *symb_table;
679 # ifdef WIDE_CHAR_VERSION
683 # define str (startp + 1)
685 const unsigned char *extra;
691 # ifdef WIDE_CHAR_VERSION
692 /* We have to convert the name to a single-byte
693 string. This is possible since the names
694 consist of ASCII characters and the internal
695 representation is UCS4. */
696 for (strcnt = 0; strcnt < c1; ++strcnt)
697 str[strcnt] = startp[1 + strcnt];
701 _NL_CURRENT_WORD (LC_COLLATE,
702 _NL_COLLATE_SYMB_HASH_SIZEMB);
703 symb_table = (const int32_t *)
704 _NL_CURRENT (LC_COLLATE,
705 _NL_COLLATE_SYMB_TABLEMB);
706 extra = (const unsigned char *)
707 _NL_CURRENT (LC_COLLATE,
708 _NL_COLLATE_SYMB_EXTRAMB);
710 /* Locate the character in the hashing
712 hash = elem_hash (str, c1);
715 elem = hash % table_size;
716 second = hash % (table_size - 2);
717 while (symb_table[2 * elem] != 0)
719 /* First compare the hashing value. */
720 if (symb_table[2 * elem] == hash
722 == extra[symb_table[2 * elem + 1]])
724 &extra[symb_table[2 * elem + 1]
727 /* Yep, this is the entry. */
728 idx = symb_table[2 * elem + 1];
729 idx += 1 + extra[idx];
737 if (symb_table[2 * elem] != 0)
739 /* Compare the byte sequence but only if
740 this is not part of a range. */
741 # ifdef WIDE_CHAR_VERSION
744 idx += 1 + extra[idx];
745 /* Adjust for the alignment. */
746 idx = (idx + 3) & ~4;
748 wextra = (int32_t *) &extra[idx + 4];
750 /* Get the collation sequence value. */
752 # ifdef WIDE_CHAR_VERSION
753 cend = wextra[1 + wextra[idx]];
755 /* Adjust for the alignment. */
756 idx += 1 + extra[idx];
757 idx = (idx + 3) & ~4;
758 cend = *((int32_t *) &extra[idx]);
761 else if (symb_table[2 * elem] != 0 && c1 == 1)
773 if (!(flags & FNM_NOESCAPE) && cend == L('\\'))
780 /* XXX It is not entirely clear to me how to handle
781 characters which are not mentioned in the
782 collation specification. */
784 # ifdef WIDE_CHAR_VERSION
785 lcollseq == 0xffffffff ||
787 lcollseq <= fcollseq)
789 /* We have to look at the upper bound. */
796 # ifdef WIDE_CHAR_VERSION
798 collseq_table_lookup (collseq, cend);
799 if (hcollseq == ~((uint32_t) 0))
801 /* Hum, no information about the upper
802 bound. The matching succeeds if the
803 lower bound is matched exactly. */
804 if (lcollseq != fcollseq)
805 goto range_not_matched;
810 hcollseq = collseq[cend];
814 if (lcollseq <= hcollseq && fcollseq <= hcollseq)
817 # ifdef WIDE_CHAR_VERSION
821 /* We use a boring value comparison of the character
822 values. This is better than comparing using
823 `strcoll' since the latter would have surprising
824 and sometimes fatal consequences. */
827 if (!(flags & FNM_NOESCAPE) && cend == L('\\'))
833 if (cold <= fn && fn <= cend)
850 /* Skip the rest of the [...] that already matched. */
857 /* [... (unterminated) loses. */
860 if (!(flags & FNM_NOESCAPE) && c == L('\\'))
864 /* XXX 1003.2d11 is unclear if this is right. */
867 else if (c == L('[') && *p == L(':'))
870 const CHAR *startp = p;
875 if (++c1 == CHAR_CLASS_MAX_LENGTH)
878 if (*p == L(':') && p[1] == L(']'))
881 if (c < L('a') || c >= L('z'))
890 else if (c == L('[') && *p == L('='))
896 if (c != L('=') || p[1] != L(']'))
901 else if (c == L('[') && *p == L('.'))
910 if (*p == L('.') && p[1] == L(']'))
926 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
930 res = EXT (c, p, n, string_end, no_leading_period, flags);
937 if (NO_LEADING_PERIOD (flags))
939 if (n == string_end || c != *n)
942 new_no_leading_period = 1;
948 if (n == string_end || c != FOLD ((UCHAR) *n))
952 no_leading_period = new_no_leading_period;
959 if ((flags & FNM_LEADING_DIR) && n != string_end && *n == L('/'))
960 /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
969 END (const CHAR *pattern)
971 const CHAR *p = pattern;
975 /* This is an invalid pattern. */
977 else if (*p == L('['))
979 /* Handle brackets special. */
980 if (posixly_correct == 0)
981 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
983 /* Skip the not sign. We have to recognize it because of a possibly
985 if (*++p == L('!') || (posixly_correct < 0 && *p == L('^')))
987 /* A leading ']' is recognized as such. */
990 /* Skip over all characters of the list. */
993 /* This is no valid pattern. */
996 else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@')
997 || *p == L('!')) && p[1] == L('('))
999 else if (*p == L(')'))
1008 struct patternlist *next;
1012 #define xalloca malloc
1014 void free_xalloca(struct patternlist **top){
1015 struct patternlist *p, *next;
1029 EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
1030 int no_leading_period, int flags)
1035 struct patternlist {
1036 struct patternlist *next;
1040 struct patternlist *list = NULL;
1042 struct patternlist **lastp = &list;
1043 size_t pattern_len = STRLEN (pattern);
1047 static struct patternlist *xalloca_top = NULL;
1050 /* Parse the pattern. Store the individual parts in the list. */
1052 for (startp = p = pattern + 1; level >= 0; ++p)
1053 if (*p == L('\0')) {
1054 /* This is an invalid pattern. */
1055 free_xalloca(&xalloca_top);
1057 } else if (*p == L('[')) {
1058 /* Handle brackets special. */
1059 if (posixly_correct == 0)
1060 posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
1062 /* Skip the not sign. We have to recognize it because of a possibly
1064 if (*++p == L('!') || (posixly_correct < 0 && *p == L('^')))
1066 /* A leading ']' is recognized as such. */
1069 /* Skip over all characters of the list. */
1070 while (*p != L(']'))
1071 if (*p++ == L('\0')) {
1072 /* This is no valid pattern. */
1073 free_xalloca(&xalloca_top);
1077 else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@')
1078 || *p == L('!')) && p[1] == L('('))
1079 /* Remember the nesting level. */
1081 else if (*p == L(')'))
1085 /* This means we found the end of the pattern. */
1086 #define NEW_PATTERN \
1087 struct patternlist *newp; \
1089 if (opt == L('?') || opt == L('@')) \
1090 newp = xalloca (sizeof (struct patternlist) \
1091 + (pattern_len * sizeof (CHAR))); \
1093 newp = xalloca (sizeof (struct patternlist) \
1094 + ((p - startp + 1) * sizeof (CHAR))); \
1095 if (!xalloca_top) xalloca_top = newp; \
1096 *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
1097 newp->next = NULL; \
1103 else if (*p == L('|'))
1111 assert (list != NULL);
1112 assert (p[-1] == L(')'));
1118 if (FCT (p, string, string_end, no_leading_period, flags) == 0) {
1119 free_xalloca(&xalloca_top);
1127 for (rs = string; rs <= string_end; ++rs)
1128 /* First match the prefix with the current pattern with the
1130 if (FCT (list->str, string, rs, no_leading_period,
1131 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0
1132 /* This was successful. Now match the rest with the rest
1134 && (FCT (p, rs, string_end,
1137 : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0,
1138 flags & FNM_FILE_NAME
1139 ? flags : flags & ~FNM_PERIOD) == 0
1140 /* This didn't work. Try the whole pattern. */
1142 && FCT (pattern - 1, rs, string_end,
1145 : (rs[-1] == '/' && NO_LEADING_PERIOD (flags)
1147 flags & FNM_FILE_NAME
1148 ? flags : flags & ~FNM_PERIOD) == 0)))
1149 /* It worked. Signal success. */
1150 free_xalloca(&xalloca_top);
1153 while ((list = list->next) != NULL);
1155 /* None of the patterns lead to a match. */
1156 free_xalloca(&xalloca_top);
1160 if (FCT (p, string, string_end, no_leading_period, flags) == 0) {
1161 free_xalloca(&xalloca_top);
1168 /* I cannot believe it but `strcat' is actually acceptable
1169 here. Match the entire string with the prefix from the
1170 pattern list and the rest of the pattern following the
1172 if (FCT (STRCAT (list->str, p), string, string_end,
1174 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) {
1175 /* It worked. Signal success. */
1176 free_xalloca(&xalloca_top);
1179 while ((list = list->next) != NULL);
1181 /* None of the patterns lead to a match. */
1182 free_xalloca(&xalloca_top);
1186 for (rs = string; rs <= string_end; ++rs)
1188 struct patternlist *runp;
1190 for (runp = list; runp != NULL; runp = runp->next)
1191 if (FCT (runp->str, string, rs, no_leading_period,
1192 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
1195 /* If none of the patterns matched see whether the rest does. */
1197 && (FCT (p, rs, string_end,
1200 : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0,
1201 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
1203 /* This is successful. */
1204 free_xalloca(&xalloca_top);
1209 /* None of the patterns together with the rest of the pattern
1211 free_xalloca(&xalloca_top);
1215 assert (! "Invalid extended matching operator");
1219 free_xalloca(&xalloca_top);