1 /* 2 * sh.glob.c: Regular expression expansion 3 */ 4 /*- 5 * Copyright (c) 1980, 1991 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 #include "sh.h" 33 #include "tc.h" 34 #include "tw.h" 35 36 #include "glob.h" 37 38 /* 39 * Values for gflag 40 */ 41 #define G_NONE 0 /* No globbing needed */ 42 #define G_GLOB 1 /* string contains *?[] characters */ 43 #define G_CSH 2 /* string contains ~`{ characters */ 44 45 #define GLOBSPACE 100 /* Alloc increment */ 46 47 48 #define LBRC '{' 49 #define RBRC '}' 50 #define LBRK '[' 51 #define RBRK ']' 52 #define EOS '\0' 53 54 /* 55 * globbing is now done in two stages. In the first pass we expand 56 * csh globbing idioms ~`{ and then we proceed doing the normal 57 * globbing if needed ?*[ 58 * 59 * Csh type globbing is handled in globexpand() and the rest is 60 * handled in glob() which is part of the 4.4BSD libc. 61 * 62 */ 63 static Char *globtilde (Char *); 64 static Char *handleone (Char *, Char **, int); 65 static Char **libglob (Char **); 66 static Char **globexpand (Char **, int); 67 static int globbrace (const Char *, Char ***); 68 static void expbrace (Char ***, Char ***, int); 69 static void pword (struct blk_buf *, struct Strbuf *); 70 static void backeval (struct blk_buf *, struct Strbuf *, Char *, 71 int); 72 static Char * 73 globtilde(Char *s) 74 { 75 Char *name, *u, *home, *res; 76 77 u = s; 78 for (s++; *s && *s != '/' && *s != ':'; s++) 79 continue; 80 name = Strnsave(u + 1, s - (u + 1)); 81 cleanup_push(name, xfree); 82 home = gethdir(name); 83 if (home == NULL) { 84 if (adrof(STRnonomatch)) { 85 cleanup_until(name); 86 return u; 87 } 88 if (*name) 89 stderror(ERR_UNKUSER, short2str(name)); 90 else 91 stderror(ERR_NOHOME); 92 } 93 cleanup_until(name); 94 if (home[0] == '/' && home[1] == '\0' && s[0] == '/') 95 res = Strsave(s); 96 else 97 res = Strspl(home, s); 98 xfree(home); 99 xfree(u); 100 return res; 101 } 102 103 /* Returns a newly allocated string, old or NULL */ 104 Char * 105 globequal(Char *old) 106 { 107 int dig; 108 const Char *dir; 109 Char *b; 110 111 /* 112 * kfk - 17 Jan 1984 - stack hack allows user to get at arbitrary dir names 113 * in stack. PWP: let =foobar pass through (for X windows) 114 */ 115 if (old[1] == '-' && (old[2] == '\0' || old[2] == '/')) { 116 /* =- */ 117 const Char *olddir = varval (STRowd); 118 119 if (olddir && *olddir && 120 !dcwd->di_next->di_name && !dcwd->di_prev->di_name) 121 return Strspl(olddir, &old[2]); 122 dig = -1; 123 b = &old[2]; 124 } 125 else if (Isdigit(old[1])) { 126 /* =<number> */ 127 dig = old[1] - '0'; 128 for (b = &old[2]; Isdigit(*b); b++) 129 dig = dig * 10 + (*b - '0'); 130 if (*b != '\0' && *b != '/') 131 /* =<number>foobar */ 132 return old; 133 } 134 else 135 /* =foobar */ 136 return old; 137 138 dir = getstakd(dig); 139 if (dir == NULL) 140 return NULL; 141 return Strspl(dir, b); 142 } 143 144 static int 145 globbrace(const Char *s, Char ***bl) 146 { 147 struct Strbuf gbuf = Strbuf_INIT; 148 struct blk_buf bb = BLK_BUF_INIT; 149 int i; 150 const Char *p, *pm, *pe, *pl; 151 size_t prefix_len; 152 153 /* copy part up to the brace */ 154 for (p = s; *p != LBRC; p++) 155 ; 156 prefix_len = p - s; 157 158 /* check for balanced braces */ 159 for (i = 0, pe = ++p; *pe; pe++) 160 if (*pe == LBRK) { 161 /* Ignore everything between [] */ 162 for (++pe; *pe != RBRK && *pe != EOS; pe++) 163 continue; 164 if (*pe == EOS) 165 return (-RBRK); 166 } 167 else if (*pe == LBRC) 168 i++; 169 else if (*pe == RBRC) { 170 if (i == 0) 171 break; 172 i--; 173 } 174 175 if (i != 0 || *pe == '\0') 176 return (-RBRC); 177 178 Strbuf_appendn(&gbuf, s, prefix_len); 179 180 for (i = 0, pl = pm = p; pm <= pe; pm++) 181 switch (*pm) { 182 case LBRK: 183 for (++pm; *pm != RBRK && *pm != EOS; pm++) 184 continue; 185 if (*pm == EOS) { 186 bb_cleanup(&bb); 187 xfree(gbuf.s); 188 return (-RBRK); 189 } 190 break; 191 case LBRC: 192 i++; 193 break; 194 case RBRC: 195 if (i) { 196 i--; 197 break; 198 } 199 /* FALLTHROUGH */ 200 case ',': 201 if (i && *pm == ',') 202 break; 203 else { 204 gbuf.len = prefix_len; 205 Strbuf_appendn(&gbuf, pl, pm - pl); 206 Strbuf_append(&gbuf, pe + 1); 207 Strbuf_terminate(&gbuf); 208 bb_append(&bb, Strsave(gbuf.s)); 209 pl = pm + 1; 210 } 211 break; 212 default: 213 break; 214 } 215 *bl = bb_finish(&bb); 216 xfree(gbuf.s); 217 return bb.len; 218 } 219 220 221 static void 222 expbrace(Char ***nvp, Char ***elp, int size) 223 { 224 Char **vl, **el, **nv, *s; 225 226 vl = nv = *nvp; 227 if (elp != NULL) 228 el = *elp; 229 else 230 el = vl + blklen(vl); 231 232 for (s = *vl; s; s = *++vl) { 233 Char **vp, **bp; 234 235 /* leave {} untouched for find */ 236 if (s[0] == '{' && (s[1] == '\0' || (s[1] == '}' && s[2] == '\0'))) 237 continue; 238 if (Strchr(s, '{') != NULL) { 239 Char **bl = NULL; 240 int len; 241 242 if ((len = globbrace(s, &bl)) < 0) 243 stderror(ERR_MISSING, -len); 244 xfree(s); 245 if (len == 1) { 246 *vl-- = *bl; 247 xfree(bl); 248 continue; 249 } 250 if (&el[len] >= &nv[size]) { 251 size_t l, e; 252 l = &el[len] - &nv[size]; 253 size += GLOBSPACE > l ? GLOBSPACE : l; 254 l = vl - nv; 255 e = el - nv; 256 nv = xrealloc(nv, size * sizeof(Char *)); 257 *nvp = nv; /* To keep cleanups working */ 258 vl = nv + l; 259 el = nv + e; 260 } 261 /* nv vl el bl 262 * | | | | 263 * -.--..-- x-- 264 * | len 265 * vp 266 */ 267 vp = vl--; 268 *vp = *bl; 269 len--; 270 for (bp = el; bp != vp; bp--) 271 bp[len] = *bp; 272 el += len; 273 /* nv vl el bl 274 * | | | | 275 * -.-x --- -- 276 * |len 277 * vp 278 */ 279 vp++; 280 for (bp = bl + 1; *bp; *vp++ = *bp++) 281 continue; 282 xfree(bl); 283 } 284 285 } 286 if (elp != NULL) 287 *elp = el; 288 } 289 290 static Char ** 291 globexpand(Char **v, int noglob) 292 { 293 Char *s; 294 Char ***fnv, **vl, **el; 295 int size = GLOBSPACE; 296 297 298 fnv = xmalloc(sizeof(Char ***)); 299 *fnv = vl = xmalloc(sizeof(Char *) * size); 300 *vl = NULL; 301 cleanup_push(fnv, blk_indirect_cleanup); 302 303 /* 304 * Step 1: expand backquotes. 305 */ 306 while ((s = *v++) != NULL) { 307 if (Strchr(s, '`')) { 308 int i; 309 Char **expanded; 310 311 expanded = dobackp(s, 0); 312 for (i = 0; expanded[i] != NULL; i++) { 313 *vl++ = expanded[i]; 314 if (vl == &(*fnv)[size]) { 315 size += GLOBSPACE; 316 *fnv = xrealloc(*fnv, size * sizeof(Char *)); 317 vl = &(*fnv)[size - GLOBSPACE]; 318 } 319 } 320 xfree(expanded); 321 } 322 else { 323 *vl++ = Strsave(s); 324 if (vl == &(*fnv)[size]) { 325 size += GLOBSPACE; 326 *fnv = xrealloc(*fnv, size * sizeof(Char *)); 327 vl = &(*fnv)[size - GLOBSPACE]; 328 } 329 } 330 *vl = NULL; 331 } 332 333 if (noglob) 334 goto done; 335 336 /* 337 * Step 2: expand braces 338 */ 339 el = vl; 340 expbrace(fnv, &el, size); 341 342 343 /* 344 * Step 3: expand ~ = 345 */ 346 vl = *fnv; 347 for (s = *vl; s; s = *++vl) 348 switch (*s) { 349 Char *ns; 350 case '~': 351 *vl = globtilde(s); 352 break; 353 case '=': 354 if ((ns = globequal(s)) == NULL) { 355 if (!adrof(STRnonomatch)) 356 stderror(ERR_DEEP); /* Error */ 357 } 358 if (ns && ns != s) { 359 /* Expansion succeeded */ 360 xfree(s); 361 *vl = ns; 362 } 363 break; 364 default: 365 break; 366 } 367 vl = *fnv; 368 369 /* 370 * Step 4: expand .. if the variable symlinks==expand is set 371 */ 372 if (symlinks == SYM_EXPAND) { 373 for (s = *vl; s; s = *++vl) { 374 *vl = dnormalize(s, 1); 375 xfree(s); 376 } 377 } 378 379 done: 380 cleanup_ignore(fnv); 381 cleanup_until(fnv); 382 vl = *fnv; 383 xfree(fnv); 384 return vl; 385 } 386 387 static Char * 388 handleone(Char *str, Char **vl, int action) 389 { 390 size_t chars; 391 Char **t, *p, *strp; 392 393 switch (action) { 394 case G_ERROR: 395 setname(short2str(str)); 396 blkfree(vl); 397 stderror(ERR_NAME | ERR_AMBIG); 398 break; 399 case G_APPEND: 400 chars = 0; 401 for (t = vl; (p = *t++) != NULL; chars++) 402 chars += Strlen(p); 403 str = xmalloc(chars * sizeof(Char)); 404 for (t = vl, strp = str; (p = *t++) != NULL; chars++) { 405 while (*p) 406 *strp++ = *p++ & TRIM; 407 *strp++ = ' '; 408 } 409 *--strp = '\0'; 410 blkfree(vl); 411 break; 412 case G_IGNORE: 413 str = Strsave(strip(*vl)); 414 blkfree(vl); 415 break; 416 default: 417 break; 418 } 419 return (str); 420 } 421 422 static Char ** 423 libglob(Char **vl) 424 { 425 int gflgs = GLOB_QUOTE | GLOB_NOMAGIC | GLOB_ALTNOT; 426 glob_t globv; 427 char *ptr; 428 int nonomatch = adrof(STRnonomatch) != 0, magic = 0, match = 0; 429 430 if (adrof(STRglobdot)) 431 gflgs |= GLOB_DOT; 432 433 if (adrof(STRglobstar)) 434 gflgs |= GLOB_STAR; 435 436 if (!vl || !vl[0]) 437 return(vl); 438 439 globv.gl_offs = 0; 440 globv.gl_pathv = 0; 441 globv.gl_pathc = 0; 442 443 if (nonomatch) 444 gflgs |= GLOB_NOCHECK; 445 446 do { 447 ptr = short2qstr(*vl); 448 switch (glob(ptr, gflgs, 0, &globv)) { 449 case GLOB_ABEND: 450 globfree(&globv); 451 setname(ptr); 452 stderror(ERR_NAME | ERR_GLOB); 453 /* NOTREACHED */ 454 case GLOB_NOSPACE: 455 globfree(&globv); 456 stderror(ERR_NOMEM); 457 /* NOTREACHED */ 458 default: 459 break; 460 } 461 if (globv.gl_flags & GLOB_MAGCHAR) { 462 match |= (globv.gl_matchc != 0); 463 magic = 1; 464 } 465 gflgs |= GLOB_APPEND; 466 } 467 while (*++vl); 468 vl = (globv.gl_pathc == 0 || (magic && !match && !nonomatch)) ? 469 NULL : blk2short(globv.gl_pathv); 470 globfree(&globv); 471 return (vl); 472 } 473 474 Char * 475 globone(Char *str, int action) 476 { 477 Char *v[2], **vl, **vo; 478 int gflg, noglob; 479 480 noglob = adrof(STRnoglob) != 0; 481 v[0] = str; 482 v[1] = 0; 483 gflg = tglob(v); 484 if (gflg == G_NONE) 485 return (strip(Strsave(str))); 486 487 if (gflg & G_CSH) { 488 /* 489 * Expand back-quote, tilde and brace 490 */ 491 vo = globexpand(v, noglob); 492 if (noglob || (gflg & G_GLOB) == 0) { 493 vl = vo; 494 goto result; 495 } 496 cleanup_push(vo, blk_cleanup); 497 } 498 else if (noglob || (gflg & G_GLOB) == 0) 499 return (strip(Strsave(str))); 500 else 501 vo = v; 502 503 vl = libglob(vo); 504 if (gflg & G_CSH) { 505 if (vl != vo) 506 cleanup_until(vo); 507 else 508 cleanup_ignore(vo); 509 } 510 if (vl == NULL) { 511 setname(short2str(str)); 512 stderror(ERR_NAME | ERR_NOMATCH); 513 } 514 result: 515 if (vl && vl[0] == NULL) { 516 xfree(vl); 517 return (Strsave(STRNULL)); 518 } 519 if (vl && vl[1]) 520 return (handleone(str, vl, action)); 521 else { 522 str = strip(*vl); 523 xfree(vl); 524 return (str); 525 } 526 } 527 528 Char ** 529 globall(Char **v, int gflg) 530 { 531 Char **vl, **vo; 532 int noglob; 533 534 if (!v || !v[0]) 535 return saveblk(v); 536 537 noglob = adrof(STRnoglob) != 0; 538 539 if (gflg & G_CSH) 540 /* 541 * Expand back-quote, tilde and brace 542 */ 543 vl = vo = globexpand(v, noglob); 544 else 545 vl = vo = saveblk(v); 546 547 if (!noglob && (gflg & G_GLOB)) { 548 cleanup_push(vo, blk_cleanup); 549 vl = libglob(vo); 550 if (vl == vo) 551 cleanup_ignore(vo); 552 cleanup_until(vo); 553 } 554 else 555 trim(vl); 556 557 return vl; 558 } 559 560 Char ** 561 glob_all_or_error(Char **v) 562 { 563 int gflag; 564 565 gflag = tglob(v); 566 if (gflag) { 567 v = globall(v, gflag); 568 if (v == NULL) 569 stderror(ERR_NAME | ERR_NOMATCH); 570 } else { 571 v = saveblk(v); 572 trim(v); 573 } 574 return v; 575 } 576 577 void 578 rscan(Char **t, void (*f) (Char)) 579 { 580 Char *p; 581 582 while ((p = *t++) != NULL) 583 while (*p) 584 (*f) (*p++); 585 } 586 587 void 588 trim(Char **t) 589 { 590 Char *p; 591 592 while ((p = *t++) != NULL) 593 while (*p) { 594 #if INVALID_BYTE != 0 595 if ((*p & INVALID_BYTE) != INVALID_BYTE) /* *p < INVALID_BYTE */ 596 #endif 597 *p &= TRIM; 598 p++; 599 } 600 } 601 602 int 603 tglob(Char **t) 604 { 605 int gflag; 606 const Char *p; 607 608 gflag = 0; 609 while ((p = *t++) != NULL) { 610 if (*p == '~' || *p == '=') 611 gflag |= G_CSH; 612 else if (*p == '{' && 613 (p[1] == '\0' || (p[1] == '}' && p[2] == '\0'))) 614 continue; 615 while (*p != '\0') { 616 if (*p == '`') { 617 gflag |= G_CSH; 618 #ifdef notdef 619 /* 620 * We do want to expand echo `echo '*'`, so we don't\ 621 * use this piece of code anymore. 622 */ 623 p++; 624 while (*p && *p != '`') 625 if (*p++ == '\\') { 626 if (*p) /* Quoted chars */ 627 p++; 628 else 629 break; 630 } 631 if (!*p) /* The matching ` */ 632 break; 633 #endif 634 } 635 else if (*p == '{') 636 gflag |= G_CSH; 637 else if (isglob(*p)) 638 gflag |= G_GLOB; 639 else if (symlinks == SYM_EXPAND && 640 p[1] && ISDOTDOT(p) && (p == *(t-1) || *(p-1) == '/') ) 641 gflag |= G_CSH; 642 p++; 643 } 644 } 645 return gflag; 646 } 647 648 /* 649 * Command substitute cp. If literal, then this is a substitution from a 650 * << redirection, and so we should not crunch blanks and tabs, separating 651 * words only at newlines. 652 */ 653 Char ** 654 dobackp(Char *cp, int literal) 655 { 656 struct Strbuf word = Strbuf_INIT; 657 struct blk_buf bb = BLK_BUF_INIT; 658 Char *lp, *rp, *ep; 659 660 cleanup_push(&bb, bb_cleanup); 661 cleanup_push(&word, Strbuf_cleanup); 662 for (;;) { 663 for (lp = cp; *lp != '\0' && *lp != '`'; lp++) 664 ; 665 Strbuf_appendn(&word, cp, lp - cp); 666 if (*lp == 0) 667 break; 668 lp++; 669 for (rp = lp; *rp && *rp != '`'; rp++) 670 if (*rp == '\\') { 671 rp++; 672 if (!*rp) 673 goto oops; 674 } 675 if (!*rp) { 676 oops: 677 cleanup_until(&bb); 678 stderror(ERR_UNMATCHED, '`'); 679 } 680 ep = Strnsave(lp, rp - lp); 681 cleanup_push(ep, xfree); 682 backeval(&bb, &word, ep, literal); 683 cleanup_until(ep); 684 cp = rp + 1; 685 } 686 if (word.len != 0) 687 pword(&bb, &word); 688 cleanup_ignore(&bb); 689 cleanup_until(&bb); 690 return bb_finish(&bb); 691 } 692 693 694 static void 695 backeval(struct blk_buf *bb, struct Strbuf *word, Char *cp, int literal) 696 { 697 ssize_t icnt; 698 Char c, *ip; 699 struct command faket; 700 int hadnl; 701 int pvec[2], quoted; 702 Char *fakecom[2], ibuf[BUFSIZE]; 703 704 hadnl = 0; 705 icnt = 0; 706 if (!literal) { 707 for (ip = cp; (*ip & QUOTE) != 0; ip++) 708 continue; 709 quoted = *ip == '\0'; 710 } else 711 quoted = literal; 712 faket.t_dtyp = NODE_COMMAND; 713 faket.t_dflg = F_BACKQ; 714 faket.t_dlef = 0; 715 faket.t_drit = 0; 716 faket.t_dspr = 0; 717 faket.t_dcom = fakecom; 718 fakecom[0] = STRfakecom1; 719 fakecom[1] = 0; 720 721 /* 722 * We do the psave job to temporarily change the current job so that the 723 * following fork is considered a separate job. This is so that when 724 * backquotes are used in a builtin function that calls glob the "current 725 * job" is not corrupted. We only need one level of pushed jobs as long as 726 * we are sure to fork here. 727 */ 728 psavejob(); 729 cleanup_push(&faket, psavejob_cleanup); /* faket is only a marker */ 730 731 /* 732 * It would be nicer if we could integrate this redirection more with the 733 * routines in sh.sem.c by doing a fake execute on a builtin function that 734 * was piped out. 735 */ 736 mypipe(pvec); 737 cleanup_push(&pvec[0], open_cleanup); 738 cleanup_push(&pvec[1], open_cleanup); 739 if (pfork(&faket, -1) == 0) { 740 jmp_buf_t osetexit; 741 struct command *t; 742 size_t omark; 743 744 xclose(pvec[0]); 745 (void) dmove(pvec[1], 1); 746 (void) dmove(SHDIAG, 2); 747 initdesc(); 748 closem(); 749 arginp = cp; 750 for (arginp = cp; *cp; cp++) { 751 *cp &= TRIM; 752 if (is_set(STRcsubstnonl) && (*cp == '\n' || *cp == '\r')) 753 *cp = ' '; 754 } 755 756 /* 757 * In the child ``forget'' everything about current aliases or 758 * eval vectors. 759 */ 760 alvec = NULL; 761 evalvec = NULL; 762 alvecp = NULL; 763 evalp = NULL; 764 765 omark = cleanup_push_mark(); 766 getexit(osetexit); 767 for (;;) { 768 struct wordent paraml1; 769 initlex(¶ml1); 770 771 (void) setexit(); 772 justpr = 0; 773 774 if (haderr) { 775 /* unwind */ 776 doneinp = 0; 777 cleanup_pop_mark(omark); 778 resexit(osetexit); 779 reset(); 780 } 781 if (seterr) { 782 xfree(seterr); 783 seterr = NULL; 784 } 785 786 freelex(¶ml1); 787 (void) lex(¶ml1); 788 cleanup_push(¶ml1, lex_cleanup); 789 if (seterr) 790 stderror(ERR_OLD); 791 alias(¶ml1); 792 t = syntax(paraml1.next, ¶ml1, 0); 793 cleanup_push(t, syntax_cleanup); 794 /* The F_BACKQ flag must set so the job output is correct if 795 * printexitvalue is set. If it's not set, the job output 796 * will have "Exit N" appended where N is the exit status. */ 797 if (t) 798 t->t_dflg = F_BACKQ|F_NOFORK; 799 if (seterr) 800 stderror(ERR_OLD); 801 #ifdef SIGTSTP 802 signal(SIGTSTP, SIG_IGN); 803 #endif 804 #ifdef SIGTTIN 805 signal(SIGTTIN, SIG_IGN); 806 #endif 807 #ifdef SIGTTOU 808 signal(SIGTTOU, SIG_IGN); 809 #endif 810 execute(t, -1, NULL, NULL, TRUE); 811 812 cleanup_until(¶ml1); 813 } 814 } 815 cleanup_until(&pvec[1]); 816 c = 0; 817 ip = NULL; 818 do { 819 ssize_t cnt = 0; 820 821 for (;;) { 822 if (icnt == 0) { 823 ip = ibuf; 824 icnt = wide_read(pvec[0], ibuf, BUFSIZE, 0); 825 if (icnt <= 0) 826 goto eof; 827 } 828 if (hadnl) 829 break; 830 --icnt; 831 c = (*ip++ & TRIM); 832 if (c == 0) 833 break; 834 #if defined(WINNT_NATIVE) || defined(__CYGWIN__) 835 if (c == '\r') 836 c = ' '; 837 #endif /* WINNT_NATIVE || __CYGWIN__ */ 838 if (c == '\n') { 839 /* 840 * Continue around the loop one more time, so that we can eat 841 * the last newline without terminating this word. 842 */ 843 hadnl = 1; 844 continue; 845 } 846 if (!quoted && (c == ' ' || c == '\t')) 847 break; 848 cnt++; 849 if (c == '\\' || quoted) 850 c |= QUOTE; 851 Strbuf_append1(word, c); 852 } 853 /* 854 * Unless at end-of-file, we will form a new word here if there were 855 * characters in the word, or in any case when we take text literally. 856 * If we didn't make empty words here when literal was set then we 857 * would lose blank lines. 858 */ 859 if (c != 0 && (cnt || literal)) 860 pword(bb, word); 861 hadnl = 0; 862 } while (c > 0); 863 eof: 864 cleanup_until(&pvec[0]); 865 pwait(); 866 cleanup_until(&faket); /* psavejob_cleanup(); */ 867 } 868 869 static void 870 pword(struct blk_buf *bb, struct Strbuf *word) 871 { 872 Char *s; 873 874 s = Strbuf_finish(word); 875 bb_append(bb, s); 876 *word = Strbuf_init; 877 } 878 879 int 880 Gmatch(const Char *string, const Char *pattern) 881 { 882 return Gnmatch(string, pattern, NULL); 883 } 884 885 int 886 Gnmatch(const Char *string, const Char *pattern, const Char **endstr) 887 { 888 Char ***fblk, **p; 889 const Char *tstring = string; 890 int gpol = 1, gres = 0; 891 892 if (*pattern == '^') { 893 gpol = 0; 894 pattern++; 895 } 896 897 fblk = xmalloc(sizeof(Char ***)); 898 *fblk = xmalloc(GLOBSPACE * sizeof(Char *)); 899 (*fblk)[0] = Strsave(pattern); 900 (*fblk)[1] = NULL; 901 902 cleanup_push(fblk, blk_indirect_cleanup); 903 expbrace(fblk, NULL, GLOBSPACE); 904 905 if (endstr == NULL) 906 /* Exact matches only */ 907 for (p = *fblk; *p; p++) 908 gres |= t_pmatch(string, *p, &tstring, 1) == 2 ? 1 : 0; 909 else { 910 const Char *end; 911 912 /* partial matches */ 913 end = Strend(string); 914 for (p = *fblk; *p; p++) 915 if (t_pmatch(string, *p, &tstring, 1) != 0) { 916 gres |= 1; 917 if (end > tstring) 918 end = tstring; 919 } 920 *endstr = end; 921 } 922 923 cleanup_until(fblk); 924 return(gres == gpol); 925 } 926 927 /* t_pmatch(): 928 * Return 2 on exact match, 929 * Return 1 on substring match. 930 * Return 0 on no match. 931 * *estr will point to the end of the longest exact or substring match. 932 */ 933 int 934 t_pmatch(const Char *string, const Char *pattern, const Char **estr, int cs) 935 { 936 Char stringc, patternc, rangec; 937 int match, negate_range; 938 const Char *pestr, *nstring; 939 940 for (nstring = string;; string = nstring) { 941 stringc = *nstring++ & TRIM; 942 patternc = *pattern++ & TRIM; 943 switch (patternc) { 944 case '\0': 945 *estr = string; 946 return (stringc == '\0' ? 2 : 1); 947 case '?': 948 if (stringc == 0) 949 return (0); 950 break; 951 case '*': 952 if (!*pattern) { 953 *estr = Strend(string); 954 return (2); 955 } 956 pestr = NULL; 957 958 for (;;) { 959 switch(t_pmatch(string, pattern, estr, cs)) { 960 case 0: 961 break; 962 case 1: 963 pestr = *estr;/*FIXME: does not guarantee longest match */ 964 break; 965 case 2: 966 return 2; 967 default: 968 abort(); /* Cannot happen */ 969 } 970 stringc = *string++ & TRIM; 971 if (!stringc) 972 break; 973 } 974 975 if (pestr) { 976 *estr = pestr; 977 return 1; 978 } 979 else 980 return 0; 981 982 case '[': 983 match = 0; 984 if ((negate_range = (*pattern == '^')) != 0) 985 pattern++; 986 while ((rangec = *pattern++ & TRIM) != '\0') { 987 if (rangec == ']') 988 break; 989 if (match) 990 continue; 991 if (*pattern == '-' && pattern[1] != ']') { 992 Char rangec2; 993 pattern++; 994 rangec2 = *pattern++ & TRIM; 995 match = (globcharcoll(stringc, rangec2, 0) <= 0 && 996 globcharcoll(rangec, stringc, 0) <= 0); 997 } 998 else 999 match = (stringc == rangec); 1000 } 1001 if (rangec == '\0') 1002 stderror(ERR_NAME | ERR_MISSING, ']'); 1003 if ((!match) && (stringc == '\0')) 1004 return (0); 1005 if (match == negate_range) 1006 return (0); 1007 break; 1008 default: 1009 if (cs ? patternc != stringc 1010 : Tolower(patternc) != Tolower(stringc)) 1011 return (0); 1012 break; 1013 } 1014 } 1015 } 1016