Work on the train.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14654 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2002-10-05 17:47:54 +00:00
parent a19354dc27
commit 1462308459
17 changed files with 477 additions and 198 deletions

View file

@ -1,4 +1,28 @@
2002-10-03 Richard Frith-Macdonald <rfm@gnu.org> 2002-10-05 Richard Frith-Macdonald <rfm@gnu.org>
* Tools/AGSOutput.m: Improve warning code, support text output
in chapter/section/subsection.
* Tools/AGSParser.m: move concatenation of comments into a single
method, make it insert a linebreak between concatenated comments,
and make it refrain from appending the same comment onto itsself
(which would happen if the same file was parsed twice, as both a
header and as source).
Treat the 'main()' function specially ... don't document it as a
function but insert its comments at the end of the 'chapter' part
of the output document. These modifications make it easy to
document a directory containing tools, by listing the tool source
files as arguments to autogsdoc.
Tools/gsdoc_0_6_7.dtd: Fix bug preventing use of text in a chapter!
* Source/GSString.m: Implement -UTF8String method for better
performance.
* Source/NSPortNameServer.m: Improve diagnostic message in exception
when reporting failure to register ... try to provide all the info
needed to begin diagnosing any problem.
* Tools/gdomap.c: Make -M flag work with -N. Make -M flag work when
used after -N or -L. Improve diagnostic messages on failure so
people know what it is trying to do.
2002-10-04 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSArray.m: Tidied init from file to ensure that everything * Source/NSArray.m: Tidied init from file to ensure that everything
is released properly on failure, and we don't generate log messages is released properly on failure, and we don't generate log messages

View file

@ -135,7 +135,11 @@
@end @end
#ifndef NO_GNUSTEP #ifndef NO_GNUSTEP
NSTimeInterval GSTime(int d, int m, int y, int hh, int mm, int ss, int mil); void
GSBreakTime(NSTimeInterval when, int *year, int *month, int *day, int *hour,
int *minute, int *second, int *mil);
NSTimeInterval
GSTime(int day, int month, int year, int hour, int minute, int second, int mil);
#endif #endif
#endif /* __NSCalendarDate_h_GNUSTEP_BASE_INCLUDE*/ #endif /* __NSCalendarDate_h_GNUSTEP_BASE_INCLUDE*/

View file

@ -530,6 +530,78 @@ setup()
* peculiar to its memory management (shrinking, growing, and converting). * peculiar to its memory management (shrinking, growing, and converting).
*/ */
static inline char*
UTF8String_c(ivars self)
{
unsigned char *r;
if (self->_count == 0)
{
return "";
}
if (intEnc == NSISOLatin1StringEncoding || intEnc == NSASCIIStringEncoding)
{
r = (unsigned char*)_fastMallocBuffer(self->_count+1);
if (self->_count > 0)
{
memcpy(r, self->_contents.c, self->_count);
}
r[self->_count] = '\0';
}
else
{
unichar *u = 0;
unsigned l = 0;
unsigned s = 0;
/*
* We must convert from internal format to unicode and then to
* UTF8 string encoding.
*/
if (GSToUnicode(&u, &l, self->_contents.c, self->_count, intEnc,
NSDefaultMallocZone(), 0) == NO)
{
[NSException raise: NSCharacterConversionException
format: @"Can't convert to Unicode string."];
}
if (GSFromUnicode((unsigned char**)&r, &s, u, l, NSUTF8StringEncoding,
NSDefaultMallocZone(), GSUniTerminate|GSUniTemporary|GSUniStrict) == NO)
{
NSZoneFree(NSDefaultMallocZone(), u);
[NSException raise: NSCharacterConversionException
format: @"Can't convert from Unicode to UTF8."];
}
NSZoneFree(NSDefaultMallocZone(), u);
}
return r;
}
static inline char*
UTF8String_u(ivars self)
{
unsigned c = self->_count;
if (c == 0)
{
return "";
}
else
{
unsigned int l = 0;
unsigned char *r = 0;
if (GSFromUnicode(&r, &l, self->_contents.u, c, NSUTF8StringEncoding,
NSDefaultMallocZone(), GSUniTerminate|GSUniTemporary|GSUniStrict) == NO)
{
[NSException raise: NSCharacterConversionException
format: @"Can't get UTF8 from Unicode string."];
}
return r;
}
}
static inline BOOL static inline BOOL
boolValue_c(ivars self) boolValue_c(ivars self)
{ {
@ -1826,6 +1898,11 @@ transmute(ivars self, NSString *aString)
* 8-bit string class, storing immutable data in a single buffer. * 8-bit string class, storing immutable data in a single buffer.
*/ */
@implementation GSCString @implementation GSCString
- (const char *) UTF8String
{
return UTF8String_c((ivars)self);
}
- (BOOL) boolValue - (BOOL) boolValue
{ {
return boolValue_c((ivars)self); return boolValue_c((ivars)self);
@ -2124,6 +2201,11 @@ transmute(ivars self, NSString *aString)
@implementation GSUnicodeString @implementation GSUnicodeString
- (const char *) UTF8String
{
return UTF8String_u((ivars)self);
}
- (BOOL) boolValue - (BOOL) boolValue
{ {
return boolValue_u((ivars)self); return boolValue_u((ivars)self);

View file

@ -216,7 +216,7 @@ gregorianDateFromAbsolute(int abs, int *day, int *month, int *year)
* External - so NSDate and others can use it. * External - so NSDate and others can use it.
*/ */
NSTimeInterval NSTimeInterval
GSTime(int day, int month, int year, int h, int m, int s, int mil) GSTime(int day, int month, int year, int hour, int minute, int second, int mil)
{ {
NSTimeInterval a; NSTimeInterval a;
@ -225,9 +225,9 @@ GSTime(int day, int month, int year, int h, int m, int s, int mil)
// Calculate date as GMT // Calculate date as GMT
a -= GREGORIAN_REFERENCE; a -= GREGORIAN_REFERENCE;
a = (NSTimeInterval)a * 86400; a = (NSTimeInterval)a * 86400;
a += h * 3600; a += hour * 3600;
a += m * 60; a += minute * 60;
a += s; a += second;
a += mil/1000.0; a += mil/1000.0;
return a; return a;
} }
@ -237,7 +237,7 @@ GSTime(int day, int month, int year, int h, int m, int s, int mil)
* elements.<br /> * elements.<br />
* External - so NSDate and others can use it. * External - so NSDate and others can use it.
*/ */
static void void
GSBreakTime(NSTimeInterval when, int *year, int *month, int *day, GSBreakTime(NSTimeInterval when, int *year, int *month, int *day,
int *hour, int *minute, int *second, int *mil) int *hour, int *minute, int *second, int *mil)
{ {

View file

@ -506,6 +506,7 @@ static BOOL multi_threaded = NO;
} }
/** /**
* Not used in GNUstep
*/ */
+ (id) currentConversation + (id) currentConversation
{ {
@ -1164,7 +1165,8 @@ static BOOL multi_threaded = NO;
} }
/** /**
* Returns YES if the connection is invalid, NO otherwise. * Returns YES if the connection is valid, NO otherwise.
* A connection is valid until it has been sent an -invalidate message.
*/ */
- (BOOL) isValid - (BOOL) isValid
{ {
@ -1206,7 +1208,8 @@ static BOOL multi_threaded = NO;
/** /**
* Returns YES if the connection permits multiple threads to use it to * Returns YES if the connection permits multiple threads to use it to
* send requests, NO otherwise. * send requests, NO otherwise.<br />
* See the -enableMultipleThreads method.
*/ */
- (BOOL) multipleThreadsEnabled - (BOOL) multipleThreadsEnabled
{ {
@ -1486,8 +1489,10 @@ static BOOL multi_threaded = NO;
/** /**
* Sets the time interval that the NSConnection will wait for a * Sets the time interval that the NSConnection will wait for a
* reply to one of its requests before raising an * reply for one of its requests before raising an
* NSPortTimeoutException. * NSPortTimeoutException.<br />
* NB. In GNUstep you may also get such an exception if the connection
* becomes invalidated while waiting for a reply to a request.
*/ */
- (void) setReplyTimeout: (NSTimeInterval)to - (void) setReplyTimeout: (NSTimeInterval)to
{ {

View file

@ -317,13 +317,13 @@ static Class NSCountedSet_concrete_class;
* purge the set even when uniquing is turned off. * purge the set even when uniquing is turned off.
*/ */
void void
GSUPurge(unsigned level) GSUPurge(unsigned count)
{ {
if (uniqueLock != nil) if (uniqueLock != nil)
{ {
(*lockImp)(uniqueLock, @selector(lock)); (*lockImp)(uniqueLock, @selector(lock));
} }
[uniqueSet purge: level]; [uniqueSet purge: count];
if (uniqueLock != nil) if (uniqueLock != nil)
{ {
(*unlockImp)(uniqueLock, @selector(unlock)); (*unlockImp)(uniqueLock, @selector(unlock));
@ -339,7 +339,7 @@ GSUPurge(unsigned level)
* alter the set even when uniquing is turned off. * alter the set even when uniquing is turned off.
*/ */
id id
GSUSet(id obj, unsigned level) GSUSet(id anObject, unsigned count)
{ {
id found; id found;
unsigned i; unsigned i;
@ -348,29 +348,29 @@ GSUSet(id obj, unsigned level)
{ {
(*lockImp)(uniqueLock, @selector(lock)); (*lockImp)(uniqueLock, @selector(lock));
} }
found = [uniqueSet member: obj]; found = [uniqueSet member: anObject];
if (found == nil) if (found == nil)
{ {
found = obj; found = anObject;
for (i = 0; i < level; i++) for (i = 0; i < count; i++)
{ {
[uniqueSet addObject: obj]; [uniqueSet addObject: anObject];
} }
} }
else else
{ {
i = [uniqueSet countForObject: found]; i = [uniqueSet countForObject: found];
if (i < level) if (i < count)
{ {
while (i < level) while (i < count)
{ {
[uniqueSet addObject: found]; [uniqueSet addObject: found];
i++; i++;
} }
} }
else if (i > level) else if (i > count)
{ {
while (i > level) while (i > count)
{ {
[uniqueSet removeObject: found]; [uniqueSet removeObject: found];
i--; i--;
@ -391,7 +391,7 @@ GSUSet(id obj, unsigned level)
* If uniquing is turned off, it simply returns its argument. * If uniquing is turned off, it simply returns its argument.
*/ */
id id
GSUnique(id obj) GSUnique(id anObject)
{ {
if (uniquing == YES) if (uniquing == YES)
{ {
@ -399,13 +399,13 @@ GSUnique(id obj)
{ {
(*lockImp)(uniqueLock, @selector(lock)); (*lockImp)(uniqueLock, @selector(lock));
} }
obj = (*uniqueImp)(uniqueSet, @selector(unique:), obj); anObject = (*uniqueImp)(uniqueSet, @selector(unique:), anObject);
if (uniqueLock != nil) if (uniqueLock != nil)
{ {
(*unlockImp)(uniqueLock, @selector(unlock)); (*unlockImp)(uniqueLock, @selector(unlock));
} }
} }
return obj; return anObject;
} }
/** /**

View file

@ -461,8 +461,8 @@ failure:
* and with the specified length. Invokes * and with the specified length. Invokes
* -initWithBytesNoCopy:length:freeWhenDone: * -initWithBytesNoCopy:length:freeWhenDone:
*/ */
+ (id) dataWithBytesNoCopy: (void*)bytes + (id) dataWithBytesNoCopy: (void*)aBuffer
length: (unsigned int)length length: (unsigned int)bufferSize
freeWhenDone: (BOOL)shouldFree freeWhenDone: (BOOL)shouldFree
{ {
NSData *d; NSData *d;
@ -475,7 +475,9 @@ failure:
{ {
d = [dataStatic allocWithZone: NSDefaultMallocZone()]; d = [dataStatic allocWithZone: NSDefaultMallocZone()];
} }
d = [d initWithBytesNoCopy: bytes length: length freeWhenDone: shouldFree]; d = [d initWithBytesNoCopy: aBuffer
length: bufferSize
freeWhenDone: shouldFree];
return AUTORELEASE(d); return AUTORELEASE(d);
} }
@ -592,7 +594,8 @@ failure:
* The value fo shouldFree specifies whether the receiver should * The value fo shouldFree specifies whether the receiver should
* attempt to free the memory pointer to by aBuffer when the receiver * attempt to free the memory pointer to by aBuffer when the receiver
* is deallocated ... ie. it says whether the receiver <em>owns</em> * is deallocated ... ie. it says whether the receiver <em>owns</em>
* the memory. * the memory. Supplying the wrong value here will lead to memory
* leaks or crashes.
*/ */
- (id) initWithBytesNoCopy: (void*)aBuffer - (id) initWithBytesNoCopy: (void*)aBuffer
length: (unsigned int)bufferSize length: (unsigned int)bufferSize

View file

@ -152,7 +152,7 @@ BOOL
GSInstanceVariableInfo(id obj, NSString *iVarName, GSInstanceVariableInfo(id obj, NSString *iVarName,
const char **type, unsigned *size, unsigned *offset) const char **type, unsigned *size, unsigned *offset)
{ {
const char *name = [iVarName cString]; const char *name = [iVarName UTF8String];
return GSFindInstanceVariable(obj, name, type, size, offset); return GSFindInstanceVariable(obj, name, type, size, offset);
} }
@ -160,13 +160,13 @@ GSInstanceVariableInfo(id obj, NSString *iVarName,
/** ## deprecated ## /** ## deprecated ##
*/ */
BOOL BOOL
GSGetInstanceVariable(id obj, NSString *iVarName, void *data) GSGetInstanceVariable(id obj, NSString *name, void *data)
{ {
const char *name = [iVarName cString]; const char *cName = [name UTF8String];
int offset; int offset;
unsigned int size; unsigned int size;
if (GSFindInstanceVariable(obj, name, 0, &size, &offset) == YES) if (GSFindInstanceVariable(obj, cName, 0, &size, &offset) == YES)
{ {
GSGetVariable(obj, offset, size, data); GSGetVariable(obj, offset, size, data);
return YES; return YES;
@ -177,13 +177,13 @@ GSGetInstanceVariable(id obj, NSString *iVarName, void *data)
/** ## deprecated ## /** ## deprecated ##
*/ */
BOOL BOOL
GSSetInstanceVariable(id obj, NSString *iVarName, const void *data) GSSetInstanceVariable(id obj, NSString *name, const void *data)
{ {
const char *name = [iVarName cString]; const char *cName = [name UTF8String];
int offset; int offset;
unsigned int size; unsigned int size;
if (GSFindInstanceVariable(obj, name, 0, &size, &offset) == YES) if (GSFindInstanceVariable(obj, cName, 0, &size, &offset) == YES)
{ {
GSSetVariable(obj, offset, size, data); GSSetVariable(obj, offset, size, data);
return YES; return YES;

View file

@ -584,8 +584,8 @@ typedef enum {
return [self portForName: name onHost: nil]; return [self portForName: name onHost: nil];
} }
- (NSPort*) portForName: (NSString*)name - (BOOL) _lookupName: (NSString*)name onHost: (NSString*)host
onHost: (NSString*)host intoAddress: (NSString**)addr andPort: (unsigned*)port
{ {
GSPortCom *com = nil; GSPortCom *com = nil;
NSRunLoop *loop = [NSRunLoop currentRunLoop]; NSRunLoop *loop = [NSRunLoop currentRunLoop];
@ -593,11 +593,11 @@ typedef enum {
struct in_addr *svrs = &singleServer; struct in_addr *svrs = &singleServer;
unsigned numSvrs = 1; unsigned numSvrs = 1;
unsigned count; unsigned count;
unsigned portNum = 0;
unsigned len; unsigned len;
NSMutableArray *array; NSMutableArray *array;
NSDate *limit; NSDate *limit;
*port = 0;
if (name == nil) if (name == nil)
{ {
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException
@ -711,7 +711,7 @@ typedef enum {
{ {
unsigned i; unsigned i;
portNum = 0; *port = 0;
count = 0; count = 0;
do do
{ {
@ -740,13 +740,12 @@ typedef enum {
{ {
break; /* No servers left to try! */ break; /* No servers left to try! */
} }
[loop runMode: mode [loop runMode: mode beforeDate: limit];
beforeDate: limit];
/* /*
* Check for completed operations. * Check for completed operations.
*/ */
while (portNum == 0 && i-- > 0) while (*port == 0 && i-- > 0)
{ {
com = [array objectAtIndex: i]; com = [array objectAtIndex: i];
if ([com isActive] == NO) if ([com isActive] == NO)
@ -754,9 +753,8 @@ typedef enum {
[com close]; [com close];
if ([com state] == GSPC_DONE) if ([com state] == GSPC_DONE)
{ {
portNum *port = GSSwapBigI32ToHost(*(gsu32*)[[com data] bytes]);
= GSSwapBigI32ToHost(*(gsu32*)[[com data] bytes]); if (*port != 0)
if (portNum != 0)
{ {
singleServer = [com addr]; singleServer = [com addr];
} }
@ -765,7 +763,7 @@ typedef enum {
} }
} }
} }
while (portNum == 0 && [limit timeIntervalSinceNow] > 0); while (*port == 0 && [limit timeIntervalSinceNow] > 0);
/* /*
* Make sure that any outstanding lookups are cancelled. * Make sure that any outstanding lookups are cancelled.
@ -788,14 +786,32 @@ typedef enum {
NS_ENDHANDLER NS_ENDHANDLER
[serverLock unlock]; [serverLock unlock];
if (portNum) if (*port)
{
*addr = [NSString stringWithCString: inet_ntoa(singleServer)];
return YES;
}
else
{
return NO;
}
}
- (NSPort*) portForName: (NSString*)name
onHost: (NSString*)host
{
NSString *addr;
unsigned portNum = 0;
if ([self _lookupName: name
onHost: host
intoAddress: &addr
andPort: &portNum] == YES)
{ {
if (portClass == [GSTcpPort class]) if (portClass == [GSTcpPort class])
{ {
NSString *addr;
NSHost *host; NSHost *host;
addr = [NSString stringWithCString: inet_ntoa(singleServer)];
host = [NSHost hostWithAddress: addr]; host = [NSHost hostWithAddress: addr];
return (NSPort*)[GSTcpPort portWithNumber: portNum return (NSPort*)[GSTcpPort portWithNumber: portNum
onHost: host onHost: host
@ -854,7 +870,6 @@ typedef enum {
NS_DURING NS_DURING
{ {
NSMutableSet *known = NSMapGet(_portMap, port); NSMutableSet *known = NSMapGet(_portMap, port);
GSPortCom *tmp;
/* /*
* If there is no set of names for this port - create one. * If there is no set of names for this port - create one.
@ -875,8 +890,7 @@ typedef enum {
if ([known count] == 0) if ([known count] == 0)
{ {
com = [GSPortCom new]; com = [GSPortCom new];
[com startPortUnregistration: [port portNumber] [com startPortUnregistration: [port portNumber] withName: nil];
withName: nil];
while ([limit timeIntervalSinceNow] > 0 && [com isActive] == YES) while ([limit timeIntervalSinceNow] > 0 && [com isActive] == YES)
{ {
[loop runMode: mode [loop runMode: mode
@ -888,18 +902,14 @@ typedef enum {
[NSException raise: NSPortTimeoutException [NSException raise: NSPortTimeoutException
format: @"timed out unregistering port"]; format: @"timed out unregistering port"];
} }
tmp = com; DESTROY(com);
com = nil;
RELEASE(tmp);
} }
com = [GSPortCom new]; com = [GSPortCom new];
[com startPortRegistration: [port portNumber] [com startPortRegistration: [port portNumber] withName: name];
withName: name];
while ([limit timeIntervalSinceNow] > 0 && [com isActive] == YES) while ([limit timeIntervalSinceNow] > 0 && [com isActive] == YES)
{ {
[loop runMode: mode [loop runMode: mode beforeDate: limit];
beforeDate: limit];
} }
[com close]; [com close];
if ([com state] != GSPC_DONE) if ([com state] != GSPC_DONE)
@ -914,19 +924,53 @@ typedef enum {
result = GSSwapBigI32ToHost(*(gsu32*)[[com data] bytes]); result = GSSwapBigI32ToHost(*(gsu32*)[[com data] bytes]);
if (result == 0) if (result == 0)
{ {
[NSException raise: NSGenericException unsigned int portNum;
format: @"Unable to register name '%@' for the port -\n%@\n" NSString *addr;
BOOL found;
NS_DURING
{
found = [self _lookupName: name
onHost: @""
intoAddress: &addr
andPort: &portNum];
}
NS_HANDLER
{
found = NO;
}
NS_ENDHANDLER
if (found == YES)
{
[NSException raise: NSGenericException
format: @"Unable to register name '%@' for the port -\n%@\n"
@"It appears that a process is already registered with this name at port\n"
@"'%d' IP address %@\n"
@"Perhaps this program ran before and was shut down without unregistering,\n"
@"so another process may be running using the same network port. If this is\n"
@"the case, you can use -\n"
@"gdomap -U '%@'\n"
@"to remove the registration so that you can attempt this operation again.",
name, port, portNum, addr, name];
}
else
{
[NSException raise: NSGenericException
format: @"Unable to register name '%@' for the port -\n%@\n"
@"Typically, this might mean that a process is already running with the name\n" @"Typically, this might mean that a process is already running with the name\n"
@"'%@' ...\n" @"'%@' ...\n"
@"Try the command -\n" @"Try the command -\n"
@" gdomap -L '%@'\n" @" gdomap -M localhost -L '%@'\n"
@"to find its network details.\n" @"to find its network details.\n"
@"Alternatively, it may have been shut down without unregistering, and\n" @"Alternatively, it may have been shut down without unregistering, and\n"
@"another process may be running using the same network port. If this is\n" @"another process may be running using the same network port. If this is\n"
@"the case, you can use -\n" @"the case, you can use -\n"
@"gdomap -U '%@'\n" @"gdomap -U '%@'\n"
@"to remove the registration so that you can attempt this operation again.", @"to remove the registration so that you can attempt this operation again.",
name, port, name, name, name]; name, port, name, name, name];
}
} }
else else
{ {
@ -938,16 +982,14 @@ typedef enum {
NSMapInsert(_nameMap, name, port); NSMapInsert(_nameMap, name, port);
} }
} }
tmp = com; DESTROY(com);
com = nil;
RELEASE(tmp);
} }
NS_HANDLER NS_HANDLER
{ {
/* /*
* If we had a problem - close and unlock before continueing. * If we had a problem - close and unlock before continueing.
*/ */
RELEASE(com); DESTROY(com);
[serverLock unlock]; [serverLock unlock];
[localException raise]; [localException raise];
} }

View file

@ -4339,7 +4339,7 @@ handle_printf_atsign (FILE *stream,
* Removes the specified prefix from the string. Raises an exception * Removes the specified prefix from the string. Raises an exception
* if the prefix is not present. * if the prefix is not present.
*/ */
- (void) deletePrefix: (NSString*)prefix; - (void) deletePrefix: (NSString*)prefix
{ {
NSCAssert2([self hasPrefix: prefix], NSCAssert2([self hasPrefix: prefix],
@"'%@' does not have the prefix '%@'", self, prefix); @"'%@' does not have the prefix '%@'", self, prefix);

View file

@ -519,6 +519,7 @@ static NSMutableSet *textNodes = nil;
ssect = 0; ssect = 0;
sssect = 0; sssect = 0;
[self outputNodeList: children to: buf]; [self outputNodeList: children to: buf];
heading = nil;
} }
else if ([name isEqual: @"class"] == YES) else if ([name isEqual: @"class"] == YES)
{ {
@ -1086,16 +1087,23 @@ static NSMutableSet *textNodes = nil;
} }
else if ([name isEqual: @"heading"] == YES) else if ([name isEqual: @"heading"] == YES)
{ {
[buf appendString: indent]; if (heading == nil)
[buf appendString: @"<"]; {
[buf appendString: heading]; }
[buf appendString: @">"]; else
[buf appendFormat: @"<a name=\"%03u%03u%03u%03u\">", {
chap, sect, ssect, sssect]; [buf appendString: indent];
[self outputText: children to: buf]; [buf appendString: @"<"];
[buf appendString: @"</a></"]; [buf appendString: heading];
[buf appendString: heading]; [buf appendString: @">"];
[buf appendString: @">\n"]; [buf appendFormat: @"<a name=\"%03u%03u%03u%03u\">",
chap, sect, ssect, sssect];
[self outputText: children to: buf];
[buf appendString: @"</a></"];
[buf appendString: heading];
[buf appendString: @">\n"];
heading = nil;
}
} }
else if ([name isEqual: @"index"] == YES) else if ([name isEqual: @"index"] == YES)
{ {
@ -1394,6 +1402,7 @@ static NSMutableSet *textNodes = nil;
ssect = 0; ssect = 0;
sssect = 0; sssect = 0;
[self outputNodeList: children to: buf]; [self outputNodeList: children to: buf];
heading = @"h1";
} }
else if ([name isEqual: @"site"] == YES) else if ([name isEqual: @"site"] == YES)
{ {
@ -1442,12 +1451,14 @@ static NSMutableSet *textNodes = nil;
ssect++; ssect++;
sssect = 0; sssect = 0;
[self outputNodeList: children to: buf]; [self outputNodeList: children to: buf];
heading = @"h2";
} }
else if ([name isEqual: @"subsubsect"] == YES) else if ([name isEqual: @"subsubsect"] == YES)
{ {
heading = @"h4"; heading = @"h4";
sssect++; sssect++;
[self outputNodeList: children to: buf]; [self outputNodeList: children to: buf];
heading = @"h3";
} }
else if ([name isEqual: @"type"] == YES) else if ([name isEqual: @"type"] == YES)
{ {
@ -1593,14 +1604,28 @@ NSLog(@"Element '%@' not implemented", name); // FIXME
RELEASE(arp); RELEASE(arp);
} }
/**
* Output all the nodes from this one onwards ... try to output
* as text first, if not possible, call the main method to output
* each node.
*/
- (void) outputNodeList: (GSXMLNode*)node to: (NSMutableString*)buf - (void) outputNodeList: (GSXMLNode*)node to: (NSMutableString*)buf
{ {
while (node != nil) while (node != nil)
{ {
GSXMLNode *next = [node nextElement]; GSXMLNode *next = [node nextElement];
GSXMLNode *tmp;
[self outputNode: node to: buf]; tmp = [self outputText: node to: buf];
node = next; if (tmp == node)
{
[self outputNode: node to: buf];
node = next;
}
else
{
node = tmp;
}
} }
} }

View file

@ -33,6 +33,7 @@
NSCharacterSet *spacenl; // Blanks excluding newline NSCharacterSet *spacenl; // Blanks excluding newline
NSArray *args; // Not retained. NSArray *args; // Not retained.
BOOL verbose; BOOL verbose;
BOOL warn;
} }
- (NSString*) checkComment: (NSString*)comment - (NSString*) checkComment: (NSString*)comment
@ -58,7 +59,6 @@
- (unsigned) reformat: (NSString*)str - (unsigned) reformat: (NSString*)str
withIndent: (unsigned)ind withIndent: (unsigned)ind
to: (NSMutableString*)buf; to: (NSMutableString*)buf;
- (void) setVerbose: (BOOL)flag;
- (NSArray*) split: (NSString*)str; - (NSArray*) split: (NSString*)str;
@end @end
#endif #endif

View file

@ -81,24 +81,24 @@ static BOOL snuggleStart(NSString *t)
if ([comment length] == 0) if ([comment length] == 0)
{ {
comment = @"<em>Description forthcoming.</em>"; comment = @"<em>Description forthcoming.</em>";
if (verbose == YES) if (warn == YES)
{ {
NSString *name = [d objectForKey: @"Name"]; NSString *name = [d objectForKey: @"Name"];
NSString *type = [d objectForKey: @"Type"]; NSString *type = [d objectForKey: @"Type"];
if (unit == nil) if (unit == nil)
{ {
NSLog(@"No comments for %@ %@", type, name); NSLog(@"Warning - No comments for %@ %@", type, name);
} }
else else
{ {
if ([d objectForKey: @"ReturnType"] != nil) if ([d objectForKey: @"ReturnType"] != nil)
{ {
NSLog(@"No comments for [%@ %@]", unit, name); NSLog(@"Warning - No comments for [%@ %@]", unit, name);
} }
else else
{ {
NSLog(@"No comments for instance variable %@ in %@", NSLog(@"Warning - No comments for instance variable %@ in %@",
name, unit); name, unit);
} }
} }
@ -213,6 +213,8 @@ static BOOL snuggleStart(NSString *t)
@"_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]); @"_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]);
identStart = RETAIN([NSCharacterSet characterSetWithCharactersInString: identStart = RETAIN([NSCharacterSet characterSetWithCharactersInString:
@"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]); @"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]);
verbose = [[NSUserDefaults standardUserDefaults] boolForKey: @"Verbose"];
warn = [[NSUserDefaults standardUserDefaults] boolForKey: @"Warn"];
return self; return self;
} }
@ -629,7 +631,7 @@ static BOOL snuggleStart(NSString *t)
NSString *declared = [d objectForKey: @"Declared"]; NSString *declared = [d objectForKey: @"Declared"];
NSString *standards = nil; NSString *standards = nil;
if ([[d objectForKey: @"Implemented"] isEqual: @"YES"] == NO) if (warn == YES && [[d objectForKey: @"Implemented"] isEqual: @"YES"] == NO)
{ {
NSLog(@"Warning ... %@ %@ is not implemented where expected", kind, name); NSLog(@"Warning ... %@ %@ is not implemented where expected", kind, name);
} }
@ -680,7 +682,7 @@ static BOOL snuggleStart(NSString *t)
NSString *standards = nil; NSString *standards = nil;
unsigned i = [aa count]; unsigned i = [aa count];
if ([[d objectForKey: @"Implemented"] isEqual: @"YES"] == NO) if (warn == YES && [[d objectForKey: @"Implemented"] isEqual: @"YES"] == NO)
{ {
NSLog(@"Warning ... function %@ is not implemented where expected", name); NSLog(@"Warning ... function %@ is not implemented where expected", name);
} }
@ -861,7 +863,8 @@ static BOOL snuggleStart(NSString *t)
NSString *override = nil; NSString *override = nil;
NSString *standards = nil; NSString *standards = nil;
if (unit != nil && [[d objectForKey: @"Implemented"] isEqual: @"YES"] == NO) if (warn == YES && unit != nil
&& [[d objectForKey: @"Implemented"] isEqual: @"YES"] == NO)
{ {
NSLog(@"Warning ... method %@ %@ is not implemented where expected", NSLog(@"Warning ... method %@ %@ is not implemented where expected",
unit, name); unit, name);
@ -1056,7 +1059,7 @@ static BOOL snuggleStart(NSString *t)
[m setObject: @"YES" forKey: @"Implemented"]; [m setObject: @"YES" forKey: @"Implemented"];
} }
} }
else else if (warn == YES)
{ {
NSLog(@"Warning ... unit %@ is not implemented where expected", name); NSLog(@"Warning ... unit %@ is not implemented where expected", name);
} }
@ -1393,11 +1396,6 @@ static BOOL snuggleStart(NSString *t)
return ind; return ind;
} }
- (void) setVerbose: (BOOL)flag
{
verbose = flag;
}
- (NSArray*) split: (NSString*)str - (NSArray*) split: (NSString*)str
{ {
NSMutableArray *a = [NSMutableArray arrayWithCapacity: 128]; NSMutableArray *a = [NSMutableArray arrayWithCapacity: 128];

View file

@ -61,6 +61,7 @@
BOOL inArgList; BOOL inArgList;
BOOL documentAllInstanceVariables; BOOL documentAllInstanceVariables;
BOOL verbose; BOOL verbose;
BOOL warn;
NSDictionary *wordMap; NSDictionary *wordMap;
NSString *declared; /** Where classes were declared. */ NSString *declared; /** Where classes were declared. */
NSMutableArray *ifStack; /** Track preprocessor conditionals. */ NSMutableArray *ifStack; /** Track preprocessor conditionals. */
@ -93,7 +94,6 @@
- (void) setDocumentAllInstanceVariables: (BOOL)flag; - (void) setDocumentAllInstanceVariables: (BOOL)flag;
- (void) setGenerateStandards: (BOOL)flag; - (void) setGenerateStandards: (BOOL)flag;
- (void) setStandards: (NSMutableDictionary*)dict; - (void) setStandards: (NSMutableDictionary*)dict;
- (void) setVerbose: (BOOL)flag;
- (void) setWordMap: (NSDictionary*)map; - (void) setWordMap: (NSDictionary*)map;
- (void) setupBuffer; - (void) setupBuffer;
- (unsigned) skipArray; - (unsigned) skipArray;

View file

@ -24,6 +24,83 @@
@implementation AGSParser @implementation AGSParser
/**
* Method to add the comment from the main() function to the end
* of the initial chapter in the output document. We do this to
* support the use of autogsdoc to document tools.
*/
- (void) addMain: (NSString*)c
{
NSString *chap;
NSMutableString *m;
NSRange r;
chap = [info objectForKey: @"chapter"];
if (chap == nil)
{
chap = [NSString stringWithFormat:
@"<chapter><heading>%@</heading></chapter>",
[[fileName lastPathComponent] stringByDeletingPathExtension]];
}
m = [chap mutableCopy];
r = [m rangeOfString: @"</chapter>"];
r.length = 0;
[m replaceCharactersInRange: r withString: @"</section>\n"];
[m replaceCharactersInRange: r withString: c];
[m replaceCharactersInRange: r withString:
@"<section>\n<heading>The main() function</heading>\n"];
[info setObject: m forKey: @"chapter"];
RELEASE(m);
}
/**
* Append a comment (with leading and trailing space stripped)
* to an information dictionary.<br />
* If the dictionary is nil, accumulate in the comment ivar instead.<br />
* If the comment is empty, ignore it.<br />
* If there is no comment in the dictionary, simply set the new value.<br />
* If a comment already exists then the new comment text is appended to
* it with a separating line break inserted if necessary.<br />
*/
- (void) appendComment: (NSString*)s to: (NSMutableDictionary*)d
{
s = [s stringByTrimmingSpaces];
if ([s length] > 0)
{
NSString *old;
if (d == nil)
{
old = comment;
}
else
{
old = [d objectForKey: @"Comment"];
}
if (old != nil)
{
if ([old hasSuffix: @"</p>"] == NO
&& [old hasSuffix: @"<br />"] == NO
&& [old hasSuffix: @"<br/>"] == NO)
{
s = [old stringByAppendingFormat: @"<br />%@", s];
}
else
{
s = [old stringByAppendingString: s];
}
}
if (d == nil)
{
ASSIGN(comment, s);
}
else
{
[d setObject: s forKey: @"Comment"];
}
}
}
- (void) dealloc - (void) dealloc
{ {
DESTROY(wordMap); DESTROY(wordMap);
@ -60,6 +137,8 @@
@"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]); @"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]);
info = [[NSMutableDictionary alloc] initWithCapacity: 6]; info = [[NSMutableDictionary alloc] initWithCapacity: 6];
source = [NSMutableArray new]; source = [NSMutableArray new];
verbose = [[NSUserDefaults standardUserDefaults] boolForKey: @"Verbose"];
warn = [[NSUserDefaults standardUserDefaults] boolForKey: @"Warn"];
return self; return self;
} }
@ -731,7 +810,7 @@
} }
if (comment != nil) if (comment != nil)
{ {
[d setObject: comment forKey: @"Comment"]; [self appendComment: comment to: d];
} }
DESTROY(comment); DESTROY(comment);
} }
@ -750,7 +829,7 @@
/* /*
* Don't bother to warn about nameless enumerations. * Don't bother to warn about nameless enumerations.
*/ */
if ([t isEqual: @"enum ..."] == NO) if (verbose == YES && [t isEqual: @"enum ..."] == NO)
{ {
[self log: @"parse declaration with no name - %@", d]; [self log: @"parse declaration with no name - %@", d];
} }
@ -919,19 +998,20 @@ fail:
if (oDecl != nil) if (oDecl != nil)
{ {
NSString *tmp = [nDecl objectForKey: @"Comment"]; NSString *oc = [oDecl objectForKey: @"Comment"];
NSString *nc = [nDecl objectForKey: @"Comment"];
if (tmp != nil) /*
* If the old comment from the header parsing is
* the same as the new comment from the source
* parsing, assume we parsed the same file as both
* source and header ... otherwise append the new
* comment.
*/
if ([oc isEqual: nc] == NO)
{ {
NSString *old = [oDecl objectForKey: @"Comment"]; [self appendComment: nc to: oDecl];
if (old != nil)
{
tmp = [old stringByAppendingString: tmp];
}
[oDecl setObject: tmp forKey: @"Comment"];
} }
[oDecl setObject: @"YES" forKey: @"Implemented"]; [oDecl setObject: @"YES" forKey: @"Implemented"];
if ([kind isEqualToString: @"Functions"] == YES) if ([kind isEqualToString: @"Functions"] == YES)
@ -944,6 +1024,23 @@ fail:
[self log: @"Function %@ args missmatch - " [self log: @"Function %@ args missmatch - "
@"%@ %@", name, a1, a2]; @"%@ %@", name, a1, a2];
} }
/*
* A main function is not documented as a
* function, but as a special case its
* comments are added to the 'front'
* section of the documentation.
*/
if ([name isEqual: @"main"] == YES)
{
NSString *c;
c = [oDecl objectForKey: @"Comment"];
if (c != nil)
{
[self addMain: c];
}
[dict removeObjectForKey: name];
}
} }
} }
} }
@ -1036,16 +1133,7 @@ fail:
/* /*
* Append any comment we have for this * Append any comment we have for this
*/ */
if (tmp != nil) [self appendComment: tmp to: dict];
{
NSString *old = [dict objectForKey: @"Comment"];
if (old != nil)
{
tmp = [old stringByAppendingString: tmp];
}
[dict setObject: tmp forKey: @"Comment"];
}
/* /*
* Update base class if necessary. * Update base class if necessary.
*/ */
@ -1096,7 +1184,7 @@ fail:
*/ */
if (comment != nil) if (comment != nil)
{ {
[dict setObject: comment forKey: @"Comment"]; [self appendComment: comment to: dict];
DESTROY(comment); DESTROY(comment);
} }
@ -1584,18 +1672,7 @@ fail:
*/ */
if (comment != nil) if (comment != nil)
{ {
NSString *old; [self appendComment: comment to: method];
old = [method objectForKey: @"Comment"];
if (old != nil)
{
[method setObject: [old stringByAppendingString: comment]
forKey: @"Comment"];
}
else
{
[method setObject: comment forKey: @"Comment"];
}
DESTROY(comment); DESTROY(comment);
} }
@ -1716,17 +1793,8 @@ fail:
} }
} }
token = [method objectForKey: @"Comment"]; [self appendComment: [method objectForKey: @"Comment"]
if (token != nil) to: exist];
{
NSString *old = [exist objectForKey: @"Comment"];
if (old != nil)
{
token = [old stringByAppendingString: token];
}
[exist setObject: token forKey: @"Comment"];
}
[exist setObject: @"YES" forKey: @"Implemented"]; [exist setObject: @"YES" forKey: @"Implemented"];
} }
break; break;
@ -2099,14 +2167,6 @@ fail:
} }
} }
/**
* Control boolean option to do verbose logging of the parsing process.
*/
- (void) setVerbose: (BOOL)flag
{
verbose = flag;
}
/** /**
* Sets up a dictionary used for mapping identifiers/keywords to other * Sets up a dictionary used for mapping identifiers/keywords to other
* words. This is used to help cope with cases where C preprocessor * words. This is used to help cope with cases where C preprocessor
@ -2447,11 +2507,7 @@ fail:
NSString *tmp; NSString *tmp;
tmp = [NSString stringWithCharacters: start length: end - start]; tmp = [NSString stringWithCharacters: start length: end - start];
if (comment != nil) [self appendComment: tmp to: nil];
{
tmp = [comment stringByAppendingFormat: @"<br />\n%@", tmp];
}
ASSIGN(comment, tmp);
} }
if (commentsRead == NO && comment != nil) if (commentsRead == NO && comment != nil)

View file

@ -32,7 +32,7 @@
parse corresponding source files in the same directory as the parse corresponding source files in the same directory as the
headers (or the current directory, or the directory specified headers (or the current directory, or the directory specified
using the DocumentationDirectory default), and produce gsdoc using the DocumentationDirectory default), and produce gsdoc
files as output. and html files as output.
</p> </p>
<p> <p>
Even without any human assistance, this tool will produce skeleton Even without any human assistance, this tool will produce skeleton
@ -44,7 +44,18 @@
Any comment beginning with slash and <em>two</em> asterisks rather than Any comment beginning with slash and <em>two</em> asterisks rather than
the common slash and single asterisk, is taken to be gsdoc markup, to the common slash and single asterisk, is taken to be gsdoc markup, to
be use as the description of the class or method following it. This be use as the description of the class or method following it. This
comment text is reformatted and then inserted into the output. comment text is reformatted and then inserted into the output.<br />
Where multiple comments are associatd with the same item, they are
joined together with a line break (&lt;br /&gt;) between each if
necessary.
</p>
<p>
The tool can easily be used to document programs as well as libraries,
simply by giving it the name of the source file containing the main()
function of the program - it takes the special comments from that
function and handles them specially, inserting them as a section at
the end of the first chapter of the document (it creates the first
chapter if necessary).
</p> </p>
<p> <p>
There are some cases where special extra processing is performed, There are some cases where special extra processing is performed,
@ -90,7 +101,9 @@
<item><strong>&lt;chapter&gt;</strong> <item><strong>&lt;chapter&gt;</strong>
Placed immediately before any generated class documentation ... Placed immediately before any generated class documentation ...
intended to be used to provide overall description of how the intended to be used to provide overall description of how the
code being documented works.<br /> code being documented works.<br />Any documentation for the main()
function of a program is inserted as a section at the end of this
chapter.
</item> </item>
<item><strong>&lt;copy&gt;</strong> <item><strong>&lt;copy&gt;</strong>
Copyright of the content of the document ... placed in the head Copyright of the content of the document ... placed in the head
@ -112,7 +125,7 @@
<item><strong>&lt;title&gt;</strong> <item><strong>&lt;title&gt;</strong>
Title of the document ... placed in the head of the gsdoc output. Title of the document ... placed in the head of the gsdoc output.
If this is omitted the tool will generate a (probably poor) If this is omitted the tool will generate a (probably poor)
title of its own. title of its own - so you should include this markup manually.
</item> </item>
<item> <item>
<strong>NB</strong>This markup may be used within <strong>NB</strong>This markup may be used within
@ -178,13 +191,14 @@
</item> </item>
<item>Method specifiers including class names (beginning and ending with <item>Method specifiers including class names (beginning and ending with
square brackets) are enclosed in &lt;ref...&gt; ... &lt;/ref&gt; markup. square brackets) are enclosed in &lt;ref...&gt; ... &lt;/ref&gt; markup.
<br />eg. [ NSObject-init], <br />eg. <code>[</code>NSObject-init<code>]</code>,
will create a reference to the init method of NSObject, while will create a reference to the init method of NSObject (either the
<br />[ (NSCopying)-copyWithZone:], creates a class proper, or any of its categories), while
<br /><code>[</code>(NSCopying)-copyWithZone:<code>]</code>, creates a
reference to a method in the NSCopyIng protocol. reference to a method in the NSCopyIng protocol.
<br />Note that no spaces must appear between the square brackets <br />Note that no spaces must appear between the square brackets
in these specifiers. in these specifiers.
<br />Protocol namnes are enclosed in round brackets rather than <br />Protocol names are enclosed in round brackets rather than
the customary angle brackets, because gsdoc is an XML language, and the customary angle brackets, because gsdoc is an XML language, and
XML treats angle brackets specially. XML treats angle brackets specially.
</item> </item>
@ -197,16 +211,16 @@
<item><strong>ConstantsTemplate</strong> <item><strong>ConstantsTemplate</strong>
Specify the name of a template document into which documentation Specify the name of a template document into which documentation
about constants should be inserted from all files in the project.<br /> about constants should be inserted from all files in the project.<br />
This is useful if constanr in the source code are scattered around many This is useful if constants in the source code are scattered around many
files, and you need to group them into one place.<br /> files, and you need to group them into one place.<br />
You are responsible for ensuring that the basic template document You are responsible for ensuring that the basic template document
(into which individual constant documentation is inserted) contains (into which individual constant documentation is inserted) contains
all the other information you want, but as a conveniencem autogsdoc all the other information you want, but as a convenience autogsdoc
will generate a simple template (which you may then edit) for you will generate a simple template (which you may then edit) for you
if the file does not exist. if the file does not exist.
<br />Insertion takes place immediately before the <em>back</em> <br />Insertion takes place immediately before the <em>back</em>
element (or if that does not exist, immediately before the end element (or if that does not exist, immediately before the end
of the <em>body</em> lement) in the template. of the <em>body</em> element) in the template.
</item> </item>
<item><strong>Declared</strong> <item><strong>Declared</strong>
Specify where headers are to be documented as being found.<br /> Specify where headers are to be documented as being found.<br />
@ -239,7 +253,7 @@
files, and you need to group it into one place.<br /> files, and you need to group it into one place.<br />
You are responsible for ensuring that the basic template document You are responsible for ensuring that the basic template document
(into which individual function documentation is inserted) contains (into which individual function documentation is inserted) contains
all the other information you want, but as a conveniencem autogsdoc all the other information you want, but as a convenience autogsdoc
will generate a simple template (which you may then edit) for you will generate a simple template (which you may then edit) for you
if the file does not exist. if the file does not exist.
<br />Insertion takes place immediately before the <em>back</em> <br />Insertion takes place immediately before the <em>back</em>
@ -336,7 +350,7 @@
files, and you need to group it into one place.<br /> files, and you need to group it into one place.<br />
You are responsible for ensuring that the basic template document You are responsible for ensuring that the basic template document
(into which individual typedef documentation is inserted) contains (into which individual typedef documentation is inserted) contains
all the other information you want, but as a conveniencem autogsdoc all the other information you want, but as a convenience autogsdoc
will generate a simple template (which you may then edit) for you will generate a simple template (which you may then edit) for you
if the file does not exist. if the file does not exist.
<br />Insertion takes place immediately before the <em>back</em> <br />Insertion takes place immediately before the <em>back</em>
@ -357,13 +371,21 @@
files, and you need to group it into one place.<br /> files, and you need to group it into one place.<br />
You are responsible for ensuring that the basic template document You are responsible for ensuring that the basic template document
(into which individual variable documentation is inserted) contains (into which individual variable documentation is inserted) contains
all the other information you want, but as a conveniencem autogsdoc all the other information you want, but as a convenience autogsdoc
will generate a simple template (which you may then edit) for you will generate a simple template (which you may then edit) for you
if the file does not exist. if the file does not exist.
<br />Insertion takes place immediately before the <em>back</em> <br />Insertion takes place immediately before the <em>back</em>
element (or if that does not exist, immediately before the end element (or if that does not exist, immediately before the end
of the <em>body</em> lement) in the template. of the <em>body</em> lement) in the template.
</item> </item>
<item><strong>Verbose</strong>
A boolean used to specify whether you want verbose debug/warning
output to be produced.
</item>
<item><strong>Warn</strong>
A boolean used to specify whether you want standard warning
output (eg report of undocumented methods) produced.
</item>
<item><strong>WordMap</strong> <item><strong>WordMap</strong>
This value is a dictionary used to map identifiers/keywords found This value is a dictionary used to map identifiers/keywords found
in the source files to other words. Generally you will not have in the source files to other words. Generally you will not have
@ -443,6 +465,7 @@ main(int argc, char **argv, char **env)
BOOL ignoreDependencies = NO; BOOL ignoreDependencies = NO;
BOOL showDependencies = NO; BOOL showDependencies = NO;
BOOL verbose = NO; BOOL verbose = NO;
BOOL warn = NO;
NSArray *files; NSArray *files;
NSMutableArray *sFiles = nil; // Source NSMutableArray *sFiles = nil; // Source
NSMutableArray *gFiles = nil; // GSDOC NSMutableArray *gFiles = nil; // GSDOC
@ -469,6 +492,7 @@ main(int argc, char **argv, char **env)
nil]]; nil]];
verbose = [defs boolForKey: @"Verbose"]; verbose = [defs boolForKey: @"Verbose"];
warn = [defs boolForKey: @"Warn"];
ignoreDependencies = [defs boolForKey: @"IgnoreDependencies"]; ignoreDependencies = [defs boolForKey: @"IgnoreDependencies"];
showDependencies = [defs boolForKey: @"ShowDependencies"]; showDependencies = [defs boolForKey: @"ShowDependencies"];
if (ignoreDependencies == YES) if (ignoreDependencies == YES)
@ -607,9 +631,7 @@ main(int argc, char **argv, char **env)
parser = [AGSParser new]; parser = [AGSParser new];
[parser setWordMap: [defs dictionaryForKey: @"WordMap"]]; [parser setWordMap: [defs dictionaryForKey: @"WordMap"]];
[parser setVerbose: verbose];
output = [AGSOutput new]; output = [AGSOutput new];
[output setVerbose: verbose];
if ([defs boolForKey: @"Standards"] == YES) if ([defs boolForKey: @"Standards"] == YES)
{ {
[parser setGenerateStandards: YES]; [parser setGenerateStandards: YES];

View file

@ -3854,7 +3854,8 @@ nameServer(const char* name, const char* host, int op, int ptype, struct sockadd
rval = tryHost(GDO_SERVERS, 0, 0, ptype, &sin, &num, (uptr*)&b); rval = tryHost(GDO_SERVERS, 0, 0, ptype, &sin, &num, (uptr*)&b);
if (rval != 0 && host == local_hostname) if (rval != 0 && host == local_hostname)
{ {
sprintf(ebuf, "failed to contact gdomap (%s)\n", strerror(errno)); sprintf(ebuf, "failed to contact gdomap on %s(%s) - %s",
local_hostname, inet_ntoa(sin.sin_addr), strerror(errno));
gdomap_log(LOG_ERR); gdomap_log(LOG_ERR);
return -1; return -1;
} }
@ -3907,7 +3908,8 @@ nameServer(const char* name, const char* host, int op, int ptype, struct sockadd
rval = tryHost(op, len, name, ptype, &sin, &port, 0); rval = tryHost(op, len, name, ptype, &sin, &port, 0);
if (rval != 0 && host == local_hostname) if (rval != 0 && host == local_hostname)
{ {
sprintf(ebuf, "failed to contact gdomap (%s)", strerror(errno)); sprintf(ebuf, "failed to contact gdomap on %s(%s) - %s",
local_hostname, inet_ntoa(sin.sin_addr), strerror(errno));
gdomap_log(LOG_ERR); gdomap_log(LOG_ERR);
return -1; return -1;
} }
@ -3956,7 +3958,7 @@ lookup(const char *name, const char *host, int ptype)
} }
static void static void
donames() donames(const char *host)
{ {
struct sockaddr_in sin; struct sockaddr_in sin;
struct servent* sp; struct servent* sp;
@ -3966,7 +3968,6 @@ donames()
int rval; int rval;
uptr b; uptr b;
char *first_dot; char *first_dot;
const char *host;
#ifdef __MINGW__ #ifdef __MINGW__
char local_hostname[INTERNET_MAX_HOST_NAME_LENGTH]; char local_hostname[INTERNET_MAX_HOST_NAME_LENGTH];
#else #else
@ -3986,23 +3987,25 @@ donames()
} }
#endif #endif
/* if (host == 0 || *host == '\0')
* If no host name is given, we use the name of the local host. {
* NB. This should always be the case for operations other than lookup. /*
*/ * If no host name is given, we use the name of the local host.
*/
if (gethostname(local_hostname, sizeof(local_hostname)) < 0) if (gethostname(local_hostname, sizeof(local_hostname)) < 0)
{ {
sprintf(ebuf, "gethostname() failed: %s", strerror(errno)); sprintf(ebuf, "gethostname() failed: %s", strerror(errno));
gdomap_log(LOG_ERR); gdomap_log(LOG_ERR);
return; return;
}
first_dot = strchr(local_hostname, '.');
if (first_dot)
{
*first_dot = '\0';
}
host = local_hostname;
} }
first_dot = strchr(local_hostname, '.');
if (first_dot)
{
*first_dot = '\0';
}
host = local_hostname;
if ((hp = gethostbyname(host)) == 0) if ((hp = gethostbyname(host)) == 0)
{ {
sprintf(ebuf, "gethostbyname() failed: %s", strerror(errno)); sprintf(ebuf, "gethostbyname() failed: %s", strerror(errno));
@ -4024,7 +4027,8 @@ donames()
rval = tryHost(GDO_NAMES, 0, 0, 0, &sin, &num, (uptr*)&b); rval = tryHost(GDO_NAMES, 0, 0, 0, &sin, &num, (uptr*)&b);
if (rval != 0) if (rval != 0)
{ {
sprintf(ebuf, "failed to contact gdomap (%s)", strerror(errno)); sprintf(ebuf, "failed to contact gdomap on %s(%s) - %s",
local_hostname, inet_ntoa(sin.sin_addr), strerror(errno));
gdomap_log(LOG_ERR); gdomap_log(LOG_ERR);
return; return;
} }
@ -4099,11 +4103,13 @@ int
main(int argc, char** argv) main(int argc, char** argv)
{ {
extern char *optarg; extern char *optarg;
char *options = "CHI:L:M:NP:R:T:U:a:bc:dfi:p"; char *options = "-CHI:L:M:NP:R:T:U:a:bc:dfi:p";
int c; int c;
int ptype = GDO_TCP_GDO; int ptype = GDO_TCP_GDO;
int port = 0; int port = 0;
const char *machine = 0; const char *machine = 0;
const char *lookupf = 0;
int donamesf = 0;
#ifdef HAVE_SYSLOG #ifdef HAVE_SYSLOG
/* Initially, gdomap_log errors to stderr as well as to syslogd. */ /* Initially, gdomap_log errors to stderr as well as to syslogd. */
@ -4154,8 +4160,8 @@ main(int argc, char** argv)
printf("-H general help\n"); printf("-H general help\n");
printf("-I pid file to write pid\n"); printf("-I pid file to write pid\n");
printf("-L name perform lookup for name then quit.\n"); printf("-L name perform lookup for name then quit.\n");
printf("-M name machine name for L (default local)\n"); printf("-M name machine name for -L and -N\n");
printf("-N list all names registered on this host\n"); printf("-N list all names registered on host\n");
printf("-P number port number required for R option.\n"); printf("-P number port number required for R option.\n");
printf("-R name register name locally then quit.\n"); printf("-R name register name locally then quit.\n");
printf("-T type port type for L, R and U options -\n"); printf("-T type port type for L, R and U options -\n");
@ -4220,16 +4226,16 @@ printf(
exit(0); exit(0);
case 'L': case 'L':
lookup(optarg, machine, ptype); lookupf = optarg;
exit(0); break;
case 'M': case 'M':
machine = optarg; machine = optarg;
break; break;
case 'N': case 'N':
donames(); donamesf = 1;
exit(0); break;
case 'P': case 'P':
port = atoi(optarg); port = atoi(optarg);
@ -4415,6 +4421,18 @@ printf(
exit(0); exit(0);
} }
} }
if (donamesf || lookupf)
{
if (donamesf)
{
donames(machine);
}
if (lookupf)
{
lookup(lookupf, machine, ptype);
}
exit (0);
}
#ifdef __MINGW__ /* On Win32, we don't fork */ #ifdef __MINGW__ /* On Win32, we don't fork */
if (nofork == 0) if (nofork == 0)