From 7598cbd9711c7bd72bb68af85a081c25fd2a10f0 Mon Sep 17 00:00:00 2001 From: CaS Date: Sun, 3 Feb 2002 17:21:20 +0000 Subject: [PATCH] Improve documentation generation git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@12399 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 16 ++++++ Source/GNUmakefile | 8 ++- Source/NSDictionary.m | 27 +++++++--- Source/NSDistantObject.m | 2 +- Source/NSPortCoder.m | 6 +-- Source/NSScanner.m | 26 +++++----- Source/NSTimer.m | 22 ++++----- Tools/AGSParser.h | 4 ++ Tools/AGSParser.m | 104 ++++++++++++++++++++++++++++++++++++--- Tools/autogsdoc.m | 20 ++++++-- 10 files changed, 187 insertions(+), 48 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8e727834c..c6554db25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2002-02-03 Richard Frith-Macdonald + + * Source/GNUmakefile: use -WordMap flag with autogsdoc to cope with + C-preprocessor constants that would otherwise confuse parsing. + * Source/NSDictionary.m: Tidy to match interface. + * Source/NSDistantObject.m: Tidy to match interface. + * Source/NSPortCoder.m: Tidy to match interface. + * Source/NSScanner.m: Tidy to match interface. Remove some illegal + semicolons after method names. + * Source/NSTimer.m: Tidy to match interface. + * Tools/AGSParser.h: Handle word mappings. + * Tools/AGSParser.m: Handle word mappings and deal with function + attributes. + * Tools/autogsdoc.m: Handle word mappings and make default logging + less verbose. + 2002-02-02 Richard Frith-Macdonald * Source/NSObject.m: Fix some maptable problems when using non-local diff --git a/Source/GNUmakefile b/Source/GNUmakefile index 5d41518f1..4c67dab87 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -381,7 +381,13 @@ Base_AGSDOC_FLAGS = \ -HeaderDirectory ../Headers/Foundation \ -Declared Foundation \ -Standards YES \ - -Up Base + -WordMap '{\ + FOUNDATION_EXPORT=extern;FOUNDATION_STATIC_INLINE="";\ + GS_GEOM_SCOPE=extern;GS_GEOM_ATTR="";\ + GS_EXPORT=extern;GS_DECLARE="";\ + GS_RANGE_SCOPE=extern;GS_RANGE_ATTR="";\ + GS_ZONE_SCOPE=extern;GS_ZONE_ATTR="";\ + }' -Up Base -include Makefile.preamble diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index c2f7da6ca..a92ca2487 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -354,12 +354,18 @@ static SEL appSel; return [self initWithObjects: NULL forKeys: NULL count: 0]; } -- (id) initWithDictionary: (NSDictionary*)other +- (id) initWithDictionary: (NSDictionary*)otherDictionary { - return [self initWithDictionary: other copyItems: NO]; + return [self initWithDictionary: otherDictionary copyItems: NO]; } -- (id) initWithDictionary: (NSDictionary*)other copyItems: (BOOL)shouldCopy +/** + * Initialise dictionary with the keys and values of otherDictionary. + * If the shouldCopy flag is YES then the values are copied into the + * newly initialised dictionary, otherwise they are simply retained. + */ +- (id) initWithDictionary: (NSDictionary*)other + copyItems: (BOOL)shouldCopy { unsigned c = [other count]; @@ -1062,19 +1068,24 @@ static NSString *indentStrings[] = { } } -- (void) addEntriesFromDictionary: (NSDictionary*)other +/** + * Merges information from otherDictionary into the receiver. + * If a key exists in both dictionaries, the value from otherDictionary + * replaces that which was originally in the reciever. + */ +- (void) addEntriesFromDictionary: (NSDictionary*)otherDictionary { - if (other != nil && other != self) + if (otherDictionary != nil && otherDictionary != self) { id k; - NSEnumerator *e = [other keyEnumerator]; + NSEnumerator *e = [otherDictionary keyEnumerator]; IMP nxtObj = [e methodForSelector: nxtSel]; - IMP getObj = [other methodForSelector: objSel]; + IMP getObj = [otherDictionary methodForSelector: objSel]; IMP setObj = [self methodForSelector: setSel]; while ((k = (*nxtObj)(e, nxtSel)) != nil) { - (*setObj)(self, setSel, (*getObj)(other, objSel, k), k); + (*setObj)(self, setSel, (*getObj)(otherDictionary, objSel, k), k); } } } diff --git a/Source/NSDistantObject.m b/Source/NSDistantObject.m index 121b6e58a..a750b0eb6 100644 --- a/Source/NSDistantObject.m +++ b/Source/NSDistantObject.m @@ -68,7 +68,7 @@ enum PROXY_LOCAL_FOR_RECEIVER = 0, PROXY_LOCAL_FOR_SENDER, PROXY_REMOTE_FOR_BOTH -}; +} proxyLocation; diff --git a/Source/NSPortCoder.m b/Source/NSPortCoder.m index bdc0e5ef0..22c566589 100644 --- a/Source/NSPortCoder.m +++ b/Source/NSPortCoder.m @@ -329,7 +329,7 @@ static IMP _xRefImp; /* Serialize a crossref. */ + (NSPortCoder*) portCoderWithReceivePort: (NSPort*)recv sendPort: (NSPort*)send - components: (NSArray*)comp; + components: (NSArray*)comp { id coder; @@ -1266,11 +1266,11 @@ static IMP _xRefImp; /* Serialize a crossref. */ * array, and simply record the array index, so the corresponding decode * method can tell which component to use. */ -- (void) encodePortObject: (NSPort*)anObject +- (void) encodePortObject: (NSPort*)aPort { unsigned pos = [_comp count]; - [_comp addObject: anObject]; + [_comp addObject: aPort]; [self encodeValueOfObjCType: @encode(unsigned) at: &pos]; } diff --git a/Source/NSScanner.m b/Source/NSScanner.m index 4124c2e68..6b29e703f 100644 --- a/Source/NSScanner.m +++ b/Source/NSScanner.m @@ -708,7 +708,7 @@ typedef struct { * containing the scanned characters is returned by reference in value. */ - (BOOL) scanCharactersFromSet: (NSCharacterSet *)aSet - intoString: (NSString **)value; + intoString: (NSString **)value { unsigned int saveScanLocation = _scanLocation; @@ -766,8 +766,8 @@ typedef struct { * If value is non-NULL, and any characters were scanned, a string * containing the scanned characters is returned by reference in value. */ -- (BOOL) scanUpToCharactersFromSet: (NSCharacterSet *)set - intoString: (NSString **)value; +- (BOOL) scanUpToCharactersFromSet: (NSCharacterSet *)aSet + intoString: (NSString **)value { unsigned int saveScanLocation = _scanLocation; unsigned int start; @@ -776,18 +776,18 @@ typedef struct { if (!skipToNextField()) return NO; - if (set == _charactersToBeSkipped) + if (aSet == _charactersToBeSkipped) memImp = _skipImp; else memImp = (BOOL (*)(NSCharacterSet*, SEL, unichar)) - [set methodForSelector: memSel]; + [aSet methodForSelector: memSel]; start = _scanLocation; if (_isUnicode) { while (_scanLocation < myLength()) { - if ((*memImp)(set, memSel, myUnicode(_scanLocation)) == YES) + if ((*memImp)(aSet, memSel, myUnicode(_scanLocation)) == YES) break; _scanLocation++; } @@ -796,7 +796,7 @@ typedef struct { { while (_scanLocation < myLength()) { - if ((*memImp)(set, memSel, myChar(_scanLocation)) == YES) + if ((*memImp)(aSet, memSel, myChar(_scanLocation)) == YES) break; _scanLocation++; } @@ -826,17 +826,17 @@ typedef struct { * If value is non-NULL, and the characters at the scan location match aString, * a string containing the matching string is returned by reference in value. */ -- (BOOL) scanString: (NSString *)aString intoString: (NSString **)value; +- (BOOL) scanString: (NSString *)string intoString: (NSString **)value { NSRange range; unsigned int saveScanLocation = _scanLocation; skipToNextField(); range.location = _scanLocation; - range.length = [aString length]; + range.length = [string length]; if (range.location + range.length > myLength()) return NO; - range = [_string rangeOfString: aString + range = [_string rangeOfString: string options: _caseSensitive ? 0 : NSCaseInsensitiveSearch range: range]; if (range.length == 0) @@ -857,8 +857,8 @@ typedef struct { * If value is non-NULL, and any characters were scanned, a string * containing the scanned characters is returned by reference in value. */ -- (BOOL) scanUpToString: (NSString *)aString - intoString: (NSString **)value; +- (BOOL) scanUpToString: (NSString *)string + intoString: (NSString **)value { NSRange range; NSRange found; @@ -867,7 +867,7 @@ typedef struct { skipToNextField(); range.location = _scanLocation; range.length = myLength() - _scanLocation; - found = [_string rangeOfString: aString + found = [_string rangeOfString: string options: _caseSensitive ? 0 : NSCaseInsensitiveSearch range: range]; if (found.length) diff --git a/Source/NSTimer.m b/Source/NSTimer.m index 2d69ed68f..b75dd6e5a 100644 --- a/Source/NSTimer.m +++ b/Source/NSTimer.m @@ -46,25 +46,25 @@ static Class NSDate_class; } } -/* +/** * * Initialise a newly allocated NSTimer object. */ -- (id) initWithTimeInterval: (NSTimeInterval)seconds - targetOrInvocation: (id)t - selector: (SEL)sel - userInfo: info +- (id) initWithTimeInterval: (NSTimeInterval)ti + targetOrInvocation: (id)object + selector: (SEL)selector + userInfo: (id)info repeats: (BOOL)f { - if (seconds <= 0) + if (ti <= 0) { - seconds = 0.0001; + ti = 0.0001; } - _interval = seconds; + _interval = ti; _date = [[NSDate_class allocWithZone: [self zone]] - initWithTimeIntervalSinceNow: seconds]; - _target = t; - _selector = sel; + initWithTimeIntervalSinceNow: ti]; + _target = object; + _selector = selector; _info = info; _repeats = f; return self; diff --git a/Tools/AGSParser.h b/Tools/AGSParser.h index 782cd4abf..d263bed55 100644 --- a/Tools/AGSParser.h +++ b/Tools/AGSParser.h @@ -59,6 +59,8 @@ BOOL inInstanceVariables; BOOL inArgList; BOOL documentAllInstanceVariables; + BOOL verbose; + NSDictionary *wordMap; NSString *declared; /** Where classes were declared. */ NSMutableArray *ifStack; /** Track preprocessor conditionals. */ @@ -89,6 +91,8 @@ - (void) setDocumentAllInstanceVariables: (BOOL)flag; - (void) setGenerateStandards: (BOOL)flag; - (void) setStandards: (NSMutableDictionary*)dict; +- (void) setVerbose: (BOOL)flag; +- (void) setWordMap: (NSDictionary*)map; - (void) setupBuffer; - (unsigned) skipArray; - (unsigned) skipBlock; diff --git a/Tools/AGSParser.m b/Tools/AGSParser.m index 601d885b3..15b3f037c 100644 --- a/Tools/AGSParser.m +++ b/Tools/AGSParser.m @@ -26,6 +26,7 @@ - (void) dealloc { + DESTROY(wordMap); DESTROY(ifStack); DESTROY(declared); DESTROY(info); @@ -272,6 +273,7 @@ NSString *s; BOOL isTypedef = NO; BOOL isPointer = NO; + BOOL isFunction = NO; BOOL baseConstant = NO; BOOL needScalarType = NO; @@ -574,6 +576,7 @@ if (isPointer == NO || [d objectForKey: @"Suffix"] == nil) { [d setObject: @"function" forKey: @"Kind"]; + isFunction = YES; } } @@ -595,6 +598,27 @@ } else { + if (isFunction == YES) + { + NSString *ident = [self parseIdentifier]; + + if ([ident isEqual: @"__attribute__"] == YES) + { + if ([self skipSpaces] < length && buffer[pos] == '(') + { + [self skipBlock]; // Skip the attributes + } + else + { + [self log: @"strange format function attributes"]; + } + } + else if (ident != nil) + { + [self log: @"ignoring '%@' in function declaration", ident]; + } + } + if (buffer[pos] == ';') { [self skipStatement]; @@ -631,7 +655,10 @@ { [d setObject: comment forKey: @"Comment"]; } - [self log: @"parse '%@'", d]; + if (verbose == YES) + { + [self log: @"parse '%@'", d]; + } DESTROY(comment); } @@ -1021,10 +1048,19 @@ fail: return nil; } +/** + * Attempt to parse an identifier/keyword (with optional whitespace in + * front of it). Perform mappings using the wordMap dictionary. If a + * mapping produces an empty string, we treat it as if we had read + * whitespace and try again. + * If we read end of data, or anything which is invalid inside an + * identifier, we return nil. + */ - (NSString*) parseIdentifier { unsigned start; +try: [self skipWhiteSpace]; if (pos >= length || [identStart characterIsMember: buffer[pos]] == NO) { @@ -1035,8 +1071,21 @@ fail: { if ([identifier characterIsMember: buffer[pos]] == NO) { - return [NSString stringWithCharacters: &buffer[start] - length: pos - start]; + NSString *tmp; + NSString *val; + + tmp = [NSString stringWithCharacters: &buffer[start] + length: pos - start]; + val = [wordMap objectForKey: tmp]; + if (val == nil) + { + return tmp; // No mapping found. + } + else if ([val length] > 0) + { + return val; // Got mapped identifier. + } + goto try; // Mapping removed the identifier. } pos++; } @@ -1849,6 +1898,24 @@ fail: } } +/** + * Control boolean option to do verbose logging of the parsing process. + */ +- (void) setVerbose: (BOOL)flag +{ + verbose = flag; +} + +/** + * Sets up a dictionary used for mapping identifiers/keywords to other + * words. This is used to help cope with cases where C preprocessor + * definitions are confusing the parsing process. + */ +- (void) setWordMap: (NSDictionary*)map +{ + ASSIGNCOPY(wordMap, map); +} + /** * Read in the file to be parsed and store it in a temporary unicode * buffer. Perform basic transformations on the buffer to simplify @@ -2001,12 +2068,22 @@ fail: } /** - * Skip until we encounter an '}' marking the end of a block. + * Skip a bracketed block. * Expect the current character position to be pointing to the - * '{' at the start of a block. + * bracket at the start of a block. */ - (unsigned) skipBlock { + unichar term = '}'; + + if (buffer[pos] == '(') + { + term = ')'; + } + else if (buffer[pos] == '[') + { + term = ']'; + } pos++; while ([self skipWhiteSpace] < length) { @@ -2029,8 +2106,21 @@ fail: [self skipBlock]; break; - case '}': - return pos; + case '(': + pos--; + [self skipBlock]; + break; + + case '[': + pos--; + [self skipBlock]; + break; + + default: + if (c == term) + { + return pos; + } } } return pos; diff --git a/Tools/autogsdoc.m b/Tools/autogsdoc.m index 3128ee66a..a0bd562e1 100644 --- a/Tools/autogsdoc.m +++ b/Tools/autogsdoc.m @@ -246,7 +246,7 @@ items in this project. Projects - This value may be supplies as a dictionary containing the paths to + This value may be supplied as a dictionary containing the paths to the igsdoc index/reference files used by external projects, along with values to be used to map the filenames found in the indexes.
For example, if a project index (igsdoc) file says that the class @@ -289,6 +289,13 @@ If this is missing or set to an empty string, then no 'up' link will be provided in the documents.
+ WordMap + This value is a dictionary used to map identifiers/keywords found + in the source files to other words. Generally you will not have + to use this, but it is sometimes helpful to avoid the parser being + confused by the use of C preprocessor macros. You can effectively + redefine the macro to something less confusing. +
Inter-document linkage @@ -430,9 +437,12 @@ main(int argc, char **argv, char **env) gFiles = [NSMutableArray array]; hFiles = [NSMutableArray array]; count = [files count]; -NSLog(@"Proc ... %@", proc); -NSLog(@"Name ... %@", [proc processName]); -NSLog(@"Files ... %@", files); + if (verbose == YES) + { + NSLog(@"Proc ... %@", proc); + NSLog(@"Name ... %@", [proc processName]); + NSLog(@"Files ... %@", files); + } for (i = 1; i < count; i++) { NSString *arg = [files objectAtIndex: i]; @@ -484,6 +494,8 @@ NSLog(@"Files ... %@", files); pool = [NSAutoreleasePool new]; parser = [AGSParser new]; + [parser setWordMap: [defs dictionaryForKey: @"WordMap"]]; + [parser setVerbose: verbose]; output = [AGSOutput new]; if ([defs boolForKey: @"Standards"] == YES) {