1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
41 * nsWildCard.cpp: shell-like wildcard match routines
43 * See nsIZipReader.findEntries documentation in nsIZipReader.idl for
44 * a description of the syntax supported by the routines in this file.
50 #include "nsWildCard.h"
54 /* ----------------------------- _valid_subexp ------------------------------ */
58 _valid_subexp(char *expr
, char stop
)
65 while(expr
[x
] && (expr
[x
] != stop
)) {
68 if(tld
) return INVALID_SXP
;
78 if((!expr
[++x
]) || (expr
[x
] == ']'))
80 for(;expr
[x
] && (expr
[x
] != ']');++x
)
92 for(y
=x
;(expr
[y
]) && (expr
[y
] != '|') && (expr
[y
] != ')');++y
)
100 t
= _valid_subexp(&expr
[x
],expr
[y
]);
122 if((!stop
) && (!nsc
))
124 return ((expr
[x
] == stop
) ? x
: INVALID_SXP
);
128 NS_WildCardValid(char *expr
)
132 x
= _valid_subexp(expr
, '\0');
133 return (x
< 0 ? x
: VALID_SXP
);
137 /* ----------------------------- _shexp_match ----------------------------- */
144 static int _shexp_match(char *str
, char *expr
, PRBool case_insensitive
);
147 _handle_union(char *str
, char *expr
, PRBool case_insensitive
)
149 char *e2
= (char *) PR_Malloc(sizeof(char)*strlen(expr
));
150 register int t
,p2
,p1
= 1;
154 for(cp
=1;expr
[cp
] != ')';cp
++)
157 for(p2
= 0;(expr
[p1
] != '|') && (p1
!= cp
);p1
++,p2
++) {
159 e2
[p2
++] = expr
[p1
++];
162 for (t
=cp
+1; ((e2
[p2
] = expr
[t
]) != 0); ++t
,++p2
) {}
163 if(_shexp_match(str
,e2
, case_insensitive
) == MATCH
) {
177 _shexp_match(char *str
, char *expr
, PRBool case_insensitive
)
183 for(x
=0,y
=0;expr
[y
];++y
,++x
) {
184 if((!str
[x
]) && (expr
[y
] != '(') && (expr
[y
] != '$') && (expr
[y
] != '*'))
192 --x
; /* we don't want loop to increment x */
195 while(expr
[++y
] == '*'){}
199 switch(_shexp_match(&str
[x
++],&expr
[y
], case_insensitive
)) {
210 if((expr
[y
] == '$') && (expr
[y
+1] == '\0') && (!str
[x
]))
216 neg
= ((expr
[++y
] == '^') && (expr
[y
+1] != ']'));
220 if ((isalnum(expr
[y
])) && (expr
[y
+1] == '-') &&
221 (isalnum(expr
[y
+2])) && (expr
[y
+3] == ']'))
223 int start
= expr
[y
], end
= expr
[y
+2];
225 /* Droolproofing for pinheads not included */
226 if(neg
^ ((str
[x
] < start
) || (str
[x
] > end
))) {
235 for (matched
=0;expr
[y
] != ']';y
++) {
236 /* match an escaped ']' character */
237 if('\\' == expr
[y
] && ']' == expr
[y
+1]) {
240 y
++; /* move an extra char to compensate for '\\' */
243 matched
|= (str
[x
] == expr
[y
]);
245 if (neg
^ (!matched
))
250 return _handle_union(&str
[x
],&expr
[y
], case_insensitive
);
259 if(toupper(str
[x
]) != toupper(expr
[y
]))
264 if(str
[x
] != expr
[y
])
273 return (ret
? ret
: (str
[x
] ? NOMATCH
: MATCH
));
277 NS_WildCardMatch(char *str
, char *xp
, PRBool case_insensitive
) {
279 char *expr
= PL_strdup(xp
);
284 for(x
=strlen(expr
)-1;x
;--x
) {
285 if((expr
[x
] == '~') && (expr
[x
-1] != '\\')) {
287 if(_shexp_match(str
,&expr
[++x
], case_insensitive
) == MATCH
)
292 if(_shexp_match(str
,expr
, case_insensitive
) == MATCH
) {