This is MiscCommandLineParameterParser.m in view mode; [Download] [Up]
/*************************************************************************
* File Name: MiscCommandLineParameterParser.m
* Version : 0.6 beta
* Date : 08-jul-1995
*************************************************************************
* COPYRIGHT (C) 1995, 1996 by SciTools Project *
* and Georg Tuparev *
* ALL RIGHTS RESERVED. *
* *
*************************************************************************
* This software is furnished without a license and may be freely used, *
* copied, modified and redistributed, provided that the above copyright *
* notice is not removed. This software or any other copies thereof may *
* be provided or otherwise made available to any other person in any *
* form. No title to and ownership of the software is hereby *
* transferred. It is not permitted to sell this software. The *
* information in this software is subject to change without notice and *
* should not be construed as a commitment by the SciTools Project or by *
* the authors. *
* NEITHER THE SCITOOLS PROJECT, NOR THE AUTHORS ASSUME RESPONSIBILITY *
* FOR THE USE OR RELIABILITY OF THIS SOFTWARE PRODUCT. WE DO HOPE, *
* HOWEVER, TO GET RESPONSES FROM USERS, ESPECIALLY WHEN IMPROVEMENTS *
* HAVE BEEN MADE. *
*************************************************************************
* Description:
* Notes :
* To Do :
* Bugs :
* Author(s) : Georg Tuparev, EMBL & Academia Naturalis,
* Heidelberg, Germany
* Last update: 08-jul-1995
* History : 10-jun-1995 - Birth;
* 07-jul-1995 - First beta (more or less tested) version;
* 08-jul-1995 - Full implementation of NSCoding stuff &
* description method;
*************************************************************************/
#import "MiscCommandLineParameterParser.h"
#import <stdarg.h>
#import <string.h>
//#import <objc/objc-runtime.h>
#import <Foundation/NSZone.h>
#import <Foundation/NSException.h>
#import <Foundation/NSCoder.h>
#define MISC_CLASS_VERSION 2 // Current MiscCommandLineParameterParser version
#define MISC_CLASS_NAME @"MiscCommandLineParameterParser" // Class name
#define MISC_EMPTY @"Undefined object"
#define MISC_YES_STR @"Yes"
#define MISC_NO_STR @"No"
#define MISC_UNKNOWN_POINTER @"Pointer with unknown type"
/*
* __MiscCommandLineParameter is a private class. One should never attempt to
* use it from outside MiscCommandLineParameterParser.
* There is no guarantee, that the class interface will not be changed in
* the future!
* This class provides a wrapper around a single parameter and its argument
* list. It provide methods for notifying the delegate and is a placeholder
* for a call-back function. Checking for conflicting parameters is also
* __MiscCommandLineParameter's responsibility.
* Care was taken to avoid multiple calls of the call-back function and
* the delegate's action.
*/
@interface __MiscCommandLineParameter:NSObject <NSCoding>
{
BOOL acceptsArguments;
BOOL isUsed;
BOOL isActionPerformed;
NSMutableArray* values;
Misc_ArgProc handler;
SEL method;
id delegate;
NSMutableArray* conflicts;
}
+ (void)initialize;
+ (NSString *)className;
+ (NSString *)description;
- (id)init;
- (void)dealloc;
- (id)initWithCoder:(NSCoder *)aDecoder;
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (NSString *)description;
- (NSString *)className;
- (void)setDelegate:(id)aDelegate;
- (void)setAcceptsArgumentsEnabled:(BOOL)flag;
- (BOOL)isAcceptsArgumentsEnabled;
- (void)setConflictingParameter:(char *)param;
- (NSArray *)conflictingParameters;
- (void)setHandler:(Misc_ArgProc)aHandler;
- (void)setSelector:(SEL)aMethod;
- (void)useIt;
- (BOOL)isUsed;
- (void)addValue:(NSString *)aValue;
- (NSArray *)values;
- (void)performAction;
@end
@implementation __MiscCommandLineParameter
#define __MISC_CLASS_VERSION 1 // Current MiscObject version
#define __MISC_CLASS_NAME @"__MiscCommandLineParameter - Private class" // Class name
+ (void)initialize
{
if (self == [__MiscCommandLineParameter class]) {
[self setVersion:__MISC_CLASS_VERSION]; // Set the class version
}
else
[self doesNotRecognizeSelector:_cmd]; // Prints an error and aborts the app
return;
}
+ (NSString *)className
{
return [NSString stringWithFormat:@"%@",__MISC_CLASS_NAME];
}
+ (NSString *)description
{
return [NSString stringWithFormat:@"%@", __MISC_CLASS_NAME];
}
- (id)init
{
[super init];
acceptsArguments = NO;
isUsed = NO;
handler = NULL;
method = NULL;
delegate = nil;
isActionPerformed = NO;
conflicts = [NSMutableArray arrayWithCapacity:0];
[conflicts retain];
return self;
}
- (void)dealloc
{
if (delegate)
[delegate release];
[conflicts removeAllObjects];
[conflicts release];
return [super dealloc];
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeValuesOfObjCTypes:"ccc", &acceptsArguments, &isUsed,
&isActionPerformed];
[aCoder encodeObject:values];
[aCoder encodeObject:conflicts];
return;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
[aDecoder decodeValuesOfObjCTypes:"ccc", &acceptsArguments, &isUsed,
&isActionPerformed];
values = [[aDecoder decodeObject] retain];
handler = NULL;
method = NULL;
delegate = nil;
conflicts = [[aDecoder decodeObject] retain];
return self;
}
- (NSString *)description
{
NSMutableDictionary* descDict =
[NSMutableDictionary dictionaryWithCapacity:8];
if (acceptsArguments)
[descDict setObject:MISC_YES_STR
forKey:[NSString stringWithCString:"acceptsArguments"]];
else
[descDict setObject:MISC_NO_STR
forKey:[NSString stringWithCString:"acceptsArguments"]];
if (isUsed)
[descDict setObject:MISC_YES_STR
forKey:[NSString stringWithCString:"isUsed"]];
else
[descDict setObject:MISC_NO_STR
forKey:[NSString stringWithCString:"isUsed"]];
if (isActionPerformed)
[descDict setObject:MISC_YES_STR
forKey:[NSString stringWithCString:"isActionPerformed"]];
else
[descDict setObject:MISC_NO_STR
forKey:[NSString stringWithCString:"isActionPerformed"]];
if (values)
[descDict setObject:values
forKey:[NSString stringWithCString:"values"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"values"]];
if (delegate)
[descDict setObject:delegate
forKey:[NSString stringWithCString:"delegate"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"delegate"]];
if (conflicts)
[descDict setObject:conflicts
forKey:[NSString stringWithCString:"conflicts"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"conflicts"]];
if (method)
[descDict setObject:[NSString stringWithCString:sel_getName(method)]
forKey:[NSString stringWithCString:"method"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"method"]];
if (handler)
[descDict setObject:MISC_UNKNOWN_POINTER
forKey:[NSString stringWithCString:"handler"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"handler"]];
return [descDict description];
}
- (NSString *)className
{
return [NSString stringWithFormat:@"%@",__MISC_CLASS_NAME];
}
- (void)setDelegate:(id)aDelegate
{
delegate = aDelegate;
[delegate retain];
return;
}
- (void)setAcceptsArgumentsEnabled:(BOOL)flag
{
acceptsArguments = flag;
return;
}
- (BOOL)isAcceptsArgumentsEnabled
{
return acceptsArguments;
}
- (void)setConflictingParameter:(char *)param
{
NSString *newP;
if (param) {
newP = [NSString stringWithCString:param];
[conflicts addObject:newP];
}
return;
}
- (NSArray *)conflictingParameters
{
return conflicts;
}
- (void)setHandler:(Misc_ArgProc)aHandler
{
handler = aHandler;
return ;
}
- (void)setSelector:(SEL)aMethod
{
method = aMethod;
return;
}
- (void)addValue:(NSString *)aValue
{
if (!values) {
values = [NSMutableArray arrayWithCapacity:1];
[values retain];
}
[values addObject:aValue];
return;
}
- (NSArray *)values
{
return values;
}
- (void)useIt
{
isUsed = YES;
return;
}
- (BOOL)isUsed
{
return isUsed;
}
- (void)performAction
{
char** arguments;
int i;
if (isActionPerformed)
return;
if (handler) {
if (values && ([values count] > 0)) {
// Create a NULL-term array of strings
arguments = (char **)NSZoneMalloc([self zone],
sizeof(char **) * ([values count]+1));
for (i = 0; i < [values count]; i++) {
arguments[i] = NSZoneMalloc([self zone],
[[values objectAtIndex:i] cStringLength]);
strcpy(arguments[i], [[values objectAtIndex:i] cString]);
}
arguments[[values count]] = NULL;
handler(arguments);
}
else
handler(NULL);
}
if (method && delegate && [delegate respondsToSelector:method]) {
if (values && ([values count] > 0))
[delegate performSelector:method withObject:values];
else
[delegate performSelector:method withObject:nil];
}
// Prevent repetitive execution (e.g. help, ...)
isActionPerformed = YES;
return;
}
@end
@interface MiscCommandLineParameterParser(__Local_MiscCommandLineParameterParser)
// Errors
typedef enum __errorCodes {
ERR_AppName,
ERR_MultipleParameters,
ERR_WrongParameter,
ERR_UnknownParameter,
ERR_ArgumentNotAllowed,
ERR_ConflictingParameters
} ErrorCodes;
static NSString* __errorMessages[] = {
@"Bad first parameter (application name)",
@"Multiple parameters are not allowed",
@"Wrong parameter",
@"Unknown parameter",
@"Argument not allowed",
@"Conflicting parameters"
};
static const numberOfIvars = 17;
- (void)__freeArgVector;
- (void)__freeIvars;
- (void)__addAllowedParameter:(char *)param hasValue:(BOOL)flag
handler:(Misc_ArgProc)proc selector:(SEL)method;
- (void)__parseAppName;
- (void)__addError:(ErrorCodes)errNumb withString:(NSString *)comment;
- (void)__prepareSeparators;
- (void)__prepareHelpParsing;
- (BOOL)__isParameter:(int)paramNumb;
- (__MiscCommandLineParameter *)__pushParameter:(char *)param;
- (__MiscCommandLineParameter *)__newParameter;
- (BOOL)__noConflictsFound;
- (BOOL)__noWrongArgumentsFound;
- (void)__performActions;
@end
@implementation MiscCommandLineParameterParser
/*************************************************************************
*** Initializing the class
*************************************************************************/
+ (void)initialize
{
if (self == [MiscCommandLineParameterParser class]) {
[self setVersion:MISC_CLASS_VERSION]; // Set the class version
}
else
[self doesNotRecognizeSelector:_cmd]; // Prints an error and aborts the app
return;
}
/*************************************************************************
*** Class & object Name and Description
*************************************************************************/
+ (NSString *)className
{
return [NSString stringWithFormat:@"%@",MISC_CLASS_NAME];
}
+ (NSString *)description
{
return [NSString stringWithFormat:MISC_CLASS_NAME];
}
- (NSString *)description
{
NSMutableDictionary* descDict =
[NSMutableDictionary dictionaryWithCapacity:numberOfIvars];
NSMutableString* argList = [NSMutableString stringWithCapacity:0];
int i;
[descDict setObject:[NSString stringWithFormat:@"%d", argCount]
forKey:[NSString stringWithCString:"argCount"]];
for (i = 0; i < argCount; i++)
[argList appendFormat:@"%s\n", argVector[i]];
[descDict setObject:argList
forKey:[NSString stringWithCString:"argVector"]];
if (parameterDictionary)
[descDict setObject:parameterDictionary
forKey:[NSString stringWithCString:"parameterDictionary"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"parameterDictionary"]];
if (parameterSeparators)
[descDict setObject:parameterSeparators
forKey:[NSString stringWithCString:"parameterSeparators"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"parameterSeparators"]];
if (parseErrors)
[descDict setObject:parseErrors
forKey:[NSString stringWithCString:"parseErrors"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"parseErrors"]];
if (parsedParameters)
[descDict setObject:parsedParameters
forKey:[NSString stringWithCString:"parsedParameters"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"parsedParameters"]];
if (unixStyle)
[descDict setObject:MISC_YES_STR
forKey:[NSString stringWithCString:"unixStyle"]];
else
[descDict setObject:MISC_NO_STR
forKey:[NSString stringWithCString:"unixStyle"]];
if (gnuStyle)
[descDict setObject:MISC_YES_STR
forKey:[NSString stringWithCString:"gnuStyle"]];
else
[descDict setObject:MISC_NO_STR
forKey:[NSString stringWithCString:"gnuStyle"]];
if (multipleCharacterParameters)
[descDict setObject:MISC_YES_STR
forKey:[NSString stringWithCString:"multipleCharacterParameters"]];
else
[descDict setObject:MISC_NO_STR
forKey:[NSString stringWithCString:"multipleCharacterParameters"]];
if (multipleParameterString)
[descDict setObject:MISC_YES_STR
forKey:[NSString stringWithCString:"multipleParameterString"]];
else
[descDict setObject:MISC_NO_STR
forKey:[NSString stringWithCString:"multipleParameterString"]];
if (parameterChecking)
[descDict setObject:MISC_YES_STR
forKey:[NSString stringWithCString:"parameterChecking"]];
else
[descDict setObject:MISC_NO_STR
forKey:[NSString stringWithCString:"parameterChecking"]];
if (helpParsing)
[descDict setObject:MISC_YES_STR
forKey:[NSString stringWithCString:"helpParsing"]];
else
[descDict setObject:MISC_NO_STR
forKey:[NSString stringWithCString:"helpParsing"]];
if (parsed)
[descDict setObject:MISC_YES_STR
forKey:[NSString stringWithCString:"parsed"]];
else
[descDict setObject:MISC_NO_STR
forKey:[NSString stringWithCString:"parsed"]];
if (applicationName)
[descDict setObject:applicationName
forKey:[NSString stringWithCString:"applicationName"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"applicationName"]];
if (delegate)
[descDict setObject:delegate
forKey:[NSString stringWithCString:"delegate"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"delegate"]];
if (helpHandler)
[descDict setObject:MISC_UNKNOWN_POINTER
forKey:[NSString stringWithCString:"helpHandler"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"helpHandler"]];
if (helpMethod)
[descDict setObject:[NSString stringWithCString:sel_getName(helpMethod)]
forKey:[NSString stringWithCString:"helpMethod"]];
else
[descDict setObject:MISC_EMPTY
forKey:[NSString stringWithCString:"helpMethod"]];
return [descDict description];
}
- (NSString *)className
{
return [NSString stringWithFormat:@"%@",MISC_CLASS_NAME];
}
/*************************************************************************
*** Creating and destroying instances
*************************************************************************/
- (id)init
{
return [self initWithArgumentCount:NO_PARAMETERS argumentVector:NULL];
}
- (id)initWithArgumentCount:(const int)argc argumentVector:(const char **)argv
{
[super init];
argCount = NO_PARAMETERS;
argVector = NULL;
// Check and Set argv & argc
if ( (argc > 0) && ![self setArgumentCount:argc argumentVector:argv]) {
[self __freeIvars]; // Init error
return nil;
}
parameterDictionary = [NSMutableDictionary dictionaryWithCapacity:1];
[parameterDictionary retain];
// Default settings. NOTE: NEVER CHANGE THE LINES BELOW!
unixStyle = YES;
gnuStyle = YES;
multipleCharacterParameters = YES;
multipleParameterString = NO;
parameterChecking = NO;
helpParsing = YES;
delegate = nil;
return self;
}
- (void)__freeArgVector
{
int i;
for(i = 0; i < argCount; i++)
NSZoneFree([self zone],argVector[i]);
NSZoneFree([self zone],argVector);
}
- (void)__freeIvars
{
[self __freeArgVector];
// Empty the parameter dictionary
[parameterDictionary release];
// Empty all arrays
[parameterSeparators release];
[parseErrors release];
[parsedParameters release];
// release the delegate
[delegate release];
return;
}
- (void)dealloc
{
[self __freeIvars];
return [super dealloc];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
int i;
[aDecoder decodeValuesOfObjCTypes:"S", &argCount];
argVector = (char **)NSZoneMalloc([self zone],sizeof(char**) * (argCount+1));
for (i = 0; i < argCount; i++)
[aDecoder decodeValuesOfObjCTypes:"*", argVector[i]];
argVector[argCount] = NULL;
parameterDictionary = [[aDecoder decodeObject] retain];
parameterSeparators = [[aDecoder decodeObject] retain];
parseErrors = [[aDecoder decodeObject] retain];
parsedParameters = [[aDecoder decodeObject] retain];
[aDecoder decodeValuesOfObjCTypes:"ccccccc", &unixStyle, &gnuStyle,
&multipleCharacterParameters, &multipleParameterString,
¶meterChecking, &helpParsing, &parsed];
applicationName = [[aDecoder decodeObject] retain];
delegate = nil;
helpHandler = NULL;
helpMethod = NULL;
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
int i;
[aCoder encodeValuesOfObjCTypes:"S", &argCount];
for (i = 0; i < argCount; i++)
[aCoder encodeValuesOfObjCTypes:"*", argVector[i]];
[aCoder encodeObject:parameterDictionary];
[aCoder encodeObject:parameterSeparators];
[aCoder encodeObject:parseErrors];
[aCoder encodeObject:parsedParameters];
[aCoder encodeValuesOfObjCTypes:"ccccccc", &unixStyle, &gnuStyle,
&multipleCharacterParameters, &multipleParameterString,
¶meterChecking, &helpParsing, &parsed];
[aCoder encodeObject:applicationName];
return;
}
/*************************************************************************
*** Argument vector & count
*************************************************************************/
- (id)setArgumentCount:(const int)argc argumentVector:(const char **)argv
{
int i;
char *cp;
NS_DURING
if ( (argc <= 0 && argv) || (argc > 0 && !argv) ) {
[NSException raise:NSInvalidArgumentException
format:@"Invalid arguments"];
}
NS_HANDLER
NSLog(
@">>>MiscCommandLineParameterParser$setArgumentCount:argumentVector:\n%@\n%@",
[localException name], [localException reason]);
[localException raise];
return nil;
NS_ENDHANDLER
if (argVector)
[self __freeArgVector];
argVector = (char **)NSZoneMalloc([self zone],sizeof(char**)*argc);
for (i = 0; i < argc; i++) {
cp = (char *)NSZoneMalloc([self zone],strlen(argv[i])+1);
argVector[i] = cp;
strcpy(*(argVector+i),argv[i]);
}
argVector[argc] = NULL;
argCount = argc;
parsed = NO;
return self;
}
- (int)argumentCount
{
return argCount;
}
- (char **)argumentVector
{
return argVector;
}
/*************************************************************************
*** Parameter options
*************************************************************************/
- (void)setUnixStyleParametersEnabled:(BOOL)flag
{
unixStyle = flag;
return;
}
- (BOOL)areUnixStyleParametersEnabled
{
return unixStyle;
}
- (void)setGNUStyleParametersEnabled:(BOOL)flag
{
gnuStyle = flag;
return;
}
- (BOOL)areGNUStyleParametersEnabled
{
return gnuStyle;
}
- (void)addMiscParameterSeparator:(char *)separator
{
NSString *sep = nil;
if (separator == NULL)
return;
if (!parameterSeparators) {
parameterSeparators = [NSMutableArray arrayWithCapacity:1];
[parameterSeparators retain];
}
sep = [NSString stringWithCString:separator];
[parameterSeparators addObject:sep];
return;
}
- (void)removeMiscParameterSeparator:(char *)separator
{
NSEnumerator *enumerator;
id aSep;
if (parameterSeparators)
enumerator = [parameterSeparators objectEnumerator];
else
return;
while (aSep = [enumerator nextObject]) {
if (strcmp(separator,[aSep cString]) == 0 ) {
[parameterSeparators removeObject:aSep];
return;
}
}
return;
}
- (void)removeAllMiscParameterSeparators
{
[parameterSeparators removeAllObjects];
return;
}
- (void)setMulipleCharacterParametersEnabled:(BOOL)flag
{
multipleCharacterParameters = flag;
if (multipleCharacterParameters == YES)
multipleParameterString = NO;
return;
}
- (BOOL)areMultipleCharacterParametersEnabled
{
return multipleCharacterParameters;
}
- (void)setMultipleParameterStringEnabled:(BOOL)flag
{
multipleParameterString = flag;
if (multipleParameterString == YES)
multipleCharacterParameters = NO;
return;
}
- (BOOL)isMultipleParameterStringEnabled
{
return multipleParameterString;
}
- (void)setParameterCheckingEnabled:(BOOL)flag
{
parameterChecking = flag;
return;
}
- (BOOL)isParameterCheckingEnabled
{
return parameterChecking;
}
- (void)setAutomaticHelpParsingEnabled:(BOOL)flag
{
helpParsing = flag;
return;
}
- (BOOL)isAutomaticHelpParsingEnabled
{
return helpParsing;
}
/*************************************************************************
*** Maintainig the list of allowed parameters
*************************************************************************/
- (void)setDelegate:(id)anObject
{
if (anObject == nil)
return;
if (delegate)
[delegate release];
delegate = [anObject retain];
return;
}
- (id)delegate
{
return delegate;
}
- (void)addAllowedParameter:(char *)param hasValue:(BOOL)flag
{
return [self __addAllowedParameter:param hasValue:flag handler:NULL selector:NULL];
}
- (void)addAllowedParameter:(char *)param hasValue:(BOOL)flag
handler:(Misc_ArgProc)proc
{
return [self __addAllowedParameter:param hasValue:flag handler:proc selector:NULL];
}
- (void)addAllowedParameter:(char *)param hasValue:(BOOL)flag
selector:(SEL)method
{
return [self __addAllowedParameter:param hasValue:flag handler:NULL
selector:method];
}
- (void)__addAllowedParameter:(char *)param hasValue:(BOOL)flag
handler:(Misc_ArgProc)proc selector:(SEL)method
{
id newParam;
NSString *key = [NSString stringWithCString:param];
if ((newParam = [parameterDictionary objectForKey:key]) == nil ) {
newParam = [self __newParameter];
[parameterDictionary setObject:newParam forKey:key];
}
[newParam setAcceptsArgumentsEnabled:flag];
[newParam setHandler:proc];
[newParam setSelector:method];
return;
}
- (void)setHelpHandler:(Misc_ArgProc)proc
{
helpHandler = proc;
return;
}
- (void)setHelpSelector:(SEL)method
{
helpMethod = method;
return;
}
- (NSArray *)allowedParameters
{
return [parameterDictionary allKeys];
}
- (void)removeAllowedParameters
{
[parameterDictionary removeAllObjects];
return;
}
- (void)parameter:(char *)param conflictsWith:(char *)anotherParam,...
{
va_list ap;
char *cp;
__MiscCommandLineParameter *p;
p = [parameterDictionary objectForKey:[NSString stringWithCString:param]];
if (!p)
return;
va_start(ap,anotherParam);
cp = anotherParam;
do {
[p setConflictingParameter:cp];
} while (cp = va_arg(ap,char *));
va_end(ap);
return;
}
/*************************************************************************
*** Parsing end error detection
*************************************************************************/
- (void)__parseAppName
{
char* buf;
char* cp;
buf = NSZoneMalloc([self zone],strlen(argVector[0])+1);
strcpy(buf,argVector[0]);
cp = strrchr(buf,'/');
if (!cp) {
cp = argVector[0];
}
else {
cp++;
}
[applicationName autorelease];
applicationName = [NSString stringWithCString:cp];
[applicationName retain];
NSZoneFree([self zone],buf);
return;
}
- (void)parse
{
int i = 1;
__MiscCommandLineParameter *lastParameter;
// Clear all errors
if (parseErrors)
[parseErrors removeAllObjects];
[self __prepareSeparators]; // Push unix & gnu separators in the list
[self __prepareHelpParsing]; // .. for -h or --help
[self __parseAppName]; // Get the app name
while (i < argCount) {
// Check if it's a parameter
if ([self __isParameter:i]) {
lastParameter = [self __pushParameter:argVector[i]];
i++;
while ((i < argCount) && ![self __isParameter:i]) {
[lastParameter addValue:[NSString stringWithCString:argVector[i]]];
i++;
}
}
else {
[self __addError:ERR_WrongParameter withString:
[NSString stringWithFormat:@"[%s]",argVector[i]]];
}
}
if ( ([parseErrors count] == 0) && [self __noConflictsFound] &&
[self __noWrongArgumentsFound]) {
[self __performActions];
}
parsed = YES;
return;
}
- (NSArray *)parseErrors
{
return parseErrors;
}
/*************************************************************************
*** Maintaining & querying the dictionary of parameters
*************************************************************************/
- (NSString *)applicationName
{
return applicationName;
}
- (BOOL)isHelpRequired
{
if (unixStyle && [[parameterDictionary objectForKey:@"h"] isUsed])
return YES;
if (gnuStyle && [[parameterDictionary objectForKey:@"help"] isUsed])
return YES;
return NO;
}
- (NSEnumerator *)parameterEnumerator
{
NSEnumerator *enumerator = [parameterDictionary keyEnumerator];
__MiscCommandLineParameter *value;
NSString *key;
if (parsedParameters)
[parsedParameters removeAllObjects];
else {
parsedParameters = [NSMutableArray arrayWithCapacity:0];
[parsedParameters retain];
}
while (key = [enumerator nextObject]) {
value = [parameterDictionary objectForKey:key];
if ([value isUsed]) {
[parsedParameters addObject:key];
}
}
return [parsedParameters objectEnumerator];
}
- (NSArray *)argumentsForParameter:(NSString *)key
{
if ([[parameterDictionary objectForKey:key] isUsed])
return [[parameterDictionary objectForKey:key] values];
else
return nil;
}
/*************************************************************************
*** Misc Methods
*************************************************************************/
- (void)__addError:(ErrorCodes)errNumb withString:(NSString *)comment;
{
NSMutableString *nS = [NSMutableString
stringWithFormat:@"%@",__errorMessages[errNumb]];
if (!parseErrors) {
parseErrors = [NSMutableArray arrayWithCapacity:0];
[parseErrors retain];
}
if (comment)
[nS appendString:comment];
[parseErrors addObject:nS];
return;
}
- (void)__prepareSeparators
{
// Note: The order of the both if statements is IMPORTANT.
if (gnuStyle)
[self addMiscParameterSeparator:"--"];
if (unixStyle)
[self addMiscParameterSeparator:"-"];
return;
}
- (void)__prepareHelpParsing
{
__MiscCommandLineParameter *param;
if (helpParsing) {
param = [self __newParameter];
[param setHandler:helpHandler];
[param setSelector:helpMethod];
if (unixStyle)
[parameterDictionary setObject:param forKey:
[NSString stringWithCString:"h"]];
if (gnuStyle)
[parameterDictionary setObject:param forKey:
[NSString stringWithCString:"help"]];
}
return;
}
- (BOOL)__isParameter:(int)paramNumb
{
NSEnumerator *enumerator = [parameterSeparators objectEnumerator];
id aSep;
char* cp;
char arg[100];
// Check for obvious case ;-)
if ([parameterSeparators count] == 0)
return YES; // Everything is a parameter
strcpy(arg,argVector[paramNumb]);
while (aSep = [enumerator nextObject]) {
cp = strstr(arg,[aSep cString]);
if (cp)
return YES;
}
return NO;
}
- (__MiscCommandLineParameter *)__pushParameter:(char *)param
{
__MiscCommandLineParameter *newParameter = nil;
NSEnumerator *enumerator = [parameterSeparators objectEnumerator];
id aSep;
char* cp = NULL;
BOOL done = NO;
char scp[2] = {'\000','\000'};
while (!done && (aSep = [enumerator nextObject])) {
cp = strstr(param,[aSep cString]);
if (cp) {
cp += strlen([aSep cString]);
done = YES;
}
}
if (parameterChecking) {
if (multipleCharacterParameters) {
if (newParameter = [parameterDictionary objectForKey:
[NSString stringWithCString:cp]]) {
[newParameter useIt];
}
else {
[self __addError:ERR_UnknownParameter withString:
[NSString stringWithFormat:@"[%s]",cp]];
}
}
else if (multipleParameterString) {
do {
scp[0] = *cp;
if (newParameter = [parameterDictionary objectForKey:
[NSString stringWithCString:cp]]) {
[newParameter useIt];
}
else {
[self __addError:ERR_UnknownParameter withString:
[NSString stringWithFormat:@"[%s]",cp]];
}
[newParameter useIt];
cp++;
} while (*cp);
}
else {
[self __addError:ERR_MultipleParameters withString:
[NSString stringWithFormat:@"[%s]",cp]];
}
}
else {
if (multipleCharacterParameters) {
newParameter = [self __newParameter];
[parameterDictionary setObject:newParameter forKey:
[NSString stringWithCString:cp]];
[newParameter useIt];
}
else if (multipleParameterString) {
do {
scp[0] = *cp;
newParameter = [self __newParameter];
[parameterDictionary setObject:newParameter forKey:
[NSString stringWithCString:scp]];
[newParameter useIt];
cp++;
} while (*cp);
}
else {
[self __addError:ERR_MultipleParameters withString:
[NSString stringWithFormat:@"[%s]",param]];
}
}
return newParameter;
}
- (__MiscCommandLineParameter *)__newParameter
{
__MiscCommandLineParameter *newParameter;
newParameter = [[[__MiscCommandLineParameter allocWithZone:[self zone]] init]
autorelease];
return newParameter;
}
- (BOOL)__noConflictsFound
{
NSEnumerator *enumerator = [parameterDictionary keyEnumerator];
NSEnumerator *confEnumerator;
__MiscCommandLineParameter *value;
NSString *key;
NSArray *conflicts;
NSString *confParam;
while (key = [enumerator nextObject]) {
value = [parameterDictionary objectForKey:key];
conflicts = [value conflictingParameters];
if ( [value isUsed] && ([conflicts count] > 0) ) {
confEnumerator = [conflicts objectEnumerator];
while (confParam = [confEnumerator nextObject]) {
if ([[parameterDictionary objectForKey:confParam] isUsed])
[self __addError:ERR_ArgumentNotAllowed withString:
[NSString stringWithFormat:@"[%@ and %@]",key,confParam]];
return NO;
}
}
}
return YES;
}
- (BOOL)__noWrongArgumentsFound
{
NSEnumerator *enumerator = [parameterDictionary keyEnumerator];
__MiscCommandLineParameter *value;
NSString *key;
while (key = [enumerator nextObject]) {
value = [parameterDictionary objectForKey:key];
if ( [value isUsed] && (![value isAcceptsArgumentsEnabled]) &&
([[value values] count] > 0) ) {
[self __addError:ERR_ArgumentNotAllowed withString:key];
return NO;
}
}
return YES;
}
- (void)__performActions
{
NSEnumerator *enumerator = [parameterDictionary keyEnumerator];
__MiscCommandLineParameter *value;
NSString *key;
while (key = [enumerator nextObject]) {
value = [parameterDictionary objectForKey:key];
if ([value isUsed]) {
[value setDelegate:delegate];
[value performAction];
}
}
return;
}
@endThese are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.