/*
* -------------------------------------------------------
* Copyright (C) 2003-2007 Tommi Saviranta <wnd@iki.fi>
* (C) 1998-2002 Sebastian Kienzl <zap@riot.org>
* -------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* ifdef HAVE_CONFIG_H */
#include "match.h"
#include "tools.h"
#include "common.h"
#include <string.h>
/**
* match:
* @string: String to match
* @pattern: Pattern to match against
*
* Issues: This algorithm is non-greedy. It will not match string "foobar"
* against pattern "*ob*".
*
* Return value: 1 if string matches patters, 0 if not.
*/
int
match(const char *string, const char *pattern)
{
char *str, *pat;
int str_p, pat_p;
if (string == NULL || pattern == NULL) {
return 0;
}
str = xstrdup(string);
upcase(str);
pat = xstrdup(pattern);
upcase(pat);
str_p = pat_p = 0;
/* Then to the matching part. */
while (1) {
if (str[str_p] == '\0') {
if ((pat[pat_p] == '*' && pat[pat_p + 1] == '\0')
|| pat[pat_p] == '\0') {
xfree(str);
xfree(pat);
return 1;
}
}
if (str[str_p] == '\0' || pat[pat_p] == '\0') {
xfree(str);
xfree(pat);
return 0;
}
if (str[str_p] == pat[pat_p] || pat[pat_p] == '?') {
str_p++;
pat_p++;
} else if (pat[pat_p] == '*') {
if (str[str_p] == pat[pat_p + 1]) {
pat_p++;
} else if (pat[pat_p + 1] == str[str_p + 1]) {
str_p++;
pat_p++;
} else {
str_p++;
}
} else {
xfree(str);
xfree(pat);
return 0;
}
}
} /* int match(const char *string, const char *pattern) */
/**
* match:
* @string: String to match
* @pattern: Pattern to match against
* @foo: String to replace. Can be NULL.
* @foo_len: Length of foo or -1 if unknown
* @replace: String to replace foo with. Can be NULL.
*
* Return value: 1 if string matches patters, 0 if not.
*/
int
match_replace(const char *string, const char *pattern, const char *foo,
const int foo_len, const char *replace)
{
char *pat;
int pat_len;
int replace_len;
int foo_len_real;
int at;
int ret;
/* Nothing to replace? Don't waste time here. */
if (foo == NULL || replace == NULL) {
return match(string, pattern);
}
/* Replace "@@" in pattern with "replace" if it was given. */
replace_len = (int) strlen(replace);
foo_len_real = foo_len == -1 ? strlen(foo) : foo_len;
for (at = strlen(pattern) - foo_len_real; at >= 0; at--) {
if (xstrncmp(pattern + at, foo, foo_len_real) == 0) {
break;
}
}
/* No "foo" found. */
if (at == -1) {
return match(string, pattern);
}
pat_len = strlen(pattern) + replace_len - foo_len_real + 1;
pat = (char *) xmalloc(pat_len);
memcpy(pat, pattern, at);
memcpy(pat + at, replace, replace_len);
memcpy(pat + at + replace_len, pattern + at + foo_len_real,
strlen(pattern) - at - foo_len_real);
pat[pat_len - 1] = '\0';
ret = match(string, pat);
xfree(pat);
return ret;
} /* int match_replace(const char *string, const char *pattern,
const char *foo, const int foo_len, const char *replace) */
syntax highlighted by Code2HTML, v. 0.9.1