Rewritten to use a different better link system which is also compatible

with the current autogsdoc link systme


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@12012 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
nico 2002-01-07 01:09:15 +00:00
parent 18503e9b22
commit e626c6fab9

View file

@ -31,15 +31,22 @@ static NSFileManager *fileManager = nil;
/* [[NSFileManager defaulManager] currentDirectoryPath] */ /* [[NSFileManager defaulManager] currentDirectoryPath] */
static NSString *currentPath = nil; static NSString *currentPath = nil;
/* Enumerate all .html files in a directory and subdirectories. */ /* Enumerate all .html (or .htmlink) files in a directory and
subdirectories. */
@interface HTMLDirectoryEnumerator : NSEnumerator @interface HTMLDirectoryEnumerator : NSEnumerator
{ {
NSDirectoryEnumerator *e; NSDirectoryEnumerator *e;
NSString *basePath; NSString *basePath;
BOOL looksForHTMLLinkFiles;
BOOL returnsAbsolutePaths;
} }
- (id)initWithBasePath: (NSString *)path; - (id)initWithBasePath: (NSString *)path;
- (void)setReturnsAbsolutePaths: (BOOL)flag;
- (void)setLooksForHTMLLinkFiles: (BOOL)flag;
@end @end
@implementation HTMLDirectoryEnumerator : NSEnumerator @implementation HTMLDirectoryEnumerator : NSEnumerator
@ -58,22 +65,52 @@ static NSString *currentPath = nil;
[super dealloc]; [super dealloc];
} }
- (void)setReturnsAbsolutePaths: (BOOL)flag
{
returnsAbsolutePaths = flag;
}
- (void)setLooksForHTMLLinkFiles: (BOOL)flag
{
looksForHTMLLinkFiles = YES;
}
- (id)nextObject - (id)nextObject
{ {
NSString *s; NSString *s;
while ((s = [e nextObject]) != nil) while ((s = [e nextObject]) != nil)
{ {
BOOL found = NO;
NSString *extension = [s pathExtension]; NSString *extension = [s pathExtension];
if ([extension isEqualToString: @"html"] if (looksForHTMLLinkFiles)
|| [extension isEqualToString: @"HTML"]
|| [extension isEqualToString: @"htm"]
|| [extension isEqualToString: @"HTM"])
{ {
/* NSDirectoryEnumerator returns the relative path, we if ([extension isEqualToString: @"htmlink"])
return the absolute. */ {
return [basePath stringByAppendingPathComponent: s]; found = YES;
}
}
else if ([extension isEqualToString: @"html"]
|| [extension isEqualToString: @"HTML"]
|| [extension isEqualToString: @"htm"]
|| [extension isEqualToString: @"HTM"])
{
found = YES;
}
if (found)
{
if (returnsAbsolutePaths)
{
/* NSDirectoryEnumerator returns the relative path, we
return the absolute. */
return [basePath stringByAppendingPathComponent: s];
}
else
{
return s;
}
} }
} }
@ -82,65 +119,31 @@ static NSString *currentPath = nil;
@end @end
/*
* An object representing a file which can be a destination of links.
*/
@interface DestinationFile : NSObject
{
/* Full name to be used when fixing up links to this file. */
NSString *fullName;
/* Path on disk needed to read the file from disk - needed only when
performing link checking. pathOnDisk might be different from
fullName, for example for a file on a web server. In that case,
fullName is the URI to the file on the web server, while
pathOnDisk is the path to the file on disk. */
NSString *pathOnDisk;
/* If the file has already been read to perform link checking, names
is the array of all names (for any <a name="xxx"> in the file,
xxx is put in the names array for that file) in the file. If it
hasn't yet been read, it's nil. We read the file and parse it
lazily, only if needed. */
NSArray *names;
}
/* Return the full name. */
- (NSString *)fullName;
/* Checks that the file on disk contains <a name="xxx"> where xxx is
name, lazily loading and parsing the file if needed. Return YES if
the file contains name, NO if it doesn't. */
- (BOOL)checkAnchorName: (NSString *)name;
@end
/* The HTMLLinker class is very simple and is the core of the linker. /* The HTMLLinker class is very simple and is the core of the linker.
It just keeps a table of the available destination files, and is It just keeps a relocation, and is able to fixup a link by using
able to fixup a link to point to one of those files. */ the relocation table. */
@interface HTMLLinker : NSObject @interface HTMLLinker : NSObject
{ {
BOOL verbose; BOOL warn;
BOOL checkLinks; BOOL hasPathMappings;
NSMutableDictionary *files;
NSMutableDictionary *pathMappings; NSMutableDictionary *pathMappings;
NSMutableDictionary *relocationTable;
} }
- (id)initWithVerboseFlag: (BOOL)v - (id)initWithWarnFlag: (BOOL)v;
checkLinksFlag: (BOOL)f;
/* Register the file as available for resolving references. */ - (void)registerRelocationFile: (NSString *)pathOnDisk;
- (void)registerFile: (NSString *)pathOnDisk;
- (void)registerDestinationFile: (NSString *)pathOnDisk;
/* Register a new path mapping. */ /* Register a new path mapping. */
- (void)registerPathMappings: (NSDictionary *)dict; - (void)registerPathMappings: (NSDictionary *)dict;
/* Resolve the link 'link' by fixing it up using the registered /* Resolve the link 'link' by fixing it up using the relocation table.
destination files. Return the resolved link. 'logFile' is only Return the resolved link. 'logFile' is only used to print error
used to print error messages. It is the file in which the link is messages. It is the file in which the link is originally found; if
originally found; if there is problem resolving the link, the there is problem resolving the link, the warning message printed
warning message printed out states that the problem is in file out states that the problem is in file 'logFile'. */
'logFile'. */
- (NSString *)resolveLink: (NSString *)link - (NSString *)resolveLink: (NSString *)link
logFile: (NSString *)logFile; logFile: (NSString *)logFile;
@ -156,7 +159,8 @@ static NSString *currentPath = nil;
library, so you can use the HTML linker on any system. This class library, so you can use the HTML linker on any system. This class
was written in order to perform its trivial, mechanical duty /very was written in order to perform its trivial, mechanical duty /very
fast/. You want to be able to run the linker often and on a lot of fast/. You want to be able to run the linker often and on a lot of
files and still be happy. */ files and still be happy. FIXME - Need to implement support for
newer HTML where you can use id="name" in any tag. */
@interface HTMLParser : NSObject @interface HTMLParser : NSObject
{ {
/* The HTML code that we work on. */ /* The HTML code that we work on. */
@ -172,15 +176,14 @@ static NSString *currentPath = nil;
/* Fix up all the links in the HTML code by feeding each of them to /* Fix up all the links in the HTML code by feeding each of them to
the provided HTMLLinker; return the fixed up HTML code. If the provided HTMLLinker; return the fixed up HTML code. If
fixupAllLinks is 'NO', only fixup links with rel="dynamical"; if linksMarker is nil, attempts to fix up all links in the HTML code;
fixupAllLinks is 'YES', attempt to fixup all links in the HTML if it is not-nil, only attempt to fixup links with rel=marker.
code. logFile is the file we are fixing up; it's only used when a logFile is the file we are fixing up; it's only used when a warning
warning is issued because there is problem in the linking - the is issued because there is problem in the linking - the warning
warning message is displayed as being about links in the file message is displayed as being about links in the file logFile. */
logFile. */
- (NSString *)resolveLinksUsingHTMLLinker: (HTMLLinker *)linker - (NSString *)resolveLinksUsingHTMLLinker: (HTMLLinker *)linker
logFile: (NSString *)logFile logFile: (NSString *)logFile
fixupAllLinks: (BOOL)fixupAllLinks; linksMarker: (NSString *)marker;
@end @end
@ -358,12 +361,10 @@ static NSString *currentPath = nil;
{ {
name = [NSString stringWithCharacters: &chars[s] name = [NSString stringWithCharacters: &chars[s]
length: (i - s)]; length: (i - s)];
/* Per HTML specs we lowercase name. */
name = [name lowercaseString];
} }
} }
} }
if (name != nil) if (name != nil)
{ {
[names addObject: name]; [names addObject: name];
@ -378,7 +379,7 @@ static NSString *currentPath = nil;
- (NSString *)resolveLinksUsingHTMLLinker: (HTMLLinker *)linker - (NSString *)resolveLinksUsingHTMLLinker: (HTMLLinker *)linker
logFile: (NSString *)logFile logFile: (NSString *)logFile
fixupAllLinks: (BOOL)fixupAllLinks linksMarker: (NSString *)marker
{ {
/* We represent the output as a linked list. Each element in the /* We represent the output as a linked list. Each element in the
linked list represents a string; concatenating all the strings in linked list represents a string; concatenating all the strings in
@ -638,8 +639,8 @@ static NSString *currentPath = nil;
} }
} }
} }
if (href != nil && (fixupAllLinks if (href != nil && ((marker == nil)
|| [rel isEqualToString: @"dynamical"])) || [rel isEqualToString: marker]))
{ {
/* Ok - fixup the link. */ /* Ok - fixup the link. */
NSString *link; NSString *link;
@ -727,78 +728,109 @@ static NSString *currentPath = nil;
@end @end
@implementation DestinationFile
- (id)initWithFullName: (NSString *)f
pathOnDisk: (NSString *)p
{
ASSIGN (fullName, f);
ASSIGN (pathOnDisk, p);
return [super init];
}
- (void)dealloc
{
RELEASE (fullName);
RELEASE (pathOnDisk);
RELEASE (names);
[super dealloc];
}
- (NSString *)fullName
{
return fullName;
}
- (BOOL)checkAnchorName: (NSString *)name
{
/* No anchor. */
if (name == nil || [name isEqualToString: @""])
{
return YES;
}
if (names == nil)
{
/* Load the file and parse it, saving the result in names. */
NSString *file = [NSString stringWithContentsOfFile: pathOnDisk];
HTMLParser *parser = [[HTMLParser alloc] initWithCode: file];
ASSIGN (names, [parser names]);
RELEASE (parser);
}
return [names containsObject: name];
}
@end
@implementation HTMLLinker @implementation HTMLLinker
- (id)initWithVerboseFlag: (BOOL)v - (id)initWithWarnFlag: (BOOL)v
checkLinksFlag: (BOOL)f
{ {
verbose = v; warn = v;
checkLinks = f; relocationTable = [NSMutableDictionary new];
files = [NSMutableDictionary new];
pathMappings = [NSMutableDictionary new]; pathMappings = [NSMutableDictionary new];
return [super init]; return [super init];
} }
- (void)dealloc - (void)dealloc
{ {
RELEASE (files); RELEASE (relocationTable);
RELEASE (pathMappings); RELEASE (pathMappings);
[super dealloc]; [super dealloc];
} }
- (void)registerFile: (NSString *)pathOnDisk - (void)registerRelocationFile: (NSString *)pathOnDisk
{
/* We only accept absolute paths. */
if (![pathOnDisk isAbsolutePath])
{
pathOnDisk = [currentPath stringByAppendingPathComponent: pathOnDisk];
}
/* Check if it's a directory; if it is, enumerate all .htmlink files
inside it, and add all of them. */
{
BOOL isDir;
if (![fileManager fileExistsAtPath: pathOnDisk isDirectory: &isDir])
{
NSLog (@"Warning - relocation file '%@' not found - ignored",
pathOnDisk);
return;
}
else
{
if (isDir)
{
HTMLDirectoryEnumerator *e;
NSString *filename;
e = [HTMLDirectoryEnumerator alloc];
e = [e initWithBasePath: pathOnDisk];
[e setLooksForHTMLLinkFiles: YES];
[e setReturnsAbsolutePaths: YES];
while ((filename = [e nextObject]) != nil)
{
[self registerRelocationFile: filename];
}
return;
}
}
}
/* Now, read the mappings in the file. */
{
NSString *file = [NSString stringWithContentsOfFile: pathOnDisk];
NSString *path = [pathOnDisk stringByDeletingLastPathComponent];
NSDictionary *d = [file propertyList];
NSEnumerator *e = [d keyEnumerator];
NSString *name;
while ((name = [e nextObject]) != nil)
{
NSString *v = [d objectForKey: name];
NSString *filePath;
filePath = [path stringByAppendingPathComponent: v];
if (hasPathMappings)
{
/* Manage pathMappings: try to match any of the
pathMappings against pathOnDisk, and perform the path
mapping if we can match. */
NSEnumerator *en = [pathMappings keyEnumerator];
NSString *key;
while ((key = [en nextObject]))
{
if ([filePath hasPrefix: key])
{
NSString *value = [pathMappings objectForKey: key];
filePath = [filePath substringFromIndex: [key length]];
filePath = [value stringByAppendingPathComponent:
filePath];
break;
}
}
}
[relocationTable setObject: filePath forKey: name];
}
}
}
- (void)registerDestinationFile: (NSString *)pathOnDisk
{ {
NSString *fullPath = pathOnDisk; NSString *fullPath = pathOnDisk;
DestinationFile *file;
/* We only accept absolute paths. */ /* We only accept absolute paths. */
if (![pathOnDisk isAbsolutePath]) if (![pathOnDisk isAbsolutePath])
@ -813,13 +845,8 @@ static NSString *currentPath = nil;
if (![fileManager fileExistsAtPath: pathOnDisk isDirectory: &isDir]) if (![fileManager fileExistsAtPath: pathOnDisk isDirectory: &isDir])
{ {
if (verbose) NSLog (@"Warning - destination file '%@' not found - ignored",
{ pathOnDisk);
/* FIXME - Perhaps we should not actually ignore it but
act as if it were there. */
NSLog (@"Warning - destination file '%@' not found - ignored",
pathOnDisk);
}
return; return;
} }
else else
@ -831,41 +858,55 @@ static NSString *currentPath = nil;
e = [HTMLDirectoryEnumerator alloc]; e = [HTMLDirectoryEnumerator alloc];
e = [e initWithBasePath: pathOnDisk]; e = [e initWithBasePath: pathOnDisk];
[e setReturnsAbsolutePaths: YES];
while ((filename = [e nextObject]) != nil) while ((filename = [e nextObject]) != nil)
{ {
[self registerFile: filename]; [self registerDestinationFile: filename];
} }
return; return;
} }
} }
} }
/* Manage pathMappings: try to match any of the pathMappings against if (hasPathMappings)
pathOnDisk, and perform the path mapping if we can match. */ {
/* Manage pathMappings: try to match any of the pathMappings
against pathOnDisk, and perform the path mapping if we can
match. */
NSEnumerator *e = [pathMappings keyEnumerator];
NSString *key;
while ((key = [e nextObject]))
{
if ([pathOnDisk hasPrefix: key])
{
NSString *value = [pathMappings objectForKey: key];
fullPath = [pathOnDisk substringFromIndex: [key length]];
fullPath = [value stringByAppendingPathComponent: fullPath];
break;
}
}
}
/* Now, read all the names from the file. */
{ {
NSEnumerator *e = [pathMappings keyEnumerator]; NSString *file = [NSString stringWithContentsOfFile: pathOnDisk];
NSString *key; HTMLParser *p = [[HTMLParser alloc] initWithCode: file];
NSArray *names = [p names];
unsigned i, count;
while ((key = [e nextObject])) RELEASE (p);
count = [names count];
for (i = 0; i < count; i++)
{ {
if ([pathOnDisk hasPrefix: key]) NSString *name = [names objectAtIndex: i];
{ [relocationTable setObject: fullPath forKey: name];
NSString *value = [pathMappings objectForKey: key];
fullPath = [pathOnDisk substringFromIndex: [key length]];
fullPath = [value stringByAppendingPathComponent: fullPath];
break;
}
} }
} }
/* Save the file properly prepared into our dictionary of
destination files. */
file = [[DestinationFile alloc] initWithFullName: fullPath
pathOnDisk: pathOnDisk];
[files setObject: file forKey: [pathOnDisk lastPathComponent]];
RELEASE (file);
} }
- (void)registerPathMappings: (NSDictionary *)dict - (void)registerPathMappings: (NSDictionary *)dict
@ -878,6 +919,7 @@ static NSString *currentPath = nil;
NSString *value = [dict objectForKey: key]; NSString *value = [dict objectForKey: key];
[pathMappings setObject: value forKey: key]; [pathMappings setObject: value forKey: key];
} }
hasPathMappings = YES;
} }
- (NSString *)resolveLink: (NSString *)link - (NSString *)resolveLink: (NSString *)link
@ -886,7 +928,7 @@ static NSString *currentPath = nil;
NSString *fileLink; NSString *fileLink;
NSString *nameLink; NSString *nameLink;
NSString *relocatedFileLink; NSString *relocatedFileLink;
DestinationFile *file; NSString *file;
/* Do nothing if this is evidently *not* a dynamical link to fixup. */ /* Do nothing if this is evidently *not* a dynamical link to fixup. */
if ([link hasPrefix: @"mailto:"] || [link hasPrefix: @"news:"]) if ([link hasPrefix: @"mailto:"] || [link hasPrefix: @"news:"])
@ -924,40 +966,28 @@ static NSString *currentPath = nil;
} }
} }
/* Now lookup fileLink. */ /* Now lookup nameLink. */
/* If it's "", it means a reference to something inside the same /* If it's "", it is not something we can fixup. */
file. Leave it untouched - no fixup needed. Normally these if (nameLink == nil || [nameLink isEqualToString: @""])
should not be marked as need linker fixup anyway. */
if ([fileLink isEqualToString: @""])
{ {
if (checkLinks)
{
/* FIXME - not really the linker's task, but we might want
to add checking of intra-document links. */
}
relocatedFileLink = fileLink; relocatedFileLink = fileLink;
} }
else else
{ {
/* First, extract the path-less filename, because it might have /* Now simply look it up in our relocation table. */
already been fixed up by a previous run of the linker. */ file = [relocationTable objectForKey: nameLink];
fileLink = [fileLink lastPathComponent];
/* Now simply look it up in our list of files. */
file = [files objectForKey: fileLink];
/* Not found - leave it unfixed. */ /* Not found - leave it unfixed. */
if (file == nil) if (file == nil)
{ {
if (verbose || checkLinks) if (warn)
{ {
NSString *m; NSString *m;
m = [NSString stringWithFormat: m = [NSString stringWithFormat:
@"%@: Unresolved reference to file '%@'\n", @"%@: Unresolved reference to '%@'\n",
logFile, fileLink]; logFile, nameLink];
fprintf (stderr, [m lossyCString]); fprintf (stderr, [m lossyCString]);
} }
@ -965,27 +995,14 @@ static NSString *currentPath = nil;
} }
else else
{ {
relocatedFileLink = [file fullName]; relocatedFileLink = file;
if (checkLinks)
{
if (![file checkAnchorName: nameLink])
{
NSString *m;
m = [NSString stringWithFormat:
@"%@: Unresolved reference to '%@' in file '%@'\n",
logFile, nameLink, fileLink];
fprintf (stderr, [m lossyCString]);
}
}
} }
} }
/* Now build up the final relocated link, and return it. */ /* Now build up the final relocated link, and return it. */
if (nameLink != nil) if (nameLink != nil)
{ {
return [NSString stringWithFormat: @"%@#%@", relocatedFileLink, return [NSString stringWithFormat: @"%@#%@", relocatedFileLink,
nameLink]; nameLink];
} }
else else
@ -996,21 +1013,85 @@ static NSString *currentPath = nil;
@end @end
static NSString *build_relocation_table_for_directory (NSString *dir)
{
BOOL isDir;
/* Check if it's a directory; if it is, enumerate all HTML files
inside it, and add all of them. */
if (![fileManager fileExistsAtPath: dir isDirectory: &isDir])
{
NSLog (@"%@ does not exist - exiting", dir);
exit (1);
}
else if (!isDir)
{
NSLog (@"%@ is not a directory - exiting", dir);
exit (1);
}
else
{
HTMLDirectoryEnumerator *e;
NSString *filename;
NSMutableDictionary *relocationTable;
relocationTable = [NSMutableDictionary new];
AUTORELEASE (relocationTable);
e = [HTMLDirectoryEnumerator alloc];
e = [e initWithBasePath: dir];
/* The relocation table for a directory is relative to the
directory top, so that the whole directory can be moved
around without having to regenerate the .htmlink file. */
[e setReturnsAbsolutePaths: NO];
while ((filename = [e nextObject]) != nil)
{
NSString *fullPath;
NSString *file;
HTMLParser *p;
NSArray *names;
unsigned i, count;
fullPath = [dir stringByAppendingPathComponent: filename];
file = [NSString stringWithContentsOfFile: fullPath];
p = [[HTMLParser alloc] initWithCode: file];
names = [p names];
RELEASE (p);
count = [names count];
for (i = 0; i < count; i++)
{
NSString *name = [names objectAtIndex: i];
[relocationTable setObject: filename forKey: name];
}
}
return [relocationTable description];
}
}
static void print_help_and_exit () static void print_help_and_exit ()
{ {
printf ("GNUstep HTMLLinker (gnustep-base version %d.%d.%d)\n", printf ("GNUstep HTMLLinker (gnustep-base version %d.%d.%d)\n",
GNUSTEP_BASE_MAJOR_VERSION, GNUSTEP_BASE_MAJOR_VERSION,
GNUSTEP_BASE_MINOR_VERSION, GNUSTEP_BASE_MINOR_VERSION,
GNUSTEP_BASE_SUBMINOR_VERSION); GNUSTEP_BASE_SUBMINOR_VERSION);
printf ("Usage: HTMLLinker [options] input_files [--Destinations destination_files]\n"); printf ("Usage: HTMLLinker [options] input_files [-l relocation_file] [-d destination_file]\n");
printf ("Multiple input files, and multiple -l and -d options are allowed.\n");
printf (" `options' include:\n"); printf (" `options' include:\n");
printf (" --help: print this message;\n"); printf (" --help: print this message;\n");
printf (" --version: print version information;\n"); printf (" --version: print version information;\n");
printf (" -Verbose YES: print verbose messages;\n"); printf (" -Warn NO: do not print warnings about unresolved links;\n");
printf (" -CheckLinks NO: do not check links as they are fixed up;\n"); printf (" -LinksMarker xxx: only fixup links with attribute rel=xxx;\n");
printf (" -FixupAllLinks YES: attempt to fixup all links (not only dynamical ones);\n"); printf (" -FixupAllLinks YES: attempt to fixup all links (not only ones with the marker);\n");
printf (" -PathMappingsFile file: read path mappings from file (a dictionary);\n"); printf (" -PathMappingsFile file: read path mappings from file (a dictionary);\n");
printf (" -PathMappings '{\"/usr/doc\"=\"/Doc\";}': use the supplied path mappings;\n"); printf (" -PathMappings '{\"/usr/doc\"=\"/Doc\";}': use the supplied path mappings;\n");
printf (" -BuildRelocationFileForDir yyy: build a relocation file for the dir yyy\n");
printf (" and save it into yyy/table.htmlink. This option is special\n");
printf (" and prevents any other processing by the linker.\n");
exit (0); exit (0);
} }
@ -1030,9 +1111,9 @@ int main (int argc, char** argv, char** env)
NSArray *args; NSArray *args;
NSMutableArray *inputFiles; NSMutableArray *inputFiles;
unsigned i, count; unsigned i, count;
BOOL verbose, checkLinks, fixupAllLinks; BOOL warn, fixupAllLinks;
NSString *linksMarker;
HTMLLinker *linker; HTMLLinker *linker;
BOOL destinations;
#ifdef GS_PASS_ARGUMENTS #ifdef GS_PASS_ARGUMENTS
[NSProcessInfo initializeWithArguments:argv count:argc environment:env]; [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
@ -1046,21 +1127,47 @@ int main (int argc, char** argv, char** env)
userDefs = [NSUserDefaults standardUserDefaults]; userDefs = [NSUserDefaults standardUserDefaults];
/* defaults are - /* defaults are -
-Verbose NO -Warn YES
-CheckLinks YES -LinksMarker dynamic
-FixupAllLinks NO -FixupAllLinks NO
*/ */
[userDefs registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys: [userDefs registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys:
@"YES", @"CheckLinks", nil]]; @"dynamic", @"LinksMarker",
@"YES", @"Warn",
nil]];
verbose = [userDefs boolForKey: @"Verbose"]; warn = [userDefs boolForKey: @"Warn"];
checkLinks = [userDefs boolForKey: @"CheckLinks"];
fixupAllLinks = [userDefs boolForKey: @"FixupAllLinks"]; fixupAllLinks = [userDefs boolForKey: @"FixupAllLinks"];
linksMarker = [userDefs stringForKey: @"LinksMarker"];
/* If -BuildRelocationFileForDir xxx is passed on the command line,
build a relocation file for the directory xxx and save it in
xxx/table.htmlink. */
{
NSString *relFile;
relFile = [userDefs stringForKey: @"BuildRelocationFileForDir"];
if (relFile != nil)
{
NSString *table;
NSString *outputFile;
outputFile = [relFile stringByAppendingPathComponent:
@"table.htmlink"];
table = build_relocation_table_for_directory (relFile);
[table writeToFile: outputFile atomically: YES];
exit (0);
}
}
/* Create the linker object. */ /* Create the linker object. */
linker = [[HTMLLinker alloc] initWithVerboseFlag: verbose linker = [[HTMLLinker alloc] initWithWarnFlag: warn];
checkLinksFlag: checkLinks];
/* First, read all path mappings (before reading any destination
file / relocation file, so we can relocate properly. */
/* Read path mappings from PathMappingsFile if specified. */ /* Read path mappings from PathMappingsFile if specified. */
{ {
NSString *pathMapFile = [userDefs stringForKey: @"PathMappingsFile"]; NSString *pathMapFile = [userDefs stringForKey: @"PathMappingsFile"];
@ -1095,9 +1202,11 @@ int main (int argc, char** argv, char** env)
/* All non-options on the command line are: /* All non-options on the command line are:
input files if they come before --Destinations input files
destination files if they come after --Destinations destination files if they come after a -d
relocation files if they come after a -l
Directories as input files or destination files means 'all .html, .htm, Directories as input files or destination files means 'all .html, .htm,
.HTML, .HTM files in the directory and subdirectories'. .HTML, .HTM files in the directory and subdirectories'.
@ -1107,7 +1216,6 @@ int main (int argc, char** argv, char** env)
count = [args count]; count = [args count];
destinations = NO;
inputFiles = AUTORELEASE ([NSMutableArray new]); inputFiles = AUTORELEASE ([NSMutableArray new]);
for (i = 1; i < count; i++) for (i = 1; i < count; i++)
@ -1124,13 +1232,6 @@ int main (int argc, char** argv, char** env)
{ {
print_version_and_exit (); print_version_and_exit ();
} }
else if ([arg isEqualToString: @"--Destinations"])
{
/* Next file names to be interpreted as destination
files. */
destinations = YES;
}
else else
{ {
/* Ignore it for future expansions. */ /* Ignore it for future expansions. */
@ -1138,49 +1239,73 @@ int main (int argc, char** argv, char** env)
} }
else if ([arg hasPrefix: @"-"]) else if ([arg hasPrefix: @"-"])
{ {
/* A GNUstep default - skip it and the next argument. */ if ([arg isEqualToString: @"-d"])
if ((i + 1) < count)
{ {
i++; if ((i + 1) < count)
continue;
}
}
else
{
if (destinations)
{
[linker registerFile: arg];
}
else
{
BOOL isDir;
if (![fileManager fileExistsAtPath: arg
isDirectory: &isDir])
{ {
NSLog (@"Warning - input file '%@' not found - ignored", i++;
arg); /* Register a destination file. */
[linker registerDestinationFile: [args objectAtIndex: i]];
} }
else else
{ {
if (isDir) NSLog (@"Missing argument to -d");
}
}
else if ([arg isEqualToString: @"-l"])
{
if ((i + 1) < count)
{
i++;
/* Register a destination file. */
[linker registerRelocationFile: [args objectAtIndex: i]];
}
else
{
NSLog (@"Missing argument to -l");
}
}
else
{
/* A GNUstep default - skip it and the next argument. */
if ((i + 1) < count)
{
i++;
continue;
}
}
}
else
{
BOOL isDir;
if (![fileManager fileExistsAtPath: arg
isDirectory: &isDir])
{
NSLog (@"Warning - input file '%@' not found - ignored",
arg);
}
else
{
if (isDir)
{
HTMLDirectoryEnumerator *e;
NSString *filename;
e = [HTMLDirectoryEnumerator alloc];
e = [e initWithBasePath: arg];
[e setReturnsAbsolutePaths: YES];
while ((filename = [e nextObject]) != nil)
{ {
HTMLDirectoryEnumerator *e; [inputFiles addObject: filename];
NSString *filename;
e = [HTMLDirectoryEnumerator alloc];
e = [e initWithBasePath: arg];
while ((filename = [e nextObject]) != nil)
{
[inputFiles addObject: filename];
}
}
else
{
[inputFiles addObject: arg];
} }
} }
else
{
[inputFiles addObject: arg];
}
} }
} }
} }
@ -1205,7 +1330,7 @@ int main (int argc, char** argv, char** env)
parser = [[HTMLParser alloc] initWithCode: inputFileContents]; parser = [[HTMLParser alloc] initWithCode: inputFileContents];
inputFileContents = [parser resolveLinksUsingHTMLLinker: linker inputFileContents = [parser resolveLinksUsingHTMLLinker: linker
logFile: inputFile logFile: inputFile
fixupAllLinks: fixupAllLinks]; linksMarker: linksMarker];
[inputFileContents writeToFile: inputFile [inputFileContents writeToFile: inputFile
atomically: YES]; atomically: YES];
RELEASE (parser); RELEASE (parser);