diff --git a/ChangeLog b/ChangeLog index 98e0213fe..2121e3e92 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2001-10-15 Richard Frith-Macdonald + + * Source/GNUmakefile: + * Source/GSXML.m: + * Headers/Foundation/GSXML.h: Build and install dummy version if + libxml is not available. + * Tools/GNUmakefile: + * Tools/AGSIndex.h: + * Tools/AGSIndex.m: + * Tools/AGSOutput.h: + * Tools/AGSOutput.m: + * Tools/AGSParser.h: + * Tools/AGSParser.m: + * Tools/autogsdoc.m: Many bugfixes and additions, bew code to + generate indexes. + 2001-10-15 Richard Frith-Macdonald * Tools/AGSOutput.m: Added new 'unit' pseudo-markup to permit diff --git a/Source/GNUmakefile b/Source/GNUmakefile index dd1e87815..64957a950 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -169,6 +169,7 @@ GSMime.m \ GSSet.m \ GSString.m \ GSValue.m \ +GSXML.m \ NSAttributedString.m \ NSArchiver.m \ NSArray.m \ @@ -246,10 +247,6 @@ NSZone.m \ externs.m \ objc-load.m -ifeq ($(HAVE_LIBXML),1) -BASE_MFILES += GSXML.m -endif - ifeq ($(WITH_FFI),libffi) GNU_MFILES += cifframe.m BASE_MFILES += GSFFIInvocation.m @@ -282,6 +279,7 @@ tzfile.h FOUNDATION_HEADERS = \ Foundation.h \ GSMime.h \ +GSXML.h \ NSArchiver.h \ NSArray.h \ NSAttributedString.h \ @@ -351,10 +349,6 @@ objc-load.h \ NSURL.h \ NSURLHandle.h -ifeq ($(HAVE_LIBXML),1) -FOUNDATION_HEADERS += GSXML.h -endif - UNICODE_HEADERS = \ unicode/caseconv.h \ unicode/cop.h \ diff --git a/Source/GSXML.m b/Source/GSXML.m index 46220a4da..47cc4f861 100644 --- a/Source/GSXML.m +++ b/Source/GSXML.m @@ -28,6 +28,8 @@ #include +#ifdef HAVE_LIBXML + #include #include #include @@ -2134,3 +2136,64 @@ fatalErrorFunction(void *ctx, const char *msg, ...) } } @end + +#else + +#include +#include + +/* + * Build dummy implementations of the classes if libxml is not available + */ +@interface GSXMLDummy : NSObject +@end +@interface GSXMLAttribute : GSXMLDummy +@end +@interface GSXMLDocument : GSXMLDummy +@end +@interface GSXMLHandler : GSXMLDummy +@end +@interface GSXMLNamespace : GSXMLDummy +@end +@interface GSXMLNode : GSXMLDummy +@end +@interface GSSAXHandler : GSXMLDummy +@end + +@implementation GSXMLDummy ++ (id) allocWithZone: (NSZone*)z +{ + NSLog(@"Not built with libxml ... %@ unusable in %@", + NSStringFromClass(self), NSStringFromSelector(_cmd)); + return nil; +} +- (id) init +{ + NSLog(@"Not built with libxml ... %@ unusable in %@", + NSStringFromClass([self class]), NSStringFromSelector(_cmd)); + RELEASE(self); + return nil; +} +- (id) initWithCoder: (NSCoder*)aCoder +{ + NSLog(@"Not built with libxml ... %@ unusable in %@", + NSStringFromClass([self class]), NSStringFromSelector(_cmd)); + RELEASE(self); + return nil; +} +@end +@implementation GSXMLAttribute +@end +@implementation GSXMLDocument +@end +@implementation GSXMLHandler +@end +@implementation GSXMLNamespace +@end +@implementation GSXMLNode +@end +@implementation GSSAXHandler +@end + +#endif + diff --git a/Source/NSEnumerator.m b/Source/NSEnumerator.m index 878c2daa4..87b2d140e 100644 --- a/Source/NSEnumerator.m +++ b/Source/NSEnumerator.m @@ -28,16 +28,26 @@ @implementation NSEnumerator -- (NSArray *)allObjects +- (NSArray*) allObjects { - NSMutableArray *array; - id obj; + NSMutableArray *array; + id obj; + SEL nsel; + IMP nimp; + SEL asel; + IMP aimp; - array = [NSMutableArray arrayWithCapacity:10]; + array = [NSMutableArray arrayWithCapacity: 10]; - while((obj = [self nextObject])) - [array addObject:obj]; + nsel = @selector(nextObject); + nimp = [self methodForSelector: nsel]; + asel = @selector(addObject:); + aimp = [array methodForSelector: asel]; + while ((obj = (*nimp)(self, nsel)) != nil) + { + (*aimp)(array, asel, obj); + } return array; } diff --git a/Tools/AGSIndex.h b/Tools/AGSIndex.h new file mode 100644 index 000000000..48ddbc0b2 --- /dev/null +++ b/Tools/AGSIndex.h @@ -0,0 +1,38 @@ +/** + + AGSIndex ... a class to create references for a gsdoc file + Copyright (C) 2001 Free Software Foundation, Inc. + + Written by: + richard@brainstorm.co.uk + Created: October 2001 + + This file is part of the GNUstep Project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + You should have received a copy of the GNU General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +#include + +@interface AGSIndex : NSObject +{ + NSMutableDictionary *refs; + NSString *base; // Not retained + NSString *unit; // Not retained +} +- (void) makeRefs: (GSXMLNode*)node; +- (void) mergeRefs: (NSDictionary*)more; +- (NSMutableDictionary*) refs; +- (void) setGlobalRef: (NSString*)ref type: (NSString*)type; +- (void) setUnitRef: (NSString*)ref type: (NSString*)type; +@end + diff --git a/Tools/AGSIndex.m b/Tools/AGSIndex.m new file mode 100644 index 000000000..b3f8a5775 --- /dev/null +++ b/Tools/AGSIndex.m @@ -0,0 +1,363 @@ +/** + + AGSIndex ... a class to create references for a gsdoc file + Copyright (C) 2001 Free Software Foundation, Inc. + + Written by: + richard@brainstorm.co.uk + Created: October 2001 + + This file is part of the GNUstep Project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + You should have received a copy of the GNU General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +#include +#include "AGSIndex.h" + +static int XML_ELEMENT_NODE; +static int XML_TEXT_NODE; + +static void +mergeDictionaries(NSMutableDictionary *dst, NSDictionary *src) +{ + static NSMutableArray *stack = nil; + NSEnumerator *e = [src keyEnumerator]; + NSString *k; + + if (stack == nil) + { + stack = [[NSMutableArray alloc] initWithCapacity: 8]; + } + while ((k = [e nextObject]) != nil) + { + id s = [src objectForKey: k]; + id d = [dst objectForKey: k]; + + [stack addObject: k]; + if (d == nil) + { + if ([s isKindOfClass: [NSString class]] == YES) + { + [dst setObject: s forKey: k]; + } + else if ([s isKindOfClass: [NSDictionary class]] == YES) + { + d = [[NSMutableDictionary alloc] initWithCapacity: [s count]]; + [dst setObject: d forKey: k]; + RELEASE(d); + } + else + { + NSLog(@"Unexpected class in merge %@ ignored", stack); + d = nil; + } + } + if (d != nil) + { + if ([d isKindOfClass: [s class]] == NO) + { + NSLog(@"Class missmatch in merge for %@", stack); + } + else if ([d isKindOfClass: [NSString class]] == YES) + { + if ([d isEqual: s] == NO) + { + NSLog(@"String missmatch in merge for %@", stack); + } + } + else if ([d isKindOfClass: [NSDictionary class]] == YES) + { + mergeDictionaries(d, s); + } + } + [stack removeLastObject]; + } +} + +@implementation AGSIndex + ++ (void) initialize +{ + if (self == [AGSIndex class]) + { + /* + * Cache XML node information. + */ + XML_ELEMENT_NODE = [GSXMLNode typeFromDescription: @"XML_ELEMENT_NODE"]; + XML_TEXT_NODE = [GSXMLNode typeFromDescription: @"XML_TEXT_NODE"]; + } +} + +- (void) dealloc +{ + RELEASE(refs); + [super dealloc]; +} + +- (id) init +{ + refs = [[NSMutableDictionary alloc] initWithCapacity: 8]; + return self; +} + +/** + * Given the root node of a gsdoc document, we traverse the tree + * looking for interestng nodes, and recording their names in a + * dictionary of references. The references are held in a tree + * consisting of dictionaries with strings at the leaves -
+ * method method-name class-name file-name
+ * method method-name category-name file-name
+ * method method-name protocol-name file-name
+ * ivariable variable-name class-name file-name
+ * class class-name file-name
+ * category category-name file-name
+ * protocol protocol-name file-name
+ * function function-name file-name
+ * type type-name file-name
+ * constant constant-name file-name
+ * variable variable-name file-name
+ * entry entry-name file-name ref
+ * label label-name file-name ref
+ * In addition to the tree providing file reference information we + * store a record of the superclasses of each class. + */ +- (void) makeRefs: (GSXMLNode*)node +{ + GSXMLNode *children = [node children]; + GSXMLNode *next = [node next]; + BOOL newUnit = NO; + + if ([node type] == XML_ELEMENT_NODE) + { + NSString *name = [node name]; + NSDictionary *prop = [node propertiesAsDictionary]; + + if ([name isEqual: @"category"] == YES) + { + newUnit = YES; + unit = [NSString stringWithFormat: @"%@(%@)", + [prop objectForKey: @"class"], [prop objectForKey: @"name"]]; + + [self setGlobalRef: unit type: name]; + } + else if ([name isEqual: @"class"] == YES) + { + NSString *tmp; + + newUnit = YES; + unit = [prop objectForKey: @"name"]; + [self setGlobalRef: unit type: name]; + + tmp = [prop objectForKey: @"super"]; + if (tmp != nil) + { + [self setGlobalRef: unit type: @"super"]; + } + } + else if ([name isEqual: @"gsdoc"] == YES) + { + base = [prop objectForKey: @"base"]; + if (base == nil) + { + NSLog(@"No 'base' document name supplied in gsdoc element"); + return; + } + } + else if ([name isEqual: @"ivariable"] == YES) + { + NSString *tmp = [prop objectForKey: @"name"]; + + [self setUnitRef: tmp type: name]; + } + else if ([name isEqual: @"entry"] || [name isEqual: @"label"]) + { + NSMutableDictionary *all; + NSMutableDictionary *byFile; + NSString *text; + NSString *val; + + text = [children content]; + children = nil; + all = [refs objectForKey: name]; + if (all == nil) + { + all = [[NSMutableDictionary alloc] initWithCapacity: 8]; + [refs setObject: all forKey: name]; + RELEASE(all); + } + byFile = [all objectForKey: base]; + if (byFile == nil) + { + byFile = [[NSMutableDictionary alloc] initWithCapacity: 2]; + [all setObject: byFile forKey: base]; + RELEASE(byFile); + } + val = [prop objectForKey: @"id"]; + if (val == nil) + { + val = text; + } + [byFile setObject: val forKey: @"text"]; + } + else if ([name isEqual: @"method"] == YES) + { + NSString *sel = @""; + GSXMLNode *tmp = children; + + sel = [prop objectForKey: @"factory"]; + if (sel != nil && [sel boolValue] == YES) + { + sel = @"+"; + } + else + { + sel = @"-"; + } + children = nil; + while (tmp != nil) + { + if ([tmp type] == XML_ELEMENT_NODE) + { + if ([[tmp name] isEqual: @"sel"] == YES) + { + GSXMLNode *t = [tmp children]; + + while (t != nil) + { + if ([t type] == XML_TEXT_NODE) + { + sel = [sel stringByAppendingString: [t content]]; + } + t = [t next]; + } + } + else if ([[tmp name] isEqual: @"arg"] == NO) + { + children = tmp; + break; + } + else if ([[tmp name] isEqual: @"vararg"] == YES) + { + sel = [sel stringByAppendingString: @",..."]; + children = [tmp next]; + break; + } + } + tmp = [tmp next]; + } + if ([sel length] > 1) + { + [self setUnitRef: sel type: name]; + } + } + else if ([name isEqual: @"protocol"] == YES) + { + newUnit = YES; + unit = [prop objectForKey: @"name"]; + [self setGlobalRef: unit type: name]; + } + else if ([name isEqual: @"constant"] == YES + || [name isEqual: @"EOEntity"] == YES + || [name isEqual: @"EOModel"] == YES + || [name isEqual: @"function"] == YES + || [name isEqual: @"macro"] == YES + || [name isEqual: @"type"] == YES + || [name isEqual: @"variable"] == YES) + { + NSString *tmp = [prop objectForKey: @"name"]; + + [self setGlobalRef: tmp type: name]; + } + else + { + } + } + + if (children != nil) + { + [self makeRefs: children]; + } + if (newUnit == YES) + { + unit = nil; + } + if (next != nil) + { + [self makeRefs: next]; + } +} + +- (void) mergeRefs: (NSDictionary*)more +{ + mergeDictionaries(refs, more); +} + +- (NSMutableDictionary*) refs +{ + return refs; +} + +- (void) setGlobalRef: (NSString*)ref + type: (NSString*)type +{ + NSMutableDictionary *t; + NSString *old; + + t = [refs objectForKey: type]; + if (t == nil) + { + t = [NSMutableDictionary new]; + [refs setObject: t forKey: type]; + RELEASE(t); + } + old = [t objectForKey: ref]; + if (old != nil && [old isEqual: base] == NO) + { + NSLog(@"Warning ... %@ %@ appears in %@ and %@ ... using the latter", + type, ref, old, base); + } + [t setObject: base forKey: ref]; +} + +- (void) setUnitRef: (NSString*)ref + type: (NSString*)type +{ + NSMutableDictionary *t; + NSMutableDictionary *r; + NSString *old; + + t = [refs objectForKey: type]; + if (t == nil) + { + t = [NSMutableDictionary new]; + [refs setObject: t forKey: type]; + RELEASE(t); + } + r = [t objectForKey: ref]; + if (r == nil) + { + r = [NSMutableDictionary new]; + [t setObject: r forKey: ref]; + RELEASE(r); + } + old = [r objectForKey: unit]; + if (old != nil && [old isEqual: base] == NO) + { + NSLog(@"Warning ... %@ %@ %@ appears in %@ and %@ ... using the latter", + type, ref, unit, old, base); + } + [r setObject: base forKey: unit]; +} + +@end + diff --git a/Tools/AGSOutput.m b/Tools/AGSOutput.m index a1719f5cd..b3137d7fb 100644 --- a/Tools/AGSOutput.m +++ b/Tools/AGSOutput.m @@ -22,6 +22,13 @@ #include "AGSOutput.h" +static NSString *escapeType(NSString *str) +{ + str = [str stringByReplacingString: @"<" withString: @"<"]; + str = [str stringByReplacingString: @">" withString: @">"]; + return str; +} + static BOOL snuggleEnd(NSString *t) { static NSCharacterSet *set = nil; @@ -193,32 +200,36 @@ static BOOL snuggleStart(NSString *t) [str appendString: @"\"http://www.gnustep.org/gsdoc-0_6_6.xml\">\n"]; [str appendFormat: @"\n"]; @@ -400,7 +411,7 @@ static BOOL snuggleStart(NSString *t) NSArray *sels = [d objectForKey: @"Sels"]; NSArray *types = [d objectForKey: @"Types"]; NSString *name = [d objectForKey: @"Name"]; - NSString *tmp; + NSString *comment; unsigned i; BOOL isInitialiser = NO; NSString *override = nil; @@ -408,79 +419,91 @@ static BOOL snuggleStart(NSString *t) args = [d objectForKey: @"Args"]; // Used when splitting. - tmp = [d objectForKey: @"Comment"]; + comment = [d objectForKey: @"Comment"]; /** * Check special markup which should be removed from the text * actually placed in the gsdoc method documentation ... the * special markup is included in the gsdoc markup differently. */ - if (tmp != nil) + if (comment != nil) { NSMutableString *m = nil; NSRange r; do { - r = [tmp rangeOfString: @""]; + r = [comment rangeOfString: @""]; + if (r.length == 0) + r = [comment rangeOfString: @""]; + if (r.length == 0) + r = [comment rangeOfString: @""]; if (r.length > 0) { if (m == nil) { - m = [tmp mutableCopy]; + m = [comment mutableCopy]; } [m deleteCharactersInRange: r]; - tmp = m; + comment = m; isInitialiser = YES; } } while (r.length > 0); do { - r = [tmp rangeOfString: @""]; + r = [comment rangeOfString: @""]; + if (r.length == 0) + r = [comment rangeOfString: @""]; + if (r.length == 0) + r = [comment rangeOfString: @""]; if (r.length > 0) { if (m == nil) { - m = [tmp mutableCopy]; + m = [comment mutableCopy]; } [m deleteCharactersInRange: r]; - tmp = m; + comment = m; override = @"subclass"; } } while (r.length > 0); do { - r = [tmp rangeOfString: @""]; + r = [comment rangeOfString: @""]; + if (r.length == 0) + r = [comment rangeOfString: @""]; + if (r.length == 0) + r = [comment rangeOfString: @""]; if (r.length > 0) { if (m == nil) { - m = [tmp mutableCopy]; + m = [comment mutableCopy]; } [m deleteCharactersInRange: r]; - tmp = m; + comment = m; override = @"never"; } } while (r.length > 0); - r = [tmp rangeOfString: @""]; + r = [comment rangeOfString: @""]; if (r.length > 0) { unsigned i = r.location; - r = NSMakeRange(i, [tmp length] - i); - r = [tmp rangeOfString: @"" + r = NSMakeRange(i, [comment length] - i); + r = [comment rangeOfString: @"" options: NSLiteralSearch range: r]; if (r.length > 0) { r = NSMakeRange(i, NSMaxRange(r) - i); - standards = [tmp substringWithRange: r]; + standards = [comment substringWithRange: r]; if (m == nil) { - m = [tmp mutableCopy]; + m = [comment mutableCopy]; } [m deleteCharactersInRange: r]; - tmp = m; + comment = m; } else { @@ -489,12 +512,12 @@ static BOOL snuggleStart(NSString *t) } if (m != nil) { - RELEASE(m); + AUTORELEASE(m); } } [str appendString: @" "]; [str appendString: [args objectAtIndex: i]]; [str appendString: @"\n"]; } } + if ([[d objectForKey: @"VarArg"] boolValue] == YES) + { + [str appendString: @"\n"]; + } [str appendString: @" \n"]; - tmp = [d objectForKey: @"Comment"]; - if (tmp != nil) + if (comment != nil) { - [self reformat: tmp withIndent: 12 to: str]; + [self reformat: comment withIndent: 12 to: str]; } [str appendString: @" \n"]; if (standards != nil) @@ -1229,6 +1255,15 @@ static BOOL snuggleStart(NSString *t) } pos++; } + /* + * Varags methods end with ',...' + */ + if (ePos - pos >= 4 + && [[tmp substringWithRange: NSMakeRange(pos, 4)] + isEqual: @",..."]) + { + pos += 4; + } /* * The end of the method name should be immediately * before the closing square bracket at 'ePos' @@ -1329,6 +1364,16 @@ static BOOL snuggleStart(NSString *t) } pos++; } + /* + * Varags methods end with ',...' + */ + if (ePos - pos >= 4 + && [[tmp substringWithRange: NSMakeRange(pos, 4)] + isEqual: @",..."]) + { + pos += 4; + c = [tmp characterAtIndex: pos]; + } if (pos > 1 && (pos == ePos || c == ',' || c == '.' || c == ';')) { NSString *end; diff --git a/Tools/AGSParser.h b/Tools/AGSParser.h index e8a799a4b..751aae286 100644 --- a/Tools/AGSParser.h +++ b/Tools/AGSParser.h @@ -57,7 +57,7 @@ NSCharacterSet *spacenl; // Blanks excluding newline } -- (NSDictionary*) info; +- (NSMutableDictionary*) info; - (id) init; /** Simple initialiser */ - (NSMutableDictionary*) parseFile: (NSString*)name isSource: (BOOL)isSource; - (NSString*) parseIdentifier; diff --git a/Tools/AGSParser.m b/Tools/AGSParser.m index e68bd5748..3df9f91d3 100644 --- a/Tools/AGSParser.m +++ b/Tools/AGSParser.m @@ -35,7 +35,7 @@ [super dealloc]; } -- (NSDictionary*) info +- (NSMutableDictionary*) info { return info; } diff --git a/Tools/GNUmakefile b/Tools/GNUmakefile index fc7a20c06..8452317f9 100644 --- a/Tools/GNUmakefile +++ b/Tools/GNUmakefile @@ -47,7 +47,7 @@ CTOOL_NAME = gdomap TEST_TOOL_NAME = locale_alias # The source files to be compiled -autogsdoc_OBJC_FILES = autogsdoc.m AGSParser.m AGSOutput.m +autogsdoc_OBJC_FILES = autogsdoc.m AGSParser.m AGSOutput.m AGSIndex.m gdomap_C_FILES = gdomap.c gdnc_OBJC_FILES = gdnc.m gsdoc_OBJC_FILES = gsdoc.m diff --git a/Tools/autogsdoc.m b/Tools/autogsdoc.m index 0d6bdd9e0..7a41bc373 100644 --- a/Tools/autogsdoc.m +++ b/Tools/autogsdoc.m @@ -109,14 +109,14 @@ following markup is removed from the text and handled specially -

- <init> + <init /> The method is marked as being the designated initialiser for the class. - <override-subclass> + <override-subclass /> The method is marked as being one which subclasses must override (eg an abstract method). - <override-never> + <override-never /> The method is marked as being one which subclasses should NOT override. @@ -161,19 +161,30 @@ command line. +
+ Inter-document linkage +

+ When supplied with a list of documents to process, the tool will + set up linkage between documents using the gsdoc 'prev', 'next', + and 'up' attributes. +

+

+ The first document processed will be the 'up' link for all + subsequent documents. +

+

+ The 'prev' and 'next' links will be set up to link the documents + in the order in which they are processed. +

+
*/ -#include "AGSParser.h" -#include "AGSOutput.h" - #include -#if HAVE_LIBXML -#include - -static int XML_ELEMENT_NODE; -#endif +#include "AGSParser.h" +#include "AGSOutput.h" +#include "AGSIndex.h" int main(int argc, char **argv, char **env) @@ -185,8 +196,11 @@ main(int argc, char **argv, char **env) NSFileManager *mgr; NSString *documentationDirectory; NSString *sourceDirectory; + AGSIndex *indexer; AGSParser *parser; AGSOutput *output; + NSString *up = nil; + NSString *prev = nil; CREATE_AUTORELEASE_POOL(pool); #ifdef GS_PASS_ARGUMENTS @@ -209,6 +223,7 @@ main(int argc, char **argv, char **env) mgr = [NSFileManager defaultManager]; + indexer = [AGSIndex new]; parser = [AGSParser new]; output = [AGSOutput new]; @@ -221,25 +236,33 @@ main(int argc, char **argv, char **env) { i++; // Skip next value ... it is a default. } - else if ([arg hasSuffix: @".h"]) + else if ([arg hasSuffix: @".h"] || [arg hasSuffix: @".m"]) { NSString *ddir; NSString *sdir; NSString *file; NSString *generated; + BOOL isSource = [arg hasSuffix: @".m"]; file = [[arg lastPathComponent] stringByDeletingPathExtension]; - if (sourceDirectory == nil) + if (isSource == YES) { - sdir = [arg stringByDeletingLastPathComponent]; + sdir = arg; } else { - sdir = sourceDirectory; + if (sourceDirectory == nil) + { + sdir = [arg stringByDeletingLastPathComponent]; + } + else + { + sdir = sourceDirectory; + } + sdir = [sdir stringByAppendingPathComponent: file]; + sdir = [sdir stringByAppendingPathExtension: @"m"]; } - sdir = [sdir stringByAppendingPathComponent: file]; - sdir = [sdir stringByAppendingPathExtension: @"m"]; if (documentationDirectory == nil) { @@ -265,74 +288,65 @@ main(int argc, char **argv, char **env) [parser parseFile: sdir isSource: YES]; } + [[parser info] setObject: file forKey: @"base"]; + if (up == nil) + { + up = file; + } + else + { + [[parser info] setObject: up forKey: @"up"]; + } + if (prev != nil) + { + [[parser info] setObject: prev forKey: @"prev"]; + } + prev = file; + if (i < [args count] - 1) + { + unsigned j = i + 1; + + while (j < [args count]) + { + NSString *name = [args objectAtIndex: j++]; + + if ([name hasSuffix: @".h"] || [name hasSuffix: @".m"]) + { + name = [[name lastPathComponent] + stringByDeletingPathExtension]; + [[parser info] setObject: name forKey: @"next"]; + break; + } + } + } + generated = [output output: [parser info]]; -#if HAVE_LIBXML - { - NSData *data; - GSXMLParser *parser; - - /* - * Cache XML node information. - */ - XML_ELEMENT_NODE - = [GSXMLNode typeFromDescription: @"XML_ELEMENT_NODE"]; - - data = [generated dataUsingEncoding: NSUTF8StringEncoding]; - parser = [GSXMLParser parser]; - [parser substituteEntities: YES]; - [parser doValidityChecking: YES]; - if ([parser parse: data] == NO || [parser parse: nil] == NO) - { - NSLog(@"WARNING %@ did not produce a valid document", arg); - } - if (![[[[parser doc] root] name] isEqualToString: @"gsdoc"]) - { - NSLog(@"not a gsdoc document - because name node is %@", - [[[parser doc] root] name]); - return 1; - } - } -#endif if ([generated writeToFile: ddir atomically: YES] == NO) { NSLog(@"Sorry unable to write %@", ddir); } - } - else if ([arg hasSuffix: @".m"]) - { - NSString *ddir; - NSString *file; - - file = [[arg lastPathComponent] stringByDeletingPathExtension]; - - if (documentationDirectory == nil) - { - ddir = [arg stringByDeletingLastPathComponent]; - } else { - ddir = documentationDirectory; + CREATE_AUTORELEASE_POOL(pool); + GSXMLParser *parser; + + parser = [GSXMLParser parserWithContentsOfFile: ddir]; + [parser substituteEntities: YES]; + [parser doValidityChecking: YES]; + if ([parser parse] == NO) + { + NSLog(@"WARNING %@ did not produce a valid document", arg); + } + if (![[[[parser doc] root] name] isEqualToString: @"gsdoc"]) + { + NSLog(@"not a gsdoc document - because name node is %@", + [[[parser doc] root] name]); + return 1; + } + [indexer makeRefs: [[parser doc] root]]; + RELEASE(pool); } - ddir = [ddir stringByAppendingPathComponent: file]; - ddir = [ddir stringByAppendingPathExtension: @"gsdoc"]; - - if ([mgr isReadableFileAtPath: arg] == NO) - { - NSLog(@"No readable file at '%@' ... skipping", arg); - continue; - } - - /* - * If we have been given a '.m' file, we assume that it contains - * interface details to be exported ... so we parse it first as - * if it were a header file, and then again as a source file. - */ - [parser reset]; - [parser parseFile: arg isSource: NO]; - [parser parseFile: arg isSource: YES]; - - [output output: [parser info] file: ddir]; } else {