//
//	NSScanner+MiscRegex.m 
//         Regular expression support for NSScanner (using NSString+MiscRegex)
//
//		Written by Carl Lindberg Copyright (c) 1997 by Carl Lindberg.
//			         Version 1.0  All rights reserved.
//		    This notice may not be removed from this source code.
//
//	This object is included in the MiscKit by permission from the author
//	and its use is governed by the MiscKit license, found in the file
//	"LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
//	for a list of all applicable permissions and restrictions.
//	
//  This file formatted with 4 spaces per tabstop.

#import "NSScanner+MiscRegex.h"
#import "NSString+MiscRegex.h"
#import <stdlib.h>

@interface NSScanner (Misc_NeXT_Private)
/*
 * This skips past any "skip" characters, updating the scanLocation. It
 * returns an NSCharacterSet, presumably the charactersToSkip set.
 */
- (NSCharacterSet *)skipCharacters;
@end


@implementation NSScanner (MiscRegex)

- (BOOL)scanRegex:(NSString *)regex intoString:(NSString **)value
{
	int			options = [self caseSensitive]? 0 : NSCaseInsensitiveSearch;
	regexp_t	pattern = MiscNewRegexStruct(regex, options);
	BOOL		retVal;

	retVal = [self scanRegexStruct:pattern intoString:value];
	MiscFreeRegexStruct(pattern);
	return retVal;
}

- (BOOL)scanUpToRegex:(NSString *)regex intoString:(NSString **)value;
{
	int			options = MiscFasterSearch;
	regexp_t	pattern;
	BOOL		retVal;

	if (![self caseSensitive]) options |= NSCaseInsensitiveSearch;

	pattern = MiscNewRegexStruct(regex, options);
	retVal = [self scanUpToRegexStruct:pattern intoString:value];

	MiscFreeRegexStruct(pattern);
	return retVal;
}

- (BOOL)scanRegexStruct:(regexp_t)pattern intoString:(NSString **)value
{
	NSString	*theString = [self string];
	NSRange		scanRange;
	NSRange		foundRange;
	int			options = NSAnchoredSearch;
	
	[self skipCharacters];

	scanRange.location = [self scanLocation];
	scanRange.length   = [theString length] - scanRange.location;

	foundRange = [theString rangeOfRegexStruct:pattern options:options range:scanRange];
	
	if (foundRange.location == NSNotFound)
	{
		return NO;
	}
	else
	{
		if (value) *value = [theString substringWithRange:foundRange];
		[self setScanLocation:NSMaxRange(foundRange)];
		return YES;
	}
}

- (BOOL)scanUpToRegexStruct:(regexp_t)pattern intoString:(NSString **)value
{
	NSString	*theString = [self string];
	NSRange		scanRange;
	NSRange		foundRange;
	NSRange		betweenRange;
	int			options = 0;
	
	if ([self isAtEnd]) return NO;

	[self skipCharacters];

	scanRange.location = [self scanLocation];
	scanRange.length   = [theString length] - scanRange.location;
	
	foundRange = [theString rangeOfRegexStruct:pattern options:options range:scanRange];

	if (foundRange.location == NSNotFound)
	{
		[self setScanLocation:[theString length]];
		if (value) *value = [theString substringWithRange:scanRange];
		return YES;
	}
	else
	{
		betweenRange.location = scanRange.location;
		betweenRange.length = foundRange.location - scanRange.location;
	
		if (betweenRange.length == 0)
		{
			return NO;
		}
		else
		{
			[self setScanLocation:foundRange.location];
			if (value) *value = [theString substringWithRange:betweenRange];
			return YES;
		}
	}
}


@end

