glob.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include <stdio.h>
  2. #include "../linux/glob.h"
  3. /* Like glob_match, but match PATTERN against any final segment of TEXT. */
  4. static int glob_match_after_star(char *pattern, char *text)
  5. {
  6. register char *p = pattern, *t = text;
  7. register char c, c1;
  8. while ((c = *p++) == '?' || c == '*')
  9. if (c == '?' && *t++ == '\0')
  10. return 0;
  11. if (c == '\0')
  12. return 1;
  13. if (c == '\\')
  14. c1 = *p;
  15. else
  16. c1 = c;
  17. while (1) {
  18. if ((c == '[' || *t == c1) && glob_match(p - 1, t))
  19. return 1;
  20. if (*t++ == '\0')
  21. return 0;
  22. }
  23. }
  24. /* Return nonzero if PATTERN has any special globbing chars in it. */
  25. static int glob_pattern_p(char *pattern)
  26. {
  27. register char *p = pattern;
  28. register char c;
  29. int open = 0;
  30. while ((c = *p++) != '\0')
  31. switch (c) {
  32. case '?':
  33. case '*':
  34. return 1;
  35. case '[': /* Only accept an open brace if there is a close */
  36. open++; /* brace to match it. Bracket expressions must be */
  37. continue; /* complete, according to Posix.2 */
  38. case ']':
  39. if (open)
  40. return 1;
  41. continue;
  42. case '\\':
  43. if (*p++ == '\0')
  44. return 0;
  45. }
  46. return 0;
  47. }
  48. /* Match the pattern PATTERN against the string TEXT;
  49. return 1 if it matches, 0 otherwise.
  50. A match means the entire string TEXT is used up in matching.
  51. In the pattern string, `*' matches any sequence of characters,
  52. `?' matches any character, [SET] matches any character in the specified set,
  53. [!SET] matches any character not in the specified set.
  54. A set is composed of characters or ranges; a range looks like
  55. character hyphen character (as in 0-9 or A-Z).
  56. [0-9a-zA-Z_] is the set of characters allowed in C identifiers.
  57. Any other character in the pattern must be matched exactly.
  58. To suppress the special syntactic significance of any of `[]*?!-\',
  59. and match the character exactly, precede it with a `\'.
  60. */
  61. int glob_match(char *pattern, char *text)
  62. {
  63. register char *p = pattern, *t = text;
  64. register char c;
  65. while ((c = *p++) != '\0')
  66. switch (c) {
  67. case '?':
  68. if (*t == '\0')
  69. return 0;
  70. else
  71. ++t;
  72. break;
  73. case '\\':
  74. if (*p++ != *t++)
  75. return 0;
  76. break;
  77. case '*':
  78. return glob_match_after_star(p, t);
  79. case '[':
  80. {
  81. register char c1 = *t++;
  82. int invert;
  83. if (!c1)
  84. return (0);
  85. invert = ((*p == '!') || (*p == '^'));
  86. if (invert)
  87. p++;
  88. c = *p++;
  89. while (1) {
  90. register char cstart = c, cend = c;
  91. if (c == '\\') {
  92. cstart = *p++;
  93. cend = cstart;
  94. }
  95. if (c == '\0')
  96. return 0;
  97. c = *p++;
  98. if (c == '-' && *p != ']') {
  99. cend = *p++;
  100. if (cend == '\\')
  101. cend = *p++;
  102. if (cend == '\0')
  103. return 0;
  104. c = *p++;
  105. }
  106. if (c1 >= cstart && c1 <= cend)
  107. goto match;
  108. if (c == ']')
  109. break;
  110. }
  111. if (!invert)
  112. return 0;
  113. break;
  114. match:
  115. /* Skip the rest of the [...] construct that already matched. */
  116. while (c != ']') {
  117. if (c == '\0')
  118. return 0;
  119. c = *p++;
  120. if (c == '\0')
  121. return 0;
  122. else if (c == '\\')
  123. ++p;
  124. }
  125. if (invert)
  126. return 0;
  127. break;
  128. }
  129. default:
  130. if (c != *t++)
  131. return 0;
  132. }
  133. return *t == '\0';
  134. }