diff --git a/ChangeLog b/ChangeLog index e543f7ebd..d686f24f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +2004-03-29 Richard Frith-Macdonald + + * 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 + + * 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 * Source/NSMessagePort.m: diff --git a/Documentation/Base.gsdoc b/Documentation/Base.gsdoc index 41076de6e..644f3d4ff 100644 --- a/Documentation/Base.gsdoc +++ b/Documentation/Base.gsdoc @@ -1,5 +1,5 @@ - + GNUstep Base diff --git a/Documentation/BaseAdditions.gsdoc b/Documentation/BaseAdditions.gsdoc index 28c06ab95..79edd11d8 100644 --- a/Documentation/BaseAdditions.gsdoc +++ b/Documentation/BaseAdditions.gsdoc @@ -1,5 +1,5 @@ - + GNUstep Base Additions diff --git a/Documentation/Functions.gsdoc b/Documentation/Functions.gsdoc index 586c8e1ed..83df3fc3c 100644 --- a/Documentation/Functions.gsdoc +++ b/Documentation/Functions.gsdoc @@ -1,5 +1,5 @@ - + Functions diff --git a/Documentation/Makefile.postamble b/Documentation/Makefile.postamble index 8a3626cab..3d22ed95d 100644 --- a/Documentation/Makefile.postamble +++ b/Documentation/Makefile.postamble @@ -44,6 +44,7 @@ after-all:: ifeq ($(HAVE_LIBXML),1) $(MAKE) -C ../Source -f DocMakefile + $(MAKE) -C ../Tools -f DocMakefile endif # Things to do before installing diff --git a/Documentation/TypesAndConstants.gsdoc b/Documentation/TypesAndConstants.gsdoc index 091fa0f5a..80935dc32 100644 --- a/Documentation/TypesAndConstants.gsdoc +++ b/Documentation/TypesAndConstants.gsdoc @@ -1,5 +1,5 @@ - + Types and Constants diff --git a/Tools/AGSHtml.h b/Tools/AGSHtml.h index 4a703de6c..e5666f0cc 100644 --- a/Tools/AGSHtml.h +++ b/Tools/AGSHtml.h @@ -42,6 +42,7 @@ unsigned sect; unsigned ssect; unsigned sssect; + BOOL isContentsDoc; } - (void) decIndent; - (void) incIndent; diff --git a/Tools/AGSHtml.m b/Tools/AGSHtml.m index ea429186b..70c939dca 100644 --- a/Tools/AGSHtml.m +++ b/Tools/AGSHtml.m @@ -278,6 +278,8 @@ static NSMutableSet *textNodes = nil; - (void) outputIndex: (NSString*)type scope: (NSString*)scope title: (NSString*)title + style: (NSString*)style + target: (NSString*)target to: (NSMutableString*)buf { NSDictionary *refs = [localRefs refs]; @@ -285,6 +287,7 @@ static NSMutableSet *textNodes = nil; NSArray *a; unsigned c; unsigned i; + BOOL isBareStyle = [@"bare" isEqualToString: style]; if (globalRefs != nil && [scope isEqual: @"global"] == YES) { @@ -320,11 +323,14 @@ static NSMutableSet *textNodes = nil; if ([dict count] > 1 && [type isEqual: @"title"] == YES) { - [buf appendString: indent]; - [buf appendFormat: @"%@\n", title]; - [buf appendString: indent]; - [buf appendString: @"
    \n"]; - [self incIndent]; + if (!isBareStyle) + { + [buf appendString: indent]; + [buf appendFormat: @"%@ Index\n", title]; + [buf appendString: indent]; + [buf appendString: @"
      \n"]; + [self incIndent]; + } a = [dict allKeys]; a = [a sortedArrayUsingSelector: @selector(compare:)]; @@ -342,14 +348,34 @@ static NSMutableSet *textNodes = nil; } [buf appendString: indent]; - [buf appendString: @"
    • %@
    • \n", + if (!isBareStyle) + { + [buf appendString: @"
    • "]; + } + [buf appendString: @"%@", file, type, ref, text]; + if (!isBareStyle) + { + [buf appendString: @"
    • "]; + } + else + { + [buf appendString: @"
      "]; + } + [buf appendString: @"\n"]; } - [self decIndent]; - [buf appendString: indent]; - [buf appendString: @"
    \n"]; + if (!isBareStyle) + { + [self decIndent]; + [buf appendString: indent]; + [buf appendString: @"
\n"]; + } } else if ([dict count] > 0) { @@ -418,10 +444,16 @@ static NSMutableSet *textNodes = nil; } [buf appendString: indent]; - [buf appendFormat: @"%@\n", title]; + if (!isBareStyle) + { + [buf appendFormat: @"%@\n", title]; + } [buf appendString: indent]; - [buf appendString: @"
    \n"]; - [self incIndent]; + if (!isBareStyle) { + [buf appendString: @"
      "]; + [self incIndent]; + } + [buf appendString: @"\n"]; a = [dict allKeys]; a = [a sortedArrayUsingSelector: @selector(compare:)]; @@ -457,22 +489,43 @@ static NSMutableSet *textNodes = nil; } [buf appendString: indent]; - [buf appendString: @"
    • "]; + } + [buf appendString: @"%@
    • \n", + [buf appendFormat: @"href=\"%@.html#%@$%@%@%@\">%@", file, type, u, sep, ref, text]; } else { - [buf appendFormat: @"\"%@.html#%@$%@\">%@\n", + [buf appendFormat: @"href=\"%@.html#%@$%@\">%@", file, type, ref, text]; } + if (!isBareStyle) + { + [buf appendString: @""]; + } + else + { + [buf appendString: @"
      "]; + } + [buf appendString: @"\n"]; + } - [self decIndent]; - [buf appendString: indent]; - [buf appendString: @"
    \n"]; + if (!isBareStyle) { + [self decIndent]; + [buf appendString: indent]; + [buf appendString: @"
"]; + } + [buf appendString: @"\n"]; } } @@ -526,6 +579,15 @@ static NSMutableSet *textNodes = nil; [self decIndent]; [buf appendString: indent]; + + // special formatting for table-of-contents frames; ultimately + // this should be moved to stylesheet + if (isContentsDoc) + { + [buf appendString: indent]; + [buf appendString: @"\n"]; + } + [buf appendString: @"\n"]; } else if ([name isEqual: @"br"] == YES) @@ -966,6 +1028,8 @@ static NSMutableSet *textNodes = nil; } else if ([name isEqual: @"gsdoc"] == YES) { + NSString *stylesheetURL = [prop objectForKey: @"stylesheeturl"]; + base = [prop objectForKey: @"base"]; if (base == nil) { @@ -978,10 +1042,19 @@ static NSMutableSet *textNodes = nil; prevFile = [prevFile stringByAppendingPathExtension: @"html"]; upFile = [prop objectForKey: @"up"]; 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]; } else if ([name isEqual: @"head"] == YES) { + NSString *headerTag; + [buf appendString: indent]; [buf appendString: @"\n"]; [self incIndent]; @@ -999,6 +1072,14 @@ static NSMutableSet *textNodes = nil; [buf appendString: @"\n"]; [self incIndent]; + // special formatting for table-of-contents frames; ultimately + // this should be moved to stylesheet + if (isContentsDoc) + { + [buf appendString: indent]; + [buf appendString: @"\n"]; + } + if (prevFile != nil) { [buf appendString: indent]; @@ -1014,13 +1095,24 @@ static NSMutableSet *textNodes = nil; [buf appendString: indent]; [buf appendFormat: @"Next\n", nextFile]; } - [buf appendString: indent]; - [buf appendString: @"
\n"]; + if (prevFile != nil || upFile != nil || nextFile != nil) + { + [buf appendString: indent]; + [buf appendString: @"
\n"]; + } [buf appendString: indent]; - [buf appendFormat: @"

", base]; + if (isContentsDoc) + { + headerTag = @"h2"; + } + else + { + headerTag = @"h1"; + } + [buf appendFormat: @"<%@>", headerTag, base]; [self outputText: [children firstChild] to: buf]; - [buf appendString: @"

\n"]; + [buf appendFormat: @"\n", headerTag]; children = [children nextElement]; if ([[children name] isEqual: @"author"] == YES) @@ -1092,10 +1184,8 @@ static NSMutableSet *textNodes = nil; if (desc != nil) { [self incIndent]; - while (desc != nil) - { - desc = [self outputBlock: desc to: buf inPara: NO]; - } + [self outputNode: desc to: buf]; + desc = nil; [self decIndent]; } [buf appendString: indent]; @@ -1170,9 +1260,12 @@ static NSMutableSet *textNodes = nil; { NSString *scope = [prop objectForKey: @"scope"]; NSString *type = [prop objectForKey: @"type"]; + NSString *target = [prop objectForKey: @"target"]; 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 { @@ -1519,6 +1612,10 @@ static NSMutableSet *textNodes = nil; NSString *c = [prop objectForKey: @"class"]; NSString *s; + // fill in default value + if ((type == nil) || [type isEqual: @""]) + type = @"label"; + if ([type isEqual: @"method"] || [type isEqual: @"ivariable"]) { s = [self makeLink: r ofType: type inUnit: c isRef: YES]; @@ -1588,8 +1685,6 @@ static NSMutableSet *textNodes = nil; else if ([name isEqual: @"EOEntity"] == YES || [name isEqual: @"EOModel"] == YES) { - NSString *tmp = [prop objectForKey: @"name"]; - NSLog(@"Element '%@' not implemented", name); // FIXME } else if ([name isEqual: @"section"] == YES) @@ -1722,7 +1817,12 @@ static NSMutableSet *textNodes = nil; } 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: @""]; + [buf appendString: [prop objectForKey: @"url"]]; + [buf appendString: @""]; } else if ([name isEqual: @"var"] == YES) // %phrase { @@ -1788,7 +1888,7 @@ NSLog(@"Element '%@' not implemented", name); // FIXME { GSXMLNode *tmp; /* - * Try outputing as any of the list elements. + * Try outputting as any of the list elements. */ tmp = [self outputList: node to: buf]; if (tmp == node) @@ -1900,6 +2000,7 @@ NSLog(@"Element '%@' not implemented", name); // FIXME else { NSLog(@"Non-block element '%@' in block ...", n); + NSLog(@"%@",node); return nil; } } @@ -2033,7 +2134,52 @@ NSLog(@"Element '%@' not implemented", name); // FIXME } else if ([name isEqual: @"dictionary"] == YES) { -NSLog(@"Element '%@' not implemented", name); // FIXME + [buf appendString: indent]; + [buf appendString: @"
{\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: @"
"]; + [buf appendString: [dProp objectForKey: @"key"]]; + [buf appendString: @" =
\n"]; + [buf appendString: indent]; + [buf appendString: @"
\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: @";
\n"]; + } + [self decIndent]; + [buf appendString: indent]; + [buf appendString: @"
}\n"]; } else { @@ -2183,6 +2329,8 @@ NSLog(@"Element '%@' not implemented", name); // FIXME [self outputIndex: @"method" scope: @"global" title: @"Method summary" + style: nil + target: nil to: buf]; [buf appendString: indent]; [buf appendString: @"
\n"]; diff --git a/Tools/AGSIndex.m b/Tools/AGSIndex.m index e7379818a..09c019579 100644 --- a/Tools/AGSIndex.m +++ b/Tools/AGSIndex.m @@ -156,27 +156,27 @@ setDirectory(NSMutableDictionary *dict, NSString *path) /** * This class is used to build and manipulate a dictionary of * cross-reference information.
- * The references are held in a tree consisting of dictionaries - * with strings at the leaves -
- * method method-name class-name file-name
- * method method-name protocol-name file-name
- * ivariable variable-name class-name file-name
- * class class-name file-name
- * category category-name file-name
- * protocol protocol-name file-name
- * function function-name file-name
- * type type-name file-name
- * constant constant-name file-name
- * variable variable-name file-name
- * entry entry-name file-name ref
- * label label-name file-name ref
- * contents ref text
- * super class-name superclass-name
- * categories class-name category-name file-name
- * unitmethods unit-name method-name
- * classvars class-name variables-name
- * title file-name text
- * source file-name array-of-source-files
+ * The references are held in a nested dictionary + * with strings at the leaves (persisted to 'projectName'.igsdoc) -
+ * method : method-name - { class-name file-name }
+ * method : method-name - { protocol-name file-name }
+ * ivariable : variable-name - { class-name file-name }
+ * class : class-name - file-name
+ * category : category-name - file-name
+ * protocol : protocol-name - file-name
+ * function : function-name - file-name
+ * type : type-name - file-name
+ * constant : constant-name - file-name
+ * variable : variable-name - file-name
+ * entry : entry-name - { file-name ref }
+ * label : label-name - { file-name ref }
+ * contents : ref - text
+ * super : class-name - superclass-name
+ * categories : class-name - { category-name file-name }
+ * unitmethods : unit-name - method-name
+ * classvars : class-name - variables-name
+ * title : file-name - text
+ * source : file-name - array-of-source-files
*/ @implementation AGSIndex @@ -228,6 +228,14 @@ setDirectory(NSMutableDictionary *dict, NSString *path) NSString *name = [node name]; 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) { newUnit = YES; @@ -302,7 +310,6 @@ setDirectory(NSMutableDictionary *dict, NSString *path) else if ([name isEqual: @"entry"] || [name isEqual: @"label"]) { NSMutableDictionary *all; - NSMutableDictionary *byFile; NSString *text; NSString *val; @@ -316,19 +323,12 @@ setDirectory(NSMutableDictionary *dict, NSString *path) [refs setObject: all forKey: name]; RELEASE(all); } - byFile = [all objectForKey: base]; - if (byFile == nil) - { - byFile = [[NSMutableDictionary alloc] initWithCapacity: 2]; - [all setObject: byFile forKey: base]; - RELEASE(byFile); - } val = [prop objectForKey: @"id"]; if (val == nil) { val = text; } - [byFile setObject: val forKey: @"text"]; + [all setObject: base forKey: val]; } else if ([name isEqual: @"method"] == YES) { @@ -408,6 +408,7 @@ setDirectory(NSMutableDictionary *dict, NSString *path) } else if ([name isEqual: @"section"] == YES) { + //FIXME- this info needs to be placed into the "label" refs somehow sect++; ssect = 0; sssect = 0; diff --git a/Tools/AGSOutput.m b/Tools/AGSOutput.m index bea5abdf9..3e2e60d84 100644 --- a/Tools/AGSOutput.m +++ b/Tools/AGSOutput.m @@ -71,14 +71,14 @@ static BOOL snuggleStart(NSString *t) * far too special purpose.

* *

Here is the afterword for the class.

- *

Ad here is some automated cross referencing ... + *

And here is some automated cross referencing ... * A method in a protocol: [(NSCopying)-copyWithZone:], a class: * [NSString], a protocol: [(NSCopying)], and a * category: [NSRunLoop(GNUstepExtensions)]. *

*
* 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 @@ -283,8 +283,8 @@ static BOOL snuggleStart(NSString *t) [str appendString: @"\n"]; [str appendString: @"\n"]; + [str appendString: @"\"-//GNUstep//DTD gsdoc 1.0.1//EN\" "]; + [str appendString: @"\"http://www.gnustep.org/gsdoc-1_0_1.xml\">\n"]; [str appendFormat: @"\n"]; @@ -2296,8 +2296,8 @@ static BOOL snuggleStart(NSString *t) [str appendString: @"\n"]; [str appendString: @"\n"]; + [str appendString: @"\"-//GNUstep//DTD gsdoc 1.0.1//EN\" "]; + [str appendString: @"\"http://www.gnustep.org/gsdoc-1_0_1.xml\">\n"]; [str appendString: @"AGSParser ... a tool to get documention info from ObjC source + AGSParser ...a class to get documention info from ObjC source Copyright (C) 2001 Free Software Foundation, Inc. Written by: Richard Frith-Macdonald @@ -22,17 +22,10 @@ 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. - - - AGSParser front page -

- 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. -

-
-
*/ @@ -115,8 +108,4 @@ - (NSMutableArray*) sources; @end -/** Let's document a macro - */ -#define fibble(a,b,c) feep /** with three arguments: a, b, c */ - #endif diff --git a/Tools/AGSParser.m b/Tools/AGSParser.m index 0e248aea7..8a32ced5e 100644 --- a/Tools/AGSParser.m +++ b/Tools/AGSParser.m @@ -1,6 +1,4 @@ -/** - - AGSParser ... a tool to get documention info from ObjC source +/* Copyright (C) 2001 Free Software Foundation, Inc. Written by: Richard Frith-Macdonald @@ -34,23 +32,38 @@ - (void) addMain: (NSString*)c { NSString *chap; + NSString *toolName; + NSString *secHeading; + BOOL createSec = NO; NSMutableString *m; NSRange r; chap = [info objectForKey: @"chapter"]; + toolName = [[fileName lastPathComponent] stringByDeletingPathExtension]; if (chap == nil) { chap = [NSString stringWithFormat: - @"%@", - [[fileName lastPathComponent] stringByDeletingPathExtension]]; + @"%@", toolName]; + } + else + { + createSec = YES; } m = [chap mutableCopy]; r = [m rangeOfString: @""]; r.length = 0; - [m replaceCharactersInRange: r withString: @"\n"]; + if (createSec) + { + [m replaceCharactersInRange: r withString: @"\n"]; + } [m replaceCharactersInRange: r withString: c]; - [m replaceCharactersInRange: r withString: - @"
\nThe main() function\n"]; + if (createSec) + { + secHeading = [NSString stringWithFormat: + @"
\n\n", toolName]; + //The %@ tool + [m replaceCharactersInRange: r withString: secHeading]; + } [info setObject: m forKey: @"chapter"]; RELEASE(m); } @@ -488,6 +501,9 @@ [self appendComment: tmp to: nil]; } + /* + * We're in the first comment of a file; perform special processing. + */ if (commentsRead == NO && comment != nil) { unsigned commentLength = [comment length]; diff --git a/Tools/GNUmakefile b/Tools/GNUmakefile index b22cb057d..c49b8b629 100644 --- a/Tools/GNUmakefile +++ b/Tools/GNUmakefile @@ -35,14 +35,16 @@ DTD_FILES = plist-0_9.dtd \ gsdoc-0_6_5.dtd \ gsdoc-0_6_6.dtd \ gsdoc-0_6_7.dtd \ - gsdoc-1_0_0.dtd + gsdoc-1_0_0.dtd \ + gsdoc-1_0_1.dtd # DocTemplates to install doctemplatesdir = $(GNUSTEP_LIBRARY)/DocTemplates DOCTEMPLATES_FILES = indextemplate.gsdoc AutoDocTemplate.gsdoc # 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 # The application to be compiled diff --git a/Tools/autogsdoc.m b/Tools/autogsdoc.m index 3b70099ed..ddb23bb05 100644 --- a/Tools/autogsdoc.m +++ b/Tools/autogsdoc.m @@ -1,4 +1,4 @@ -/** This tool produces gsdoc files from source files. +/** This tool produces GSDoc files from source files. Autogsdoc ... a tool to make documentation from source code Copyright (C) 2001 Free Software Foundation, Inc. @@ -21,33 +21,68 @@ The autogsdoc tool
- overview + Overview

- The autogsdoc tool is a command-line utility for parsing ObjectiveC - source code (header files and optionally source files) in order to - generate documentation covering the public interface of the various - classes, categories, and protocols in the source. + The autogsdoc tool is a command-line utility that helps developers + produce reference documentation for GNUstep APIs. It also enables + developers to write and maintain other documentation in XML and have it + converted to HTML. In detail, autogsdoc will:

+ + + 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. + + + Convert GSDoc XML files, whether generated from source code or written + manually by developers, into HTML. + + + Construct indices based on GSDoc XML file sets, and convert those + to HTML as well. + +

- The simple way to use this is to run the command with one or more + synopsis: autogsdoc (options) (files)
+     (options) described below
+     (files) .h, .m, .gsdoc, and/or .html files, in any order. +

+

+ The most common usage this is to run the command with one or more header file names as arguments ... the tool will automatically parse corresponding source files in the same directory as the headers (or the current directory, or the directory specified - using the DocumentationDirectory default), and produce gsdoc - and html files as output. + using the DocumentationDirectory default), and produce GSDoc + and HTML files as output. For best results this mode should be + run from the directory containing the source files.

- Even without any human assistance, this tool will produce skeleton - documents listing the methods in the classes found in the source - files, but more importantly it can take specially formatted comments - from the source files and insert those comments into the gsdoc output. + GSDoc files may also be given directly in addition or by themselves, and + will be converted to HTML. See the + GSDoc reference for information + on the GSDoc format. +

+

+ 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. +

+
+
+ Source Code Markup +

+ 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.

Any comment beginning with slash and two 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 comment text is reformatted and then inserted into the output.
- 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 (<br />) between each if necessary.

@@ -59,38 +94,42 @@ the end of the first chapter of the document (it creates the first chapter if necessary).

+

+ Options are described in the section + Arguments and Defaults below. +

Extra markup

There are some cases where special extra processing is performed, 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 -

- AutogsdocSource - In any line where AutogsdocSource: is found, the remainder - of the line is taken as a source file name to be used instead of - making the assumption that each .h file processed uses a .m file - of the same name. You may supply multiple AutogsdocSource: - lines where a header file declares items which are defined in - multiple source files.
- If a file name is absolute, it is used just as supplied.
- If on the other hand, it is a relative path, the software looks for - the source file first relative to the location of the header file, - and if not found there, relative to the current directory in which - autogsdoc is running, and finally relative to the directory - specified by the DocumentationDirectory default. + AutogsdocSource:  + In any line where AutogsdocSource:  is found, the + remainder of the line is taken as a source file name to be used + instead of making the assumption that each .h file processed uses + a  .m file of the same name. You may supply multiple + AutogsdocSource:  lines where a header file declares + items which are defined in multiple source files.
If a file name + is absolute, it is used just as supplied.
If on the other hand, + it is a relative path, the software looks for the source file first + relative to the location of the header file, and if not found there, + relative to the current directory in which autogsdoc is running, and + finally relative to the directory specified by the + DocumentationDirectory default.
<abstract> An abstract of the content of the document ... placed in the head - of the gsdoc output. + of the GSDoc output. <author> A description of the author of the code - may be repeated to handle the case where a document has multiple authors. Placed in the - head of the gsdoc output.
+ head of the GSDoc output.
As an aid to readability of the source, some special additional processing is performed related to the document author -
Any line of the form 'Author: name <email-address>', @@ -100,8 +139,8 @@ possibly containing an email element.
<back> - Placed in the gsdoc output just before the end of the body of the - document - intended to be used for appendices, index etc. + Placed in the GSDoc output just before the end of the body of the + document - intended to be used for appendices, index etc.. <chapter> Placed immediately before any generated class documentation ... @@ -112,7 +151,7 @@ <copy> Copyright of the content of the document ... placed in the head - of the gsdoc output.
+ of the GSDoc output.
As an aid to readability of the source, some special additional processing is performed -
Any line of the form 'Copyright (C) text' will be recognised and @@ -120,7 +159,7 @@
<date> 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). <front> @@ -128,26 +167,25 @@ to provide for introduction or contents pages etc. <title> - 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) title of its own - so you should include this markup manually. - - NBThis 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 <unit /> pseudo-element within the - <chapter> element. - <version> 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).
+

+ NBThe 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 <unit /> pseudo-element within the + <chapter> element. +

Method markup @@ -161,7 +199,7 @@ <override-subclass /> The method is marked as being one which subclasses must override - (eg an abstract method). + (e.g. an abstract method). <override-never /> The method is marked as being one which subclasses should NOT @@ -169,7 +207,7 @@ <standards> ... </standards> The markup is removed from the description and placed after - 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. @@ -192,7 +230,7 @@ Method names (beginning with a plus or minus) are enclosed in <ref...> ... </ref> markup.
- 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 class or, if only one known class had an init method, it would refer to the method of that class. @@ -202,52 +240,54 @@
Method specifiers including class names (beginning and ending with square brackets) are enclosed in <ref...> ... </ref> markup. -
eg. [NSObject-init], +
e.g. [NSObject-init], will create a reference to the init method of NSObject (either the class proper, or any of its categories), while
[(NSCopying)-copyWithZone:], creates a - reference to a method in the NSCopyIng protocol. + reference to a method in the NSCopying protocol.
Note that no spaces must appear between the square brackets in these specifiers.
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.
Class names (and also protocol and category names) enclosed in square brackets are also cross referenced.
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.
Function names (ending with '()') other than 'main()' are enclosed in <ref...> ... </ref> markup.
- 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.
Note the fact that the function name must be surrounded by whitespace (though a comma, fullstop, or semicolon at the end of the specifier will also act as a whitespace terminator). +
Arguments and Defaults

- The tools accepts certain user defaults (which can of course be - supplied as command-line arguments as usual) - + The tool accepts certain user defaults (which can of course be + supplied as command-line arguments by prepending '-' before the default + name and giving the value afterwards, as in -Clean YES):

Clean 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 - 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.
- The only exception to this is that template gsdoc files (ie those - specifield using "-ConstantsTemplate ...", "-FunctionsTemplate ..." + The only exception to this is that template GSDoc files (i.e. those + specified using "-ConstantsTemplate ...", "-FunctionsTemplate ..." arguments etc) are not deleted unless the CleanTemplates flag is set.
CleanTemplates - 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. The default is for them not to be removed ... since these templates may have been produced manually and just had data inserted into them. @@ -285,10 +325,15 @@ 'protected' will be documented. DocumentationDirectory - May be used to specify the directory in which generated - documentation is to be placed. If this is not set, output - is placed in the current directory. This directory is also - used as a last resort to locate source files (not headers). + May be used to specify the directory in which generated documentation + is to be placed. If this is not set, output is placed in the current + directory. This directory is also used as a last resort to locate + source files (not headers), and more importantly, it is used as the + first and only resort to locate any .gsdoc files + that are passed in on the command line. Any path information given + for these files is removed and they are + searched for in DocumentationDirectory (even though they + may not have been autogenerated). Files Specifies the name of a file containing a list of file names as @@ -361,13 +406,16 @@ of the body element) in the template. MakeDependencies - 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 + Project). Project - 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 to provide information enabling other projects to cross-reference to - items in this project. + items in this project. If not set, 'Untitled' is used. Projects This value may be supplied as a dictionary containing the paths to @@ -377,7 +425,10 @@ Foo is found in the file Foo, and the path associated with that project index is /usr/doc/proj, Then generated html output may reference the class as being in - /usr/doc/prj/Foo.html + /usr/doc/prj/Foo.html . 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. ShowDependencies A boolean value which may be used to specify that the program should @@ -386,7 +437,7 @@ Standards 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 and tools themselves as it assumes that the code being documented is part of GNUstep and possibly complies with the OpenStep standard @@ -426,7 +477,7 @@ Up 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.
If this is missing or set to an empty string, then no 'up' link will be provided in the documents. @@ -451,7 +502,7 @@
Warn 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. WordMap This value is a dictionary used to map identifiers/keywords found @@ -463,6 +514,9 @@ Another identifier,
An empty string - the value is ignored,
Two slashes ('//') - the rest of the line is ignored.
+ 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.
@@ -473,13 +527,13 @@ should be used as the 'up' link for any other documents used.
This name must not include a path or extension.
Generally, the document referred to by this default should be a - hand-edited gsdoc document which should have a back - section containing a project index. eg. + hand-edited GSDoc document which should have a back + section containing a project index. e.g.

<?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="index"> <head> <title>My project reference</title> @@ -496,11 +550,32 @@ </gsdoc>
+ +
+ Implementation Notes +

+ The autogsdoc tool internally makes use of the following four classes- +

+ + + Parses source code comments to an internal representation. + + + Converts internal representation of source comments to a gsdoc + document. + + Internal representation of an igsdoc file, representing indices + of a project's files. + + Converts gsdoc XML to HTML, using AGSIndex instances. + +
+ - + */ #include @@ -514,11 +589,13 @@ #include "GNUstepBase/GSCategories.h" #endif +/** Invokes the autogsdoc tool. */ int main(int argc, char **argv, char **env) { NSProcessInfo *proc; unsigned i; + NSDictionary *argsRecognized; NSUserDefaults *defs; NSFileManager *mgr; NSString *documentationDirectory; @@ -548,6 +625,63 @@ main(int argc, char **argv, char **env) NSAutoreleasePool *pool = nil; #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 [NSProcessInfo initializeWithArguments: argv count: argc environment: env]; #endif @@ -563,11 +697,84 @@ main(int argc, char **argv, char **env) exit(EXIT_FAILURE); #endif + /* + * 1) Get/test defaults and arguments. + */ defs = [NSUserDefaults standardUserDefaults]; [defs registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys: @"Untitled", @"Project", 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"]; warn = [defs boolForKey: @"Warn"]; 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"]; if (obj != nil) @@ -675,8 +882,9 @@ main(int argc, char **argv, char **env) mgr = [NSFileManager defaultManager]; /* - * Load any old project indexing information and determine when the - * indexing information was last updated (never ==> distant past) + * 3) Load old project indexing information from the .igsdoc file if + * present and determine when the indexing information was last + * updated (never ==> distant past). */ refsFile = [documentationDirectory stringByAppendingPathComponent: project]; @@ -702,6 +910,9 @@ main(int argc, char **argv, char **env) } } + /* + * 4) Clean if desired: + */ if ([defs boolForKey: @"Clean"] == YES) { NSDictionary *output; @@ -720,7 +931,7 @@ main(int argc, char **argv, char **env) nil]; /* - * Build a set of all template files. + * 4a) Build a set of all template files. */ templates = AUTORELEASE([NSMutableSet new]); enumerator = [keys objectEnumerator]; @@ -741,8 +952,8 @@ main(int argc, char **argv, char **env) } /* - * Unless we are supposed to clean templates, we preserve any - * template gsdoc files, but remove any generated content. + * 4b) Unless we are supposed to clean templates, we preserve any + * template gsdoc files, but remove any generated content. */ 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 - * and their corresponding html documents. + * 4b) Build a list of all generated gsdoc files, then remove them + * and their corresponding html documents. */ output = [[projectRefs refs] objectForKey: @"output"]; enumerator = [output objectEnumerator]; @@ -836,7 +1047,7 @@ main(int argc, char **argv, char **env) RELEASE(allPaths); /* - * Remove the project index file. + * 4c) Remove the project index file. */ 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 - * were specified on the command line rather than generated. + * 4d) Remove any HTML documents resulting from gsdoc files which + * were specified on the command line rather than generated. */ enumerator = [gFiles objectEnumerator]; 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) { - NSLog(@"No filename arguments found ... giving up"); + NSLog(@"No .h, .m, or .gsdoc filename arguments found ... giving up"); 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]; if (count > 0) { @@ -1137,6 +1356,11 @@ main(int argc, char **argv, char **env) 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]; if (count > 0) { @@ -1158,6 +1382,14 @@ main(int argc, char **argv, char **env) arp = [NSAutoreleasePool new]; } #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]; 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 - * unless the project index is already more up to date than - * this file (or the gsdoc file does not exist of course). + * 6b) Now we try to process the gsdoc data to make index info + * unless the project index is already more up to date than + * this file (or the gsdoc file does not exist of course). */ if (gDate != nil && [gDate earlierDate: rDate] == rDate) { @@ -1198,6 +1430,7 @@ main(int argc, char **argv, char **env) GSXMLParser *parser; AGSIndex *localRefs; + // This parses the file for index info parser = [GSXMLParser parserWithContentsOfFile: gsdocfile]; [parser doValidityChecking: YES]; [parser keepBlanks: NO]; @@ -1215,6 +1448,7 @@ main(int argc, char **argv, char **env) } localRefs = AUTORELEASE([AGSIndex new]); + // This is the main call that computes index information [localRefs makeRefs: root]; /* @@ -1224,7 +1458,7 @@ main(int argc, char **argv, char **env) } else { - NSLog(@"No readable documentation at '%@' ... skipping", + NSLog(@"File '%@' not found in $DocumentationDirectory or '.' ... skipping indexing", gsdocfile); } } @@ -1234,7 +1468,8 @@ main(int argc, char **argv, char **env) #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]; if (projectIndex != nil && [originalIndex isEqual: projectIndex] == NO) @@ -1250,9 +1485,13 @@ main(int argc, char **argv, char **env) globalRefs = [AGSIndex new]; /* - * If we are either generating html output, or relocating existing - * html documents, we must build up the indexing information needed - * for any cross-referencing etc. + * 8) If we are either generating html output, or relocating existing + * html documents, we must build up the indexing information needed + * 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) { @@ -1275,8 +1514,7 @@ main(int argc, char **argv, char **env) AUTORELEASE(projects); /* - * Merge any external project references into the - * main cross reference index. + * Merge any system project references. */ 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) { NSString *base = [NSSearchPathForDirectoriesInDomains( @@ -1357,6 +1598,9 @@ main(int argc, char **argv, char **env) } } + /* + * Merge any "plain project" references. + */ if (projects != nil) { 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 :@"\n" +"\n" +"\n" +" \n" +" [typeU]\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n"]; + [tocSkel replaceOccurrencesOfString: @"[prjName]" withString: project + options: 0 + range: NSMakeRange(0, [tocSkel length])]; + + idxIndexFile = [@"MainIndex" stringByAppendingPathExtension: @"html"]; + [idxIndex setString: @"\n \n" +" Index

\n" +" "]; + + framesetFile = [@"index" stringByAppendingPathExtension: @"html"]; + [frameset setString: @"\n" +"\n" +" \n" +" \n" +" Autogsdoc-generated Documentation for [prjName]\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\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: + @" %@
\n", + htmlFile, typeU]; + } + } + + [idxIndex appendString: @"
\n"]; + [idxIndex appendFormat: + @" (intro) ", + project]; + [idxIndex appendFormat: + @" (no frames)\n", + project]; + [idxIndex appendString: @"
\n \n\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]; if (generateHtml == YES && count > 0) @@ -1440,6 +1802,11 @@ main(int argc, char **argv, char **env) pool = [NSAutoreleasePool new]; } #endif + /* + * 9a) As before in connection with (6a), drop path information + * and look for gsdoc files in 'documentationDirectory' or + * CWD. + */ file = [[arg lastPathComponent] stringByDeletingPathExtension]; gsdocfile = [documentationDirectory @@ -1487,6 +1854,7 @@ main(int argc, char **argv, char **env) NSLog(@"%@: gsdoc %@, html %@ ==> regenerate", file, gDate, hDate); } + // 9b) parse the .gsdoc file parser = [GSXMLParser parserWithContentsOfFile: gsdocfile]; [parser doValidityChecking: YES]; [parser keepBlanks: NO]; @@ -1507,7 +1875,8 @@ main(int argc, char **argv, char **env) [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 setGlobalRefs: globalRefs]; @@ -1522,7 +1891,7 @@ main(int argc, char **argv, char **env) } else if ([arg hasSuffix: @".gsdoc"] == YES) { - NSLog(@"No readable documentation at '%@' ... skipping", + NSLog(@"File '%@' not found in $DocumentationDirectory or '.' ... skipping", gsdocfile); } } @@ -1532,8 +1901,10 @@ main(int argc, char **argv, char **env) } /* - * Relocate existing html documents if required ... adjust all cross - * referencing within those documents. + * 10) Relocate existing html documents if required ... adjust all cross + * referencing within those documents. This entails searching for + * links, parsing the key, and replacing the + * contents as per our current index info (which may have changed). */ count = [hFiles count]; if (count > 0) @@ -1723,12 +2094,20 @@ main(int argc, char **argv, char **env) { NSLog(@"No readable documentation at '%@' ... skipping", src); } + else + { + NSLog(@"Type of file '%@' unrecognized ... skipping", src); + } } #if GS_WITH_GCC == 0 RELEASE(pool); #endif } + /* + * 11) If MakeDependencies was requested, list all header and source files + * as colon-dependencies of the project name. + */ if ([defs stringForKey: @"MakeDependencies"] != nil) { NSString *stamp = [defs stringForKey: @"MakeDependencies"]; @@ -1756,7 +2135,7 @@ main(int argc, char **argv, char **env) [depend writeToFile: stamp atomically: YES]; } + RELEASE(outer); return 0; } - diff --git a/Tools/cvtenc.m b/Tools/cvtenc.m index c91abbaf9..d3749c0de 100644 --- a/Tools/cvtenc.m +++ b/Tools/cvtenc.m @@ -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. Written by: Richard Frith-Macdonald @@ -35,13 +35,21 @@ #include +/** Return whether value ch between min and max. */ #define inrange(ch,min,max) ((ch)>=(min) && (ch)<=(max)) +/** Convert hex digit in ascii to decimal equivalent. */ #define char2num(ch) \ inrange(ch,'0','9') \ ? ((ch)-0x30) \ : (inrange(ch,'a','f') \ ? ((ch)-0x57) : ((ch)-0x37)) + +/**

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.

+ */ int main(int argc, char** argv, char **env) { diff --git a/Tools/defaults.m b/Tools/defaults.m index ba9f9e10f..e77606fe7 100644 --- a/Tools/defaults.m +++ b/Tools/defaults.m @@ -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. Written by: Richard Frith-Macdonald @@ -35,6 +35,9 @@ #define GSEXIT_FAILURE EXIT_FAILURE #define GSEXIT_NOTFOUND 2 +/**

This tool mimics the OPENSTEP command line tool for handling defaults. + Please see the man page for more information. +

*/ int 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"); printf( "defaults help\n" -" list options fo the defaults command.\n\n"); +" list options for the defaults command.\n\n"); [pool release]; exit(GSEXIT_SUCCESS); } @@ -673,7 +676,7 @@ main(int argc, char** argv, char **env) domain = [[defs persistentDomainForName: owner] mutableCopy]; 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]); } else diff --git a/Tools/gdnc.1 b/Tools/gdnc.1 index 2d5eec30a..35effbc58 100644 --- a/Tools/gdnc.1 +++ b/Tools/gdnc.1 @@ -19,7 +19,7 @@ Every user needs to have his own instance of running. While .B gdnc will be started automatically as soon as it is needed, -it is recommend to start +it is recommended to start .B gdnc in a personal login script like ~/.bashrc or ~/.cshrc. Alternatively you can launch gpbs when your windowing system or the diff --git a/Tools/gdnc.m b/Tools/gdnc.m index a546f111c..212a7473b 100644 --- a/Tools/gdnc.m +++ b/Tools/gdnc.m @@ -1,4 +1,4 @@ -/* Implementation of GNUstep Distributed Notification Center +/** Implementation of GNUstep Distributed Notification Center Copyright (C) 1998 Free Software Foundation, Inc. Written by: Richard Frith-Macdonald @@ -286,7 +286,7 @@ ihandler(int sig) - (void) addObserver: (unsigned long)anObserver selector: (NSString*)aSelector - name: (NSString*)notificationname + name: (NSString*)notificationName object: (NSString*)anObject suspensionBehavior: (NSNotificationSuspensionBehavior)suspensionBehavior for: (id)client; @@ -297,7 +297,7 @@ ihandler(int sig) - (id) connectionBecameInvalid: (NSNotification*)notification; - (void) postNotificationName: (NSString*)notificationName - object: (NSString*)anObject + object: (NSString*)notificationObject userInfo: (NSData*)d deliverImmediately: (BOOL)deliverImmediately for: (id)client; @@ -307,8 +307,8 @@ ihandler(int sig) - (void) removeObserversForClients: (NSMapTable*)clients; - (void) removeObserver: (unsigned long)anObserver - name: (NSString*)notificationname - object: (NSString*)anObject + name: (NSString*)notificationName + object: (NSString*)notificationObject for: (id)client; - (void) setSuspended: (BOOL)flag @@ -559,7 +559,7 @@ ihandler(int sig) } - (BOOL) connection: (NSConnection*)ancestor - shouldMakeNewConnection: (NSConnection*)newConn; + shouldMakeNewConnection: (NSConnection*)newConn { 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; - objList = [observersForObjects objectForKey: obs->notificationObject]; + objList= [observersForObjects objectForKey: observer->notificationObject]; if (objList != nil) { - [objList removeObjectIdenticalTo: obs]; + [objList removeObjectIdenticalTo: observer]; } } - if (obs->notificationName) + if (observer->notificationName) { NSMutableArray *namList; - namList = [observersForNames objectForKey: obs->notificationName]; + namList = [observersForNames objectForKey: observer->notificationName]; if (namList != nil) { - [namList removeObjectIdenticalTo: obs]; + [namList removeObjectIdenticalTo: observer]; } } - NSHashRemove(allObservers, obs); - [obs->client->observers removeObjectIdenticalTo: obs]; + NSHashRemove(allObservers, observer); + [observer->client->observers removeObjectIdenticalTo: observer]; } - (void) removeObserversForClients: (NSMapTable*)clients @@ -971,6 +971,22 @@ ihandler(int sig) @end + +/**

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.

+ +

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.

+ +

Please see the man page for more information. +

*/ int main(int argc, char** argv, char** env) { diff --git a/Tools/gdomap.h b/Tools/gdomap.h index 89b82ba91..f25e2f2c4 100644 --- a/Tools/gdomap.h +++ b/Tools/gdomap.h @@ -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. Written by: Richard Frith-Macdonald diff --git a/Tools/gsdoc.gsdoc b/Tools/gsdoc.gsdoc index 84c971b6d..613b7722d 100644 --- a/Tools/gsdoc.gsdoc +++ b/Tools/gsdoc.gsdoc @@ -1,5 +1,5 @@ - + GNUstep Documentation XML markup language (GSDoc) @@ -7,13 +7,13 @@ - A person who has devotes far too much time to GNUstep development. + A person who devotes far too much time to GNUstep development. - 0.2 - 21 June, 2000 + 1.0.1 + 8 March, 2004 - This documents the GNUstep Documentation markup language and tools + This documents the GNUstep Documentation markup language. Free Software Foundation, Inc. @@ -23,100 +23,103 @@ - Introduction -

- The GSDoc markup language is an XML language designed specifically - for writing documentation for the - GNUstep project. - In practice, that means that it is designed for writing about - software, and in particular, for writing about Objective-C classes. -

-

- This is also an example, as well as a test case, of the new - GNUstep documentation markup language (GSDoc). -

-
- Why another documentation language? -

- There are several reasons for producing the new markup - language - -

- - - There were no existing markup languages that dealt well with - documenting software written in the Objective-C language, - except the GDML language - which has no easy to use support - software. - - - While the DocBook system works nicely for general software - documentation, it requires a relatively large amount of - support software and comes with a lot of baggage that's - not directly useful for GNUstep. - - - The GNU info system comes with easy to use, lightweight - conversion tools, but is particularly ill suited to - Objective-C documentation because the colon character - using in Objective-C method names is used in info markup. - - - LinuxDoc, while being a nice basic system, seems to be - in the process of being replaced by DocBook. - - -

- So, with only one markup language available that supported - Objective-C, and with XML software becoming available, the - decision was to take GDML and update it to be an XML - language, in the hope that this would - -

- - - Provide optimal support for GNUstep documentation. - - - Minimize the amount of work needed for development of - software tools. - - - Provide future-proofing in that documentation written in one - XML language should be quite easy to convert to another if - necessary. - - -
+ Introduction +

+ The GSDoc markup language is an XML language designed specifically + for writing documentation for the + GNUstep project. + In practice, that means that it is designed for writing about + software, and in particular, for writing about Objective-C classes. +

+

+ This is also an example, as well as a test case, of the new + GNUstep documentation markup language (GSDoc). +

+
+ Why another documentation language? +

+ There are several reasons for producing the new markup + language - +

+ + + There were no existing markup languages that dealt well with + documenting software written in the Objective-C language, + except the GDML language - which has no easy to use support + software. + + + While the DocBook system works nicely for general software + documentation, it requires a relatively large amount of + support software and comes with a lot of baggage that's + not directly useful for GNUstep. + + + The GNU info system comes with easy to use, lightweight + conversion tools, but is particularly ill suited to + Objective-C documentation because the colon character + using in Objective-C method names is used in info markup. + + + LinuxDoc, while being a nice basic system, seems to be + in the process of being replaced by DocBook. + + +

+ So, with only one markup language available that supported + Objective-C, and with XML software becoming available, the + decision was to take GDML and update it to be an XML + language, in the hope that this would - +

+ + + Provide optimal support for GNUstep documentation. + + + Minimize the amount of work needed for development of + software tools. + + + Provide future-proofing in that documentation written in one + XML language should be quite easy to convert to another if + necessary. + + +
The gsdoc DTD and what it means

- The GSDoc markup language is defined by an SGML DTD, that specifies - the tags that may be used in marking up a GSDoc document, and how - and where those tags may be placed. Please see the DTD for a - precise specification. + The GSDoc markup language is defined by an SGML DTD, that specifies + the tags that may be used in marking up a GSDoc document, and how + and where those tags may be placed. The reader is encouraged to + consult the DTD directly on any points that the present document leaves + unclear. The DTD is stored under + $GNUSTEP_ROOT/System/Library/DTDs in a standard GNUstep + installation.

- The gsdoc DTD defines an XML language - that is, a markup language - that conforms to a specific subset of SGML features defined as XML. - The advantage of XML is that it provides most of the useful features - of SGML while being much more light-weight (easy to use) because - you can forget about the rest of SGML. - As XML looks set to become increasingly popular, we can hope that - documentation written with an XML language will be easily imported - into XML software tools as they become available, so we will not - (in the GNUstep project) need to devote a lot of time and effort - to maintaining documentation tools. + The gsdoc DTD defines an XML language - that is, a markup language + that conforms to a specific subset of SGML features defined as XML. + The advantage of XML is that it provides most of the useful features + of SGML while being much more light-weight (easy to use) because + you can forget about the rest of SGML. + As XML looks set to become increasingly popular, we can hope that + documentation written with an XML language will be easily imported + into XML software tools as they become available, so we will not + (in the GNUstep project) need to devote a lot of time and effort + to maintaining documentation tools.

-
- Overall document structure -

- A GSDoc document consists of a head and a - body wrapped inside the overall document - framework that looks like this - -

- +
-