summaryrefslogtreecommitdiff
path: root/dviware/quicspool/libglob/glob.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/quicspool/libglob/glob.c
Initial commit
Diffstat (limited to 'dviware/quicspool/libglob/glob.c')
-rw-r--r--dviware/quicspool/libglob/glob.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/dviware/quicspool/libglob/glob.c b/dviware/quicspool/libglob/glob.c
new file mode 100644
index 0000000000..a407361557
--- /dev/null
+++ b/dviware/quicspool/libglob/glob.c
@@ -0,0 +1,223 @@
+static char *rcs= "$Header: glob.c,v 1.1 88/01/15 12:15:45 simpson Rel $";
+/*
+$Log: glob.c,v $
+ * Revision 1.1 88/01/15 12:15:45 simpson
+ * initial release
+ *
+ * Revision 0.1 87/12/11 17:18:05 simpson
+ * beta test
+ *
+*/
+#include "glob.h"
+
+#define SLOP 5
+#define MAX_SET 0177
+
+/* control codes for regular expression evaluation */
+#define PATTERN_ANY '?'
+#define PATTERN_CHARACTER 'X'
+#define PATTERN_END '$'
+#define PATTERN_SET '['
+#define PATTERN_SET_MEMBER 'M'
+#define PATTERN_SET_RANGE '-'
+#define PATTERN_STAR '*'
+
+/*
+ * Examples (=> denotes `compiles into')
+ *
+ * a => Xa
+ * ? => ?
+ * [x0-9] => [^EMx-09 (^E is control-E)
+ * * => *
+ * END => $
+ *
+ * a?[x0-9]* => Xa?[^EMx-09*$
+ */
+
+glob_compile (pattern, buffer)
+char *pattern;
+char *buffer; /* compiled pattern */
+{
+ char *x; /* pointer into compiled pattern */
+ int c;
+ int result;
+
+ if (pattern == 0 || pattern[0] == 0)
+ return(GLOB_PATTERN_EMPTY);
+
+ x = buffer;
+ while (x < &buffer[GLOB_MAX_PATTERN - SLOP]) {
+ c = *pattern++;
+ if (c == 0) {
+ *x++ = PATTERN_END;
+ return(GLOB_OK);
+ }
+
+ switch (c) {
+ case '?':
+ *x++ = PATTERN_ANY;
+ continue;
+
+ case '[':
+ if ((result = compile_set(pattern, x, &buffer[GLOB_MAX_PATTERN - SLOP])) < 0)
+ return(result);
+ pattern += result + 1;
+ x += x[1] + 2;
+ continue;
+
+ case '*':
+ *x++ = PATTERN_STAR;
+ continue;
+
+ default:
+ *x++ = PATTERN_CHARACTER;
+ *x++ = c;
+ continue;
+ }
+ }
+ return(GLOB_PATTERN_TOO_BIG);
+}
+
+int glob_execute (pattern, s)
+char *pattern; /* compiled pattern */
+char *s; /* string to be matched against */
+{
+ char *current;
+ int result;
+
+ for (;;)
+ switch (*pattern++) {
+ case PATTERN_ANY:
+ if (*s++)
+ continue;
+ return(0);
+
+ case PATTERN_CHARACTER:
+ if (*pattern++ == *s++)
+ continue;
+ return(0);
+
+ case PATTERN_END:
+ return(*s == 0);
+
+ case PATTERN_SET:
+ if ((result = in_set(pattern, *s++)) == 1) {
+ pattern += *pattern + 1;
+ continue;
+ }
+ return(result);
+
+ case PATTERN_STAR:
+ current = s;
+ while (*s++)
+ continue;
+ do {
+ s--;
+ if (result = glob_execute(pattern, s))
+ return(result);
+ } while (s > current);
+ return(0);
+
+ default:
+ return(GLOB_EXECUTION_ERROR);
+ }
+}
+
+int glob_match (pattern, s)
+char *pattern;
+char *s;
+{
+ int result;
+ char buffer[GLOB_MAX_PATTERN];
+
+ if ((result = glob_compile(pattern, buffer)) < 0)
+ return(result);
+ else
+ return(glob_execute(buffer, s));
+}
+
+/* returns 1 if character c is member of set and 0 otherwise */
+static int in_set (set, c)
+char *set; /* compiled set pattern */
+char c;
+{
+ int n;
+
+ if (c == 0)
+ return(0);
+ n = *set++;
+ while (n > 0)
+ switch (*set++) {
+ case PATTERN_SET_MEMBER:
+ if (*set++ == c)
+ return(1);
+ n -= 2;
+ continue;
+
+ case PATTERN_SET_RANGE:
+ if (*set++ <= c && c <= *set++)
+ return(1);
+ n -= 3;
+ continue;
+
+ default:
+ return(GLOB_EXECUTION_ERROR);
+ }
+ return(0);
+}
+
+#define IS_RANGE(s) (s[1] && s[2] && s[1] == '-' && s[2] != ']')
+
+/* compiles a set returning the number of pattern characters consumed */
+static int compile_set (pattern, x, limit)
+char *pattern;
+char *x;
+char *limit;
+{
+ char *slot; /* size of set goes here */
+ int size; /* number of bytes in compiled set */
+ char *start = pattern;
+
+ if (*pattern == 0)
+ return(GLOB_BRACKET_MISSING);
+
+ *x++ = PATTERN_SET;
+ slot = x++;
+ size = 0;
+
+ if (IS_RANGE(pattern)) {
+ if (pattern[0] > pattern[2]) /* pattern[1] == '-' */
+ return(GLOB_RANGE_INVERTED);
+ *x++ = PATTERN_SET_RANGE;
+ *x++ = pattern[0];
+ *x++ = pattern[2];
+ pattern += 3;
+ size += 3;
+ } else {
+ *x++ = PATTERN_SET_MEMBER;
+ *x++ = *pattern++;
+ size += 2;
+ }
+
+ while (*pattern != ']' && x < limit) {
+ if (*pattern == 0)
+ return(GLOB_BRACKET_MISSING);
+ if (IS_RANGE(pattern)) {
+ if (pattern[0] > pattern[2]) /* pattern[1] == '-' */
+ return(GLOB_RANGE_INVERTED);
+ *x++ = PATTERN_SET_RANGE;
+ *x++ = pattern[0];
+ *x++ = pattern[2];
+ pattern += 3;
+ size += 3;
+ } else {
+ *x++ = PATTERN_SET_MEMBER;
+ *x++ = *pattern++;
+ size += 2;
+ }
+ }
+ if (size > MAX_SET)
+ return(GLOB_SET_TOO_BIG);
+ *slot = size;
+ return(pattern - start);
+}