/*****
 NAME
	cstring-test.m - test program for CString class
 VERSION
	$Id$
 CHANGELOG
	$Log$
 */

#include <coconut/cstring.h>
#include <coconut/cconststr.h>
#include <coconut/cpagealloc.h>
#include <coconut/cmemalloc.h>
#include <stdio.h>
#include <stdlib.h>

void print_str(const utf8_char * msg, CString * str)
{
	static const char null_str[] = "<null>" ;
	const utf8_char * ptr ;

	ptr = [str ptr] ; 
	if(ptr == NULL)
		ptr = null_str ;
	printf("[%s] str:\"%s\", size: %d\n", msg, ptr, [str size]) ;
}

void print_error(const utf8_char * msg)
{
	printf("ERROR: %s\n", msg) ;
	exit(1) ;
}

int main(int argc, char **argv)
{
	const utf8_char final[] = "The Steel Wheels Project" ;
	const utf8_char message1[] = "Steel " ;
	const utf8_char message2[] = "!?Project???" ;
	const utf8_char message3[] = "Wheel " ;
	const utf8_char message4[] = "dangerous usage. be careful." ;
	const utf8_char message5[] = "0123456789" ;
	const utf8_char message6[] = "ifmmp" ;
	const utf8_char message7[] = "   1stword, 2nd and 3rd   " ;
	const utf8_char message8[] = "nospaces" ;
	const utf8_char message9[] = " " ;
	const utf8_char message10[] = "hello\\t,\\nworld" ;
	const utf8_char addmsg1[] = "The" ;
	const utf8_char	space1[] = " \n \n a   \n \n \n" ;
	const utf8_char	space2[] = " \na   b\n   c" ;
	const utf8_char	empty[] = "" ;
	const utf8_char countspaces[] = " \t hello" ;
	size_t len ;
	u_int	count ;
	id <PString> str1 ;
	id <PString> str2 ;
	id <PString> str3 ;
	id <PString> str4 ;
	id <PConstStr>	cons1 ;

	printf("*** test program for CString class\n");

	printf("initial state:\n") ;
	str1 = [[CString alloc] init] ;
	str2 = [[CString alloc] initStringWithPtr: message2] ;
	str3 = [[CString alloc] initStringWithPtrAndPage: message3 page: 64] ;
	str4 = [[CString alloc] initStringWithPage: 128] ;
	print_str("str1", str1) ;
	print_str("str2", str2) ;
	print_str("str3", str3) ;
	print_str("str4", str4) ;

	printf("set without copy:\n") ;
	[str1 setPtr: message1 length: strlen(message1)] ;
	print_str("str1", str1) ;

	printf("set with format:\n") ;
	[str4 setFormat: "hello. str \"%s\", digit: %d, hex: %x", "S", 10, 0xa];
	print_str("str4", str4) ;

	/* appendStr */
	printf("append:\n") ;
	[str1 appendStr: str2] ;
	print_str("str1", str1) ;

	/* prependStr */
	printf("prepend:\n") ;
	[str1 prependChar: ' '] ;
	[str1 prependPtr: addmsg1] ;
	print_str("str1", str1) ;

	/* insertStr */
	printf("insert:\n") ;
	[str1 insertStr: 10 str: str3] ;
	[str1 insertChar: 15 char: 's'] ;
	print_str("str1", str1) ;

	/* remove */
	printf("remove:\n") ;
	[str1 remove: 17 length: 2] ;
	[str1 remove: [str1 length] - 3 length: 3] ;
	print_str("str1", str1) ;

	/* compare results */
	printf("checking result ... ") ;
	if([str1 comparePtr: final length: strlen(final)] == 0){
		printf("OK\n") ;
	} else {
		printf("FAILED\n") ;
		print_error("covertion was failed !!!") ;
	}

	/* make upper cases */
	printf("to upper:\n") ;
	[str1 toUpper] ;
	print_str("upper str1", str1) ;

	/* check original strings */
	printf("check: \"%s\", \"%s\", \"%s\", \"%s\"\n",
	  message1, message2, message3, addmsg1) ;

	/* remove spaces */
	printf("remove spaces:\n") ;
	[str1 release] ;
	str1 = [[CString alloc] initStringWithPtr: space1] ;
	print_str("before remove", str1) ;
	[str1 removeHeadSpaces] ;
	print_str("removing head spaces ", str1) ;
	[str1 removeTailSpaces] ;
	print_str("and removing tail spaces ", str1) ;

	printf("removing step by step\n") ;
	[str1 setPtr: message5 length: strlen(message5)] ;
	for(len = [str1 length] ; len > 0 ; len--){
		printf("%d: \"%s\"\n", len, [str1 ptr]) ;
		[str1 remove: len-1 length: 1] ;
	}
	printf("%d: \"%s\"\n", len, [str1 ptr]) ;
	[str1 setPtr: message5] ;
	for(len = [str1 length] ; len > 0 ; len--){
		printf("%d: \"%s\"\n", len, [str1 ptr]) ;
		[str1 remove: 0 length: 1] ;
	}
	printf("%d: \"%s\"\n", len, [str1 ptr]) ;

	printf("removing overrun\n") ;
	[str1 remove: 3 length: 4] ;
	printf("\"%s\"\n", [str1 ptr]) ;

	printf("removing multiple spaces\n");
	[str2 setPtr: space2] ;
	[str2 removeMultipleSpaces: TRUE] ;
	printf("\"%s\"", [str2 ptr]) ;

	printf("replace characters:\n") ;
	[str2 setPtr: message6 length: strlen(message6)] ;
	[str2 replaceChar: 'i' by: 'h'] ;
	[str2 replaceChar: 'f' by: 'e'] ;
	[str2 replaceChar: 'm' by: 'l'] ;
	[str2 replaceChar: 'p' by: 'o'] ;
	printf("\"%s\" -> \"%s\"\n", message6, [str2 ptr]) ;

	printf("replace char by string:\n") ;
	printf("\"%s\" -> ", [str2 ptr]) ;
	[str2 replaceCharByStr: 'l' by: "LL" length: 2] ;
	printf("\"%s\" (%d) \n", [str2 ptr], [str2 length]) ;

	printf("replace string by string:\n") ;
	printf("\"%s\" -> ", [str2 ptr]) ;
	[str2 replaceStrByStr: "LL" length: 2 by: "L" length: 1] ;
	printf("\"%s\" (%d) \n", [str2 ptr], [str2 length]) ;

	/* split first test */
	printf("split first test:\n") ;
	[str3 release] ;
	[str1 setPtr: message7] ;
	printf("\"%s\" -> ", [str1 ptr]) ;
	str3 = [str1 splitFirstWord] ;
	printf("\"%s\" && \"%s\"\n", [str3 ptr], [str1 ptr]);

	[str3 release] ;
	[str1 setPtr: message8 length: strlen(message8)] ;
	printf("\"%s\" -> ", [str1 ptr]) ;
	str3 = [str1 splitFirstWord] ;
	printf("\"%s\" && \"%s\"\n", [str3 ptr], [str1 ptr]);

	[str3 release] ;
	[str1 setPtr: message9 length: strlen(message9)] ;
	printf("\"%s\" -> ", [str1 ptr]) ;
	str3 = [str1 splitFirstWord] ;
	printf("\"%s\" && \"%s\"\n", [str3 ptr], [str1 ptr]);

	/* split last test */
	printf("split last test:\n") ;
	[str3 release] ;
	[str1 setPtr: message4 length: strlen(message4)] ;
	printf("\"%s\" -> ", [str1 ptr]) ;
	str3 = [str1 splitLastWord] ;
	printf("\"%s\" && \"%s\"\n", [str1 ptr], [str3 ptr]);

	[str3 release] ;
	[str1 setPtr: message8 length: strlen(message8)] ;
	printf("\"%s\" -> ", [str1 ptr]) ;
	str3 = [str1 splitLastWord] ;
	printf("\"%s\" && \"%s\"\n", [str1 ptr], [str3 ptr]);

	[str3 release] ;
	[str1 setPtr: message9 length: strlen(message9)] ;
	printf("\"%s\" -> ", [str1 ptr]) ;
	str3 = [str1 splitLastWord] ;
	printf("\"%s\" && \"%s\"\n", [str1 ptr], [str3 ptr]);

	[str3 release] ;
	[str1 setPtr: message7 length: strlen(message7)] ;
	printf("\"%s\" -> ", [str1 ptr]) ;
	str3 = [str1 splitLastWord] ;
	printf("\"%s\" && \"%s\"\n", [str1 ptr], [str3 ptr]);

	[str3 release] ;
	[str1 setPtr: empty length: strlen(empty)] ;
	printf("\"%s\" -> ", [str1 ptr]) ;
	str3 = [str1 splitLastWord] ;
	printf("\"%s\" && \"%s\"\n", [str1 ptr], [str3 ptr]);
	[str3 release] ;

	/* remove char */
	printf("removeChar & removeStr:\n") ;
	[str1 setPtr: message5 length: strlen(message5)] ;
	[str1 removeChar: '4'] ;
	printf("\"%s\"\n", [str1 ptr]) ;
	[str1 removeStr: "567" length: 3] ;
	printf("\"%s\"\n", [str1 ptr]) ;

	/* duplicate */
	printf("set \"hello, world!!\" to str1:\n") ;
	[str1 setPtr: "hello, world!!"] ;
	printf("duplicate:\n");
	str3 = [str1 duplicate] ;
	g_assert(str3 != nil) ;

	printf("converting to upper cases:\n");
	[str3 toUpper] ;
	printf("\"%s\" -> \"%s\"\n", [str1 ptr], [str3 ptr]) ;

	/* compare without case */
	[str3 setPtr: "TRUE"] ;
	if([str3 comparePtrWoCase: "true"] == 0){
		printf("\"%s\" == \"true\" ... OK\n", [str3 ptr]) ;
	} else {
		printf("\"%s\" == \"true\" ... ERROR\n", [str3 ptr]) ;
	}

	/* make string from const str */
	cons1 = [CConstStr newConstStr: "Good evening" copy: FALSE free:FALSE];
	[str1 release] ;
	str1 = [CString newStringFromBasicStr: cons1] ;
	[str1 toUpper] ;
	printf("generate \"%s\" from \"%s\"\n", [str1 ptr], [cons1 ptr]) ;
	[cons1 release] ;

	/* count spaces */
	printf("count spaces for \"%s\"\n", countspaces) ;
	count = [CString countSpaces: countspaces tab: 0] ;
	printf(" result will be 2 -> %u\n", count) ;

	/* skip spaces */
	printf("count skips to remove spaces:\n") ;
	count = [CString stepSpaces: countspaces step: count - 2 tab: 0] ;
	printf(" result = %u\n", count);

	/* replace formatted chars */
	printf("replacing formatted characters:\n") ;
	[str1 setPtr: message10] ;
	printf(" before: ") ; fputs([str1 ptr], stdout) ; putc('\n', stdout) ;
	[str1 expandEscape] ;
	printf(" after:  ") ; fputs([str1 ptr], stdout) ; putc('\n', stdout) ;

	/* finish */
	[str1 release] ;
	[str2 release] ;
	[str3 release] ;
	printf("bye.\n") ;
	exit(0) ;
}

