home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2627 < prev    next >
Encoding:
Internet Message Format  |  1991-01-31  |  4.1 KB

  1. From: bernie@metapro.DIALix.oz.au (Bernd Felsche)
  2. Newsgroups: alt.sources
  3. Subject: Repost: Shell-style wildcard matching
  4. Message-ID: <1991Jan29.041342.26733@metapro.DIALix.oz.au>
  5. Date: 29 Jan 91 04:13:42 GMT
  6.  
  7. [ Sorry to those of you who are seeing this again, but I think this got    ]
  8. [ zapped somewhere, on its way to the real world. (no flames or comment)]
  9.  
  10. Thanks mainly to Rich Salz, we now have a useful shell-style 
  11. wildcard matching routine.  It took a little bashing to make it
  12. behave the same way as the Bourne shell (and Korn shell).
  13.  
  14. This posting is without the permission of Rich, though I'm sure he
  15. won't mind, as it fixes a few problems that have been unearthed.
  16.  
  17. Remember, UTSL.
  18.  
  19. --------------------cut here if you're brave----------------
  20. #!/bin/sh
  21. # manually shar'ed, so don't complain, all right?
  22. # at the end of this shar you should seen the message
  23. # "wildmat.c complete".
  24. #
  25. # Here's shar!
  26. if test -f wildmat.c
  27. then
  28.     echo wildmat.c exists, won\'t clobber.
  29.     exit 1
  30. fi
  31. echo extracting wildmat.c
  32. sed 's/^X//' > wildmat.c << 'SHAR_EOF' &&
  33. X/*
  34. X**  Do shell-style pattern matching for ?, \, [], and * characters.
  35. X**  Might not be robust in face of malformed patterns; e.g., "foo[a-"
  36. X**  could cause a segmentation violation.  It is 8bit clean.
  37. X**
  38. X**  Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
  39. X**  Special thanks to Lars Mathiesen for the ABORT code.  This can greatly
  40. X**  speed up failing wildcard patterns.  For example:
  41. X**    pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-*
  42. X**    text 1:     -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1
  43. X**    text 2:     -adobe-courier-bold-o-normal--12-120-75-75-p-70-iso8859-1
  44. X**  Text 1 matches with 51 calls, while text 2 fails with 54 calls.  Without
  45. X**  the ABORT, then it takes 22310 calls to fail.  Ugh.
  46. X**
  47. X**  bernie    613-01 91/01/04 19:34 
  48. X**  Fixed problem with terminating * not matching with (null)
  49. X**
  50. X**  bernie    597-00 91/01/08 11:24 
  51. X**  Fixed shell glob negate from '^' to '!'
  52. X**
  53. X**  bernie    597-02 91/01/21 13:43 
  54. X**    Fixed . matching * or ? on first char.
  55. X*/
  56. X
  57. X#define TRUE        1
  58. X#define FALSE        0
  59. X#define ABORT        -1
  60. X
  61. Xstatic int
  62. XStar(s, p)
  63. X    register char    *s;
  64. X    register char    *p;
  65. X{
  66. X    while (DoMatch(s, p) == FALSE) /* gobble up * match */
  67. X    if (*++s == '\0') return ABORT;
  68. X    return TRUE;
  69. X}
  70. X
  71. X
  72. Xstatic int
  73. XDoMatch(s, p)    /* match string "s" to pattern "p" */
  74. X    register char    *s;
  75. X    register char    *p;
  76. X{
  77. X    register int      last;
  78. X    register int      matched;
  79. X    register int      reverse;
  80. X
  81. X    for ( ; *p; s++, p++) { /* parse the string to end */
  82. X
  83. X    if (*s == '\0')
  84. X        return *p == '*' && *++p == '\0' ? TRUE : ABORT;
  85. X
  86. X    switch (*p) { /* parse pattern */
  87. X
  88. X    case '\\':
  89. X        /* Literal match with following character. */
  90. X        p++;
  91. X        /* FALLTHROUGH */
  92. X
  93. X    default: /*literal match*/
  94. X        if (*s != *p)
  95. X        return FALSE;
  96. X        continue;
  97. X
  98. X    case '?':
  99. X        /* Match anything. */
  100. X        continue;
  101. X
  102. X    case '*':
  103. X        /* Trailing star matches everything. */
  104. X        return( *++p ? Star(s, p) : TRUE );
  105. X
  106. X    case '[':
  107. X        /* [!....] means inverse character class. */
  108. X        if (reverse = p[1] == '!') p++;
  109. X
  110. X        for (last = 0400, matched = FALSE; *++p && *p != ']'; last = *p)
  111. X        /* This next line requires a good C compiler. */
  112. X        /*     range?        (in bounds)                  (equal) */
  113. X        if ( ( *p == '-' ) ? (*s <= *++p && *s >= last ) : (*s == *p) )
  114. X            matched = TRUE;
  115. X
  116. X        if (matched == reverse) return FALSE;
  117. X        continue;
  118. X
  119. X    }
  120. X    }
  121. X
  122. X    return *s == '\0';
  123. X}
  124. X
  125. X
  126. Xint wildmat(s, p)
  127. X    char    *s;
  128. X    char    *p;
  129. X{
  130. X    if ( (*p == '?' || *p == '*' ) && *s == '.' ) {
  131. X        return FALSE;
  132. X    } else {
  133. X        return DoMatch(s, p) == TRUE;
  134. X    }
  135. X}
  136. SHAR_EOF
  137. chmod 0644 wildmat.c ||
  138. echo extract failed - squezze it yourself!
  139. if test `wc -c < wildmat.c` -ne 2524
  140. then
  141.     echo possible file size error with wildmat.c
  142.     exit 2
  143. fi
  144. echo "wildmat.c complete"
  145.  
  146. exit    # because you shouldn't execute my signature
  147. -- 
  148.  _--_|\  Bernd Felsche         #include <std/disclaimer.h>
  149. /      \ Metapro Systems, 328 Albany Highway, Victoria Park,  Western Australia
  150. \_.--._/ Fax: +61 9 472 3337   Phone: +61 9 362 9355  TZ=WST-8
  151.       v  E-Mail: bernie@metapro.DIALix.oz.au | bernie@DIALix.oz.au
  152.