File: wild.c

package info (click to toggle)
xmake 1.04-2
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 104 kB
  • ctags: 121
  • sloc: ansic: 1,346; makefile: 51
file content (108 lines) | stat: -rw-r--r-- 2,220 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108

/*
 *  WILD.C
 */

#include "defs.h"

#define MAXLEVELS   10

Prototype int  WildConvert(char *, char *, char *, char *);

/*
 *  Run srcBuf through the srcMat pattern matcher and if it matches
 *  convert it via dstMat into dstBuf, else dstBuf \0 len.
 */

int
WildConvert(srcBuf, dstBuf, srcMat, dstMat)
char *srcBuf;
char *dstBuf;
char *srcMat;
char *dstMat;
{
    short r = 0;
    long i;
    static short Index;
    static short SubLen[MAXLEVELS];
    static char *SubStr[MAXLEVELS];

    if (Index == MAXLEVELS)
	fatal(NULL, "maximum recursion reached in WildConvert (%s,%s,%s,%s)", srcBuf, dstBuf, srcMat, dstMat);

    /*
     *	skip non-wildcards, srcBuf must match srcMat
     */

    while (*srcMat && *srcMat != '*' && *srcMat != '?') {
	if (*srcBuf != *srcMat)
	    return(-1);
	++srcBuf;
	++srcMat;
    }

    switch(*srcMat) {
    case '\0':                      /*  match end, terminating case */
	if (*srcBuf)                /*  buf srcBuf not exhausted!   */
	    r = -1;
	break;
    case '?':                       /*  match 1 */
	if (*srcBuf == 0)           /*  match failed against srcbuf  */
	    return(-1);
	SubStr[Index] = srcBuf;
	SubLen[Index] = 1;
	++Index;
	r = WildConvert(srcBuf + 1, NULL, srcMat + 1, NULL);
	--Index;
	break;
    case '*':                       /*  match any   */
	/*
	 *  strangeness in loop is so \0 (nil string) is checked for,
	 *  it is perfectly valid for the remainder to be nil.
	 *
	 *  note: bug in NeXT's GCC -O/-O2, had to reorder r == -1 to
	 *  the right side of the &&
	 */

	r = -1;
	for (i = 0; (i == 0 || srcBuf[i-1]) && r == -1; ++i) {
	    SubStr[Index] = srcBuf;
	    SubLen[Index] = i;
	    ++Index;
	    r = WildConvert(srcBuf + i, NULL, srcMat + 1, NULL);
	    --Index;
	}
	break;
    }
    if (r == 0 && dstMat) {
	short k = 0;
	short n = -1;

	while (*dstMat) {
	    switch(*dstMat) {
	    case '%':
		n = (dstMat[1] - '1');
	    case '*':
	    case '?':
		if (*dstMat == '%')
		    ++dstMat;
		else
		    n = k++;

		if (n >= 0 && n < MAXLEVELS) {
		    memmove(dstBuf, SubStr[n], SubLen[n]);
		    dstBuf += SubLen[n];
		}
		break;
	    default:
		*dstBuf++ = *dstMat;
		break;
	    }
	    ++dstMat;
	}
	*dstBuf = 0;
    }
    return(r);
}