#include <ctype.h>
#include <limits.h>

//-----------------------------------------------------------------
// copy max n-1 chars append '\0'
char *strncpyf(char *dest, const char *src, int n)
{
	int i;
	if(n-- <= 0) return dest;
	for(i=0; i<n && *src; i++) *dest++ = *src++;
	*dest = '\0';
	return dest;
}
//-----------------------------------------------------------------
// trim blank chars from left
char *strltrimf(char *str)
{
	char *pc;

	for(pc = str; *pc>'\0' && *pc<=' '; pc++);
	if(pc > str) {
		while(*pc) *str++ = *pc++;
		*str = '\0';
	}
	return str;
}
//-----------------------------------------------------------------
// trim blank chars from right;
char *strrtrimf(char *str)
{
	char *pc;

	for(pc = str; *pc; pc++);
	while(pc > str) {
		pc--;
		if(*pc>'\0' && *pc<=' ') {*pc = '\0'; continue;}
		break;
	}
	return str;
}
//-----------------------------------------------------------------
// trim blank chars;
char *strtrimf(char *str)
{
	return strltrimf(strrtrimf(str));
}
//-----------------------------------------------------------------
// converts sring to uppercase
char *strupperf(char *str)
{
	char *pc = str;
	for(pc=str; *pc; pc++) *pc = toupper(*pc);
	return str;
}
//-----------------------------------------------------------------
// converts sring to lowercase
char *strlowerf(char *str)
{
	char *pc = str;
	for(pc=str; *pc; pc++) *pc = tolower(*pc);
	return str;
}
//-----------------------------------------------------------------
// support function for strmatchf(...)
int charmatchf(char c, char *p, char icase)
{
	int not = 0;
	int rl = 1;
	int i, ret;

	if(!c) return 0;
	if(*p == '^') {not = 1; p++;}
	if(*p == '[') {
		for(; p[rl] && p[rl]!=']'; rl++);
		p++;
	}
	else if(*p == '\\') rl++;

	for(i=0; i<rl; i++) {
		if(p[i] == '.') break;
		else if(p[i] == '_') {
			if('\0'<c && c<=' ') break;
		}
		else {
			if(p[i] == '\\') i++;
			if(icase) {
				if(tolower(c) == tolower(p[i])) break;
			}
			else {
				if(c == p[i]) break;
			}
		}
	}
	ret = (i < rl);
	if(not) ret = !ret;
	return ret;
}
// ..................................................................
// check if pattern is start sequence of str;
// return the number of matching chars if whole pattern match
// or negative number of matching chars in case of partialy match
// the pattern can contain . for one char
// \i switch the ignore case flag, default is ON
// _ for blank char '\0' < c <= ' '
// x* for any number (including zero) of occurences of x
// ^ for not
// \* , \. , \\ for '*' , '.' , '\' etc...
// [abc] for one of a,b,c
// example "^_*" anything other than blank char
// "_*token" matches token and trailing spaces
// ".*" matches anything
// ^[ \t]* any number of not tabs and not spaces
int strmatchf(char *str, char *pattern)
{
	char *p,*s;
	int icase = 1;
	int rl;
	int i,n1,nn;
 
	for(p=pattern, s=str; *p; ) {
		if(*p == '\\') {
			if(p[1] == 'i') {icase = !icase; p += 2; continue;}
		}
		n1 = 1; nn = 0;
		rl = 0;
		// find len of curr regexp
		if(p[rl] == '^') rl++;
		if(p[rl] == '[') {
			for(; p[rl] && p[rl]!=']'; rl++);
		}
		else {
			if(p[rl] == '\\') rl++;
			rl++;
		}
		if(p[rl] == '*') {rl++; n1 = 0; nn = INT_MAX;}

		// exact number of matches
		for(i=0; i<n1; i++) {
			if(!charmatchf(*s, p, icase)) break;
			s++;
		}
		if(i != n1) break;
		// any number of matches
		for(i=0; i<nn; i++) {
			if(!charmatchf(*s, p, icase)) break;
			s++;
		}
		p += rl;
	}
	if(!*p) return s - str;
	return -(s - str);
}
//-----------------------------------------------------------------
#define MAX_INT_LEN 10
// len(-2147483648) = 11
int strgetintf(const char *str, int *intval)
{
	char nbuff[MAX_INT_LEN+1];
	int nlen=0;
	int i=0;
	int val=0;
	int sign = 1;
	
	for(i=0; str[i]>'\0' && str[i]<=' '; i++);  //skip spaces
	if(str[i] == '+') i++;
	else if(str[i] == '-') {
		sign = -1;
		i++;
	}
	while(str[i]>='0' && str[i]<='9' && nlen<MAX_INT_LEN) nbuff[nlen++] = str[i++];
	nbuff[nlen] = '\0';
	if(intval == (int*)0) return i;
	for(nlen = 0; nbuff[nlen]; nlen++) val = 10*val + (nbuff[nlen] - '0');
	*intval = val * sign;
	return i;
}
//-----------------------------------------------------------------
