/* Flexible string comparison function with wildcard support
 * Version 1.1 (11/06/07)
 * Copyright (C) 2007 Daniel Collins <solemnwarning@solemnwarning.net>
 *
 * Released to public domain, I take no responsibility for this code or it's
 * users, it may work, it may not, it may destroy the universe but it has no
 * warranty, so no sending lawyers my way if this code breaks somthing.
 *
 * If you find a bug please email me :)
*/

/* Version history:
 *
 * 1.0 (11/06/2007):
 * Initial release
 *
 * 1.1 (11/06/2007):
 * Fixed a bug:
 *	maxlen was read with stdarg, whether the STR_MAXLEN flag was set or
 *	not, this causes undefined behavior according to C so it could crash
 *	or cause other errors on some platforms.
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>

#define STR_NOCASE	0x0001
#define STR_MAXLEN	0x0002
#define STR_WCARD	0x0004

/* Check two strings to compare if they are the same
 * Returns 1 for match, 0 for no match
 *
 * Flags:
 * STR_NOCASE	Makes string_cmp() ignore case
 * STR_MAXLEN	Causes strncmp() behaviour, pass 'n' as ...
 * STR_WCARD	Enable support for the wildcards '?' and '*'
*/
int string_cmp(const char* str1, const char* str2, int flags, ...) {
	size_t maxlen = 0, parsed = 0;
	
	va_list args;
	va_start(args, flags);
	if(flags & STR_MAXLEN) {
		maxlen = va_arg(args, size_t);
	}
	va_end(args);
	
	while(maxlen == 0 || parsed < maxlen) {
		if(str1[0] == str2[0]) {
			if(str1[0] == '\0') {
				return(1);
			}
			str1++;
			str2++;
		}else if(flags & STR_NOCASE && tolower(str1[0]) == tolower(str2[0])) {
			str1++;
			str2++;
		}else if(flags & STR_WCARD && (str1[0] == '?' || str2[0] == '?' || str1[0] == '*' || str2[0] == '*')) {
			if((str1[0] == '*' && str1[1] == '\0') || (str2[0] == '*' && str2[1] == '\0')) {
				return(1);
			}else if((str1[0] == '?' && str2[0] != '\0') || (str2[0] == '?' && str1[0] != '\0')) {
				str1++;
				str2++;
			}else if(str1[0] == '*') {
				str2++;
				if(str1[1] == str2[0]) {
					str1++;
				}
			}else if(str2[0] == '*') {
				str1++;
				if(str2[1] == str1[0]) {
					str2++;
				}
			}else{
				return(0);
			}
		}else{
			return(0);
		}
		parsed++;
	}
	return(1);
}
