Esempio n. 1
0
/* strdup but trim whitespaces at head and tail */
char *
strdup_trim(const char *str)
{
	size_t	len;

	if (str == NULL)
		return NULL;

	while (IsSpace(str[0])) { str++; }
	len = strlen(str);
	while (len > 0 && IsSpace(str[len - 1])) { len--; }

	return strdup_with_len(str, len);
}
static int
MatchText(const char *t, size_t tlen, const char *p, size_t plen, List **params)
{
	while (tlen > 0 && plen > 0)
	{
		if (plen < 2 || *p != '%')
		{
			/* non-wildcard pattern char fails to match text char */
			if (*p != *t)
				return LIKE_FALSE;
		}
		else if (p[1] == '%')
		{
			/* %% is % */
			NextByte(p, plen);
			if (*p != *t)
				return LIKE_FALSE;
		}
		else
		{
			const char *begin = p;
			const char *w = t;
			char		firstpat;

			/* Skip until the type specifer */
			p = strpbrk(begin + 1, "diouxXeEfFgGaAcspm");
			if (p == NULL)
				return LIKE_FALSE;	/* bad format */
			p++;
			plen -= p - begin;
			if (plen <= 0)
			{
				if (params)
					*params = lcons(strdup_with_len(t, tlen), *params);
				return LIKE_TRUE;	/* matches everything. */
			}

			/*
			 * Otherwise, scan for a text position at which we can match the
			 * rest of the pattern.
			 */
			firstpat = *p;

			while (tlen > 0)
			{
				/*
				 * Optimization to prevent most recursion: don't recurse
				 * unless first pattern byte matches first text byte.
				 */
				if (*t == firstpat)
				{
					int		matched = MatchText(t, tlen, p, plen, params);

					if (matched == LIKE_TRUE && params)
						*params = lcons(strdup_with_len(w, t - w), *params);
					if (matched != LIKE_FALSE)
						return matched;		/* TRUE or ABORT */
				}

				NextChar(t, tlen);
			}

			/*
			 * End of text with no match, so no point in trying later places
			 * to start matching this pattern.
			 */
			return LIKE_ABORT;
		}

		NextByte(t, tlen);
		NextByte(p, plen);
	}
	if (tlen > 0)
		return LIKE_FALSE;		/* end of pattern, but not of text */

	/* End of text string.	Do we have matching pattern remaining? */
	while (plen > 0 && *p == '%')
	{
		const char *begin = p;
		p = strpbrk(begin + 1, "diouxXeEfFgGaAcspm");
		if (p == NULL)
			return LIKE_FALSE;	/* bad format */
		p++;
		plen -= p - begin;
	}
	if (plen <= 0)
		return LIKE_TRUE;

	/*
	 * End of text with no match, so no point in trying later places to start
	 * matching this pattern.
	 */
	return LIKE_ABORT;
}