


#import <eoaccess/eoaccess.h>
#import "NSString+MiscRegex.h"
#import <foundation/NSException.h>
#import <foundation/NSAutoreleasePool.h>
//#import <misckit/regexpr.h>
#import "regexpr.h"
#import <stdio.h>


const char *strFromRange(NSRange range)
{
	NSString *theString;

	if (range.location == NSNotFound)
		theString = [NSString stringWithFormat:@"{location = NSNotFound; length = %d}",
							range.length];
	else
		theString = [NSString stringWithFormat:@"{location = %d; length = %d}",
							range.location, range.length];
	
	return [theString cString];
}

void MyLog(NSString *format, ...)
{
	NSString	*theString = nil;
    va_list		args;
	const char	*cString;
	int			length = 0;

    va_start (args, format);
	theString = [[NSString alloc] initWithFormat:format arguments:args];
    va_end(args);

	cString = [theString cString];
	length = [theString cStringLength];
	
	fwrite(cString, 1, length, stdout); putc('\n', stdout);
	[theString release];
}

void PrintError(NSString *format, ...)
{
	NSString	*theString = nil;
    va_list		args;
	const char	*cString;
	int			length = 0;

    va_start (args, format);
	theString = [[NSString alloc] initWithFormat:format arguments:args];
    va_end(args);

	cString = [theString cString];
	length = [theString cStringLength];
	
	fwrite(cString, 1, length, stdout); putc('\n', stdout);
	fwrite(cString, 1, length, stderr); putc('\n', stderr);

	[theString release];
}

void main(int argc, char *argv[])
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

	NSString		*testsFile  = (argv[1])? [NSString stringWithCString:argv[1]] : 
	                                         @"MiscRegexTest.tests";
	NSString		*fileString = [[NSString alloc] initWithContentsOfFile:testsFile];
	NSArray			*strings    = [fileString componentsSeparatedByString:@"\n"];
	NSEnumerator	*stringEnum = [strings objectEnumerator];
	NSString		*currLine;
	int num, i;


	re_set_syntax(RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_CONTEXT_INDEP_OPS);

	while ((currLine = [stringEnum nextObject]) && [currLine length])
	{
		NSArray		*tokens       = [currLine componentsSeparatedByString:@"\t"];
		NSString	*currRegex    = [tokens objectAtIndex:0];
		NSString	*currString   = [tokens objectAtIndex:1];
		NSString	*expect       = [tokens objectAtIndex:2];
		NSString	*currReplace  = [tokens objectAtIndex:3];
		NSString	*afterReplace = [tokens objectAtIndex:4];
		NSString	*afterString;
		BOOL		isValid;
		NSRange		foundRange;

		if ([currRegex isEqual:@"-"]) continue;

	NS_DURING
			
		MyLog(@"String is: \"%@\"", currString);
		MyLog(@"Regex is:  \"%@\"\n", currRegex);
		

		isValid = [currRegex isValidRegex];
		MyLog(@"Valid regex?         %s", isValid? "YES":"NO");
		if (!isValid && ![expect isEqual:@"c"])
			PrintError(@"ERROR**: regex '%@' supposed to be valid", currRegex);
		if (isValid && [expect isEqual:@"c"])
			PrintError(@"ERROR**: regex should have been illegal");


		foundRange = [currString rangeOfRegex:currRegex options:MiscFasterSearch];
		MyLog(@"Range of first occurrence: %s", strFromRange(foundRange));
		
		if (foundRange.location == NSNotFound && [expect isEqual:@"y"])
			PrintError(@"ERROR**: regex not found but should have been");
		if (foundRange.location != NSNotFound && [expect isEqual:@"n"])
			PrintError(@"ERROR**: regex found but should not have been");
		
		
		MyLog(@"Num               : %d", num = [currString numOfRegex:currRegex]);
		MyLog(@"Num nocase        : %d",
				[currString numOfRegex:currRegex options:NSCaseInsensitiveSearch]);
				
		for (i=-1; i <= num; i++)
		{
			NSRange findRange = [currString rangeOfRegex:currRegex occurrenceNum:i];
			MyLog(@"          Occurrence %2d: %s", i, strFromRange(findRange));
		}

		for (i=-1; i <=num; i++)
		{
			NSRange findRange = [currString rangeOfRegex:currRegex
			                      options:NSBackwardsSearch occurrenceNum:i];
			MyLog(@"Backwards Occurrence %2d: %s", i, strFromRange(findRange));
		}

		for (i=0; i <=1; i++)
		{
			NSRange findRange = [currString rangeOfRegex:currRegex
			                      options:NSAnchoredSearch occurrenceNum:i];
			MyLog(@"Anchored  Occurrence %2d: %s", i, strFromRange(findRange));
		}

		for (i=0; i <=1; i++)
		{
			NSRange findRange = [currString rangeOfRegex:currRegex
			                      options:NSAnchoredSearch|NSBackwardsSearch
								  occurrenceNum:i];
			MyLog(@"Back,Anch Occurrence %2d: %s", i, strFromRange(findRange));
		}

		if (![currReplace isEqual:@"-"] && foundRange.location != NSNotFound)
		{
			NSString *substring = [currString substringFromRange:foundRange];
			afterString = [substring stringByReplacingRegex:currRegex withString:currReplace
								options:MiscUseMatchSubstitutions];
			if (![afterString isEqual:afterReplace])
				PrintError(@"ERROR**: replace didn't work: was '%@', should be '%@'",
							afterString, afterReplace);
		}

		
		if (![currReplace isEqual:@"-"] && ![currReplace isEqual:@"&"])
		{
			afterString = [currString stringByReplacingEveryOccurrenceOfRegex:currRegex
						withString:currReplace options:MiscUseMatchSubstitutions];
			MyLog(@"After replace all with '%@': '%@'", currReplace, afterString);
		}
		afterString = [currString stringByReplacingEveryOccurrenceOfRegex:currRegex
						withString:@"[&]" options:MiscUseMatchSubstitutions];
		MyLog(@"After replace all with '[&]': '%@'", afterString);
		
		MyLog(@"Matches for: %@",[currString stringsMatchedByRegex:currRegex]);
		
		MyLog(@"Components separated by: %@",
					[currString componentsSeparatedByRegex:currRegex]);
		
		for (i=-1; i <= num; i++)     // shows what happens when occurrenceNum: isn't found
//		for (i=0; i < num; i++)
		{
			NSArray			*keys = [NSArray arrayWithObjects:MiscBeforePiece, MiscMiddlePiece,
										MiscAfterPiece, MiscSubstringsPiece,nil];
			NSDictionary	*dict =	[currString grep:currRegex forPieces:keys occurrenceNum:i];

			MyLog(@"Occurrence %d",i);
			MyLog(@"   Before: '%@'",[dict objectForKey:MiscBeforePiece]);
			MyLog(@"   Middle: '%@'",[dict objectForKey:MiscMiddlePiece]);
			MyLog(@"   After:  '%@'",[dict objectForKey:MiscAfterPiece]);
			MyLog(@"   Subs:  %@",   [dict objectForKey:MiscSubstringsPiece]);
		}
		
		MyLog(@"----------------------------------------------------------");


	NS_HANDLER
			
		MyLog(@"%@: %@", [exception exceptionName], [exception exceptionReason]);
		MyLog(@"----------------------------------------------------------");

	NS_ENDHANDLER
	}
	

	[pool release];
}
