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; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.