Tweaks to make preprocessor documentation more reliable

This commit is contained in:
rfm 2023-10-30 12:27:25 +00:00
parent 8a7612857e
commit 112c60b48b
4 changed files with 173 additions and 234 deletions

View file

@ -224,18 +224,6 @@ GS_EXPORT NSString * const NSNetServicesErrorDomain;
@end @end
/** /**
* <unit>
* <heading>
* NSNetServiceBrowserDelegate protocol description
* </heading>
* <p>
* <!-- Foreword -->
* </p>
* <unit />
* <p>
* <!-- Afterword -->
* </p>
* </unit>
* <p> * <p>
* This protocol must be adopted by any class wishing to implement * This protocol must be adopted by any class wishing to implement
* an [NSNetServiceBrowser] delegate. * an [NSNetServiceBrowser] delegate.
@ -336,18 +324,6 @@ GS_EXPORT NSString * const NSNetServicesErrorDomain;
/** /**
* <unit>
* <heading>
* NSNetService class description
* </heading>
* <p>
* <!-- Foreword -->
* </p>
* <unit />
* <p>
* <!-- Afterword -->
* </p>
* </unit>
* <p> * <p>
* [NSNetService] lets you publish a network service in a domain using * [NSNetService] lets you publish a network service in a domain using
* multicast DNS. Additionally, it lets you resolve a network service that * multicast DNS. Additionally, it lets you resolve a network service that
@ -416,18 +392,6 @@ GS_EXPORT_CLASS
@end @end
/** /**
* <unit>
* <heading>
* NSNetServiceBrowser class description
* </heading>
* <p>
* <!-- Foreword -->
* </p>
* <unit />
* <p>
* <!-- Afterword -->
* </p>
* </unit>
* <p> * <p>
* [NSNetServiceBrowser] asynchronously lets you discover network domains * [NSNetServiceBrowser] asynchronously lets you discover network domains
* and, additionally, search for a type of network service. It sends its * and, additionally, search for a type of network service. It sends its
@ -473,18 +437,6 @@ GS_EXPORT_CLASS
@end @end
/** /**
* <unit>
* <heading>
* NSNetServiceDelegate protocol description
* </heading>
* <p>
* <!-- Foreword -->
* </p>
* <unit />
* <p>
* <!-- Afterword -->
* </p>
* </unit>
* <p> * <p>
* This protocol must be adopted by any class wishing to implement * This protocol must be adopted by any class wishing to implement
* an [NSNetService] delegate. * an [NSNetService] delegate.

View file

@ -1,4 +1,4 @@
/* GSVersionMacros.h - macros for managing API versioning and visibility /** GSVersionMacros.h - macros for managing API versioning and visibility
Copyright (C) 2006-2014 Free Software Foundation, Inc. Copyright (C) 2006-2014 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <rfm@gnu.org> Written by: Richard Frith-Macdonald <rfm@gnu.org>
@ -148,18 +148,6 @@
* four digit values (two digits for the major version, one for the minor, * four digit values (two digits for the major version, one for the minor,
* and one for the subminor). * and one for the subminor).
* </p> * </p>
* <p>The Apple compatibility version macros are currently:
* <ref type="macro" id="MAC_OS_X_VERSION_10_0">MAC_OS_X_VERSION_10_0</ref>,
* <ref type="macro" id="MAC_OS_X_VERSION_10_1">MAC_OS_X_VERSION_10_1</ref>,
* <ref type="macro" id="MAC_OS_X_VERSION_10_2">MAC_OS_X_VERSION_10_2</ref>,
* <ref type="macro" id="MAC_OS_X_VERSION_10_3">MAC_OS_X_VERSION_10_3</ref>,
* <ref type="macro" id="MAC_OS_X_VERSION_10_4">MAC_OS_X_VERSION_10_4</ref>,
* <ref type="macro" id="MAC_OS_X_VERSION_10_5">MAC_OS_X_VERSION_10_5</ref>,
* <ref type="macro" id="MAC_OS_X_VERSION_10_6">MAC_OS_X_VERSION_10_6</ref>,
* <ref type="macro" id="MAC_OS_X_VERSION_10_7">MAC_OS_X_VERSION_10_7</ref>,
* <ref type="macro" id="MAC_OS_X_VERSION_10_8">MAC_OS_X_VERSION_10_8</ref>
* <ref type="macro" id="MAC_OS_X_VERSION_10_9">MAC_OS_X_VERSION_10_9</ref>
* </p>
*/ */
#define OS_API_VERSION(ADD,REM) \ #define OS_API_VERSION(ADD,REM) \
(!defined(GS_OPENSTEP_V) \ (!defined(GS_OPENSTEP_V) \

View file

@ -35,6 +35,7 @@ BaseAdditions_DOC_INSTALL_DIR = Developer
Base_AGSDOC_FILES = \ Base_AGSDOC_FILES = \
../Documentation/Base.gsdoc \ ../Documentation/Base.gsdoc \
../GNUstepBase/GSVersionMacros.h \
FoundationErrors.h \ FoundationErrors.h \
Foundation.h \ Foundation.h \
FoundationLegacySwiftCompatibility.h \ FoundationLegacySwiftCompatibility.h \

View file

@ -670,11 +670,22 @@ patata
// NOTE: We could be able to eliminate that if -parseComment processes the // NOTE: We could be able to eliminate that if -parseComment processes the
// first comment tags before calling -generateParagraphMarkups: // first comment tags before calling -generateParagraphMarkups:
- (BOOL) shouldInsertParagraphMarkupInFirstComment: (NSString *)aComment - (BOOL) containsSpecialMarkup: (NSString *)aComment
{ {
NSArray *firstCommentTags = [NSArray arrayWithObjects: @"<title>", NSArray *firstCommentTags = [NSArray arrayWithObjects:
@"<abstract>", @"<author>", @"<copy>", @"<version>", @"<date>", @"<abstract>",
@"Author:", @"By:", @"Copyright (C)", nil]; @"<author>",
@"<back>",
@"<chapter>",
@"<copy>",
@"<date>",
@"<front>",
@"<title>",
@"<unit>",
@"<version>",
@"Author:",
@"By:",
@"Copyright (C)", nil];
NSEnumerator *e = [firstCommentTags objectEnumerator]; NSEnumerator *e = [firstCommentTags objectEnumerator];
NSString *tag = nil; NSString *tag = nil;
@ -683,11 +694,11 @@ patata
if ([aComment rangeOfString: tag if ([aComment rangeOfString: tag
options: NSCaseInsensitiveSearch].location != NSNotFound) options: NSCaseInsensitiveSearch].location != NSNotFound)
{ {
return NO; return YES;
} }
} }
return YES; return NO;
} }
- (NSString *) generateParagraphMarkupForString: (NSString *)aComment - (NSString *) generateParagraphMarkupForString: (NSString *)aComment
@ -697,7 +708,7 @@ patata
NSEnumerator *e; NSEnumerator *e;
if (NO == commentsRead if (NO == commentsRead
&& ![self shouldInsertParagraphMarkupInFirstComment: aComment]) && [self containsSpecialMarkup: aComment])
{ {
return aComment; return aComment;
} }
@ -741,6 +752,11 @@ patata
*/ */
- (unsigned) parseComment - (unsigned) parseComment
{ {
if (pos >= length)
{
return length;
}
NSAssert('/' == buffer[pos], NSInternalInconsistencyException);
if (buffer[pos + 1] == '/') if (buffer[pos + 1] == '/')
{ {
return [self skipRemainderOfLine]; return [self skipRemainderOfLine];
@ -761,7 +777,7 @@ comment:
pos += 2; /* Skip opening part */ pos += 2; /* Skip opening part */
/* /*
* Only comments starting with slash and TWO asterisks are special. * Only comments starting with slash and TWO asterisks are documentation.
*/ */
if (pos < length - 2 && buffer[pos] == '*' && buffer[pos + 1] != '*') if (pos < length - 2 && buffer[pos] == '*' && buffer[pos + 1] != '*')
{ {
@ -799,6 +815,7 @@ comment:
unichar *ptr = start; unichar *ptr = start;
unichar *newLine = ptr; unichar *newLine = ptr;
BOOL stripAsterisks = NO; BOOL stripAsterisks = NO;
BOOL special = NO;
/* /*
* Remove any asterisks immediately before end of comment. * Remove any asterisks immediately before end of comment.
@ -896,12 +913,20 @@ comment:
tmp = [NSString stringWithCharacters: start length: end - start]; tmp = [NSString stringWithCharacters: start length: end - start];
/* The first documentation comment in a file may be special
* containing markup not permitted elsewhere.
*/
if (NO == commentsRead)
{
special = [self containsSpecialMarkup: tmp];
}
/* /*
* If the comment does not contain block markup already and we * If the comment does not contain block markup already and we
* were asked to generate it, we insert <p> tags to get an * were asked to generate it, we insert <p> tags to get an
* explicit paragraph structure. * explicit paragraph structure.
*/ */
if ([defs boolForKey: @"GenerateParagraphMarkup"]) if (special && [defs boolForKey: @"GenerateParagraphMarkup"])
{ {
// FIXME: Should follow <ignore> processing and be called // FIXME: Should follow <ignore> processing and be called
// just before using -appendComment:to: // just before using -appendComment:to:
@ -932,10 +957,9 @@ recheck:
} }
} }
/* /* For the first comment of a file we may perform special processing.
* We're in the first comment of a file; perform special processing.
*/ */
if (commentsRead == NO && comment != nil) if (special)
{ {
unsigned commentLength = [comment length]; unsigned commentLength = [comment length];
NSMutableArray *authors; NSMutableArray *authors;
@ -1222,6 +1246,7 @@ recheck:
@"date", // date for document head @"date", // date for document head
@"front", // Forward for document body @"front", // Forward for document body
@"title", // Title for document head @"title", // Title for document head
@"unit", // Unit for document body
@"version", // Version for document head @"version", // Version for document head
nil]; nil];
enumerator = [keys objectEnumerator]; enumerator = [keys objectEnumerator];
@ -2652,7 +2677,7 @@ fail:
unsigned start; unsigned start;
try: try:
[self parseSpace]; [self parseSpace: (inPreprocessorDirective ? spaces : spacenl)];
if (pos >= length || [identStart characterIsMember: buffer[pos]] == NO) if (pos >= length || [identStart characterIsMember: buffer[pos]] == NO)
{ {
return nil; return nil;
@ -2663,128 +2688,93 @@ try:
if ([identifier characterIsMember: buffer[pos]] == NO) if ([identifier characterIsMember: buffer[pos]] == NO)
{ {
NSString *tmp; NSString *tmp;
NSString *val;
tmp = [[NSString alloc] initWithCharacters: &buffer[start] tmp = [[NSString alloc] initWithCharacters: &buffer[start]
length: pos - start]; length: pos - start];
if ([tmp isEqual: @"GS_GENERIC_CLASS"]) if (inPreprocessorDirective)
{ {
[self skipSpaces]; /* No word mapping or special processing is done inside a
if (pos < length && buffer[pos] == '(') * preprocessor directive.
{ */
pos++; return AUTORELEASE(tmp);
/* Found a GS_GENERIC_CLASS macro ... the first }
* identifier inside the macro arguments is the else
* name we want to return. {
*/ NSString *val;
RELEASE(tmp);
tmp = RETAIN([self parseIdentifier]);
while (pos < length)
{
if (buffer[pos++] == ')')
{
break;
}
}
}
}
if ([tmp isEqual: @"GS_GENERIC_TYPE"])
{
[self skipSpaces];
if (pos < length && buffer[pos] == '(')
{
pos++;
/* Found a GS_GENERIC_TYPE macro ... the second
* argument inside the macro is the name we want
* to return (or 'id' if there is no second arg).
*/
DESTROY(tmp);
while (pos < length)
{
unichar c = buffer[pos++];
if (')' == c) if ([tmp isEqual: @"GS_GENERIC_CLASS"])
{ {
break; [self skipSpaces];
} if (pos < length && buffer[pos] == '(')
else if (',' == c)
{
tmp = RETAIN([self parseMethodType]);
[self skipSpaces];
if (')' == buffer[pos])
{
pos++;
}
NSLog(@"Parsed generic type as '%@'", tmp);
break;
}
}
if (nil == tmp)
{ {
tmp = @"id"; pos++;
/* Found a GS_GENERIC_CLASS macro ... the first
* identifier inside the macro arguments is the
* name we want to return.
*/
RELEASE(tmp);
tmp = RETAIN([self parseIdentifier]);
while (pos < length)
{
if (buffer[pos++] == ')')
{
break;
}
}
} }
}
}
val = [wordMap objectForKey: tmp];
if (val == nil)
{
return AUTORELEASE(tmp); // No mapping found.
}
RELEASE(tmp);
if ([val length] > 0)
{
if ([val isEqualToString: @"//"])
{
[self skipToEndOfLine];
return [self parseIdentifier];
} }
return val; // Got mapped identifier. if ([tmp isEqual: @"GS_GENERIC_TYPE"])
}
goto try; // Mapping removed the identifier.
}
pos++;
}
return nil;
}
/** Parses an identifier as long as we don't skip to a new line.
* For use when parsing a preprocessor line.
*/
- (NSString*) parseIdentifierInLine
{
unsigned start;
try:
[self parseSpace: spaces];
if (pos >= length || [identStart characterIsMember: buffer[pos]] == NO)
{
return nil;
}
start = pos;
while (pos < length)
{
if ([identifier characterIsMember: buffer[pos]] == NO)
{
NSString *tmp;
NSString *val;
tmp = [[NSString alloc] initWithCharacters: &buffer[start]
length: pos - start];
val = [wordMap objectForKey: tmp];
if (val == nil)
{
return AUTORELEASE(tmp); // No mapping found.
}
RELEASE(tmp);
val = [val stringByTrimmingSpaces];
if ([val length] > 0)
{
if ([val isEqualToString: @"//"])
{ {
[self skipToEndOfLine]; [self skipSpaces];
return nil; if (pos < length && buffer[pos] == '(')
{
pos++;
/* Found a GS_GENERIC_TYPE macro ... the second
* argument inside the macro is the name we want
* to return (or 'id' if there is no second arg).
*/
DESTROY(tmp);
while (pos < length)
{
unichar c = buffer[pos++];
if (')' == c)
{
break;
}
else if (',' == c)
{
tmp = RETAIN([self parseMethodType]);
[self skipSpaces];
if (')' == buffer[pos])
{
pos++;
}
// NSLog(@"Parsed generic type as '%@'", tmp);
break;
}
}
if (nil == tmp)
{
tmp = @"id";
}
}
}
val = [wordMap objectForKey: tmp];
if (val == nil)
{
return AUTORELEASE(tmp); // No mapping found.
}
RELEASE(tmp);
if ([val length] > 0)
{
if ([val isEqualToString: @"//"])
{
[self skipToEndOfLine];
return [self parseIdentifier];
}
return val; // Got mapped identifier.
} }
return val; // Got mapped identifier.
} }
goto try; // Mapping removed the identifier. goto try; // Mapping removed the identifier.
} }
@ -2907,10 +2897,10 @@ fail:
NSString *name; NSString *name;
dict = [[NSMutableDictionary alloc] initWithCapacity: 4]; dict = [[NSMutableDictionary alloc] initWithCapacity: 4];
name = [self parseIdentifierInLine]; name = [self parseIdentifier];
if (nil == name) if (nil == name)
{ {
// [self log: @"Missing name in #define"]; [self log: @"Warning - missing name in #define"];
return nil; return nil;
} }
[self parseSpace: spaces]; [self parseSpace: spaces];
@ -2935,7 +2925,7 @@ fail:
{ {
NSString *s; NSString *s;
s = [self parseIdentifierInLine]; s = [self parseIdentifier];
if (s == nil) if (s == nil)
{ {
break; break;
@ -3934,7 +3924,7 @@ countAttributes(NSSet *keys, NSDictionary *a)
NSAssert(pos > 0 & '#' == buffer[pos - 1], NSInternalInconsistencyException); NSAssert(pos > 0 & '#' == buffer[pos - 1], NSInternalInconsistencyException);
inPreprocessorDirective = YES; inPreprocessorDirective = YES;
directive = [self parseIdentifierInLine]; directive = [self parseIdentifier];
if ([directive isEqual: @"define"]) if ([directive isEqual: @"define"])
{ {
/* Macro definition inside source is ignored since it is not /* Macro definition inside source is ignored since it is not
@ -4029,7 +4019,7 @@ countAttributes(NSSet *keys, NSDictionary *a)
top = [[ifStack lastObject] mutableCopy]; top = [[ifStack lastObject] mutableCopy];
while ((arg = [self parseIdentifierInLine]) != nil) while ((arg = [self parseIdentifier]) != nil)
{ {
BOOL openstep; BOOL openstep;
NSString *ver; NSString *ver;
@ -4151,7 +4141,7 @@ countAttributes(NSSet *keys, NSDictionary *a)
else if ([directive isEqual: @"ifdef"]) else if ([directive isEqual: @"ifdef"])
{ {
NSMutableDictionary *top = [[ifStack lastObject] mutableCopy]; NSMutableDictionary *top = [[ifStack lastObject] mutableCopy];
NSString *arg = [self parseIdentifierInLine]; NSString *arg = [self parseIdentifier];
if ([arg isEqual: @"NO_GNUSTEP"]) if ([arg isEqual: @"NO_GNUSTEP"])
{ {
@ -4175,7 +4165,7 @@ countAttributes(NSSet *keys, NSDictionary *a)
else if ([directive isEqual: @"ifndef"]) else if ([directive isEqual: @"ifndef"])
{ {
NSMutableDictionary *top = [[ifStack lastObject] mutableCopy]; NSMutableDictionary *top = [[ifStack lastObject] mutableCopy];
NSString *arg = [self parseIdentifierInLine]; NSString *arg = [self parseIdentifier];
if ([arg isEqual: @"NO_GNUSTEP"]) if ([arg isEqual: @"NO_GNUSTEP"])
{ {
@ -4201,11 +4191,16 @@ countAttributes(NSSet *keys, NSDictionary *a)
else if ([directive isEqual: @"error"] else if ([directive isEqual: @"error"]
|| [directive isEqual: @"import"] || [directive isEqual: @"import"]
|| [directive isEqual: @"include"] || [directive isEqual: @"include"]
|| [directive isEqual: @"line"]
|| [directive isEqual: @"pragma"] || [directive isEqual: @"pragma"]
|| [directive isEqual: @"undef"] || [directive isEqual: @"undef"]
|| [directive isEqual: @"warning"]) || [directive isEqual: @"warning"])
{ {
} }
else if ([directive length] == 0)
{
[self log: @"Warning - empty preprocessor directive"];
}
else else
{ {
[self log: @"Warning - unknown preprocessor directive %@", directive]; [self log: @"Warning - unknown preprocessor directive %@", directive];
@ -4390,62 +4385,65 @@ fail:
pos++; // Step past space character. pos++; // Step past space character.
} }
start = pos; start = pos;
if (pos < length && [identifier characterIsMember: buffer[pos]]) if (NO == inPreprocessorDirective)
{ {
while (pos < length) if (pos < length && [identifier characterIsMember: buffer[pos]])
{ {
if ([identifier characterIsMember: buffer[pos]] == NO) while (pos < length)
{ {
NSString *tmp; if ([identifier characterIsMember: buffer[pos]] == NO)
NSString *val; {
NSString *tmp;
NSString *val;
tmp = [[NSString alloc] initWithCharacters: &buffer[start] tmp = [[NSString alloc] initWithCharacters: &buffer[start]
length: pos - start]; length: pos - start];
if ([tmp isEqualToString: @"NS_FORMAT_ARGUMENT"] if ([tmp isEqualToString: @"NS_FORMAT_ARGUMENT"]
|| [tmp isEqualToString: @"NS_FORMAT_FUNCTION"]) || [tmp isEqualToString: @"NS_FORMAT_FUNCTION"])
{
if (inPreprocessorDirective)
{ {
val = tmp; if (inPreprocessorDirective)
{
val = tmp;
}
else
{
/* These macros need to be skipped as they appear
* inside method declarations.
*/
val = @"";
[self skipSpaces];
[self skipBlock];
}
} }
else else
{ {
/* These macros need to be skipped as they appear val = [wordMap objectForKey: tmp];
* inside method declarations.
*/
val = @"";
[self skipSpaces];
[self skipBlock];
} }
} RELEASE(tmp);
else if (val == nil)
{
val = [wordMap objectForKey: tmp];
}
RELEASE(tmp);
if (val == nil)
{
pos = start; // No mapping found
}
else if ([val length] > 0)
{
if ([val isEqualToString: @"//"])
{ {
[self skipToEndOfLine]; pos = start; // No mapping found
tryAgain = YES; }
else if ([val length] > 0)
{
if ([val isEqualToString: @"//"])
{
[self skipToEndOfLine];
tryAgain = YES;
}
else
{
pos = start; // Not mapped to a comment.
}
} }
else else
{ {
pos = start; // Not mapped to a comment. tryAgain = YES; // Identifier ignored.
} }
break;
} }
else pos++;
{
tryAgain = YES; // Identifier ignored.
}
break;
} }
pos++;
} }
} }
} }