Integrated documentation improvement patch by Adrian Robert

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@18943 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2004-03-29 03:37:46 +00:00
parent e845237c55
commit 196d805a28
26 changed files with 1628 additions and 811 deletions

View file

@ -1,3 +1,40 @@
2004-03-29 Richard Frith-Macdonald <rfm@gnu.org>
* Documentation/Base.gsdoc:
* Documentation/BaseAdditions.gsdoc:
* Documentation/Functions.gsdoc:
* Documentation/TypesAndConstants.gsdoc:
Update to latest gsdoc document version.
* Documentation/Makefile.postamble:
Build Tools documentation.
2004-03-29 Adrian Robert <arobert@cogsci.ucsd.edu>
* Tools/AGSHtml.h:
* Tools/AGSHtml.m:
* Tools/AGSIndex.m:
* Tools/AGSOutput.m:
* Tools/AGSParser.h:
* Tools/AGSParser.m:
* Tools/gsdoc.gsdoc:
* Tools/autogsdoc.m:
* Tools/GNUmakefile:
Added support for building frames structured project documentation
along with various other tidyups.
* Tools/cvtenc.m:
* Tools/defaults.m:
* Tools/gdnc.1:
* Tools/gdnc.m:
* Tools/gdomap.h:
* Tools/pldes.m:
* Tools/plmerge.m:
* Tools/plparse.m:
* Tools/plser.m:
* Tools/sfparse.m:
* Tools/xmlparse.m:
Added/improved documentaition.
2004-03-27 Richard Frith-Macdonald <rfm@gnu.org> 2004-03-27 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSMessagePort.m: * Source/NSMessagePort.m:

View file

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.0//EN" "http://www.gnustep.org/gsdoc-1_0_0.xml"> <!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.1//EN" "http://www.gnustep.org/gsdoc-1_0_..xml">
<gsdoc base="Base"> <gsdoc base="Base">
<head> <head>
<title>GNUstep Base</title> <title>GNUstep Base</title>

View file

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.0//EN" "http://www.gnustep.org/gsdoc-1_0_0.xml"> <!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.1//EN" "http://www.gnustep.org/gsdoc-1_0_1.xml">
<gsdoc base="BaseAdditions"> <gsdoc base="BaseAdditions">
<head> <head>
<title>GNUstep Base Additions</title> <title>GNUstep Base Additions</title>

View file

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.0//EN" "http://www.gnustep.org/gsdoc-1_0_0.xml"> <!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.1//EN" "http://www.gnustep.org/gsdoc-1_0_1.xml">
<gsdoc base="Functions" up="Base"> <gsdoc base="Functions" up="Base">
<head> <head>
<title>Functions</title> <title>Functions</title>

View file

@ -44,6 +44,7 @@
after-all:: after-all::
ifeq ($(HAVE_LIBXML),1) ifeq ($(HAVE_LIBXML),1)
$(MAKE) -C ../Source -f DocMakefile $(MAKE) -C ../Source -f DocMakefile
$(MAKE) -C ../Tools -f DocMakefile
endif endif
# Things to do before installing # Things to do before installing

View file

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.0//EN" "http://www.gnustep.org/gsdoc-1_0_0.xml"> <!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.1//EN" "http://www.gnustep.org/gsdoc-1_0_1.xml">
<gsdoc base="TypesAndConstants" up="Base"> <gsdoc base="TypesAndConstants" up="Base">
<head> <head>
<title>Types and Constants</title> <title>Types and Constants</title>

View file

@ -42,6 +42,7 @@
unsigned sect; unsigned sect;
unsigned ssect; unsigned ssect;
unsigned sssect; unsigned sssect;
BOOL isContentsDoc;
} }
- (void) decIndent; - (void) decIndent;
- (void) incIndent; - (void) incIndent;

View file

@ -278,6 +278,8 @@ static NSMutableSet *textNodes = nil;
- (void) outputIndex: (NSString*)type - (void) outputIndex: (NSString*)type
scope: (NSString*)scope scope: (NSString*)scope
title: (NSString*)title title: (NSString*)title
style: (NSString*)style
target: (NSString*)target
to: (NSMutableString*)buf to: (NSMutableString*)buf
{ {
NSDictionary *refs = [localRefs refs]; NSDictionary *refs = [localRefs refs];
@ -285,6 +287,7 @@ static NSMutableSet *textNodes = nil;
NSArray *a; NSArray *a;
unsigned c; unsigned c;
unsigned i; unsigned i;
BOOL isBareStyle = [@"bare" isEqualToString: style];
if (globalRefs != nil && [scope isEqual: @"global"] == YES) if (globalRefs != nil && [scope isEqual: @"global"] == YES)
{ {
@ -320,11 +323,14 @@ static NSMutableSet *textNodes = nil;
if ([dict count] > 1 && [type isEqual: @"title"] == YES) if ([dict count] > 1 && [type isEqual: @"title"] == YES)
{ {
[buf appendString: indent]; if (!isBareStyle)
[buf appendFormat: @"<b>%@</b>\n", title]; {
[buf appendString: indent]; [buf appendString: indent];
[buf appendString: @"<ul>\n"]; [buf appendFormat: @"<b>%@ Index</b>\n", title];
[self incIndent]; [buf appendString: indent];
[buf appendString: @"<ul>\n"];
[self incIndent];
}
a = [dict allKeys]; a = [dict allKeys];
a = [a sortedArrayUsingSelector: @selector(compare:)]; a = [a sortedArrayUsingSelector: @selector(compare:)];
@ -342,14 +348,34 @@ static NSMutableSet *textNodes = nil;
} }
[buf appendString: indent]; [buf appendString: indent];
[buf appendString: @"<li><a rel=\"gsdoc\" href="]; if (!isBareStyle)
[buf appendFormat: @"\"%@.html#%@$%@\">%@</a></li>\n", {
[buf appendString: @"<li>"];
}
[buf appendString: @"<a rel=\"gsdoc\" "];
if (target != nil)
{
[buf appendFormat: @"target=\"%@\" ", target];
}
[buf appendFormat: @"href=\"%@.html#%@$%@\">%@</a>",
file, type, ref, text]; file, type, ref, text];
if (!isBareStyle)
{
[buf appendString: @"</li>"];
}
else
{
[buf appendString: @"<br/>"];
}
[buf appendString: @"\n"];
} }
[self decIndent]; if (!isBareStyle)
[buf appendString: indent]; {
[buf appendString: @"</ul>\n"]; [self decIndent];
[buf appendString: indent];
[buf appendString: @"</ul>\n"];
}
} }
else if ([dict count] > 0) else if ([dict count] > 0)
{ {
@ -418,10 +444,16 @@ static NSMutableSet *textNodes = nil;
} }
[buf appendString: indent]; [buf appendString: indent];
[buf appendFormat: @"<b>%@</b>\n", title]; if (!isBareStyle)
{
[buf appendFormat: @"<b>%@</b>\n", title];
}
[buf appendString: indent]; [buf appendString: indent];
[buf appendString: @"<ul>\n"]; if (!isBareStyle) {
[self incIndent]; [buf appendString: @"<ul>"];
[self incIndent];
}
[buf appendString: @"\n"];
a = [dict allKeys]; a = [dict allKeys];
a = [a sortedArrayUsingSelector: @selector(compare:)]; a = [a sortedArrayUsingSelector: @selector(compare:)];
@ -457,22 +489,43 @@ static NSMutableSet *textNodes = nil;
} }
[buf appendString: indent]; [buf appendString: indent];
[buf appendString: @"<li><a rel=\"gsdoc\" href="]; if (!isBareStyle)
{
[buf appendString: @"<li>"];
}
[buf appendString: @"<a rel=\"gsdoc\" "];
if (target != nil)
{
[buf appendFormat: @"target=\"%@\" ", target];
}
if (isInUnit == YES) if (isInUnit == YES)
{ {
[buf appendFormat: @"\"%@.html#%@$%@%@%@\">%@</a></li>\n", [buf appendFormat: @"href=\"%@.html#%@$%@%@%@\">%@</a>",
file, type, u, sep, ref, text]; file, type, u, sep, ref, text];
} }
else else
{ {
[buf appendFormat: @"\"%@.html#%@$%@\">%@</a></li>\n", [buf appendFormat: @"href=\"%@.html#%@$%@\">%@</a>",
file, type, ref, text]; file, type, ref, text];
} }
if (!isBareStyle)
{
[buf appendString: @"</li>"];
}
else
{
[buf appendString: @"<br/>"];
}
[buf appendString: @"\n"];
} }
[self decIndent]; if (!isBareStyle) {
[buf appendString: indent]; [self decIndent];
[buf appendString: @"</ul>\n"]; [buf appendString: indent];
[buf appendString: @"</ul>"];
}
[buf appendString: @"\n"];
} }
} }
@ -526,6 +579,15 @@ static NSMutableSet *textNodes = nil;
[self decIndent]; [self decIndent];
[buf appendString: indent]; [buf appendString: indent];
// special formatting for table-of-contents frames; ultimately
// this should be moved to stylesheet
if (isContentsDoc)
{
[buf appendString: indent];
[buf appendString: @"</font>\n"];
}
[buf appendString: @"</body>\n"]; [buf appendString: @"</body>\n"];
} }
else if ([name isEqual: @"br"] == YES) else if ([name isEqual: @"br"] == YES)
@ -966,6 +1028,8 @@ static NSMutableSet *textNodes = nil;
} }
else if ([name isEqual: @"gsdoc"] == YES) else if ([name isEqual: @"gsdoc"] == YES)
{ {
NSString *stylesheetURL = [prop objectForKey: @"stylesheeturl"];
base = [prop objectForKey: @"base"]; base = [prop objectForKey: @"base"];
if (base == nil) if (base == nil)
{ {
@ -978,10 +1042,19 @@ static NSMutableSet *textNodes = nil;
prevFile = [prevFile stringByAppendingPathExtension: @"html"]; prevFile = [prevFile stringByAppendingPathExtension: @"html"];
upFile = [prop objectForKey: @"up"]; upFile = [prop objectForKey: @"up"];
upFile = [upFile stringByAppendingPathExtension: @"html"]; upFile = [upFile stringByAppendingPathExtension: @"html"];
// special formatting for table-of-contents frames; ultimately
// this should be moved to stylesheet
isContentsDoc = ((stylesheetURL != nil) &&
([stylesheetURL rangeOfString: @"gsdoc_contents"].length > 0)) ?
YES : NO;
[self outputNodeList: children to: buf]; [self outputNodeList: children to: buf];
} }
else if ([name isEqual: @"head"] == YES) else if ([name isEqual: @"head"] == YES)
{ {
NSString *headerTag;
[buf appendString: indent]; [buf appendString: indent];
[buf appendString: @"<head>\n"]; [buf appendString: @"<head>\n"];
[self incIndent]; [self incIndent];
@ -999,6 +1072,14 @@ static NSMutableSet *textNodes = nil;
[buf appendString: @"<body>\n"]; [buf appendString: @"<body>\n"];
[self incIndent]; [self incIndent];
// special formatting for table-of-contents frames; ultimately
// this should be moved to stylesheet
if (isContentsDoc)
{
[buf appendString: indent];
[buf appendString: @"<font face=\"sans\" size=\"-1\">\n"];
}
if (prevFile != nil) if (prevFile != nil)
{ {
[buf appendString: indent]; [buf appendString: indent];
@ -1014,13 +1095,24 @@ static NSMutableSet *textNodes = nil;
[buf appendString: indent]; [buf appendString: indent];
[buf appendFormat: @"<a href=\"%@\">Next</a>\n", nextFile]; [buf appendFormat: @"<a href=\"%@\">Next</a>\n", nextFile];
} }
[buf appendString: indent]; if (prevFile != nil || upFile != nil || nextFile != nil)
[buf appendString: @"<br />\n"]; {
[buf appendString: indent];
[buf appendString: @"<br />\n"];
}
[buf appendString: indent]; [buf appendString: indent];
[buf appendFormat: @"<h1><a name=\"title$%@\">", base]; if (isContentsDoc)
{
headerTag = @"h2";
}
else
{
headerTag = @"h1";
}
[buf appendFormat: @"<%@><a name=\"title$%@\">", headerTag, base];
[self outputText: [children firstChild] to: buf]; [self outputText: [children firstChild] to: buf];
[buf appendString: @"</a></h1>\n"]; [buf appendFormat: @"</a></%@>\n", headerTag];
children = [children nextElement]; children = [children nextElement];
if ([[children name] isEqual: @"author"] == YES) if ([[children name] isEqual: @"author"] == YES)
@ -1092,10 +1184,8 @@ static NSMutableSet *textNodes = nil;
if (desc != nil) if (desc != nil)
{ {
[self incIndent]; [self incIndent];
while (desc != nil) [self outputNode: desc to: buf];
{ desc = nil;
desc = [self outputBlock: desc to: buf inPara: NO];
}
[self decIndent]; [self decIndent];
} }
[buf appendString: indent]; [buf appendString: indent];
@ -1170,9 +1260,12 @@ static NSMutableSet *textNodes = nil;
{ {
NSString *scope = [prop objectForKey: @"scope"]; NSString *scope = [prop objectForKey: @"scope"];
NSString *type = [prop objectForKey: @"type"]; NSString *type = [prop objectForKey: @"type"];
NSString *target = [prop objectForKey: @"target"];
NSString *title = [type capitalizedString]; NSString *title = [type capitalizedString];
NSString *style = [prop objectForKey: @"style"];
[self outputIndex: type scope: scope title: title to: buf]; [self outputIndex: type scope: scope title: title style: style
target: target to: buf ];
} }
else if ([name isEqual: @"ivar"] == YES) // %phrase else if ([name isEqual: @"ivar"] == YES) // %phrase
{ {
@ -1519,6 +1612,10 @@ static NSMutableSet *textNodes = nil;
NSString *c = [prop objectForKey: @"class"]; NSString *c = [prop objectForKey: @"class"];
NSString *s; NSString *s;
// fill in default value
if ((type == nil) || [type isEqual: @""])
type = @"label";
if ([type isEqual: @"method"] || [type isEqual: @"ivariable"]) if ([type isEqual: @"method"] || [type isEqual: @"ivariable"])
{ {
s = [self makeLink: r ofType: type inUnit: c isRef: YES]; s = [self makeLink: r ofType: type inUnit: c isRef: YES];
@ -1588,8 +1685,6 @@ static NSMutableSet *textNodes = nil;
else if ([name isEqual: @"EOEntity"] == YES else if ([name isEqual: @"EOEntity"] == YES
|| [name isEqual: @"EOModel"] == YES) || [name isEqual: @"EOModel"] == YES)
{ {
NSString *tmp = [prop objectForKey: @"name"];
NSLog(@"Element '%@' not implemented", name); // FIXME NSLog(@"Element '%@' not implemented", name); // FIXME
} }
else if ([name isEqual: @"section"] == YES) else if ([name isEqual: @"section"] == YES)
@ -1722,7 +1817,12 @@ static NSMutableSet *textNodes = nil;
} }
else if ([name isEqual: @"url"] == YES) else if ([name isEqual: @"url"] == YES)
{ {
NSLog(@"Element '%@' not implemented", name); // FIXME // create an HREF as before but use the URL itself as marker text
[buf appendString: @"<a href=\""];
[buf appendString: [prop objectForKey: @"url"]];
[buf appendString: @"\">"];
[buf appendString: [prop objectForKey: @"url"]];
[buf appendString: @"</a>"];
} }
else if ([name isEqual: @"var"] == YES) // %phrase else if ([name isEqual: @"var"] == YES) // %phrase
{ {
@ -1788,7 +1888,7 @@ NSLog(@"Element '%@' not implemented", name); // FIXME
{ {
GSXMLNode *tmp; GSXMLNode *tmp;
/* /*
* Try outputing as any of the list elements. * Try outputting as any of the list elements.
*/ */
tmp = [self outputList: node to: buf]; tmp = [self outputList: node to: buf];
if (tmp == node) if (tmp == node)
@ -1900,6 +2000,7 @@ NSLog(@"Element '%@' not implemented", name); // FIXME
else else
{ {
NSLog(@"Non-block element '%@' in block ...", n); NSLog(@"Non-block element '%@' in block ...", n);
NSLog(@"%@",node);
return nil; return nil;
} }
} }
@ -2033,7 +2134,52 @@ NSLog(@"Element '%@' not implemented", name); // FIXME
} }
else if ([name isEqual: @"dictionary"] == YES) else if ([name isEqual: @"dictionary"] == YES)
{ {
NSLog(@"Element '%@' not implemented", name); // FIXME [buf appendString: indent];
[buf appendString: @"<dl>{\n"];
[self incIndent];
// all children should be dictionaryItems w/key and value attributes;
// if the value attribute is absent, the content is the value
for (; children != nil; children = [children nextElement])
{
GSXMLNode *dItem = children;
NSDictionary *dProp = [dItem attributes];
NSString *value = [dProp objectForKey: @"value"];
GSXMLNode *dChild;
if (![@"dictionaryItem" isEqualToString: [dItem name]])
{
continue;
}
[buf appendString: indent];
[buf appendString: @"<dt>"];
[buf appendString: [dProp objectForKey: @"key"]];
[buf appendString: @" = </dt>\n"];
[buf appendString: indent];
[buf appendString: @"<dd>\n"];
[self incIndent];
if (value != nil)
{
[buf appendString: value];
}
else
{
dChild = [dItem firstChildElement];
if ( dChild == nil )
{
// no elements, just text contents
dChild = [dItem firstChild];
[buf appendString: indent];
}
dItem = [self outputBlock: dChild to: buf inPara: NO];
//PENDING should check that dItem is what it should be...
}
[buf appendString: @"\n"];
[self decIndent];
[buf appendString: indent];
[buf appendString: @";</dd>\n"];
}
[self decIndent];
[buf appendString: indent];
[buf appendString: @"</dl>}\n"];
} }
else else
{ {
@ -2183,6 +2329,8 @@ NSLog(@"Element '%@' not implemented", name); // FIXME
[self outputIndex: @"method" [self outputIndex: @"method"
scope: @"global" scope: @"global"
title: @"Method summary" title: @"Method summary"
style: nil
target: nil
to: buf]; to: buf];
[buf appendString: indent]; [buf appendString: indent];
[buf appendString: @"<hr width=\"50%\" align=\"left\" />\n"]; [buf appendString: @"<hr width=\"50%\" align=\"left\" />\n"];

View file

@ -156,27 +156,27 @@ setDirectory(NSMutableDictionary *dict, NSString *path)
/** /**
* This class is used to build and manipulate a dictionary of * This class is used to build and manipulate a dictionary of
* cross-reference information.<br /> * cross-reference information.<br />
* The references are held in a tree consisting of dictionaries * The references are held in a nested dictionary
* with strings at the leaves -<br /> * with strings at the leaves (persisted to 'projectName'.igsdoc) -<br />
* method method-name class-name file-name<br /> * method : method-name - { class-name file-name }<br />
* method method-name protocol-name file-name<br /> * method : method-name - { protocol-name file-name }<br />
* ivariable variable-name class-name file-name<br /> * ivariable : variable-name - { class-name file-name }<br />
* class class-name file-name<br /> * class : class-name - file-name<br />
* category category-name file-name<br /> * category : category-name - file-name<br />
* protocol protocol-name file-name<br /> * protocol : protocol-name - file-name<br />
* function function-name file-name<br /> * function : function-name - file-name<br />
* type type-name file-name<br /> * type : type-name - file-name<br />
* constant constant-name file-name<br /> * constant : constant-name - file-name<br />
* variable variable-name file-name<br /> * variable : variable-name - file-name<br />
* entry entry-name file-name ref<br /> * entry : entry-name - { file-name ref }<br />
* label label-name file-name ref<br /> * label : label-name - { file-name ref }<br />
* contents ref text<br /> * contents : ref - text<br />
* super class-name superclass-name<br /> * super : class-name - superclass-name<br />
* categories class-name category-name file-name<br /> * categories : class-name - { category-name file-name }<br />
* unitmethods unit-name method-name<br /> * unitmethods : unit-name - method-name<br />
* classvars class-name variables-name<br /> * classvars : class-name - variables-name<br />
* title file-name text<br /> * title : file-name - text<br />
* source file-name array-of-source-files<br /> * source : file-name - array-of-source-files<br />
*/ */
@implementation AGSIndex @implementation AGSIndex
@ -228,6 +228,14 @@ setDirectory(NSMutableDictionary *dict, NSString *path)
NSString *name = [node name]; NSString *name = [node name];
NSDictionary *prop = [node attributes]; NSDictionary *prop = [node attributes];
// special case- if has an id of "_main" this gsdoc is from a tool
// file; add an entry to the index to indicate so
if (([name isEqual: @"chapter"] || [name isEqual: @"section"])
&& [@"_main" isEqual: [prop objectForKey: @"id"]] == YES)
{
[self setGlobalRef: base type: @"tool"];
}
if ([name isEqual: @"category"] == YES) if ([name isEqual: @"category"] == YES)
{ {
newUnit = YES; newUnit = YES;
@ -302,7 +310,6 @@ setDirectory(NSMutableDictionary *dict, NSString *path)
else if ([name isEqual: @"entry"] || [name isEqual: @"label"]) else if ([name isEqual: @"entry"] || [name isEqual: @"label"])
{ {
NSMutableDictionary *all; NSMutableDictionary *all;
NSMutableDictionary *byFile;
NSString *text; NSString *text;
NSString *val; NSString *val;
@ -316,19 +323,12 @@ setDirectory(NSMutableDictionary *dict, NSString *path)
[refs setObject: all forKey: name]; [refs setObject: all forKey: name];
RELEASE(all); 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"]; val = [prop objectForKey: @"id"];
if (val == nil) if (val == nil)
{ {
val = text; val = text;
} }
[byFile setObject: val forKey: @"text"]; [all setObject: base forKey: val];
} }
else if ([name isEqual: @"method"] == YES) else if ([name isEqual: @"method"] == YES)
{ {
@ -408,6 +408,7 @@ setDirectory(NSMutableDictionary *dict, NSString *path)
} }
else if ([name isEqual: @"section"] == YES) else if ([name isEqual: @"section"] == YES)
{ {
//FIXME- this info needs to be placed into the "label" refs somehow
sect++; sect++;
ssect = 0; ssect = 0;
sssect = 0; sssect = 0;

View file

@ -71,14 +71,14 @@ static BOOL snuggleStart(NSString *t)
* far too special purpose.</p> * far too special purpose.</p>
* <unit /> * <unit />
* <p>Here is the afterword for the class.</p> * <p>Here is the afterword for the class.</p>
* <p> Ad here is some automated cross referencing ... * <p> And here is some automated cross referencing ...
* A method in a protocol: [(NSCopying)-copyWithZone:], a class: * A method in a protocol: [(NSCopying)-copyWithZone:], a class:
* [NSString], a protocol: [(NSCopying)], and a * [NSString], a protocol: [(NSCopying)], and a
* category: [NSRunLoop(GNUstepExtensions)]. * category: [NSRunLoop(GNUstepExtensions)].
* </p> * </p>
* </unit> * </unit>
* And finally, here is the actual class description ... outside the chapter. * And finally, here is the actual class description ... outside the chapter.
* With a reference to foo() in it. * With a reference to escapeType() in it.
*/ */
@implementation AGSOutput @implementation AGSOutput
@ -283,8 +283,8 @@ static BOOL snuggleStart(NSString *t)
[str appendString: @"<?xml version=\"1.0\"?>\n"]; [str appendString: @"<?xml version=\"1.0\"?>\n"];
[str appendString: @"<!DOCTYPE gsdoc PUBLIC "]; [str appendString: @"<!DOCTYPE gsdoc PUBLIC "];
[str appendString: @"\"-//GNUstep//DTD gsdoc 1.0.0//EN\" "]; [str appendString: @"\"-//GNUstep//DTD gsdoc 1.0.1//EN\" "];
[str appendString: @"\"http://www.gnustep.org/gsdoc-1_0_0.xml\">\n"]; [str appendString: @"\"http://www.gnustep.org/gsdoc-1_0_1.xml\">\n"];
[str appendFormat: @"<gsdoc"]; [str appendFormat: @"<gsdoc"];
if (base != nil) if (base != nil)
@ -324,7 +324,7 @@ static BOOL snuggleStart(NSString *t)
} }
else else
{ {
[str appendFormat: @"%@ autogsdoc generated documentation", [str appendFormat: @"%@ documentation",
[info objectForKey: @"base"]]; [info objectForKey: @"base"]];
} }
[str appendString: @"</title>\n"]; [str appendString: @"</title>\n"];
@ -2296,8 +2296,8 @@ static BOOL snuggleStart(NSString *t)
[str appendString: @"<?xml version=\"1.0\"?>\n"]; [str appendString: @"<?xml version=\"1.0\"?>\n"];
[str appendString: @"<!DOCTYPE gsdoc PUBLIC "]; [str appendString: @"<!DOCTYPE gsdoc PUBLIC "];
[str appendString: @"\"-//GNUstep//DTD gsdoc 1.0.0//EN\" "]; [str appendString: @"\"-//GNUstep//DTD gsdoc 1.0.1//EN\" "];
[str appendString: @"\"http://www.gnustep.org/gsdoc-1_0_0.xml\">\n"]; [str appendString: @"\"http://www.gnustep.org/gsdoc-1_0_1.xml\">\n"];
[str appendString: @"<gsdoc base=\""]; [str appendString: @"<gsdoc base=\""];
[str appendString: [name lastPathComponent]]; [str appendString: [name lastPathComponent]];
/* /*

View file

@ -2,7 +2,7 @@
#define _INCLUDED_AGSPARSER_H #define _INCLUDED_AGSPARSER_H
/** /**
<title>AGSParser ... a tool to get documention info from ObjC source</title> <title>AGSParser ...a class to get documention info from ObjC source</title>
Copyright (C) 2001 Free Software Foundation, Inc. Copyright (C) 2001 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk> Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
@ -22,17 +22,10 @@
<abstract> <abstract>
This is the AGSParser class ... and some autogsdoc examples. This is the AGSParser class ... and some autogsdoc examples.
The AGSParser class is designed to produce a property-list
which can be handled by AGSOutput ... one class is not much
use without the other.
</abstract> </abstract>
<front>
<chapter>
<heading>AGSParser front page</heading>
<p>
The AGSParser class is designed to produce a property-list
which can be handled by AGSOutput ... one class is not much
use without the other.
</p>
</chapter>
</front>
*/ */
@ -115,8 +108,4 @@
- (NSMutableArray*) sources; - (NSMutableArray*) sources;
@end @end
/** Let's document a macro
*/
#define fibble(a,b,c) feep /** with three arguments: a, b, c */
#endif #endif

View file

@ -1,6 +1,4 @@
/** /*
<title>AGSParser ... a tool to get documention info from ObjC source</title>
Copyright (C) 2001 Free Software Foundation, Inc. Copyright (C) 2001 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk> Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
@ -34,23 +32,38 @@
- (void) addMain: (NSString*)c - (void) addMain: (NSString*)c
{ {
NSString *chap; NSString *chap;
NSString *toolName;
NSString *secHeading;
BOOL createSec = NO;
NSMutableString *m; NSMutableString *m;
NSRange r; NSRange r;
chap = [info objectForKey: @"chapter"]; chap = [info objectForKey: @"chapter"];
toolName = [[fileName lastPathComponent] stringByDeletingPathExtension];
if (chap == nil) if (chap == nil)
{ {
chap = [NSString stringWithFormat: chap = [NSString stringWithFormat:
@"<chapter><heading>%@</heading></chapter>", @"<chapter id=\"_main\"><heading>%@</heading></chapter>", toolName];
[[fileName lastPathComponent] stringByDeletingPathExtension]]; }
else
{
createSec = YES;
} }
m = [chap mutableCopy]; m = [chap mutableCopy];
r = [m rangeOfString: @"</chapter>"]; r = [m rangeOfString: @"</chapter>"];
r.length = 0; r.length = 0;
[m replaceCharactersInRange: r withString: @"</section>\n"]; if (createSec)
{
[m replaceCharactersInRange: r withString: @"</section>\n"];
}
[m replaceCharactersInRange: r withString: c]; [m replaceCharactersInRange: r withString: c];
[m replaceCharactersInRange: r withString: if (createSec)
@"<section>\n<heading>The main() function</heading>\n"]; {
secHeading = [NSString stringWithFormat:
@"<section id=\"_main\">\n<heading></heading>\n", toolName];
//The %@ tool
[m replaceCharactersInRange: r withString: secHeading];
}
[info setObject: m forKey: @"chapter"]; [info setObject: m forKey: @"chapter"];
RELEASE(m); RELEASE(m);
} }
@ -488,6 +501,9 @@
[self appendComment: tmp to: nil]; [self appendComment: tmp to: nil];
} }
/*
* We're in the first comment of a file; perform special processing.
*/
if (commentsRead == NO && comment != nil) if (commentsRead == NO && comment != nil)
{ {
unsigned commentLength = [comment length]; unsigned commentLength = [comment length];

View file

@ -35,14 +35,16 @@ DTD_FILES = plist-0_9.dtd \
gsdoc-0_6_5.dtd \ gsdoc-0_6_5.dtd \
gsdoc-0_6_6.dtd \ gsdoc-0_6_6.dtd \
gsdoc-0_6_7.dtd \ gsdoc-0_6_7.dtd \
gsdoc-1_0_0.dtd gsdoc-1_0_0.dtd \
gsdoc-1_0_1.dtd
# DocTemplates to install # DocTemplates to install
doctemplatesdir = $(GNUSTEP_LIBRARY)/DocTemplates doctemplatesdir = $(GNUSTEP_LIBRARY)/DocTemplates
DOCTEMPLATES_FILES = indextemplate.gsdoc AutoDocTemplate.gsdoc DOCTEMPLATES_FILES = indextemplate.gsdoc AutoDocTemplate.gsdoc
# Manual pages to install # Manual pages to install
MAN1_PAGES = gdnc.1 MAN1_PAGES = gdnc.1 autogsdoc.1 cvtenc.1 defaults.1 pldes.1 sfparse.1 xmlparse.1
MAN7_PAGES = gsdoc.7
MAN8_PAGES = gdomap.8 MAN8_PAGES = gdomap.8
# The application to be compiled # The application to be compiled

View file

@ -1,4 +1,4 @@
/** This tool produces gsdoc files from source files. /** This tool produces GSDoc files from source files.
<title>Autogsdoc ... a tool to make documentation from source code</title> <title>Autogsdoc ... a tool to make documentation from source code</title>
Copyright (C) 2001 Free Software Foundation, Inc. Copyright (C) 2001 Free Software Foundation, Inc.
@ -21,33 +21,68 @@
<chapter> <chapter>
<heading>The autogsdoc tool</heading> <heading>The autogsdoc tool</heading>
<section> <section>
<heading>overview</heading> <heading>Overview</heading>
<p> <p>
The autogsdoc tool is a command-line utility for parsing ObjectiveC The autogsdoc tool is a command-line utility that helps developers
source code (header files and optionally source files) in order to produce reference documentation for GNUstep APIs. It also enables
generate documentation covering the public interface of the various developers to write and maintain other documentation in XML and have it
classes, categories, and protocols in the source. converted to HTML. In detail, autogsdoc will:
</p>
<list>
<item>
Extract special comments describing the public interfaces of classes,
categories, protocols, functions, and macros from Objective C source
code (header files and optionally source files) into GSDoc XML files.
</item>
<item>
Convert GSDoc XML files, whether generated from source code or written
manually by developers, into HTML.
</item>
<item>
Construct indices based on GSDoc XML file sets, and convert those
to HTML as well.
</item>
</list>
<p>
synopsis: <code>autogsdoc (options) (files)</code><br/>
&#160;&#160;&#160;&#160;(options) described below<br/>
&#160;&#160;&#160;&#160;(files) <code>.h</code>, <code>.m</code>, <code>.gsdoc</code>, and/or <code>.html</code> files, in any order.
</p> </p>
<p> <p>
The simple way to use this is to run the command with one or more The most common usage this is to run the command with one or more
header file names as arguments ... the tool will automatically header file names as arguments ... the tool will automatically
parse corresponding source files in the same directory as the parse corresponding source files in the same directory as the
headers (or the current directory, or the directory specified headers (or the current directory, or the directory specified
using the DocumentationDirectory default), and produce gsdoc using the DocumentationDirectory default), and produce GSDoc
and html files as output. and HTML files as output. For best results this mode should be
run from the directory containing the source files.
</p> </p>
<p> <p>
Even without any human assistance, this tool will produce skeleton GSDoc files may also be given directly in addition or by themselves, and
documents listing the methods in the classes found in the source will be converted to HTML. See the
files, but more importantly it can take specially formatted comments <uref url="gsdoc.html">GSDoc reference</uref> for information
from the source files and insert those comments into the gsdoc output. on the GSDoc format.
</p>
<p>
Finally, HTML files may be given on the command line. Cross-references
to other parts of code documentation found within them will be rewritten
based on what is found in the project currently.
</p>
</section>
<section>
<heading>Source Code Markup</heading>
<p>
The source code parser will automatically produce GSDoc documents
listing the methods in the classes found in the source files, and it
will include text from specially formatted comments from the source
files.
</p> </p>
<p> <p>
Any comment beginning with slash and <em>two</em> asterisks rather than Any comment beginning with slash and <em>two</em> asterisks rather than
the common slash and single asterisk, is taken to be gsdoc markup, to the common slash and single asterisk, is taken to be GSDoc markup, to
be use as the description of the class or method following it. This be use as the description of the class or method following it. This
comment text is reformatted and then inserted into the output.<br /> comment text is reformatted and then inserted into the output.<br />
Where multiple comments are associatd with the same item, they are Where multiple comments are associated with the same item, they are
joined together with a line break (&lt;br /&gt;) between each if joined together with a line break (&lt;br /&gt;) between each if
necessary. necessary.
</p> </p>
@ -59,38 +94,42 @@
the end of the first chapter of the document (it creates the first the end of the first chapter of the document (it creates the first
chapter if necessary). chapter if necessary).
</p> </p>
<p>
<strong>Options</strong> are described in the section
<em>Arguments and Defaults</em> below.
</p>
</section> </section>
<section> <section>
<heading>Extra markup</heading> <heading>Extra markup</heading>
<p> <p>
There are some cases where special extra processing is performed, There are some cases where special extra processing is performed,
predominantly in the first comment found in the source file, predominantly in the first comment found in the source file,
from which various chunks of gsdoc markup may be extracted and from which various chunks of GSDoc markup may be extracted and
placed into appropriate locations in the output document - placed into appropriate locations in the output document -
</p> </p>
<list> <list>
<item><strong>AutogsdocSource</strong> <item><strong>AutogsdocSource</strong>:&#160;
In any line where <code>AutogsdocSource</code>: is found, the remainder In any line where <code>AutogsdocSource</code>:&#160; is found, the
of the line is taken as a source file name to be used instead of remainder of the line is taken as a source file name to be used
making the assumption that each .h file processed uses a .m file instead of making the assumption that each&#160;.h file processed uses
of the same name. You may supply multiple <code>AutogsdocSource</code>: a &#160;.m file of the same name. You may supply multiple
lines where a header file declares items which are defined in <code>AutogsdocSource</code>:&#160; lines where a header file declares
multiple source files.<br /> items which are defined in multiple source files.<br /> If a file name
If a file name is absolute, it is used just as supplied.<br /> is absolute, it is used just as supplied.<br /> If on the other hand,
If on the other hand, it is a relative path, the software looks for it is a relative path, the software looks for the source file first
the source file first relative to the location of the header file, relative to the location of the header file, and if not found there,
and if not found there, relative to the current directory in which relative to the current directory in which autogsdoc is running, and
autogsdoc is running, and finally relative to the directory finally relative to the directory specified by the
specified by the DocumentationDirectory default. <code>DocumentationDirectory</code> default.
</item> </item>
<item><strong>&lt;abstract&gt;</strong> <item><strong>&lt;abstract&gt;</strong>
An abstract of the content of the document ... placed in the head An abstract of the content of the document ... placed in the head
of the gsdoc output. of the GSDoc output.
</item> </item>
<item><strong>&lt;author&gt;</strong> <item><strong>&lt;author&gt;</strong>
A description of the author of the code - may be repeated to handle A description of the author of the code - may be repeated to handle
the case where a document has multiple authors. Placed in the the case where a document has multiple authors. Placed in the
head of the gsdoc output.<br /> head of the GSDoc output.<br />
As an aid to readability of the source, some special additional As an aid to readability of the source, some special additional
processing is performed related to the document author -<br /> processing is performed related to the document author -<br />
Any line of the form '<code>Author</code>: name &lt;email-address&gt;', Any line of the form '<code>Author</code>: name &lt;email-address&gt;',
@ -100,8 +139,8 @@
possibly containing an <em>email</em> element. possibly containing an <em>email</em> element.
</item> </item>
<item><strong>&lt;back&gt;</strong> <item><strong>&lt;back&gt;</strong>
Placed in the gsdoc output just before the end of the body of the Placed in the GSDoc output just before the end of the body of the
document - intended to be used for appendices, index etc. document - intended to be used for appendices, index etc..
</item> </item>
<item><strong>&lt;chapter&gt;</strong> <item><strong>&lt;chapter&gt;</strong>
Placed immediately before any generated class documentation ... Placed immediately before any generated class documentation ...
@ -112,7 +151,7 @@
</item> </item>
<item><strong>&lt;copy&gt;</strong> <item><strong>&lt;copy&gt;</strong>
Copyright of the content of the document ... placed in the head Copyright of the content of the document ... placed in the head
of the gsdoc output.<br /> of the GSDoc output.<br />
As an aid to readability of the source, some special additional As an aid to readability of the source, some special additional
processing is performed -<br /> processing is performed -<br />
Any line of the form 'Copyright (C) text' will be recognised and Any line of the form 'Copyright (C) text' will be recognised and
@ -120,7 +159,7 @@
</item> </item>
<item><strong>&lt;date&gt;</strong> <item><strong>&lt;date&gt;</strong>
Date of the revision of the document ... placed in the head Date of the revision of the document ... placed in the head
of the gsdoc output. If this is omitted the tool will try to of the GSDoc output. If this is omitted the tool will try to
construct a value from the RCS Date tag (if available). construct a value from the RCS Date tag (if available).
</item> </item>
<item><strong>&lt;front&gt;</strong> <item><strong>&lt;front&gt;</strong>
@ -128,26 +167,25 @@
to provide for introduction or contents pages etc. to provide for introduction or contents pages etc.
</item> </item>
<item><strong>&lt;title&gt;</strong> <item><strong>&lt;title&gt;</strong>
Title of the document ... placed in the head of the gsdoc output. Title of the document ... placed in the head of the GSDoc output.
If this is omitted the tool will generate a (probably poor) If this is omitted the tool will generate a (probably poor)
title of its own - so you should include this markup manually. title of its own - so you should include this markup manually.
</item> </item>
<item>
<strong>NB</strong>This markup may be used within
class, category, or protocol documentation ... if so, it is
extracted and wrapped round the rest of the documentation for
the class as the classes chapter.
The rest of the class documentation is normally
inserted at the end of the chapter, but may instead be substituted
in in place of the &lt;unit /&gt; pseudo-element within the
&lt;chapter&gt; element.
</item>
<item><strong>&lt;version&gt;</strong> <item><strong>&lt;version&gt;</strong>
Version identifier of the document ... placed in the head Version identifier of the document ... placed in the head
of the gsdoc output. If this is omitted the tool will try to of the GSDoc output. If this is omitted the tool will try to
construct a value from the RCS Revision tag (if available). construct a value from the RCS Revision tag (if available).
</item> </item>
</list> </list>
<p>
<strong>NB</strong>The markup just described may be used within class,
category, or protocol documentation ... if so, it is extracted and
wrapped round the rest of the documentation for the class as the
class's chapter. The rest of the class documentation is normally
inserted at the end of the chapter, but may instead be substituted in
in place of the &lt;unit /&gt; pseudo-element within the
&lt;chapter&gt; element.
</p>
</section> </section>
<section> <section>
<heading>Method markup</heading> <heading>Method markup</heading>
@ -161,7 +199,7 @@
</item> </item>
<item><strong>&lt;override-subclass /&gt;</strong> <item><strong>&lt;override-subclass /&gt;</strong>
The method is marked as being one which subclasses must override The method is marked as being one which subclasses must override
(eg an abstract method). (e.g. an abstract method).
</item> </item>
<item><strong>&lt;override-never /&gt;</strong> <item><strong>&lt;override-never /&gt;</strong>
The method is marked as being one which subclasses should <em>NOT</em> The method is marked as being one which subclasses should <em>NOT</em>
@ -169,7 +207,7 @@
</item> </item>
<item><strong>&lt;standards&gt; ... &lt;/standards&gt;</strong> <item><strong>&lt;standards&gt; ... &lt;/standards&gt;</strong>
The markup is removed from the description and placed <em>after</em> The markup is removed from the description and placed <em>after</em>
it in the gsdoc output - so that the method is described as it in the GSDoc output - so that the method is described as
conforming (or not conforming) to the specified standards. conforming (or not conforming) to the specified standards.
</item> </item>
</list> </list>
@ -192,7 +230,7 @@
</item> </item>
<item>Method names (beginning with a plus or minus) are enclosed <item>Method names (beginning with a plus or minus) are enclosed
in &lt;ref...&gt; ... &lt;/ref&gt; markup.<br /> in &lt;ref...&gt; ... &lt;/ref&gt; markup.<br />
eg. "-init" (without the quotes) would be wrapped in a gsdoc e.g. "-init" (without the quotes) would be wrapped in a GSDoc
reference element to point to the init method of the current reference element to point to the init method of the current
class or, if only one known class had an init method, it class or, if only one known class had an init method, it
would refer to the method of that class. would refer to the method of that class.
@ -202,52 +240,54 @@
</item> </item>
<item>Method specifiers including class names (beginning and ending with <item>Method specifiers including class names (beginning and ending with
square brackets) are enclosed in &lt;ref...&gt; ... &lt;/ref&gt; markup. square brackets) are enclosed in &lt;ref...&gt; ... &lt;/ref&gt; markup.
<br />eg. <code>[</code>NSObject-init<code>]</code>, <br />e.g. <code>[</code>NSObject-init<code>]</code>,
will create a reference to the init method of NSObject (either the will create a reference to the init method of NSObject (either the
class proper, or any of its categories), while class proper, or any of its categories), while
<br /><code>[</code>(NSCopying)-copyWithZone:<code>]</code>, creates a <br /><code>[</code>(NSCopying)-copyWithZone:<code>]</code>, creates a
reference to a method in the NSCopyIng protocol. reference to a method in the NSCopying protocol.
<br />Note that no spaces must appear between the square brackets <br />Note that no spaces must appear between the square brackets
in these specifiers. in these specifiers.
<br />Protocol names are enclosed in round brackets rather than <br />Protocol names are enclosed in round brackets rather than
the customary angle brackets, because gsdoc is an XML language, and the customary angle brackets, because GSDoc is an XML language, and
XML treats angle brackets specially. XML treats angle brackets specially.
</item> </item>
<item>Class names (and also protocol and category names) enclosed <item>Class names (and also protocol and category names) enclosed
in square brackets are also cross referenced. in square brackets are also cross referenced.
<br />Protocol names are enclosed in round brackets rather than <br />Protocol names are enclosed in round brackets rather than
the customary angle brackets, because gsdoc is an XML language, and the customary angle brackets, because GSDoc is an XML language, and
XML treats angle brackets specially. XML treats angle brackets specially.
</item> </item>
<item>Function names (ending with '()') other than 'main()' are enclosed <item>Function names (ending with '()') other than 'main()' are enclosed
in &lt;ref...&gt; ... &lt;/ref&gt; markup.<br /> in &lt;ref...&gt; ... &lt;/ref&gt; markup.<br />
eg. "NSLogv()" (without the quotes) would be wrapped in a gsdoc e.g. "NSLogv()" (without the quotes) would be wrapped in a GSDoc
reference element to point to the documentation of the NSLog function. reference element to point to the documentation of the NSLog function.
<br />Note the fact that the function name must be surrounded by <br />Note the fact that the function name must be surrounded by
whitespace (though a comma, fullstop, or semicolon at the end whitespace (though a comma, fullstop, or semicolon at the end
of the specifier will also act as a whitespace terminator). of the specifier will also act as a whitespace terminator).
<br />
</item> </item>
</list> </list>
</section> </section>
<section> <section>
<heading>Arguments and Defaults</heading> <heading>Arguments and Defaults</heading>
<p> <p>
The tools accepts certain user defaults (which can of course be The tool accepts certain user defaults (which can of course be
supplied as command-line arguments as usual) - supplied as command-line arguments by prepending '-' before the default
name and giving the value afterwards, as in -<code>Clean YES</code>):
</p> </p>
<list> <list>
<item><strong>Clean</strong> <item><strong>Clean</strong>
If this boolean value is set to YES, then rather than generating If this boolean value is set to YES, then rather than generating
documentation, the tool removes all gsdoc files generated in the documentation, the tool removes all GSDoc files generated in the
project, and all html files generated from them (as well as any project, and all html files generated from them (as well as any
which would be generated from gsdoc files listed explicitly), which would be generated from GSDoc files listed explicitly),
and finally removes the project index file.<br /> and finally removes the project index file.<br />
The only exception to this is that template gsdoc files (ie those The only exception to this is that template GSDoc files (i.e. those
specifield using "-ConstantsTemplate ...", "-FunctionsTemplate ..." specified using "-ConstantsTemplate ...", "-FunctionsTemplate ..."
arguments etc) are not deleted unless the CleanTemplates flag is set. arguments etc) are not deleted unless the CleanTemplates flag is set.
</item> </item>
<item><strong>CleanTemplates</strong> <item><strong>CleanTemplates</strong>
This flag specifies whether template gsdoc files are to be removed This flag specifies whether template GSDoc files are to be removed
along with other files when the Clean option is specified. along with other files when the Clean option is specified.
The default is for them not to be removed ... since these templates The default is for them not to be removed ... since these templates
may have been produced manually and just had data inserted into them. may have been produced manually and just had data inserted into them.
@ -285,10 +325,15 @@
'protected' will be documented. 'protected' will be documented.
</item> </item>
<item><strong>DocumentationDirectory</strong> <item><strong>DocumentationDirectory</strong>
May be used to specify the directory in which generated May be used to specify the directory in which generated documentation
documentation is to be placed. If this is not set, output is to be placed. If this is not set, output is placed in the current
is placed in the current directory. This directory is also directory. This directory is also used as a last resort to locate
used as a last resort to locate source files (not headers). source files (not headers), and more importantly, it is used as the
<em>first and only</em> resort to locate any <code>.gsdoc</code> files
that are passed in on the command line. Any path information given
for these files is <em><strong>removed</strong></em> and they are
searched for in <code>DocumentationDirectory</code> (even though they
may not have been autogenerated).
</item> </item>
<item><strong>Files</strong> <item><strong>Files</strong>
Specifies the name of a file containing a list of file names as Specifies the name of a file containing a list of file names as
@ -361,13 +406,16 @@
of the <em>body</em> element) in the template. of the <em>body</em> element) in the template.
</item> </item>
<item><strong>MakeDependencies</strong> <item><strong>MakeDependencies</strong>
A filename to be used to output dependency information for make A filename to be used to output dependency information for make. This
will take the form of listing all header and source files known for
the project as dependencies of the project name (see
<code>Project</code>).
</item> </item>
<item><strong>Project</strong> <item><strong>Project</strong>
May be used to specify the name of this project ... determines the Specifies the name of this project ... determines the
name of the index reference file produced as part of the documentation name of the index reference file produced as part of the documentation
to provide information enabling other projects to cross-reference to to provide information enabling other projects to cross-reference to
items in this project. items in this project. If not set, 'Untitled' is used.
</item> </item>
<item><strong>Projects</strong> <item><strong>Projects</strong>
This value may be supplied as a dictionary containing the paths to This value may be supplied as a dictionary containing the paths to
@ -377,7 +425,10 @@
<code>Foo</code> is found in the file <code>Foo</code>, and the <code>Foo</code> is found in the file <code>Foo</code>, and the
path associated with that project index is <code>/usr/doc/proj</code>, path associated with that project index is <code>/usr/doc/proj</code>,
Then generated html output may reference the class as being in Then generated html output may reference the class as being in
<code>/usr/doc/prj/Foo.html</code> <code>/usr/doc/prj/Foo.html</code> . Note that a dictionary may be
given on the command line by using the standard PropertyList format
(not the XML format of OS X), using semicolons as line-separators, and
enclosing it in single quotes.
</item> </item>
<item><strong>ShowDependencies</strong> <item><strong>ShowDependencies</strong>
A boolean value which may be used to specify that the program should A boolean value which may be used to specify that the program should
@ -386,7 +437,7 @@
</item> </item>
<item><strong>Standards</strong> <item><strong>Standards</strong>
A boolean value used to specify whether the program should insert A boolean value used to specify whether the program should insert
information about standards complience into ythe documentation. information about standards complience into the documentation.
This should only be used when documenting the GNUstep libraries This should only be used when documenting the GNUstep libraries
and tools themselves as it assumes that the code being documented and tools themselves as it assumes that the code being documented
is part of GNUstep and possibly complies with the OpenStep standard is part of GNUstep and possibly complies with the OpenStep standard
@ -426,7 +477,7 @@
</item> </item>
<item><strong>Up</strong> <item><strong>Up</strong>
A string used to supply the name to be used in the 'up' link from A string used to supply the name to be used in the 'up' link from
generated gsdoc documents. This should normally be the name of a generated GSDoc documents. This should normally be the name of a
file which contains an index of the contents of a project.<br /> file which contains an index of the contents of a project.<br />
If this is missing or set to an empty string, then no 'up' link If this is missing or set to an empty string, then no 'up' link
will be provided in the documents. will be provided in the documents.
@ -451,7 +502,7 @@
</item> </item>
<item><strong>Warn</strong> <item><strong>Warn</strong>
A boolean used to specify whether you want standard warning A boolean used to specify whether you want standard warning
output (eg report of undocumented methods) produced. output (e.g. report of undocumented methods) produced.
</item> </item>
<item><strong>WordMap</strong> <item><strong>WordMap</strong>
This value is a dictionary used to map identifiers/keywords found This value is a dictionary used to map identifiers/keywords found
@ -463,6 +514,9 @@
Another identifier,<br /> Another identifier,<br />
An empty string - the value is ignored,<br /> An empty string - the value is ignored,<br />
Two slashes ('//') - the rest of the line is ignored.<br /> Two slashes ('//') - the rest of the line is ignored.<br />
Note that a dictionary may be given on the command line by using the
standard PropertyList format (not the XML format of OS X), using
semicolons as line-separators, and enclosing it in single quotes.
</item> </item>
</list> </list>
</section> </section>
@ -473,13 +527,13 @@
should be used as the 'up' link for any other documents used.<br /> should be used as the 'up' link for any other documents used.<br />
This name must not include a path or extension.<br /> This name must not include a path or extension.<br />
Generally, the document referred to by this default should be a Generally, the document referred to by this default should be a
hand-edited gsdoc document which should have a <em>back</em> hand-edited GSDoc document which should have a <em>back</em>
section containing a project index. eg. section containing a project index. e.g.
</p> </p>
<example> <example>
&lt;?xml version="1.0"?&gt; &lt;?xml version="1.0"?&gt;
&lt;!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.0//EN" &lt;!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.1//EN"
"http://www.gnustep.org/gsdoc-1_0_0.xml"&gt; "http://www.gnustep.org/gsdoc-1_0_1.xml"&gt;
&lt;gsdoc base="index"&gt; &lt;gsdoc base="index"&gt;
&lt;head&gt; &lt;head&gt;
&lt;title&gt;My project reference&lt;/title&gt; &lt;title&gt;My project reference&lt;/title&gt;
@ -496,11 +550,32 @@
&lt;/gsdoc&gt; &lt;/gsdoc&gt;
</example> </example>
</section> </section>
<section>
<heading>Implementation Notes</heading>
<p>
The autogsdoc tool internally makes use of the following four classes-
</p>
<deflist>
<term><ref type="class" id="AGSParser"/></term>
<desc>Parses source code comments to an internal representation.
</desc>
<term><ref type="class" id="AGSOutput"/></term>
<desc>Converts internal representation of source comments to a gsdoc
document.</desc>
<term><ref type="class" id="AGSIndex"/></term>
<desc>Internal representation of an igsdoc file, representing indices
of a project's files.</desc>
<term><ref type="class" id="AGSHtml"/></term>
<desc>Converts gsdoc XML to HTML, using AGSIndex instances.</desc>
</deflist>
</section>
</chapter> </chapter>
<back> <back>
<index type="title" scope="project" /> <index type="title" scope="project" />
<index type="class" scope="project" />
</back> </back>
*/ */
#include <config.h> #include <config.h>
@ -514,11 +589,13 @@
#include "GNUstepBase/GSCategories.h" #include "GNUstepBase/GSCategories.h"
#endif #endif
/** Invokes the autogsdoc tool. */
int int
main(int argc, char **argv, char **env) main(int argc, char **argv, char **env)
{ {
NSProcessInfo *proc; NSProcessInfo *proc;
unsigned i; unsigned i;
NSDictionary *argsRecognized;
NSUserDefaults *defs; NSUserDefaults *defs;
NSFileManager *mgr; NSFileManager *mgr;
NSString *documentationDirectory; NSString *documentationDirectory;
@ -548,6 +625,63 @@ main(int argc, char **argv, char **env)
NSAutoreleasePool *pool = nil; NSAutoreleasePool *pool = nil;
#endif #endif
/*
Overall process in this file is as follows:
1) Get/test defaults and arguments.
2) Init filename list, and move .h/.m into "source files", .gsdoc into
"gsdoc files", and .html into "html files".
3) Load existing .igsdoc file (PropertyList/Dictionary format) if found,
initializing an AGSIndex from it.
4) Clean if desired:
4a) Build list of all template files, and remove generated content
from them if not cleaning templates.
4b) Figure out generated files from index file (if none assumes none
generated) and remove them (but not template files unless
supposed to).
4c) Remove index file.
4d) Remove HTML files corresponding to .gsdoc files in current list.
5) Start with "source files".. for each one (hereafter called a "header
file"):
5a) Parse declarations (in .h or .m) using an AGSParser object.
5b) Determine (possibly multiple) dependent .m files corresponding to
a .h and parse them.
5c) Feed parser results to an AGSOutput instance.
6) Move to "gsdoc files" (including both command-line given ones and
just-generated ones).. and generate the index; for each one:
6a) Remove any path specification and search in
documentationDirectory then CWD for it.
6b) Parse the file, call [localRefs makeRefs: root],
[projectRefs mergeRefs: localRefs] to make indices.
7) Write the .igsdoc file.
8) Build index references to external projects.
8.5) Create HTML frames auxiliary files.
9) If needed, re-pass through the "gsdoc files" to generate HTML.
9a) Find files as before.
9b) Parse as before.
9c) Feed the DOM tree to an AGSHtml instance, and dump the result to
a file.
10) For HTML files that were given on the command line, adjust all cross
reference HREFs to paths given in arguments.
11) If MakeDependencies was requested, list all header and source files
as colon-dependencies of the project name.
*/
#ifdef GS_PASS_ARGUMENTS #ifdef GS_PASS_ARGUMENTS
[NSProcessInfo initializeWithArguments: argv count: argc environment: env]; [NSProcessInfo initializeWithArguments: argv count: argc environment: env];
#endif #endif
@ -563,11 +697,84 @@ main(int argc, char **argv, char **env)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
#endif #endif
/*
* 1) Get/test defaults and arguments.
*/
defs = [NSUserDefaults standardUserDefaults]; defs = [NSUserDefaults standardUserDefaults];
[defs registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys: [defs registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys:
@"Untitled", @"Project", @"Untitled", @"Project",
nil]]; nil]];
// BEGIN test for any unrecognized arguments, or "--help"
argsRecognized = [NSDictionary dictionaryWithObjectsAndKeys:
@"\t\t\tBOOL\t(NO)\n\tproduce verbose output", @"Verbose",
@"\t\t\tBOOL\t(NO)\n\tproduce warnings", @"Warn",
@"\tBOOL\t(NO)\n\tignore file mod times (always generate)", @"IgnoreDependencies",
@"\t\tBOOL\t(NO)\n\tlog files being regenerated due to dependencies", @"ShowDependencies",
@"\t\tBOOL\t(YES)\n\tgenerate HTML output (as opposed to just gsdoc from source)", @"GenerateHtml",
@"\t\t\tSTR\t(\"\")\n\tspecify where headers are to be documented as being found", @"Declared",
@"\t\t\tSTR\t(\"Untitled\")\n\thead title name of this documentation", @"Project",
@"\t\tSTR\t(.)\n\tdirectory to search for .h files", @"HeaderDirectory",
@"\tSTR\t(.)\n\tdirectory to place generated files and search for gsdoc files", @"DocumentationDirectory",
@"\t\t\tSTR\t(\"\")\n\tname of file containing filenames to document", @"Files",
@"\t\t\tBOOL\t(NO)\n\tremove all generated files", @"Clean",
@"\t\tBOOL\t(NO)\n\tremove template files when cleaning", @"CleanTemplates",
@"\t\t\tSTR\t(\"\")\n\tfilename to link to from generated HTML", @"Up",
@"\t\t\tspecial\t(nil)\n\tdictionary used to preprocess (see docs)", @"WordMap",
@"\t\t\tBOOL\t(NO)\n\twhether to insert information on standards compliance", @"Standards",
@"BOOL\t(NO)\n\tdocument private instance variables", @"DocumentAllInstanceVariables",
@"\t\tSTR\t(\"None\")\n\twhether to include other projects in index", @"LocalProjects",
@"\t\tSTR\t(\"None\")\n\twhether to include system projects in index", @"SystemProjects",
@"\t\t\tSTR\t(\"None\")\n\texplicit list of other projects to index", @"Projects",
@"\t\tSTR\t(\"\")\n\tfile to output dependency info for 'make' into", @"MakeDependencies",
@"\t\tSTR\t(\"\")\n\tfile into which docs for constants should be consolidated", @"ConstantsTemplate",
@"\t\tSTR\t(\"\")\n\tfile into which docs for functions should be consolidated", @"FunctionsTemplate",
@"\t\tSTR\t(\"\")\n\tfile into which docs for macros should be consolidated", @"MacrosTemplate",
@"\t\tSTR\t(\"\")\n\tfile into which docs for typedefs should be consolidated", @"TypedefsTemplate",
@"\t\tSTR\t(\"\")\n\tfile into which docs for variables should be consolidated", @"VariablesTemplate",
@"\t\tBOOL\t(NO)\n\tif YES, create documentation pages for display in HTML frames", @"MakeFrames",
nil];
NSString *arg;
NSString *opt;
NSSet *argSet = [NSSet setWithArray: [argsRecognized allKeys]];
NSArray *argsGiven = [[NSProcessInfo processInfo] arguments];
for (i=0; i<[argsGiven count]; i++) {
arg = [argsGiven objectAtIndex: i];
if ([arg characterAtIndex: 0] == '-')
{
opt = ([arg characterAtIndex: 1] == '-') ?
[arg substringFromIndex: 2] : [arg substringFromIndex: 1];
}
else
{
continue;
}
if (![argSet containsObject: opt] || [@"help" isEqual: opt])
{
NSArray *args = [argsRecognized allKeys];
GSPrintf(stderr, @"Usage:\n");
GSPrintf(stderr, [NSString stringWithFormat:
@" %@ [options] [files]\n",
[argsGiven objectAtIndex :0]]);
GSPrintf(stderr, @"\n Options:\n");
for (i=0; i<[args count]; i++) {
arg = [args objectAtIndex: i];
GSPrintf(stderr, [NSString stringWithFormat:
@" -%@\t%@\n\n",
arg, [argsRecognized objectForKey:
arg]]);
}
GSPrintf(stderr, @"\n Files:\n");
GSPrintf(stderr, @" [.h files]\t\tMust be in 'HeaderDirectory'\n");
GSPrintf(stderr, @" [.m files]\t\tAbsolute or relative path (from here)\n");
GSPrintf(stderr, @" [.gsdoc files]\tMust be in 'DocumentationDirectory'\n\n");
exit(1);
}
}
verbose = [defs boolForKey: @"Verbose"]; verbose = [defs boolForKey: @"Verbose"];
warn = [defs boolForKey: @"Warn"]; warn = [defs boolForKey: @"Warn"];
ignoreDependencies = [defs boolForKey: @"IgnoreDependencies"]; ignoreDependencies = [defs boolForKey: @"IgnoreDependencies"];
@ -611,7 +818,7 @@ main(int argc, char **argv, char **env)
} }
/* /*
* Build an array of files to be processed. * 2) Build an array of files to be processed.
*/ */
obj = [defs stringForKey: @"Files"]; obj = [defs stringForKey: @"Files"];
if (obj != nil) if (obj != nil)
@ -675,8 +882,9 @@ main(int argc, char **argv, char **env)
mgr = [NSFileManager defaultManager]; mgr = [NSFileManager defaultManager];
/* /*
* Load any old project indexing information and determine when the * 3) Load old project indexing information from the .igsdoc file if
* indexing information was last updated (never ==> distant past) * present and determine when the indexing information was last
* updated (never ==> distant past).
*/ */
refsFile = [documentationDirectory refsFile = [documentationDirectory
stringByAppendingPathComponent: project]; stringByAppendingPathComponent: project];
@ -702,6 +910,9 @@ main(int argc, char **argv, char **env)
} }
} }
/*
* 4) Clean if desired:
*/
if ([defs boolForKey: @"Clean"] == YES) if ([defs boolForKey: @"Clean"] == YES)
{ {
NSDictionary *output; NSDictionary *output;
@ -720,7 +931,7 @@ main(int argc, char **argv, char **env)
nil]; nil];
/* /*
* Build a set of all template files. * 4a) Build a set of all template files.
*/ */
templates = AUTORELEASE([NSMutableSet new]); templates = AUTORELEASE([NSMutableSet new]);
enumerator = [keys objectEnumerator]; enumerator = [keys objectEnumerator];
@ -741,8 +952,8 @@ main(int argc, char **argv, char **env)
} }
/* /*
* Unless we are supposed to clean templates, we preserve any * 4b) Unless we are supposed to clean templates, we preserve any
* template gsdoc files, but remove any generated content. * template gsdoc files, but remove any generated content.
*/ */
if ([defs boolForKey: @"CleanTemplates"] == NO) if ([defs boolForKey: @"CleanTemplates"] == NO)
{ {
@ -797,8 +1008,8 @@ main(int argc, char **argv, char **env)
} }
/* /*
* Build a list of all generated gsdoc files, then remove them * 4b) Build a list of all generated gsdoc files, then remove them
* and their corresponding html documents. * and their corresponding html documents.
*/ */
output = [[projectRefs refs] objectForKey: @"output"]; output = [[projectRefs refs] objectForKey: @"output"];
enumerator = [output objectEnumerator]; enumerator = [output objectEnumerator];
@ -836,7 +1047,7 @@ main(int argc, char **argv, char **env)
RELEASE(allPaths); RELEASE(allPaths);
/* /*
* Remove the project index file. * 4c) Remove the project index file.
*/ */
if ([mgr fileExistsAtPath: refsFile] == YES) if ([mgr fileExistsAtPath: refsFile] == YES)
{ {
@ -847,8 +1058,8 @@ main(int argc, char **argv, char **env)
} }
/* /*
* Remove any HTML documents resulting from gsdoc files which * 4d) Remove any HTML documents resulting from gsdoc files which
* were specified on the command line rather than generated. * were specified on the command line rather than generated.
*/ */
enumerator = [gFiles objectEnumerator]; enumerator = [gFiles objectEnumerator];
while ((path = [enumerator nextObject]) != nil) while ((path = [enumerator nextObject]) != nil)
@ -871,10 +1082,18 @@ main(int argc, char **argv, char **env)
if ([sFiles count] == 0 && [gFiles count] == 0 && [hFiles count] == 0) if ([sFiles count] == 0 && [gFiles count] == 0 && [hFiles count] == 0)
{ {
NSLog(@"No filename arguments found ... giving up"); NSLog(@"No .h, .m, or .gsdoc filename arguments found ... giving up");
return 1; return 1;
} }
/*
* 5) Start with "source files".. for each one (hereafter called a
* "header file"):
* a) Parse declarations (in .h or .m) using an AGSParser object.
* b) Determine (possibly multiple) dependent .m files corresponding to
* a .h and parse them.
* c) Feed parser results to an AGSOutput instance.
*/
count = [sFiles count]; count = [sFiles count];
if (count > 0) if (count > 0)
{ {
@ -1137,6 +1356,11 @@ main(int argc, char **argv, char **env)
DESTROY(output); DESTROY(output);
} }
/*
* 6) Now move to "gsdoc files" (including both command-line given ones and
* just-generated ones).. and generate the index.
*
*/
count = [gFiles count]; count = [gFiles count];
if (count > 0) if (count > 0)
{ {
@ -1158,6 +1382,14 @@ main(int argc, char **argv, char **env)
arp = [NSAutoreleasePool new]; arp = [NSAutoreleasePool new];
} }
#endif #endif
/*
* 6a) Chop off any path specification that might be there (for files
* given on the command line) and search for the file only in
* 'DocumentationDirectory' or the CWD (which is assumed to be
* the directory with the source files, though this will not be
* true if path information was given for them on the command
* line).
*/
file = [[arg lastPathComponent] stringByDeletingPathExtension]; file = [[arg lastPathComponent] stringByDeletingPathExtension];
gsdocfile = [documentationDirectory gsdocfile = [documentationDirectory
@ -1181,9 +1413,9 @@ main(int argc, char **argv, char **env)
} }
/* /*
* Now we try to process the gsdoc data to make index info * 6b) Now we try to process the gsdoc data to make index info
* unless the project index is already more up to date than * unless the project index is already more up to date than
* this file (or the gsdoc file does not exist of course). * 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)
{ {
@ -1198,6 +1430,7 @@ main(int argc, char **argv, char **env)
GSXMLParser *parser; GSXMLParser *parser;
AGSIndex *localRefs; AGSIndex *localRefs;
// This parses the file for index info
parser = [GSXMLParser parserWithContentsOfFile: gsdocfile]; parser = [GSXMLParser parserWithContentsOfFile: gsdocfile];
[parser doValidityChecking: YES]; [parser doValidityChecking: YES];
[parser keepBlanks: NO]; [parser keepBlanks: NO];
@ -1215,6 +1448,7 @@ main(int argc, char **argv, char **env)
} }
localRefs = AUTORELEASE([AGSIndex new]); localRefs = AUTORELEASE([AGSIndex new]);
// This is the main call that computes index information
[localRefs makeRefs: root]; [localRefs makeRefs: root];
/* /*
@ -1224,7 +1458,7 @@ main(int argc, char **argv, char **env)
} }
else else
{ {
NSLog(@"No readable documentation at '%@' ... skipping", NSLog(@"File '%@' not found in $DocumentationDirectory or '.' ... skipping indexing",
gsdocfile); gsdocfile);
} }
} }
@ -1234,7 +1468,8 @@ main(int argc, char **argv, char **env)
#endif #endif
/* /*
* Save project references if they have been modified. * 7) Save project references if they have been modified
* (into an .igsdoc file named for the project).
*/ */
projectIndex = [projectRefs refs]; projectIndex = [projectRefs refs];
if (projectIndex != nil && [originalIndex isEqual: projectIndex] == NO) if (projectIndex != nil && [originalIndex isEqual: projectIndex] == NO)
@ -1250,9 +1485,13 @@ main(int argc, char **argv, char **env)
globalRefs = [AGSIndex new]; globalRefs = [AGSIndex new];
/* /*
* If we are either generating html output, or relocating existing * 8) If we are either generating html output, or relocating existing
* html documents, we must build up the indexing information needed * html documents, we must build up the indexing information needed
* for any cross-referencing etc. * for any cross-referencing etc.. This comes from the "xxxProjects"
* defaults. Each of these is used to find a project directory, in
* which an .igsdoc index cache file is searched for. If found, its
* contents are read in and merged with the current project (but NOT
* merged into its index file).
*/ */
if (generateHtml == YES || [hFiles count] > 0) if (generateHtml == YES || [hFiles count] > 0)
{ {
@ -1275,8 +1514,7 @@ main(int argc, char **argv, char **env)
AUTORELEASE(projects); AUTORELEASE(projects);
/* /*
* Merge any external project references into the * Merge any system project references.
* main cross reference index.
*/ */
if ([systemProjects caseInsensitiveCompare: @"None"] != NSOrderedSame) if ([systemProjects caseInsensitiveCompare: @"None"] != NSOrderedSame)
{ {
@ -1317,6 +1555,9 @@ main(int argc, char **argv, char **env)
} }
} }
/*
* Merge any local project references.
*/
if ([localProjects caseInsensitiveCompare: @"None"] != NSOrderedSame) if ([localProjects caseInsensitiveCompare: @"None"] != NSOrderedSame)
{ {
NSString *base = [NSSearchPathForDirectoriesInDomains( NSString *base = [NSSearchPathForDirectoriesInDomains(
@ -1357,6 +1598,9 @@ main(int argc, char **argv, char **env)
} }
} }
/*
* Merge any "plain project" references.
*/
if (projects != nil) if (projects != nil)
{ {
NSEnumerator *e = [projects keyEnumerator]; NSEnumerator *e = [projects keyEnumerator];
@ -1413,7 +1657,125 @@ main(int argc, char **argv, char **env)
} }
/* /*
* Next pass ... generate html output from gsdoc files if required. * 8.5) If we are generating HTML frames, create the gsdoc files specifying
* indices that we will use.
*/
if ([defs boolForKey: @"MakeFrames"] == YES)
{
int i;
int cap = 1360;
NSArray *idxTypes = [NSArray arrayWithObjects:
@"class",
@"constant",
@"function",
@"macro",
@"type",
@"variable",
@"tool",
nil];
NSString *idxIndexFile;
NSMutableString *idxIndex = [NSMutableString stringWithCapacity: 5*cap];
NSString *framesetFile;
NSMutableString *frameset = [NSMutableString stringWithCapacity: cap];
NSMutableString *tocSkel = [NSMutableString stringWithCapacity: cap];
[tocSkel setString :@"<?xml version=\"1.0\"?>\n"
"<!DOCTYPE gsdoc PUBLIC \"-//GNUstep//DTD gsdoc 1.0.1//EN\" \"http://www.gnustep.org/gsdoc-1_0_1.xml\">\n"
"<gsdoc base=\"[typeU]\" stylesheeturl=\"gsdoc_contents\">\n"
" <head>\n"
" <title>[typeU]</title>\n"
" </head>\n"
" <body>\n"
" <chapter>\n"
" <index type=\"[typeL]\" scope=\"project\" target=\"mainFrame\"\n"
" style=\"bare\" />\n"
" </chapter>\n"
" </body>\n"
"</gsdoc>\n"];
[tocSkel replaceOccurrencesOfString: @"[prjName]" withString: project
options: 0
range: NSMakeRange(0, [tocSkel length])];
idxIndexFile = [@"MainIndex" stringByAppendingPathExtension: @"html"];
[idxIndex setString: @"<HTML>\n <BODY>\n"
" <FONT FACE=\"sans\" SIZE=\"+1\"><B>Index</B></FONT><BR/><BR/>\n"
" <FONT FACE=\"sans\" SIZE=\"-1\">"];
framesetFile = [@"index" stringByAppendingPathExtension: @"html"];
[frameset setString: @"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n"
"<HTML>\n"
" <HEAD>\n"
" <TITLE>\n"
" Autogsdoc-generated Documentation for [prjName]\n"
" </TITLE>\n"
" </HEAD>\n"
" <FRAMESET cols=\"20%,80%\">\n"
" <FRAMESET rows=\"30%,70%\">\n"
" <FRAME src=\"MainIndex.html\" name=\"packageListFrame\">\n"
" <FRAME src=\"ClassesTOC.html\" name=\"packageFrame\">\n"
" </FRAMESET>\n"
" <FRAME src=\"[prjName].html\" name=\"mainFrame\">\n"
" </FRAMESET>\n"
"</HTML>\n"];
[frameset replaceOccurrencesOfString: @"[prjName]" withString: project
options: 0
range: NSMakeRange(0, [frameset length])];
for (i=0; i<[idxTypes count]; i++)
{
NSString *gsdocFile;
NSString *htmlFile;
NSMutableString *contents= [NSMutableString stringWithCapacity: cap];
[contents setString: tocSkel];
NSString *typeL = [idxTypes objectAtIndex: i];
NSString *typeU = [typeL capitalizedString];
typeU = [@"Class" isEqualToString: typeU] ?
[typeU stringByAppendingString: @"es"] :
[typeU stringByAppendingString: @"s"];
[contents replaceOccurrencesOfString: @"[typeL]" withString: typeL
options: 0
range: NSMakeRange(0,[contents length])];
[contents replaceOccurrencesOfString: @"[typeU]" withString: typeU
options: 0
range: NSMakeRange(0, [contents length])];
gsdocFile = [[typeU stringByAppendingString: @"TOC"]
stringByAppendingPathExtension: @"gsdoc"];
htmlFile = [[typeU stringByAppendingString: @"TOC"]
stringByAppendingPathExtension: @"html"];
if ([[projectRefs refs] objectForKey: typeL] != nil)
{
[contents writeToFile:
[documentationDirectory stringByAppendingPathComponent:
gsdocFile]
atomically: YES];
[gFiles addObject: gsdocFile];
[idxIndex appendFormat:
@" <A HREF=\"%@\" TARGET=\"packageFrame\">%@</A><BR/>\n",
htmlFile, typeU];
}
}
[idxIndex appendString: @" <BR/>\n"];
[idxIndex appendFormat:
@" (<A HREF=\"%@.html\" TARGET=\"mainFrame\">intro</A>)&nbsp;",
project];
[idxIndex appendFormat:
@"&nbsp;(<A HREF=\"%@.html\" TARGET=\"_top\">no frames</A>)\n",
project];
[idxIndex appendString: @" </FONT>\n </BODY>\n</HTML>\n"];
[idxIndex writeToFile:
[documentationDirectory stringByAppendingPathComponent: idxIndexFile]
atomically: YES];
[frameset writeToFile:
[documentationDirectory stringByAppendingPathComponent: framesetFile]
atomically: YES];
}
/*
* 9) Next pass ... generate html output from gsdoc files if required.
*/ */
count = [gFiles count]; count = [gFiles count];
if (generateHtml == YES && count > 0) if (generateHtml == YES && count > 0)
@ -1440,6 +1802,11 @@ main(int argc, char **argv, char **env)
pool = [NSAutoreleasePool new]; pool = [NSAutoreleasePool new];
} }
#endif #endif
/*
* 9a) As before in connection with (6a), drop path information
* and look for gsdoc files in 'documentationDirectory' or
* CWD.
*/
file = [[arg lastPathComponent] stringByDeletingPathExtension]; file = [[arg lastPathComponent] stringByDeletingPathExtension];
gsdocfile = [documentationDirectory gsdocfile = [documentationDirectory
@ -1487,6 +1854,7 @@ main(int argc, char **argv, char **env)
NSLog(@"%@: gsdoc %@, html %@ ==> regenerate", NSLog(@"%@: gsdoc %@, html %@ ==> regenerate",
file, gDate, hDate); file, gDate, hDate);
} }
// 9b) parse the .gsdoc file
parser = [GSXMLParser parserWithContentsOfFile: gsdocfile]; parser = [GSXMLParser parserWithContentsOfFile: gsdocfile];
[parser doValidityChecking: YES]; [parser doValidityChecking: YES];
[parser keepBlanks: NO]; [parser keepBlanks: NO];
@ -1507,7 +1875,8 @@ main(int argc, char **argv, char **env)
[localRefs makeRefs: root]; [localRefs makeRefs: root];
/* /*
* We perform final output * 9c) Feed the XML tree to an AGSHtml instance, and dump
* the result to a file.
*/ */
html = AUTORELEASE([AGSHtml new]); html = AUTORELEASE([AGSHtml new]);
[html setGlobalRefs: globalRefs]; [html setGlobalRefs: globalRefs];
@ -1522,7 +1891,7 @@ main(int argc, char **argv, char **env)
} }
else if ([arg hasSuffix: @".gsdoc"] == YES) else if ([arg hasSuffix: @".gsdoc"] == YES)
{ {
NSLog(@"No readable documentation at '%@' ... skipping", NSLog(@"File '%@' not found in $DocumentationDirectory or '.' ... skipping",
gsdocfile); gsdocfile);
} }
} }
@ -1532,8 +1901,10 @@ main(int argc, char **argv, char **env)
} }
/* /*
* Relocate existing html documents if required ... adjust all cross * 10) Relocate existing html documents if required ... adjust all cross
* referencing within those documents. * referencing within those documents. This entails searching for
* <a rel="..." href="..."> links, parsing the key, and replacing the
* contents as per our current index info (which may have changed).
*/ */
count = [hFiles count]; count = [hFiles count];
if (count > 0) if (count > 0)
@ -1723,12 +2094,20 @@ main(int argc, char **argv, char **env)
{ {
NSLog(@"No readable documentation at '%@' ... skipping", src); NSLog(@"No readable documentation at '%@' ... skipping", src);
} }
else
{
NSLog(@"Type of file '%@' unrecognized ... skipping", src);
}
} }
#if GS_WITH_GCC == 0 #if GS_WITH_GCC == 0
RELEASE(pool); RELEASE(pool);
#endif #endif
} }
/*
* 11) If MakeDependencies was requested, list all header and source files
* as colon-dependencies of the project name.
*/
if ([defs stringForKey: @"MakeDependencies"] != nil) if ([defs stringForKey: @"MakeDependencies"] != nil)
{ {
NSString *stamp = [defs stringForKey: @"MakeDependencies"]; NSString *stamp = [defs stringForKey: @"MakeDependencies"];
@ -1756,7 +2135,7 @@ main(int argc, char **argv, char **env)
[depend writeToFile: stamp atomically: YES]; [depend writeToFile: stamp atomically: YES];
} }
RELEASE(outer); RELEASE(outer);
return 0; return 0;
} }

View file

@ -1,4 +1,4 @@
/* This tool converts a file containing a string to a C String encoding. /** This tool converts a file containing a string to a C String encoding.
Copyright (C) 2002 Free Software Foundation, Inc. Copyright (C) 2002 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk> Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
@ -35,13 +35,21 @@
#include <ctype.h> #include <ctype.h>
/** Return whether value ch between min and max. */
#define inrange(ch,min,max) ((ch)>=(min) && (ch)<=(max)) #define inrange(ch,min,max) ((ch)>=(min) && (ch)<=(max))
/** Convert hex digit in ascii to decimal equivalent. */
#define char2num(ch) \ #define char2num(ch) \
inrange(ch,'0','9') \ inrange(ch,'0','9') \
? ((ch)-0x30) \ ? ((ch)-0x30) \
: (inrange(ch,'a','f') \ : (inrange(ch,'a','f') \
? ((ch)-0x57) : ((ch)-0x37)) ? ((ch)-0x57) : ((ch)-0x37))
/** <p>Converts a file encoded in a specified or default non-unicode encoding
* to unicode, or, if the file is already in unicode, converts it to a
* specified or default non-unicode encoding. The converted text is
* printed to standard out.</p>
*/
int int
main(int argc, char** argv, char **env) main(int argc, char** argv, char **env)
{ {

View file

@ -1,4 +1,4 @@
/* This tool mimics the OPENSTEP command line tool for handling defaults. /** This tool mimics the OPENSTEP command line tool for handling defaults.
Copyright (C) 1997 Free Software Foundation, Inc. Copyright (C) 1997 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk> Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
@ -35,6 +35,9 @@
#define GSEXIT_FAILURE EXIT_FAILURE #define GSEXIT_FAILURE EXIT_FAILURE
#define GSEXIT_NOTFOUND 2 #define GSEXIT_NOTFOUND 2
/** <p>This tool mimics the OPENSTEP command line tool for handling defaults.
Please see the man page for more information.
</p>*/
int int
main(int argc, char** argv, char **env) main(int argc, char** argv, char **env)
{ {
@ -118,7 +121,7 @@ main(int argc, char** argv, char **env)
" output some information about property lists\n\n"); " output some information about property lists\n\n");
printf( printf(
"defaults help\n" "defaults help\n"
" list options fo the defaults command.\n\n"); " list options for the defaults command.\n\n");
[pool release]; [pool release];
exit(GSEXIT_SUCCESS); exit(GSEXIT_SUCCESS);
} }
@ -673,7 +676,7 @@ main(int argc, char** argv, char **env)
domain = [[defs persistentDomainForName: owner] mutableCopy]; domain = [[defs persistentDomainForName: owner] mutableCopy];
if (domain == nil || [domain objectForKey: name] == nil) if (domain == nil || [domain objectForKey: name] == nil)
{ {
printf("dremove: couldn't remove %s owned by %s\n", printf("defaults delete: couldn't remove %s owned by %s\n",
[name cString], [owner cString]); [name cString], [owner cString]);
} }
else else

View file

@ -19,7 +19,7 @@ Every user needs to have his own instance of
running. While running. While
.B gdnc .B gdnc
will be started automatically as soon as it is needed, will be started automatically as soon as it is needed,
it is recommend to start it is recommended to start
.B gdnc .B gdnc
in a personal login script like ~/.bashrc or ~/.cshrc. in a personal login script like ~/.bashrc or ~/.cshrc.
Alternatively you can launch gpbs when your windowing system or the Alternatively you can launch gpbs when your windowing system or the

View file

@ -1,4 +1,4 @@
/* Implementation of GNUstep Distributed Notification Center /** Implementation of GNUstep Distributed Notification Center
Copyright (C) 1998 Free Software Foundation, Inc. Copyright (C) 1998 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk> Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
@ -286,7 +286,7 @@ ihandler(int sig)
- (void) addObserver: (unsigned long)anObserver - (void) addObserver: (unsigned long)anObserver
selector: (NSString*)aSelector selector: (NSString*)aSelector
name: (NSString*)notificationname name: (NSString*)notificationName
object: (NSString*)anObject object: (NSString*)anObject
suspensionBehavior: (NSNotificationSuspensionBehavior)suspensionBehavior suspensionBehavior: (NSNotificationSuspensionBehavior)suspensionBehavior
for: (id<GDNCClient>)client; for: (id<GDNCClient>)client;
@ -297,7 +297,7 @@ ihandler(int sig)
- (id) connectionBecameInvalid: (NSNotification*)notification; - (id) connectionBecameInvalid: (NSNotification*)notification;
- (void) postNotificationName: (NSString*)notificationName - (void) postNotificationName: (NSString*)notificationName
object: (NSString*)anObject object: (NSString*)notificationObject
userInfo: (NSData*)d userInfo: (NSData*)d
deliverImmediately: (BOOL)deliverImmediately deliverImmediately: (BOOL)deliverImmediately
for: (id<GDNCClient>)client; for: (id<GDNCClient>)client;
@ -307,8 +307,8 @@ ihandler(int sig)
- (void) removeObserversForClients: (NSMapTable*)clients; - (void) removeObserversForClients: (NSMapTable*)clients;
- (void) removeObserver: (unsigned long)anObserver - (void) removeObserver: (unsigned long)anObserver
name: (NSString*)notificationname name: (NSString*)notificationName
object: (NSString*)anObject object: (NSString*)notificationObject
for: (id<GDNCClient>)client; for: (id<GDNCClient>)client;
- (void) setSuspended: (BOOL)flag - (void) setSuspended: (BOOL)flag
@ -559,7 +559,7 @@ ihandler(int sig)
} }
- (BOOL) connection: (NSConnection*)ancestor - (BOOL) connection: (NSConnection*)ancestor
shouldMakeNewConnection: (NSConnection*)newConn; shouldMakeNewConnection: (NSConnection*)newConn
{ {
NSMapTable *table; NSMapTable *table;
@ -766,30 +766,30 @@ ihandler(int sig)
} }
} }
- (void) removeObserver: (GDNCObserver*)obs - (void) removeObserver: (GDNCObserver*)observer
{ {
if (obs->notificationObject) if (observer->notificationObject)
{ {
NSMutableArray *objList; NSMutableArray *objList;
objList = [observersForObjects objectForKey: obs->notificationObject]; objList= [observersForObjects objectForKey: observer->notificationObject];
if (objList != nil) if (objList != nil)
{ {
[objList removeObjectIdenticalTo: obs]; [objList removeObjectIdenticalTo: observer];
} }
} }
if (obs->notificationName) if (observer->notificationName)
{ {
NSMutableArray *namList; NSMutableArray *namList;
namList = [observersForNames objectForKey: obs->notificationName]; namList = [observersForNames objectForKey: observer->notificationName];
if (namList != nil) if (namList != nil)
{ {
[namList removeObjectIdenticalTo: obs]; [namList removeObjectIdenticalTo: observer];
} }
} }
NSHashRemove(allObservers, obs); NSHashRemove(allObservers, observer);
[obs->client->observers removeObjectIdenticalTo: obs]; [observer->client->observers removeObjectIdenticalTo: observer];
} }
- (void) removeObserversForClients: (NSMapTable*)clients - (void) removeObserversForClients: (NSMapTable*)clients
@ -971,6 +971,22 @@ ihandler(int sig)
@end @end
/** <p>The gdnc daemon is used by GNUstep programs to send notifications and
messages to one another, in conjunction with the Base library
Notification-related classes.</p>
<p>Every user needs to have his own instance of gdnc running. While gdnc
will be started automatically as soon as it is needed, it is recommended
to start gdnc in a personal login script like ~/.bashrc or ~/.cshrc.
Alternatively you can launch gpbs when your windowing system or the
window manager is started. For example, on systems with X11 you can
launch gdnc from your .xinitrc script or alternatively - if you are
running Window Maker - put it in Window Maker's autostart script. See
the GNUstep Build Guide for a sample startup script.</p>
<p>Please see the man page for more information.
</p> */
int int
main(int argc, char** argv, char** env) main(int argc, char** argv, char** env)
{ {

View file

@ -1,4 +1,4 @@
/* Include for communications with GNUstep Distributed Objects name server /* Include for communications with GNUstep Distributed Objects name server.
Copyright (C) 1996, 1997 Free Software Foundation, Inc. Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk> Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* This tool converts a serialised proerty list to a text representation. /** This tool converts a serialised property list to a text representation.
Copyright (C) 1999 Free Software Foundation, Inc. Copyright (C) 1999 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk> Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
@ -31,6 +31,9 @@
#include <Foundation/NSAutoreleasePool.h> #include <Foundation/NSAutoreleasePool.h>
/** <p>This tool converts a binary serialised property list to a text
representation.
</p> */
int int
main(int argc, char** argv, char **env) main(int argc, char** argv, char **env)
{ {

View file

@ -1,4 +1,4 @@
/* This tool merges text property lists into a single property list. /** This tool merges text property lists into a single property list.
Copyright (C) 2000 Free Software Foundation, Inc. Copyright (C) 2000 Free Software Foundation, Inc.
Written by: Jonathan Gapen <jagapen@whitewater.chem.wisc.edu> Written by: Jonathan Gapen <jagapen@whitewater.chem.wisc.edu>
@ -33,6 +33,9 @@
#include "GNUstepBase/GSObjCRuntime.h" #include "GNUstepBase/GSObjCRuntime.h"
#endif #endif
/** <p> This tool merges text property lists into a single property list.
</p> */
int int
main(int argc, char** argv, char **env) main(int argc, char** argv, char **env)
{ {

View file

@ -1,4 +1,4 @@
/* This tool checks that a file contains a valid text property-list /** This tool checks that a file contains a valid text property-list.
Copyright (C) 1999 Free Software Foundation, Inc. Copyright (C) 1999 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk> Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
@ -29,6 +29,9 @@
#include <Foundation/NSAutoreleasePool.h> #include <Foundation/NSAutoreleasePool.h>
/** <p>
This tool checks that a file contains a valid text property-list.
</p> */
int int
main(int argc, char** argv, char **env) main(int argc, char** argv, char **env)
{ {

View file

@ -1,4 +1,4 @@
/* This tool converts a text property list to a serialised representation. /** This tool converts a text property list to a serialised representation.
Copyright (C) 1999 Free Software Foundation, Inc. Copyright (C) 1999 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk> Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
@ -31,6 +31,9 @@
#include <Foundation/NSAutoreleasePool.h> #include <Foundation/NSAutoreleasePool.h>
/** <p> This tool converts a text property list to a binary serialised
representation.
</p> */
int int
main(int argc, char** argv, char **env) main(int argc, char** argv, char **env)
{ {

View file

@ -1,4 +1,4 @@
/* This tool checks that a file is a valid strings-file /** This tool checks that a file is a valid strings-file
Copyright (C) 1999 Free Software Foundation, Inc. Copyright (C) 1999 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk> Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
@ -103,6 +103,13 @@ convert_utf8(NSArray *args)
return 0; return 0;
} }
/** <p>
This tool checks that a file is a valid strings-file, and can also convert
files to Unicode or UTF-8. If given the '<code>--unicode</code>' option
it converts an ASCII or UTF-8 file to unicode. If given the
'<code>--utf8</code>' option is converts an ASCII or unicode file to UTF-8.
</p> */
int int
main(int argc, char** argv, char **env) main(int argc, char** argv, char **env)
{ {

View file

@ -60,6 +60,9 @@
} }
@end @end
/** <p>This tool error-checks and validates xml documents. The parse
is simply discarded after checking.
</p> */
int int
main(int argc, char **argv, char **env) main(int argc, char **argv, char **env)
{ {