Subversion Repositories QNX 8.QNX8 IFS tool

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
26 pmbaty 1
/* ACC -- Automatic Compiler Configuration
2
 
3
   Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
4
   All Rights Reserved.
5
 
6
   This software is a copyrighted work licensed under the terms of
7
   the GNU General Public License. Please consult the file "ACC_LICENSE"
8
   for details.
9
 
10
   Markus F.X.J. Oberhumer
11
   <markus@oberhumer.com>
12
   http://www.oberhumer.com/
13
 */
14
 
15
 
16
#define __ACCLIB_FNMATCH_CH_INCLUDED 1
17
#if !defined(ACCLIB_PUBLIC)
18
#  define ACCLIB_PUBLIC(r,f)    r __ACCLIB_FUNCNAME(f)
19
#endif
20
 
21
 
22
/*************************************************************************
23
//
24
**************************************************************************/
25
 
26
typedef struct {
27
    const acc_hbyte_p s;
28
    const acc_hbyte_p s_start;
29
    int f;
30
    int f_escape;
31
    int f_casefold;
32
} acc_fnmatch_internal_t;
33
 
34
 
35
static int __ACCLIB_FUNCNAME(acc_fnmatch_internal) (const acc_hbyte_p p, acc_fnmatch_internal_t* a)
36
{
37
    const acc_hbyte_p s = a->s;
38
    int f_pathname = (a->f & (ACC_FNMATCH_PATHNAME | ACC_FNMATCH_PATHSTAR));
39
 
40
    while (*p) {
41
        switch (*p) {
42
        case '?': case '[':
43
            if (*s == 0) return 0;
44
            if (*s == '/' && f_pathname) return 0;
45
            if (*s == '.' && (a->f & ACC_FNMATCH_PERIOD) && (s == a->s_start || (f_pathname && s[-1] == '/'))) return 0;
46
            if (*p == '?') break;
47
            {
48
            int r = 0, fail = 0; unsigned char last = 0;
49
            if (*++p == '^' || *p == '!')
50
                fail = 1, ++p;
51
            do {
52
                switch (*p) {
53
                case 0:
54
                    return -1;
55
                case '-':
56
                    if (last == 0 || p[1] == ']') goto acc_label_default;
57
                    if (a->f_escape && p[1] == '\\') ++p;
58
                    if (*++p == 0) return -1;
59
                    if (!a->f_casefold && last <= *s && *s <= *p) r = 1;
60
                    else if (a->f_casefold && acc_ascii_tolower(last) <= acc_ascii_tolower(*s) && acc_ascii_tolower(*s) <= acc_ascii_tolower(*p)) r = 1;
61
                    last = 0;
62
                    continue;
63
                /* TODO: implement sets like [:alpha:] ??? */
64
                case '\\':
65
                    if (a->f_escape && *++p == 0) return -1;
66
                default: acc_label_default:
67
                    if (*s == *p) r = 1;
68
                    else if (a->f_casefold && acc_ascii_tolower(*s) == acc_ascii_tolower(*p)) r = 1;
69
                    break;
70
                }
71
                last = *p;
72
            } while (*++p != ']');
73
            if (r == fail)
74
                return 0;
75
            break;
76
        }
77
        case '*':
78
            while (*++p == '*') if (a->f & ACC_FNMATCH_PATHSTAR) f_pathname = 0;
79
            if (*s == '.' && (a->f & ACC_FNMATCH_PERIOD) && (s == a->s_start || (f_pathname && s[-1] == '/'))) return 0;
80
            if (*p == 0) {
81
                if (f_pathname) while (*s) if (*s++ == '/') return 0;
82
                return 1;
83
            }
84
            for ( ; *s; ++s) {
85
                int r;
86
                a->s = s; r = __ACCLIB_FUNCNAME(acc_fnmatch_internal)(p, a);
87
                switch (r) {
88
                case 0:  if (*s == '/' && f_pathname) return 2; break;
89
                case 2:  if (!f_pathname) break;
90
                default: return r;
91
                }
92
            }
93
            return 0;
94
        case '\\':
95
            if (a->f_escape && *++p == 0) return -1;
96
        default:
97
            if (*s == *p) break;
98
            if (a->f_casefold && acc_ascii_tolower(*s) == acc_ascii_tolower(*p)) break;
99
            return 0;
100
        }
101
        ++p, ++s;
102
    }
103
    return *s == 0;
104
}
105
 
106
 
107
ACCLIB_PUBLIC(int, acc_fnmatch) (const acc_hchar_p p, const acc_hchar_p s, int flags)
108
{
109
    int r;
110
    acc_fnmatch_internal_t args;
111
    args.s = args.s_start = (const acc_hbyte_p) s;
112
    args.f = flags;
113
    args.f_escape = !(flags & ACC_FNMATCH_NOESCAPE);
114
    args.f_casefold = (flags & ACC_FNMATCH_ASCII_CASEFOLD);
115
    r = __ACCLIB_FUNCNAME(acc_fnmatch_internal)((const acc_hbyte_p)p, &args);
116
    if (r < 0) return r;
117
    return r != 1;
118
}
119
 
120
 
121
/*
122
vi:ts=4:et
123
*/