diff --git a/ChangeLog b/ChangeLog index da1b8a7bc..74a7ad083 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2002-05-13 Richard Frith-Macdonald + + * Source/NSFileManager.m: Don't try to release memory using free() + when it was allocated using NSZoneMalloc(). + * Tools/autogsdoc.m: Improve dependency rule management. + * Tools/AGSParser.h: ditto + * Tools/AGSParser.m: ditto + * Tools/AGSIndex.h: ditto + * Tools/AGSIndex.m: ditto + Store all dependency information in the .igsdoc file and keep it up + to date. Never regenerate a file that doesn't need it. + Mostly the changes are to cope with the fact that we now have + common files into which all functions, constants, variables, and + typedefs within a project are combined. + 2002-05-11 Richard Frith-Macdonald * Source/Unicode.m: Rationalise so that all conversion operations diff --git a/Headers/gnustep/base/NSDecimal.h b/Headers/gnustep/base/NSDecimal.h index 4b27ce4df..e3ac6ce92 100644 --- a/Headers/gnustep/base/NSDecimal.h +++ b/Headers/gnustep/base/NSDecimal.h @@ -19,6 +19,7 @@ You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. + */ #ifndef __NSDecimal_h_GNUSTEP_BASE_INCLUDE diff --git a/Source/NSFileManager.m b/Source/NSFileManager.m index 975fe5f73..767d26912 100644 --- a/Source/NSFileManager.m +++ b/Source/NSFileManager.m @@ -1541,7 +1541,7 @@ typedef struct _GSEnumeratedDirectory { inline void gsedRelease(GSEnumeratedDirectory X) { - free(X.path); + NSZoneFree(NSDefaultMallocZone(), X.path); closedir(X.pointer); } diff --git a/Tools/AGSIndex.h b/Tools/AGSIndex.h index 5a7f198bf..e4c3ae39b 100644 --- a/Tools/AGSIndex.h +++ b/Tools/AGSIndex.h @@ -43,10 +43,12 @@ - (NSMutableDictionary*) refs; - (void) setDirectory: (NSString*)path; - (void) setGlobalRef: (NSString*)ref type: (NSString*)type; +- (void) setOutputs: (NSArray*)a forHeader: (NSString*)h; - (void) setRelationship: (NSString*)r from: (NSString*)from to: (NSString*)to; - (void) setSources: (NSArray*)a forHeader: (NSString*)h; - (void) setUnitRef: (NSString*)ref type: (NSString*)type; -- (NSArray*) sourcesForHeader: (NSString*)h; +- (NSMutableArray*) outputsForHeader: (NSString*)h; +- (NSMutableArray*) sourcesForHeader: (NSString*)h; - (NSDictionary*) unitRef: (NSString*)ref type: (NSString*)type; - (NSString*) unitRef: (NSString*)ref type: (NSString*)type unit: (NSString**)u; @end diff --git a/Tools/AGSIndex.m b/Tools/AGSIndex.m index a30035b41..d66d30ef8 100644 --- a/Tools/AGSIndex.m +++ b/Tools/AGSIndex.m @@ -466,6 +466,21 @@ setDirectory(NSMutableDictionary *dict, NSString *path) return [d allKeys]; } +/** + * Return a list of output files for the header + */ +- (NSMutableArray*) outputsForHeader: (NSString*)h +{ + NSDictionary *dict = [refs objectForKey: @"output"]; + NSArray *array = [dict objectForKey: h]; + + if (array == nil) + { + return [NSMutableArray arrayWithCapacity: 2]; + } + return AUTORELEASE([array mutableCopy]); +} + - (NSMutableDictionary*) refs { return refs; @@ -503,6 +518,23 @@ setDirectory(NSMutableDictionary *dict, NSString *path) [t setObject: base forKey: ref]; } +/** + * Set up an array listing the output files for a particular header. + */ +- (void) setOutputs: (NSArray*)a forHeader: (NSString*)h +{ + NSMutableDictionary *dict; + + dict = [refs objectForKey: @"output"]; + if (dict == nil) + { + dict = [NSMutableDictionary new]; + [refs setObject: dict forKey: @"output"]; + RELEASE(dict); + } + [dict setObject: a forKey: h]; +} + - (void) setRelationship: (NSString*)r from: (NSString*)from to: (NSString*)to { NSMutableDictionary *dict; @@ -585,13 +617,18 @@ setDirectory(NSMutableDictionary *dict, NSString *path) } /** - * Return a list of source files for the header (or nil) + * Return a list of source files for the header. */ - (NSArray*) sourcesForHeader: (NSString*)h { NSDictionary *dict = [refs objectForKey: @"source"]; + NSArray *array = [dict objectForKey: h]; - return [dict objectForKey: h]; + if (array == nil) + { + return [NSMutableArray arrayWithCapacity: 2]; + } + return AUTORELEASE([array mutableCopy]); } /** diff --git a/Tools/AGSOutput.m b/Tools/AGSOutput.m index f9eccf68c..aee2f064b 100644 --- a/Tools/AGSOutput.m +++ b/Tools/AGSOutput.m @@ -74,18 +74,6 @@ static BOOL snuggleStart(NSString *t) */ @implementation AGSOutput -+ (void) initialize -{ - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - - [ud registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys: - @"TypesAndConstants", @"ConstantsTemplate", - @"Functions", @"FunctionsTemplate", - @"TypesAndConstants", @"TypedefsTemplate", - @"TypesAndConstants", @"VariablesTemplate", - nil]]; -} - - (void) dealloc { DESTROY(identifier); diff --git a/Tools/AGSParser.h b/Tools/AGSParser.h index d263bed55..8a8a67262 100644 --- a/Tools/AGSParser.h +++ b/Tools/AGSParser.h @@ -55,6 +55,7 @@ unsigned length; unsigned pos; BOOL commentsRead; + BOOL haveOutput; BOOL haveSource; BOOL inInstanceVariables; BOOL inArgList; @@ -75,6 +76,7 @@ - (NSMutableDictionary*) info; - (id) init; /** Simple initialiser */ +- (NSMutableArray*) outputs; - (NSMutableDictionary*) parseDeclaration; - (NSMutableDictionary*) parseFile: (NSString*)name isSource: (BOOL)isSource; - (NSString*) parseIdentifier; @@ -105,6 +107,6 @@ - (unsigned) skipStatementLine; - (unsigned) skipUnit; - (unsigned) skipWhiteSpace; -- (NSArray*) source; +- (NSMutableArray*) sources; @end #endif diff --git a/Tools/AGSParser.m b/Tools/AGSParser.m index 613f0c83e..bfd67c98a 100644 --- a/Tools/AGSParser.m +++ b/Tools/AGSParser.m @@ -171,6 +171,73 @@ inArgList = wasInArgList; } +/** + * Return the list of known output files depending on this source/header. + */ +- (NSMutableArray*) outputs +{ + NSUserDefaults *defs = [NSUserDefaults standardUserDefaults]; + NSMutableArray *output = [NSMutableArray arrayWithCapacity: 6]; + NSString *basic = [info objectForKey: @"Header"]; + NSString *names[4] = { @"Functions", @"Typedefs", @"Variables", + @"Constants" }; + unsigned i; + + basic = [basic lastPathComponent]; + basic = [basic stringByDeletingPathExtension]; + basic = [basic stringByAppendingPathExtension: @"gsdoc"]; + + /** + * If there are any classes, categories, or protocols, there will be + * an output file for them whose name is based on the name of the header. + */ + if ([[info objectForKey: @"Classes"] count] > 0 + || [[info objectForKey: @"Categories"] count] > 0 + || [[info objectForKey: @"Protocols"] count] > 0) + { + [output addObject: basic]; + } + + /** + * If there are any constants, variables, typedefs or functions, there + * will either be a shared output file for them (defined by a template + * name set in the user defaults system), or they will go in the same + * file as classes etc. + */ + for (i = 0; i < sizeof(names) / sizeof(NSString*); i++) + { + NSString *base = names[i]; + + if ([[info objectForKey: base] count] > 0) + { + NSString *file; + + base = [base stringByAppendingString: @"Template"]; + file = [defs stringForKey: base]; + if ([file length] == 0) + { + if ([output containsObject: basic] == NO) + { + [output addObject: basic]; + } + } + else + { + if ([[file pathExtension] isEqual: @"gsdoc"] == NO) + { + file = [file stringByAppendingPathExtension: @"gsdoc"]; + } + if ([output containsObject: file] == NO) + { + [output addObject: file]; + } + } + } + } + + return output; +} + - (void) parseDeclaratorInto: (NSMutableDictionary*)d { NSMutableString *p = nil; @@ -722,6 +789,7 @@ fail: [source removeAllObjects]; if (isSource == NO) { + [info setObject: fileName forKey: @"Header"]; [source removeAllObjects]; [source addObject: [[[fileName lastPathComponent] stringByDeletingPathExtension] @@ -1900,6 +1968,7 @@ fail: { [source removeAllObjects]; [info removeAllObjects]; + haveOutput = NO; haveSource = NO; DESTROY(declared); DESTROY(comment); @@ -3038,9 +3107,9 @@ fail: return pos; } -- (NSArray*) source +- (NSMutableArray*) sources { - return AUTORELEASE([source copy]); + return AUTORELEASE([source mutableCopy]); } @end diff --git a/Tools/autogsdoc.m b/Tools/autogsdoc.m index 73fa0d653..855244e2c 100644 --- a/Tools/autogsdoc.m +++ b/Tools/autogsdoc.m @@ -391,6 +391,10 @@ main(int argc, char **argv, char **env) defs = [NSUserDefaults standardUserDefaults]; [defs registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys: @"Untitled", @"Project", + @"TypesAndConstants", @"ConstantsTemplate", + @"Functions", @"FunctionsTemplate", + @"TypesAndConstants", @"TypedefsTemplate", + @"TypesAndConstants", @"VariablesTemplate", nil]]; verbose = [defs boolForKey: @"Verbose"]; @@ -540,14 +544,14 @@ main(int argc, char **argv, char **env) for (i = 0; i < count; i++) { - NSString *hfile = [sFiles objectAtIndex: i]; - NSString *gsdocfile; - NSString *file; - NSArray *a; - NSDictionary *attrs; - NSDate *sDate = nil; - NSDate *gDate = nil; - unsigned i; + NSString *hfile = [sFiles objectAtIndex: i]; + NSString *gsdocfile; + NSString *file; + NSMutableArray *a; + NSDictionary *attrs; + NSDate *sDate = nil; + NSDate *gDate = nil; + unsigned j; if (pool != nil) { @@ -557,7 +561,7 @@ main(int argc, char **argv, char **env) /* * Note the name of the header file without path or extension. - * This will be used to generate the outut file. + * This will be used to generate the output file. */ file = [hfile stringByDeletingPathExtension]; file = [file lastPathComponent]; @@ -586,22 +590,16 @@ main(int argc, char **argv, char **env) { NSDate *d; - attrs = [mgr fileAttributesAtPath: hfile - traverseLink: YES]; - d = [attrs objectForKey: NSFileModificationDate]; - if (sDate == nil || [d earlierDate: sDate] == sDate) - { - sDate = d; - AUTORELEASE(RETAIN(sDate)); - } /* * Ask existing project info (.gsdoc file) for dependency - * information. Then check the dates on the source files. + * information. Then check the dates on the source files + * and the header file. */ a = [projectRefs sourcesForHeader: hfile]; - for (i = 0; i < [a count]; i++) + [a insertObject: hfile atIndex: 0]; + for (j = 0; j < [a count]; j++) { - NSString *sfile = [a objectAtIndex: i]; + NSString *sfile = [a objectAtIndex: j]; attrs = [mgr fileAttributesAtPath: sfile traverseLink: YES]; @@ -612,10 +610,37 @@ main(int argc, char **argv, char **env) AUTORELEASE(RETAIN(sDate)); } } + if (verbose == YES) + { + NSLog(@"Sources for %@ are %@ ... %@", hfile, a, sDate); + } - attrs = [mgr fileAttributesAtPath: gsdocfile traverseLink: YES]; - gDate = [attrs objectForKey: NSFileModificationDate]; - AUTORELEASE(RETAIN(gDate)); + /* + * Ask existing project info (.gsdoc file) for dependency + * information. Then check the dates on the output files. + * If none are set, assume the defualt. + */ + a = [projectRefs outputsForHeader: hfile]; + if ([a count] == 0) + { + [a insertObject: gsdocfile atIndex: 0]; + } + for (j = 0; j < [a count]; j++) + { + NSString *ofile = [a objectAtIndex: j]; + + attrs = [mgr fileAttributesAtPath: ofile traverseLink: YES]; + d = [attrs objectForKey: NSFileModificationDate]; + if (gDate == nil || [d laterDate: gDate] == gDate) + { + gDate = d; + AUTORELEASE(RETAIN(gDate)); + } + } + if (verbose == YES) + { + NSLog(@"Outputs for %@ are %@ ... %@", hfile, a, gDate); + } } if (gDate == nil || [sDate earlierDate: gDate] == gDate) @@ -647,18 +672,38 @@ main(int argc, char **argv, char **env) } [parser parseFile: hfile isSource: NO]; - a = [parser source]; /* * Record dependency information. */ + a = [parser outputs]; + if ([a count] > 0) + { + /* + * Adjust the location of the output files to be in the + * documentation directory. + */ + for (j = 0; j < [a count]; j++) + { + NSString *s = [a objectAtIndex: j]; + + if ([s isAbsolutePath] == NO) + { + s = [documentationDirectory + stringByAppendingPathComponent: s]; + [a replaceObjectAtIndex: j withObject: s]; + } + } + [projectRefs setOutputs: a forHeader: hfile]; + } + a = [parser sources]; if ([a count] > 0) { [projectRefs setSources: a forHeader: hfile]; } - for (i = 0; i < [a count]; i++) + for (j = 0; j < [a count]; j++) { - NSString *sfile = [a objectAtIndex: i]; + NSString *sfile = [a objectAtIndex: j]; /* * If we can read a source file, parse it for any @@ -769,9 +814,9 @@ main(int argc, char **argv, char **env) /* * Now we try to process the gsdoc data to make index info * unless the project index is already more up to date than - * this file. + * this file (or the gsdoc file does not exist of course). */ - if (gDate == nil || [gDate earlierDate: rDate] == rDate) + if (gDate != nil && [gDate earlierDate: rDate] == rDate) { if (showDependencies == YES) {