Implement support for 'standatrds' markup.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@11811 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2001-12-18 15:49:59 +00:00
parent 92cb1fb37b
commit e1a0d02d21
5 changed files with 251 additions and 8 deletions

View file

@ -1,3 +1,14 @@
2001-12-18 Richard Frith-Macdonald <rfm@gnu.org>
* Tools/AGSHtml.m: Fix 'standards' output.
* Tools/AGSOutput.m: Add 'standards' support for class, category,
and protocol. Use new standards info from parser.
* Tools/AGSParser.h: New method to set current standards.
* Tools/AGSParser.m: Implement simplistic parsing of preprocessor
conditionals to set current standards based on STRICT_MACOS_X,
STRICT_OPENSTEP, and NO_GNUSTEP. The presence of <standards>
markup in the comments still takes precedence over this mechanism.
2001-12-18 Richard Frith-Macdonald <rfm@gnu.org> 2001-12-18 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSXML.m: Bugfixes in setting parse behavior ... now turns * Source/GSXML.m: Bugfixes in setting parse behavior ... now turns

View file

@ -975,7 +975,7 @@ NSLog(@"Element '%@' not implemented", name); // FIXME
children = [node next]; children = [node next];
if ([[children name] isEqual: @"standards"]) if ([[children name] isEqual: @"standards"])
{ {
tmp = [node children]; tmp = [children children];
if (tmp != nil) if (tmp != nil)
{ {
[buf appendString: indent]; [buf appendString: indent];
@ -1515,7 +1515,7 @@ NSLog(@"Element '%@' not implemented", name); // FIXME
} }
if (node != nil && [[node name] isEqual: @"standards"] == YES) if (node != nil && [[node name] isEqual: @"standards"] == YES)
{ {
GSXMLNode *tmp = node; GSXMLNode *tmp = [node children];
if (tmp != nil) if (tmp != nil)
{ {

View file

@ -538,6 +538,10 @@ static BOOL snuggleStart(NSString *t)
AUTORELEASE(m); AUTORELEASE(m);
} }
} }
if (standards == nil)
{
standards = [d objectForKey: @"Standards"];
}
[str appendString: @" <method type=\""]; [str appendString: @" <method type=\""];
[str appendString: escapeType([d objectForKey: @"ReturnType"])]; [str appendString: escapeType([d objectForKey: @"ReturnType"])];
@ -597,6 +601,7 @@ static BOOL snuggleStart(NSString *t)
NSString *comment = [d objectForKey: @"Comment"]; NSString *comment = [d objectForKey: @"Comment"];
NSArray *names; NSArray *names;
NSArray *protocols; NSArray *protocols;
NSString *standards = nil;
NSString *tmp; NSString *tmp;
NSString *unit; NSString *unit;
NSRange r; NSRange r;
@ -604,6 +609,36 @@ static BOOL snuggleStart(NSString *t)
unsigned i; unsigned i;
unsigned j; unsigned j;
r = [comment rangeOfString: @"<standards>"];
if (comment != nil && r.length > 0)
{
unsigned i = r.location;
r = NSMakeRange(i, [comment length] - i);
r = [comment rangeOfString: @"</standards>"
options: NSLiteralSearch
range: r];
if (r.length > 0)
{
NSMutableString *m;
r = NSMakeRange(i, NSMaxRange(r) - i);
standards = [comment substringWithRange: r];
m = [comment mutableCopy];
[m deleteCharactersInRange: r];
comment = m;
AUTORELEASE(m);
}
else
{
NSLog(@"unterminated <standards> in comment for %@", name);
}
}
if (standards == nil)
{
standards = [d objectForKey: @"Standards"];
}
/* /*
* Make sure we have a 'unit' part and a class 'desc' part (comment) * Make sure we have a 'unit' part and a class 'desc' part (comment)
* to be output. * to be output.
@ -744,6 +779,10 @@ static BOOL snuggleStart(NSString *t)
[self outputMethod: [methods objectForKey: mName] to: str]; [self outputMethod: [methods objectForKey: mName] to: str];
} }
if (standards != nil)
{
[self reformat: standards withIndent: ind to: str];
}
ind -= 2; ind -= 2;
for (j = 0; j < ind; j++) [str appendString: @" "]; for (j = 0; j < ind; j++) [str appendString: @" "];
[str appendString: @"</"]; [str appendString: @"</"];

View file

@ -56,6 +56,7 @@
unsigned pos; unsigned pos;
BOOL commentsRead; BOOL commentsRead;
NSString *declared; // Where classes were declared. NSString *declared; // Where classes were declared.
NSMutableArray *ifStack; // track preprocessor conditionals.
NSString *comment; // Documentation accumulator. NSString *comment; // Documentation accumulator.
NSMutableDictionary *info; // All information parsed. NSMutableDictionary *info; // All information parsed.
@ -84,11 +85,13 @@
- (unsigned) skipBlock; - (unsigned) skipBlock;
- (unsigned) skipComment; - (unsigned) skipComment;
- (unsigned) skipLiteral; - (unsigned) skipLiteral;
- (unsigned) skipPreprocessor;
- (unsigned) skipRemainderOfLine; - (unsigned) skipRemainderOfLine;
- (unsigned) skipSpaces; - (unsigned) skipSpaces;
- (unsigned) skipStatement; - (unsigned) skipStatement;
- (unsigned) skipStatementLine; - (unsigned) skipStatementLine;
- (unsigned) skipUnit; - (unsigned) skipUnit;
- (unsigned) skipWhiteSpace; - (unsigned) skipWhiteSpace;
- (void) setStandards: (NSMutableDictionary*)dict;
@end @end
#endif #endif

View file

@ -26,6 +26,7 @@
- (void) dealloc - (void) dealloc
{ {
DESTROY(ifStack);
DESTROY(declared); DESTROY(declared);
DESTROY(info); DESTROY(info);
DESTROY(comment); DESTROY(comment);
@ -56,6 +57,7 @@
identStart = RETAIN([NSCharacterSet characterSetWithCharactersInString: identStart = RETAIN([NSCharacterSet characterSetWithCharactersInString:
@"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]); @"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]);
info = [[NSMutableDictionary alloc] initWithCapacity: 6]; info = [[NSMutableDictionary alloc] initWithCapacity: 6];
ifStack = [[NSMutableArray alloc] initWithCapacity: 4];
return self; return self;
} }
@ -146,7 +148,7 @@
* Some preprocessor directive ... must be on one line ... skip * Some preprocessor directive ... must be on one line ... skip
* past it and delete any comment accumulated while doing so. * past it and delete any comment accumulated while doing so.
*/ */
[self skipRemainderOfLine]; [self skipPreprocessor];
DESTROY(comment); DESTROY(comment);
break; break;
@ -352,6 +354,7 @@ fail:
unitName = name; unitName = name;
[dict setObject: @"class" forKey: @"Type"]; [dict setObject: @"class" forKey: @"Type"];
[self setStandards: dict];
/* /*
* After the class name, we may have a category name or * After the class name, we may have a category name or
@ -529,7 +532,7 @@ fail:
} }
else if (buffer[pos] == '#') else if (buffer[pos] == '#')
{ {
[self skipRemainderOfLine]; // Ignore preprocessor directive. [self skipPreprocessor]; // Ignore preprocessor directive.
DESTROY(comment); DESTROY(comment);
} }
else else
@ -742,6 +745,10 @@ fail:
} }
[method setObject: mname forKey: @"Name"]; [method setObject: mname forKey: @"Name"];
if (flag == YES)
{
[self setStandards: method];
}
itemName = mname; itemName = mname;
if (term == ';') if (term == ';')
@ -945,7 +952,7 @@ fail:
* Some preprocessor directive ... must be on one line ... skip * Some preprocessor directive ... must be on one line ... skip
* past it and delete any comment accumulated while doing so. * past it and delete any comment accumulated while doing so.
*/ */
[self skipRemainderOfLine]; [self skipPreprocessor];
DESTROY(comment); DESTROY(comment);
break; break;
@ -1089,6 +1096,7 @@ fail:
goto fail; goto fail;
} }
[dict setObject: name forKey: @"Name"]; [dict setObject: name forKey: @"Name"];
[self setStandards: dict];
unitName = [NSString stringWithFormat: @"(%@)", name]; unitName = [NSString stringWithFormat: @"(%@)", name];
/* /*
@ -1328,7 +1336,7 @@ fail:
switch (c) switch (c)
{ {
case '#': // preprocessor directive. case '#': // preprocessor directive.
[self skipRemainderOfLine]; [self skipPreprocessor];
break; break;
case '\'': case '\'':
@ -1804,6 +1812,151 @@ fail:
return pos; return pos;
} }
/**
* Skip past a preprocessor statement, handling preprocessor
* conditionals in a rudimentary way. We keep track of the
* level of conditional nesting, and we also track the use of
* #ifdef and #ifndef with some well-known constants to tell
* us which standards are currently supported.
*/
- (unsigned) skipPreprocessor
{
while (pos < length && [spaces characterIsMember: buffer[pos]] == YES)
{
pos++;
}
if (pos < length && buffer[pos] != '\n')
{
NSString *directive = [self parseIdentifier];
if ([directive isEqual: @"endif"] == YES)
{
unsigned c = [ifStack count];
if (c == 0)
{
[self log: @"Unexpected #endif (no matching #if)"];
}
else
{
[ifStack removeObjectAtIndex: c - 1];
}
}
else if ([directive isEqual: @"elif"] == YES)
{
unsigned c = [ifStack count];
if (c == 0)
{
[self log: @"Unexpected #else (no matching #if)"];
}
else
{
[ifStack replaceObjectAtIndex: c - 1 withObject: @""];
}
}
else if ([directive isEqual: @"else"] == YES)
{
unsigned c = [ifStack count];
if (c == 0)
{
[self log: @"Unexpected #else (no matching #if)"];
}
else
{
NSString *item = [ifStack objectAtIndex: --c];
if ([item isEqual: @"GNUstep"] == YES)
{
[ifStack replaceObjectAtIndex: c withObject: @"NotGNUstep"];
}
else if ([item isEqual: @"NotGNUstep"] == YES)
{
[ifStack replaceObjectAtIndex: c withObject: @"GNUstep"];
}
else if ([item isEqual: @"OpenStep"] == YES)
{
[ifStack replaceObjectAtIndex: c withObject: @"NotOpenStep"];
}
else if ([item isEqual: @"NotOpenStep"] == YES)
{
[ifStack replaceObjectAtIndex: c withObject: @"OpenStep"];
}
else if ([item isEqual: @"MacOS-X"] == YES)
{
[ifStack replaceObjectAtIndex: c withObject: @"NotMacOS-X"];
}
else if ([item isEqual: @"NotMacOS-X"] == YES)
{
[ifStack replaceObjectAtIndex: c withObject: @"MacOS-X"];
}
}
}
else if ([directive isEqual: @"if"] == YES)
{
[ifStack addObject: @""];
}
else if ([directive hasPrefix: @"if"] == YES)
{
BOOL isIfDef = [directive isEqual: @"ifdef"];
while (pos < length && [spaces characterIsMember: buffer[pos]] == YES)
{
pos++;
}
if (pos < length && buffer[pos] != '\n')
{
NSString *arg = [self parseIdentifier];
NSString *val = @"";
if ([arg isEqual: @"NO_GNUSTEP"] == YES)
{
if (isIfDef == YES)
{
val = @"NotGNUstep";
}
else
{
val = @"GNUstep";
}
}
else if ([arg isEqual: @"STRICT_MACOS_X"] == YES)
{
if (isIfDef == YES)
{
val = @"MacOS-X";
}
else
{
val = @"NotMacOS-X";
}
}
else if ([arg isEqual: @"STRICT_OPENSTEP"] == YES)
{
if (isIfDef == YES)
{
val = @"OpenStep";
}
else
{
val = @"NotOpenStep";
}
}
[ifStack addObject: val];
}
}
}
while (pos < length)
{
if (buffer[pos++] == '\n')
{
break;
}
}
return pos;
}
- (unsigned) skipRemainderOfLine - (unsigned) skipRemainderOfLine
{ {
while (pos < length) while (pos < length)
@ -1845,7 +1998,7 @@ fail:
switch (c) switch (c)
{ {
case '#': // preprocessor directive. case '#': // preprocessor directive.
[self skipRemainderOfLine]; [self skipPreprocessor];
break; break;
case '\'': case '\'':
@ -1899,7 +2052,7 @@ fail:
switch (c) switch (c)
{ {
case '#': // preprocessor directive. case '#': // preprocessor directive.
[self skipRemainderOfLine]; [self skipPreprocessor];
break; break;
case '\'': case '\'':
@ -1954,5 +2107,42 @@ fail:
return pos; return pos;
} }
/**
* Store the current standards information derived from preprocessor
* conditionals in the supplied dictionary ... this will be used by
* the AGSOutput class to put standards markup in the gsdoc output.
*/
- (void) setStandards: (NSMutableDictionary*)dict
{
unsigned c = [ifStack count];
if (c > 0)
{
NSMutableString *s = nil;
BOOL found = NO;
s = [NSMutableString stringWithCString: "<standards>"];
while (c-- > 0)
{
NSString *name = [ifStack objectAtIndex: c];
/*
* We don't produce output for empty strings or
* the 'NotGNUstep' string.
*/
if ([name isEqualToString: @""] == NO
&& [name isEqualToString: @"NotGNUstep"] == NO)
{
found = YES;
[s appendFormat: @"<%@ />", name];
}
}
if (found == YES)
{
[s appendString: @"</standards>"];
[dict setObject: s forKey: @"Standards"];
}
}
}
@end @end