mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 16:30:41 +00:00
New tool for generating gsdoc files
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@11126 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
a96445d01c
commit
fe43e94318
7 changed files with 3012 additions and 1 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2001-10-11 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Tools/GNUmakefile: Addend new files.
|
||||||
|
* Tools/AGSOutput.h: Support class for autogsdoc
|
||||||
|
* Tools/AGSOutput.m: ditto
|
||||||
|
* Tools/AGSParser.h: ditto
|
||||||
|
* Tools/AGSParser.m: ditto
|
||||||
|
* Tools/autogsdoc.m: New tool to generate gsdoc files from ObjC
|
||||||
|
header and source files. Uses comments with a '/**' prefix
|
||||||
|
(like javadoc) to provide nice information about classes and/or
|
||||||
|
methods.
|
||||||
|
This is very much an initial/alpha version but it is already
|
||||||
|
quite useful.
|
||||||
|
|
||||||
2001-10-06 Richard Frith-Macdonald <rfm@gnu.org>
|
2001-10-06 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/NSConnection.m: Increase default timeouts to max value.
|
* Source/NSConnection.m: Increase default timeouts to max value.
|
||||||
|
|
43
Tools/AGSOutput.h
Normal file
43
Tools/AGSOutput.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
<title>AGSOutput ... a class to output gsdoc source</title>
|
||||||
|
Copyright (C) <copy>2001 Free Software Foundation, Inc.</copy>
|
||||||
|
|
||||||
|
<author name="Richard Frith-Macdonald"></author><richard@brainstorm.co.uk>
|
||||||
|
Created: October 2001
|
||||||
|
|
||||||
|
This file is part of the GNUstep Project
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License along with this library; see the file COPYING.LIB.
|
||||||
|
If not, write to the Free Software Foundation,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@interface AGSOutput : NSObject
|
||||||
|
{
|
||||||
|
NSDictionary *info; // Not retained.
|
||||||
|
NSCharacterSet *identifier; // Legit char in identifier
|
||||||
|
NSCharacterSet *identStart; // Legit initial char of identifier
|
||||||
|
NSCharacterSet *spaces; // All blank characters
|
||||||
|
NSCharacterSet *spacenl; // Blanks excluding newline
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) output: (NSDictionary*)d file: (NSString*)name;
|
||||||
|
- (void) outputMethod: (NSDictionary*)d to: (NSMutableString*)str;
|
||||||
|
- (void) outputUnit: (NSDictionary*)d to: (NSMutableString*)str;
|
||||||
|
- (void) reformat: (NSString*)str
|
||||||
|
withIndent: (unsigned)ind
|
||||||
|
to: (NSMutableString*)buf;
|
||||||
|
- (NSArray*) split: (NSString*)str;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
851
Tools/AGSOutput.m
Normal file
851
Tools/AGSOutput.m
Normal file
|
@ -0,0 +1,851 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
<title>AGSOutput ... a class to output gsdoc source</title>
|
||||||
|
Copyright (C) <copy>2001 Free Software Foundation, Inc.</copy>
|
||||||
|
|
||||||
|
<author name="Richard Frith-Macdonald"></author><richard@brainstorm.co.uk>
|
||||||
|
Created: October 2001
|
||||||
|
|
||||||
|
This file is part of the GNUstep Project
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License along with this library; see the file COPYING.LIB.
|
||||||
|
If not, write to the Free Software Foundation,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AGSOutput.h"
|
||||||
|
|
||||||
|
@implementation AGSOutput
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
DESTROY(identifier);
|
||||||
|
DESTROY(identStart);
|
||||||
|
DESTROY(spaces);
|
||||||
|
DESTROY(spacenl);
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) init
|
||||||
|
{
|
||||||
|
NSMutableCharacterSet *m;
|
||||||
|
|
||||||
|
m = [[NSCharacterSet controlCharacterSet] mutableCopy];
|
||||||
|
[m addCharactersInString: @" "];
|
||||||
|
spacenl = [m copy];
|
||||||
|
[m removeCharactersInString: @"\n"];
|
||||||
|
spaces = [m copy];
|
||||||
|
RELEASE(m);
|
||||||
|
identifier = RETAIN([NSCharacterSet characterSetWithCharactersInString:
|
||||||
|
@"_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]);
|
||||||
|
identStart = RETAIN([NSCharacterSet characterSetWithCharactersInString:
|
||||||
|
@"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) output: (NSDictionary*)d file: (NSString*)name
|
||||||
|
{
|
||||||
|
NSMutableString *str = [NSMutableString stringWithCapacity: 10240];
|
||||||
|
NSDictionary *classes;
|
||||||
|
NSDictionary *categories;
|
||||||
|
NSDictionary *protocols;
|
||||||
|
NSArray *authors;
|
||||||
|
NSString *tmp;
|
||||||
|
|
||||||
|
info = d;
|
||||||
|
|
||||||
|
classes = [info objectForKey: @"Classes"];
|
||||||
|
categories = [info objectForKey: @"Categories"];
|
||||||
|
protocols = [info objectForKey: @"Protocols"];
|
||||||
|
|
||||||
|
[str appendString: @"<?xml version=\"1.0\"?>\n"];
|
||||||
|
[str appendString: @"<!DOCTYPE gsdoc PUBLIC "];
|
||||||
|
[str appendString: @"\"-//GNUstep//DTD gsdoc 0.6.5//EN\" "];
|
||||||
|
[str appendString: @"\"http://www.gnustep.org/gsdoc-0_6_5.xml\">\n"];
|
||||||
|
[str appendFormat: @"<gsdoc"];
|
||||||
|
|
||||||
|
tmp = [info objectForKey: @"Base"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[str appendString: @" base=\""];
|
||||||
|
[str appendString: tmp];
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = [info objectForKey: @"Next"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[str appendString: @" next=\""];
|
||||||
|
[str appendString: tmp];
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = [info objectForKey: @"Prev"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[str appendString: @" prev=\""];
|
||||||
|
[str appendString: tmp];
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = [info objectForKey: @"Up"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[str appendString: @" up=\""];
|
||||||
|
[str appendString: tmp];
|
||||||
|
}
|
||||||
|
|
||||||
|
[str appendString: @">\n"];
|
||||||
|
[str appendString: @" <head>\n"];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A title is mandatory in the head element ... obtain it
|
||||||
|
* from the info dictionary. Guess at a title if necessary.
|
||||||
|
*/
|
||||||
|
tmp = [info objectForKey: @"title"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[self reformat: tmp withIndent: 4 to: str];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[str appendString: @" <title>"];
|
||||||
|
if ([classes count] == 1)
|
||||||
|
{
|
||||||
|
[str appendString: [[classes allKeys] lastObject]];
|
||||||
|
[str appendString: @" class documentation"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[str appendString: @"Automatically generated documentation"];
|
||||||
|
}
|
||||||
|
[str appendString: @"</title>\n"];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The author element is compulsory ... fill in.
|
||||||
|
*/
|
||||||
|
authors = [info objectForKey: @"authors"];
|
||||||
|
if (authors == nil)
|
||||||
|
{
|
||||||
|
tmp = [NSString stringWithFormat: @"Generated by %@", NSUserName()];
|
||||||
|
[str appendString: @" <author name=\""];
|
||||||
|
[str appendString: tmp];
|
||||||
|
[str appendString: @"\"></author>\n"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < [authors count]; i++)
|
||||||
|
{
|
||||||
|
NSString *author = [authors objectAtIndex: i];
|
||||||
|
|
||||||
|
[self reformat: author withIndent: 4 to: str];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The version element is optional ... fill in if available.
|
||||||
|
*/
|
||||||
|
tmp = [info objectForKey: @"version"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[self reformat: tmp withIndent: 4 to: str];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The date element is optional ... fill in if available.
|
||||||
|
*/
|
||||||
|
tmp = [info objectForKey: @"date"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[self reformat: tmp withIndent: 4 to: str];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The abstract element is optional ... fill in if available.
|
||||||
|
*/
|
||||||
|
tmp = [info objectForKey: @"abstract"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[self reformat: tmp withIndent: 4 to: str];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The copy element is optional ... fill in if available.
|
||||||
|
*/
|
||||||
|
tmp = [info objectForKey: @"copy"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[self reformat: tmp withIndent: 4 to: str];
|
||||||
|
}
|
||||||
|
|
||||||
|
[str appendString: @" </head>\n"];
|
||||||
|
[str appendString: @" <body>\n"];
|
||||||
|
|
||||||
|
// Output document forward if available.
|
||||||
|
tmp = [info objectForKey: @"front"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[self reformat: tmp withIndent: 4 to: str];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output document main chapter if available
|
||||||
|
tmp = [info objectForKey: @"chapter"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[self reformat: tmp withIndent: 4 to: str];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([classes count] > 0)
|
||||||
|
{
|
||||||
|
NSArray *names;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
names = [classes allKeys];
|
||||||
|
names = [names sortedArrayUsingSelector: @selector(compare:)];
|
||||||
|
for (i = 0; i < [names count]; i++)
|
||||||
|
{
|
||||||
|
NSString *name = [names objectAtIndex: i];
|
||||||
|
NSDictionary *d = [classes objectForKey: name];
|
||||||
|
|
||||||
|
[self outputUnit: d to: str];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([categories count] > 0)
|
||||||
|
{
|
||||||
|
NSArray *names;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
names = [categories allKeys];
|
||||||
|
names = [names sortedArrayUsingSelector: @selector(compare:)];
|
||||||
|
for (i = 0; i < [names count]; i++)
|
||||||
|
{
|
||||||
|
NSString *name = [names objectAtIndex: i];
|
||||||
|
NSDictionary *d = [categories objectForKey: name];
|
||||||
|
|
||||||
|
[self outputUnit: d to: str];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([protocols count] > 0)
|
||||||
|
{
|
||||||
|
NSArray *names;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
names = [protocols allKeys];
|
||||||
|
names = [names sortedArrayUsingSelector: @selector(compare:)];
|
||||||
|
for (i = 0; i < [names count]; i++)
|
||||||
|
{
|
||||||
|
NSString *name = [names objectAtIndex: i];
|
||||||
|
NSDictionary *d = [protocols objectForKey: name];
|
||||||
|
|
||||||
|
[self outputUnit: d to: str];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output document appendix if available.
|
||||||
|
tmp = [info objectForKey: @"back"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[self reformat: tmp withIndent: 4 to: str];
|
||||||
|
}
|
||||||
|
|
||||||
|
[str appendString: @" </body>\n"];
|
||||||
|
[str appendString: @"</gsdoc>\n"];
|
||||||
|
|
||||||
|
return [str writeToFile: name atomically: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) outputMethod: (NSDictionary*)d to: (NSMutableString*)str
|
||||||
|
{
|
||||||
|
NSArray *args = [d objectForKey: @"Args"];
|
||||||
|
NSArray *sels = [d objectForKey: @"Sels"];
|
||||||
|
NSArray *types = [d objectForKey: @"Types"];
|
||||||
|
NSString *name = [d objectForKey: @"Name"];
|
||||||
|
NSString *tmp;
|
||||||
|
unsigned i;
|
||||||
|
BOOL isInitialiser = NO;
|
||||||
|
NSString *override = nil;
|
||||||
|
NSString *standards = nil;
|
||||||
|
|
||||||
|
tmp = [d objectForKey: @"Comment"];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check special markup which should be removed from the text
|
||||||
|
* actually placed in the gsdoc method documentation ... the
|
||||||
|
* special markup is included in the gsdoc markup differently.
|
||||||
|
*/
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
NSMutableString *m = nil;
|
||||||
|
NSRange r;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
r = [tmp rangeOfString: @"<init>"];
|
||||||
|
if (r.length > 0)
|
||||||
|
{
|
||||||
|
if (m == nil)
|
||||||
|
{
|
||||||
|
m = [tmp mutableCopy];
|
||||||
|
}
|
||||||
|
[m deleteCharactersInRange: r];
|
||||||
|
tmp = m;
|
||||||
|
isInitialiser = YES;
|
||||||
|
}
|
||||||
|
} while (r.length > 0);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
r = [tmp rangeOfString: @"<override-subclass>"];
|
||||||
|
if (r.length > 0)
|
||||||
|
{
|
||||||
|
if (m == nil)
|
||||||
|
{
|
||||||
|
m = [tmp mutableCopy];
|
||||||
|
}
|
||||||
|
[m deleteCharactersInRange: r];
|
||||||
|
tmp = m;
|
||||||
|
override = @"subclass";
|
||||||
|
}
|
||||||
|
} while (r.length > 0);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
r = [tmp rangeOfString: @"<override-never>"];
|
||||||
|
if (r.length > 0)
|
||||||
|
{
|
||||||
|
if (m == nil)
|
||||||
|
{
|
||||||
|
m = [tmp mutableCopy];
|
||||||
|
}
|
||||||
|
[m deleteCharactersInRange: r];
|
||||||
|
tmp = m;
|
||||||
|
override = @"never";
|
||||||
|
}
|
||||||
|
} while (r.length > 0);
|
||||||
|
r = [tmp rangeOfString: @"<standards>"];
|
||||||
|
if (r.length > 0)
|
||||||
|
{
|
||||||
|
unsigned i = r.location;
|
||||||
|
|
||||||
|
r = NSMakeRange(i, [tmp length] - i);
|
||||||
|
r = [tmp rangeOfString: @"</standards>"
|
||||||
|
options: NSLiteralSearch
|
||||||
|
range: r];
|
||||||
|
if (r.length > 0)
|
||||||
|
{
|
||||||
|
r = NSMakeRange(i, NSMaxRange(r) - i);
|
||||||
|
standards = [tmp substringWithRange: r];
|
||||||
|
if (m == nil)
|
||||||
|
{
|
||||||
|
m = [tmp mutableCopy];
|
||||||
|
}
|
||||||
|
[m deleteCharactersInRange: r];
|
||||||
|
tmp = m;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSLog(@"unterminated <standards> in comment for %@", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m != nil)
|
||||||
|
{
|
||||||
|
RELEASE(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[str appendString: @" <method type=\""];
|
||||||
|
[str appendString: [d objectForKey: @"ReturnType"]];
|
||||||
|
if ([name hasPrefix: @"+"] == YES)
|
||||||
|
{
|
||||||
|
[str appendString: @"\" factory=\"yes"];
|
||||||
|
}
|
||||||
|
if (isInitialiser == YES)
|
||||||
|
{
|
||||||
|
[str appendString: @"\" init=\"yes"];
|
||||||
|
}
|
||||||
|
if (override != nil)
|
||||||
|
{
|
||||||
|
[str appendString: @"\" override=\""];
|
||||||
|
[str appendString: override];
|
||||||
|
}
|
||||||
|
[str appendString: @"\">\n"];
|
||||||
|
|
||||||
|
for (i = 0; i < [sels count]; i++)
|
||||||
|
{
|
||||||
|
[str appendString: @" <sel>"];
|
||||||
|
[str appendString: [sels objectAtIndex: i]];
|
||||||
|
[str appendString: @"</sel>\n"];
|
||||||
|
if (i < [args count])
|
||||||
|
{
|
||||||
|
[str appendString: @" <arg type=\""];
|
||||||
|
[str appendString: [types objectAtIndex: i]];
|
||||||
|
[str appendString: @"\">"];
|
||||||
|
[str appendString: [args objectAtIndex: i]];
|
||||||
|
[str appendString: @"</arg>\n"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[str appendString: @" <desc>\n"];
|
||||||
|
tmp = [d objectForKey: @"Comment"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[self reformat: tmp withIndent: 12 to: str];
|
||||||
|
}
|
||||||
|
[str appendString: @" </desc>\n"];
|
||||||
|
if (standards != nil)
|
||||||
|
{
|
||||||
|
[self reformat: standards withIndent: 10 to: str];
|
||||||
|
}
|
||||||
|
[str appendString: @" </method>\n"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) outputUnit: (NSDictionary*)d to: (NSMutableString*)str
|
||||||
|
{
|
||||||
|
NSString *name = [d objectForKey: @"Name"];
|
||||||
|
NSString *type = [d objectForKey: @"Type"];
|
||||||
|
NSDictionary *methods = [d objectForKey: @"Methods"];
|
||||||
|
NSArray *names;
|
||||||
|
NSArray *protocols;
|
||||||
|
NSString *tmp;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
[str appendString: @" <chapter>\n"];
|
||||||
|
|
||||||
|
[str appendString: @" <heading>"];
|
||||||
|
[str appendString: @"Software documentation for the "];
|
||||||
|
[str appendString: name];
|
||||||
|
[str appendString: @" "];
|
||||||
|
[str appendString: type];
|
||||||
|
[str appendString: @"</heading>\n"];
|
||||||
|
|
||||||
|
[str appendString: @" <"];
|
||||||
|
[str appendString: type];
|
||||||
|
[str appendString: @" name=\""];
|
||||||
|
if ([type isEqual: @"category"] == YES)
|
||||||
|
{
|
||||||
|
[str appendString: [d objectForKey: @"Category"]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[str appendString: name];
|
||||||
|
}
|
||||||
|
tmp = [d objectForKey: @"BaseClass"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
if ([type isEqual: @"class"] == YES)
|
||||||
|
{
|
||||||
|
[str appendString: @"\" super=\""];
|
||||||
|
}
|
||||||
|
else if ([type isEqual: @"category"] == YES)
|
||||||
|
{
|
||||||
|
[str appendString: @"\" class=\""];
|
||||||
|
}
|
||||||
|
[str appendString: tmp];
|
||||||
|
}
|
||||||
|
[str appendString: @"\">\n"];
|
||||||
|
|
||||||
|
[str appendString: @" <declared>"];
|
||||||
|
[str appendString: [d objectForKey: @"Declared"]];
|
||||||
|
[str appendString: @"</declared>\n"];
|
||||||
|
|
||||||
|
protocols = [d objectForKey: @"Protocols"];
|
||||||
|
if ([protocols count] > 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < [protocols count]; i++)
|
||||||
|
{
|
||||||
|
[str appendString: @" <conform>"];
|
||||||
|
[str appendString: [protocols objectAtIndex: i]];
|
||||||
|
[str appendString: @"</conform>\n"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[str appendString: @" <desc>\n"];
|
||||||
|
tmp = [d objectForKey: @"Comment"];
|
||||||
|
if (tmp != nil)
|
||||||
|
{
|
||||||
|
[self reformat: tmp withIndent: 10 to: str];
|
||||||
|
}
|
||||||
|
[str appendString: @" </desc>\n"];
|
||||||
|
|
||||||
|
names = [[methods allKeys] sortedArrayUsingSelector: @selector(compare:)];
|
||||||
|
for (i = 0; i < [names count]; i++)
|
||||||
|
{
|
||||||
|
NSString *mName = [names objectAtIndex: i];
|
||||||
|
|
||||||
|
[self outputMethod: [methods objectForKey: mName] to: str];
|
||||||
|
}
|
||||||
|
|
||||||
|
[str appendString: @" </"];
|
||||||
|
[str appendString: type];
|
||||||
|
[str appendString: @">\n"];
|
||||||
|
[str appendString: @" </chapter>\n"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) reformat: (NSString*)str
|
||||||
|
withIndent: (unsigned)ind
|
||||||
|
to: (NSMutableString*)buf
|
||||||
|
{
|
||||||
|
CREATE_AUTORELEASE_POOL(arp);
|
||||||
|
unsigned l = [str length];
|
||||||
|
NSRange r = NSMakeRange(0, l);
|
||||||
|
unsigned i = 0;
|
||||||
|
NSArray *a;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Split out <example>...</example> sequences and output them literally.
|
||||||
|
* All other text has reformatting applied as necessary.
|
||||||
|
*/
|
||||||
|
r = [str rangeOfString: @"<example"];
|
||||||
|
while (r.length > 0)
|
||||||
|
{
|
||||||
|
NSString *tmp;
|
||||||
|
|
||||||
|
if (r.location > i)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* There was some text before the example - call this method
|
||||||
|
* recursively to format and output it.
|
||||||
|
*/
|
||||||
|
tmp = [str substringWithRange: NSMakeRange(i, r.location - i)];
|
||||||
|
[self reformat: str withIndent: ind to: buf];
|
||||||
|
i = r.location;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Now find the end of the exmple, and output the whole example
|
||||||
|
* literally as it appeared in the comment.
|
||||||
|
*/
|
||||||
|
r = [str rangeOfString: @"</example>"
|
||||||
|
options: NSLiteralSearch
|
||||||
|
range: NSMakeRange(i, l - i)];
|
||||||
|
if (r.length == 0)
|
||||||
|
{
|
||||||
|
NSLog(@"unterminated <example>");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tmp = [str substringWithRange: NSMakeRange(i, NSMaxRange(r) - i)];
|
||||||
|
[buf appendString: tmp];
|
||||||
|
[buf appendString: @"\n"];
|
||||||
|
/*
|
||||||
|
* Set up the start location and search for another example so
|
||||||
|
* we will loop round again if necessary.
|
||||||
|
*/
|
||||||
|
i = NSMaxRange(r);
|
||||||
|
r = [str rangeOfString: @"<example"
|
||||||
|
options: NSLiteralSearch
|
||||||
|
range: NSMakeRange(i, l - i)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If part of the string has already been consumed, just use
|
||||||
|
* the remaining substring.
|
||||||
|
*/
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
str = [str substringWithRange: NSMakeRange(i, l - i)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Split the string up into parts separated by newlines.
|
||||||
|
*/
|
||||||
|
a = [self split: str];
|
||||||
|
for (i = 0; i < [a count]; i++)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
str = [a objectAtIndex: i];
|
||||||
|
|
||||||
|
if ([str hasPrefix: @"</"] == YES)
|
||||||
|
{
|
||||||
|
if (ind > 2)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* decrement indentation after the end of an element.
|
||||||
|
*/
|
||||||
|
ind -= 2;
|
||||||
|
}
|
||||||
|
for (j = 0; j < ind; j++)
|
||||||
|
{
|
||||||
|
[buf appendString: @" "];
|
||||||
|
}
|
||||||
|
[buf appendString: str];
|
||||||
|
[buf appendString: @"\n"];
|
||||||
|
}
|
||||||
|
else if ([str hasPrefix: @"<"] == YES && [str hasSuffix: @"/>"] == NO)
|
||||||
|
{
|
||||||
|
unsigned size = ind + [str length];
|
||||||
|
unsigned nest = 0;
|
||||||
|
BOOL addSpace;
|
||||||
|
|
||||||
|
for (j = 0; j < ind; j++)
|
||||||
|
{
|
||||||
|
[buf appendString: @" "];
|
||||||
|
}
|
||||||
|
[buf appendString: str];
|
||||||
|
addSpace = ([str hasPrefix: @"<"] == YES) ? NO : YES;
|
||||||
|
for (j = i + 1; size <= 70 && j < [a count]; j++)
|
||||||
|
{
|
||||||
|
NSString *t = [a objectAtIndex: j];
|
||||||
|
|
||||||
|
size += [t length];
|
||||||
|
if ([t hasPrefix: @"</"] == YES)
|
||||||
|
{
|
||||||
|
if (nest == 0)
|
||||||
|
{
|
||||||
|
break; // End of element reached.
|
||||||
|
}
|
||||||
|
nest--;
|
||||||
|
}
|
||||||
|
else if ([t hasPrefix: @"<"] == YES)
|
||||||
|
{
|
||||||
|
addSpace = NO;
|
||||||
|
if ([t hasSuffix: @"/>"] == NO)
|
||||||
|
{
|
||||||
|
nest++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (addSpace == YES)
|
||||||
|
{
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
addSpace = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (size > 70)
|
||||||
|
{
|
||||||
|
ind += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addSpace = ([str hasPrefix: @"<"] == YES) ? NO : YES;
|
||||||
|
for (j = i + 1; j < [a count]; j++)
|
||||||
|
{
|
||||||
|
NSString *t = [a objectAtIndex: j];
|
||||||
|
|
||||||
|
if ([t hasPrefix: @"</"] == YES)
|
||||||
|
{
|
||||||
|
[buf appendString: t];
|
||||||
|
if (nest == 0)
|
||||||
|
{
|
||||||
|
break; // End of element reached.
|
||||||
|
}
|
||||||
|
nest--;
|
||||||
|
}
|
||||||
|
else if ([t hasPrefix: @"<"] == YES)
|
||||||
|
{
|
||||||
|
[buf appendString: t];
|
||||||
|
addSpace = NO;
|
||||||
|
if ([t hasSuffix: @"/>"] == NO)
|
||||||
|
{
|
||||||
|
nest++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (addSpace == YES)
|
||||||
|
{
|
||||||
|
[buf appendString: @" "];
|
||||||
|
}
|
||||||
|
[buf appendString: t];
|
||||||
|
addSpace = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = j;
|
||||||
|
}
|
||||||
|
[buf appendString: @"\n"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned size = ind + [str length];
|
||||||
|
unsigned nest = 0;
|
||||||
|
unsigned lastOk = i;
|
||||||
|
BOOL addSpace;
|
||||||
|
|
||||||
|
for (j = 0; j < ind; j++)
|
||||||
|
{
|
||||||
|
[buf appendString: @" "];
|
||||||
|
}
|
||||||
|
[buf appendString: str];
|
||||||
|
addSpace = ([str hasPrefix: @"<"] == YES) ? NO : YES;
|
||||||
|
for (j = i + 1; size <= 70 && j < [a count]; j++)
|
||||||
|
{
|
||||||
|
NSString *t = [a objectAtIndex: j];
|
||||||
|
|
||||||
|
size += [t length];
|
||||||
|
if ([t hasPrefix: @"</"] == YES)
|
||||||
|
{
|
||||||
|
if (nest == 0)
|
||||||
|
{
|
||||||
|
break; // End of element reached.
|
||||||
|
}
|
||||||
|
nest--;
|
||||||
|
}
|
||||||
|
else if ([t hasPrefix: @"<"] == YES)
|
||||||
|
{
|
||||||
|
addSpace = NO;
|
||||||
|
if ([t hasSuffix: @"/>"] == NO)
|
||||||
|
{
|
||||||
|
nest++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (addSpace == YES)
|
||||||
|
{
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
addSpace = YES;
|
||||||
|
}
|
||||||
|
if (nest == 0 && size <= 70)
|
||||||
|
{
|
||||||
|
lastOk = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lastOk > i)
|
||||||
|
{
|
||||||
|
addSpace = ([str hasPrefix: @"<"] == YES) ? NO : YES;
|
||||||
|
for (j = i + 1; j <= lastOk; j++)
|
||||||
|
{
|
||||||
|
NSString *t = [a objectAtIndex: j];
|
||||||
|
|
||||||
|
if ([t hasPrefix: @"</"] == YES)
|
||||||
|
{
|
||||||
|
[buf appendString: t];
|
||||||
|
}
|
||||||
|
else if ([t hasPrefix: @"<"] == YES)
|
||||||
|
{
|
||||||
|
[buf appendString: t];
|
||||||
|
addSpace = NO;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (addSpace == YES)
|
||||||
|
{
|
||||||
|
[buf appendString: @" "];
|
||||||
|
}
|
||||||
|
[buf appendString: t];
|
||||||
|
addSpace = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = lastOk;
|
||||||
|
}
|
||||||
|
[buf appendString: @"\n"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RELEASE(arp);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray*) split: (NSString*)str
|
||||||
|
{
|
||||||
|
NSMutableArray *a = [NSMutableArray arrayWithCapacity: 128];
|
||||||
|
unsigned l = [str length];
|
||||||
|
NSMutableData *data;
|
||||||
|
unichar *ptr;
|
||||||
|
unichar *end;
|
||||||
|
unichar *buf;
|
||||||
|
|
||||||
|
data = [[NSMutableData alloc] initWithLength: l * sizeof(unichar)];
|
||||||
|
ptr = buf = [data mutableBytes];
|
||||||
|
[str getCharacters: buf];
|
||||||
|
end = buf + l;
|
||||||
|
while (ptr < end)
|
||||||
|
{
|
||||||
|
if ([spacenl characterIsMember: *ptr] == YES)
|
||||||
|
{
|
||||||
|
if (ptr != buf)
|
||||||
|
{
|
||||||
|
NSString *tmp;
|
||||||
|
|
||||||
|
tmp = [NSString stringWithCharacters: buf length: ptr - buf];
|
||||||
|
[a addObject: tmp];
|
||||||
|
buf = ptr;
|
||||||
|
}
|
||||||
|
ptr++;
|
||||||
|
buf++;
|
||||||
|
}
|
||||||
|
else if (*ptr == '<')
|
||||||
|
{
|
||||||
|
BOOL elideSpace = YES;
|
||||||
|
unichar *optr = ptr;
|
||||||
|
|
||||||
|
if (ptr != buf)
|
||||||
|
{
|
||||||
|
NSString *tmp;
|
||||||
|
|
||||||
|
tmp = [NSString stringWithCharacters: buf length: ptr - buf];
|
||||||
|
[a addObject: tmp];
|
||||||
|
buf = ptr;
|
||||||
|
}
|
||||||
|
while (ptr < end && *ptr != '>')
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We convert whitespace sequences inside element markup
|
||||||
|
* to single space characters unless protected by quotes.
|
||||||
|
*/
|
||||||
|
if ([spacenl characterIsMember: *ptr] == YES)
|
||||||
|
{
|
||||||
|
if (elideSpace == NO)
|
||||||
|
{
|
||||||
|
*optr++ = ' ';
|
||||||
|
elideSpace = YES;
|
||||||
|
}
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
else if (*ptr == '"')
|
||||||
|
{
|
||||||
|
while (ptr < end && *ptr != '"')
|
||||||
|
{
|
||||||
|
*optr++ = *ptr++;
|
||||||
|
}
|
||||||
|
if (ptr < end)
|
||||||
|
{
|
||||||
|
*optr++ = *ptr++;
|
||||||
|
}
|
||||||
|
elideSpace = NO;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*optr++ = *ptr++;
|
||||||
|
elideSpace = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*ptr == '>')
|
||||||
|
{
|
||||||
|
*optr++ = *ptr++;
|
||||||
|
}
|
||||||
|
if (optr != buf)
|
||||||
|
{
|
||||||
|
NSString *tmp;
|
||||||
|
|
||||||
|
tmp = [NSString stringWithCharacters: buf length: ptr - buf];
|
||||||
|
[a addObject: tmp];
|
||||||
|
}
|
||||||
|
buf = ptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ptr != buf)
|
||||||
|
{
|
||||||
|
NSString *tmp;
|
||||||
|
|
||||||
|
tmp = [NSString stringWithCharacters: buf length: ptr - buf];
|
||||||
|
[a addObject: tmp];
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
84
Tools/AGSParser.h
Normal file
84
Tools/AGSParser.h
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
<title>AGSParser ... a tool to get documention info from ObjC source</title>
|
||||||
|
Copyright (C) <copy>2001 Free Software Foundation, Inc.</copy>
|
||||||
|
|
||||||
|
<author name="Richard Frith-Macdonald"></author> <richard@brainstorm.co.uk>
|
||||||
|
Created: October 2001
|
||||||
|
|
||||||
|
This file is part of the GNUstep Project
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License along with this library; see the file COPYING.LIB.
|
||||||
|
If not, write to the Free Software Foundation,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
<abstract>
|
||||||
|
This is the AGSParser class ... and some autogsdoc examples.
|
||||||
|
</abstract>
|
||||||
|
<front>
|
||||||
|
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.
|
||||||
|
</front>
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@interface AGSParser : NSObject
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The following items are used for logging/debug purposes.
|
||||||
|
*/
|
||||||
|
NSString *fileName; // Not retained - file being parsed.
|
||||||
|
NSString *unitName; // Not retained - unit being parsed.
|
||||||
|
NSString *itemName; // Not retained - item being parsed.
|
||||||
|
NSArray *lines; // Not retained - line number mapping.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The next few ivars represent the data currently being parsed.
|
||||||
|
*/
|
||||||
|
unichar *buffer;
|
||||||
|
unsigned length;
|
||||||
|
unsigned pos;
|
||||||
|
BOOL commentsRead;
|
||||||
|
|
||||||
|
NSString *comment; // Documentation accumulator.
|
||||||
|
NSMutableDictionary *info; // All information parsed.
|
||||||
|
|
||||||
|
NSCharacterSet *identifier; // Legit char in identifier
|
||||||
|
NSCharacterSet *identStart; // Legit initial char of identifier
|
||||||
|
NSCharacterSet *spaces; // All blank characters
|
||||||
|
NSCharacterSet *spacenl; // Blanks excluding newline
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary*) info;
|
||||||
|
- (id) init; /** <init> Simple initialiser */
|
||||||
|
- (NSMutableDictionary*) parseFile: (NSString*)name isSource: (BOOL)isSource;
|
||||||
|
- (NSString*) parseIdentifier;
|
||||||
|
- (NSMutableDictionary*) parseImplementation;
|
||||||
|
- (NSMutableDictionary*) parseInterface;
|
||||||
|
- (NSMutableDictionary*) parseInstanceVariables;
|
||||||
|
- (NSMutableDictionary*) parseMethodIsDeclaration: (BOOL)flag;
|
||||||
|
- (NSMutableDictionary*) parseMethodsAreDeclarations: (BOOL)flag;
|
||||||
|
- (NSString*) parseMethodType;
|
||||||
|
- (NSMutableDictionary*) parseProtocol;
|
||||||
|
- (NSMutableArray*) parseProtocolList;
|
||||||
|
- (void) reset;
|
||||||
|
- (void) setupBuffer;
|
||||||
|
- (unsigned) skipBlock;
|
||||||
|
- (unsigned) skipComment;
|
||||||
|
- (unsigned) skipLiteral;
|
||||||
|
- (unsigned) skipRemainderOfLine;
|
||||||
|
- (unsigned) skipSpaces;
|
||||||
|
- (unsigned) skipStatement;
|
||||||
|
- (unsigned) skipStatementLine;
|
||||||
|
- (unsigned) skipUnit;
|
||||||
|
- (unsigned) skipWhiteSpace;
|
||||||
|
@end
|
||||||
|
|
1740
Tools/AGSParser.m
Normal file
1740
Tools/AGSParser.m
Normal file
File diff suppressed because it is too large
Load diff
|
@ -40,13 +40,14 @@ doctemplatesdir = $(GNUSTEP_RESOURCES)/DocTemplates
|
||||||
DOCTEMPLATES_FILES = indextemplate.gsdoc AutoDocTemplate.gsdoc
|
DOCTEMPLATES_FILES = indextemplate.gsdoc AutoDocTemplate.gsdoc
|
||||||
|
|
||||||
# The application to be compiled
|
# The application to be compiled
|
||||||
TOOL_NAME = gdnc gsdoc defaults plmerge \
|
TOOL_NAME = autogsdoc gdnc gsdoc defaults plmerge \
|
||||||
plparse sfparse pldes plser
|
plparse sfparse pldes plser
|
||||||
CTOOL_NAME = gdomap
|
CTOOL_NAME = gdomap
|
||||||
|
|
||||||
TEST_TOOL_NAME = locale_alias
|
TEST_TOOL_NAME = locale_alias
|
||||||
|
|
||||||
# The source files to be compiled
|
# The source files to be compiled
|
||||||
|
autogsdoc_OBJC_FILES = autogsdoc.m AGSParser.m AGSOutput.m
|
||||||
gdomap_C_FILES = gdomap.c
|
gdomap_C_FILES = gdomap.c
|
||||||
gdnc_OBJC_FILES = gdnc.m
|
gdnc_OBJC_FILES = gdnc.m
|
||||||
gsdoc_OBJC_FILES = gsdoc.m
|
gsdoc_OBJC_FILES = gsdoc.m
|
||||||
|
|
278
Tools/autogsdoc.m
Normal file
278
Tools/autogsdoc.m
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
/** This tool produces gsdoc files from source files.
|
||||||
|
|
||||||
|
<title>Autogsdoc ... a tool to make documentation from source code</title>
|
||||||
|
Copyright <copy>(C) 2001 Free Software Foundation, Inc.</copy>
|
||||||
|
|
||||||
|
Written by: <author name="Richard Frith-Macdonald">
|
||||||
|
<email>richard@brainstorm.co.uk</email></author>
|
||||||
|
Created: October 2001
|
||||||
|
|
||||||
|
This file is part of the GNUstep Project
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public
|
||||||
|
License along with this library; see the file COPYING.LIB.
|
||||||
|
If not, write to the Free Software Foundation,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
<chapter>
|
||||||
|
<heading>The autogsdoc tool</heading>
|
||||||
|
<p>
|
||||||
|
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 in the source.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The simple way to use 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 saem directory, and produce
|
||||||
|
gsdoc files as output.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
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.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Any comment beginning with slash and <em>two</em> asterisks rathr than
|
||||||
|
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.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
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
|
||||||
|
placed into appropriate locations in the output document -
|
||||||
|
</p>
|
||||||
|
<list>
|
||||||
|
<item><strong><abstract></strong>
|
||||||
|
An abstract of the content of the document ... placed in the head
|
||||||
|
of the gsdoc output.
|
||||||
|
</item>
|
||||||
|
<item><strong><author></strong>
|
||||||
|
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.
|
||||||
|
</item>
|
||||||
|
<item><strong><back></strong>
|
||||||
|
Placed in the gsdoc output just before the end of the body of the
|
||||||
|
document - intended to be used for appendices, index etc.
|
||||||
|
</item>
|
||||||
|
<item><strong><chapter></strong>
|
||||||
|
Placed immediately before any generated class documentation ...
|
||||||
|
intended to be used to provide overall description of how the
|
||||||
|
code bing documented works.
|
||||||
|
</item>
|
||||||
|
<item><strong><copy></strong>
|
||||||
|
Copyright of the content of the document ... placed in the head
|
||||||
|
of the gsdoc output.
|
||||||
|
</item>
|
||||||
|
<item><strong><date></strong>
|
||||||
|
Date off the revision of the document ... placed in the head
|
||||||
|
of the gsdoc output. If this is omitted the tool will try to
|
||||||
|
construct a value from the RCS Date tag (if available).
|
||||||
|
</item>
|
||||||
|
<item><strong><front></strong>
|
||||||
|
Inserted into the document at the start of the body ... intended
|
||||||
|
to provide for introduction or contents pages etc.
|
||||||
|
</item>
|
||||||
|
<item><strong><title></strong>
|
||||||
|
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.
|
||||||
|
</item>
|
||||||
|
<item><strong><version></strong>
|
||||||
|
Version identifier of the document ... placed in the head
|
||||||
|
of the gsdoc output. If this is omitted the tool will try to
|
||||||
|
construct a value from the RCS Revision tag (if available).
|
||||||
|
</item>
|
||||||
|
</list>
|
||||||
|
<p>
|
||||||
|
In comments being used to provide text for a method description, the
|
||||||
|
following markup is removed from the text and handled specially -
|
||||||
|
</p>
|
||||||
|
<list>
|
||||||
|
<item><strong><init></strong>
|
||||||
|
The method is marked as being the designated initialiser for the class.
|
||||||
|
</item>
|
||||||
|
<item><strong><override-subclass></strong>
|
||||||
|
The method is marked as being one which subclasses must override
|
||||||
|
(eg an abstract method).
|
||||||
|
</item>
|
||||||
|
<item><strong><override-never></strong>
|
||||||
|
The method is marked as being one which subclasses should <em>NOT</em>
|
||||||
|
override.
|
||||||
|
</item>
|
||||||
|
<item><strong><standards> ... </standards></strong>
|
||||||
|
The markup is removed from the description and placed <em>after</em>
|
||||||
|
it in the gsdoc output - so that the method is described as
|
||||||
|
conforming (or not conforming) to the specified standards.
|
||||||
|
</item>
|
||||||
|
</list>
|
||||||
|
<p>
|
||||||
|
The tools accepts certain user defaults (which can of course be
|
||||||
|
supplied as command-line arguments as usual) -
|
||||||
|
</p>
|
||||||
|
<list>
|
||||||
|
<item><strong>DocumentationDirectory</strong>
|
||||||
|
May be used to specify the directory in which generated
|
||||||
|
gsdoc files are to be placed. If this is not set, output
|
||||||
|
is placed in thge same directory as the source files.
|
||||||
|
</item>
|
||||||
|
<item><strong>SourceDirectory</strong>
|
||||||
|
May be used to specify the directory in which the tool looks
|
||||||
|
for source files. If this is not set, the tool looks for the
|
||||||
|
source in the same directory as the header files named on the
|
||||||
|
command line.
|
||||||
|
</item>
|
||||||
|
</list>
|
||||||
|
</chapter>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AGSParser.h"
|
||||||
|
#include "AGSOutput.h"
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv, char **env)
|
||||||
|
{
|
||||||
|
NSProcessInfo *proc;
|
||||||
|
NSArray *args;
|
||||||
|
unsigned i;
|
||||||
|
NSUserDefaults *defs;
|
||||||
|
NSFileManager *mgr;
|
||||||
|
NSString *documentationDirectory;
|
||||||
|
NSString *sourceDirectory;
|
||||||
|
AGSParser *parser;
|
||||||
|
AGSOutput *output;
|
||||||
|
CREATE_AUTORELEASE_POOL(pool);
|
||||||
|
|
||||||
|
#ifdef GS_PASS_ARGUMENTS
|
||||||
|
[NSProcessInfo initializeWithArguments: argv count: argc environment: env];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
defs = [NSUserDefaults standardUserDefaults];
|
||||||
|
[defs registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
@"Yes", @"Monolithic", nil]];
|
||||||
|
|
||||||
|
sourceDirectory = [defs stringForKey: @"SourceDirectory"];
|
||||||
|
documentationDirectory = [defs stringForKey: @"DocumentationDirectory"];
|
||||||
|
|
||||||
|
proc = [NSProcessInfo processInfo];
|
||||||
|
if (proc == nil)
|
||||||
|
{
|
||||||
|
NSLog(@"unable to get process information!");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mgr = [NSFileManager defaultManager];
|
||||||
|
|
||||||
|
parser = [AGSParser new];
|
||||||
|
output = [AGSOutput new];
|
||||||
|
|
||||||
|
args = [proc arguments];
|
||||||
|
for (i = 1; i < [args count]; i++)
|
||||||
|
{
|
||||||
|
NSString *arg = [args objectAtIndex: i];
|
||||||
|
|
||||||
|
if ([arg hasPrefix: @"-"])
|
||||||
|
{
|
||||||
|
i++; // Skip next value ... it is a default.
|
||||||
|
}
|
||||||
|
else if ([arg hasSuffix: @".h"])
|
||||||
|
{
|
||||||
|
NSString *ddir;
|
||||||
|
NSString *sdir;
|
||||||
|
NSString *file;
|
||||||
|
|
||||||
|
file = [[arg lastPathComponent] stringByDeletingPathExtension];
|
||||||
|
|
||||||
|
if (sourceDirectory == nil)
|
||||||
|
{
|
||||||
|
sdir = [arg stringByDeletingLastPathComponent];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sdir = sourceDirectory;
|
||||||
|
}
|
||||||
|
sdir = [sdir stringByAppendingPathComponent: file];
|
||||||
|
sdir = [sdir stringByAppendingPathExtension: @"m"];
|
||||||
|
|
||||||
|
if (documentationDirectory == nil)
|
||||||
|
{
|
||||||
|
ddir = [arg stringByDeletingLastPathComponent];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ddir = documentationDirectory;
|
||||||
|
}
|
||||||
|
ddir = [ddir stringByAppendingPathComponent: file];
|
||||||
|
ddir = [ddir stringByAppendingPathExtension: @"gsdoc"];
|
||||||
|
|
||||||
|
if ([mgr isReadableFileAtPath: arg] == NO)
|
||||||
|
{
|
||||||
|
NSLog(@"No readable header at '%@' ... skipping", arg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
[parser reset];
|
||||||
|
[parser parseFile: arg isSource: NO];
|
||||||
|
|
||||||
|
if ([mgr isReadableFileAtPath: sdir] == YES)
|
||||||
|
{
|
||||||
|
[parser parseFile: sdir isSource: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
[output output: [parser info] file: ddir];
|
||||||
|
}
|
||||||
|
else if ([arg hasSuffix: @".m"])
|
||||||
|
{
|
||||||
|
NSString *ddir;
|
||||||
|
NSString *file;
|
||||||
|
|
||||||
|
file = [[arg lastPathComponent] stringByDeletingPathExtension];
|
||||||
|
|
||||||
|
if (documentationDirectory == nil)
|
||||||
|
{
|
||||||
|
ddir = [arg stringByDeletingLastPathComponent];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ddir = documentationDirectory;
|
||||||
|
}
|
||||||
|
ddir = [ddir stringByAppendingPathComponent: file];
|
||||||
|
ddir = [ddir stringByAppendingPathExtension: @"gsdoc"];
|
||||||
|
|
||||||
|
if ([mgr isReadableFileAtPath: arg] == NO)
|
||||||
|
{
|
||||||
|
NSLog(@"No readable file at '%@' ... skipping", arg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we have been given a '.m' file, we assume that it contains
|
||||||
|
* interface details to be exported ... so we parse it first as
|
||||||
|
* if it were a header file, and then again as a source file.
|
||||||
|
*/
|
||||||
|
[parser reset];
|
||||||
|
[parser parseFile: arg isSource: NO];
|
||||||
|
[parser parseFile: arg isSource: YES];
|
||||||
|
|
||||||
|
[output output: [parser info] file: ddir];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSLog(@"Unknown argument '%@' ... ignored", arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RELEASE(pool);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue