Add -where to report the current parser line and position within it

This commit is contained in:
rfm 2023-10-28 15:37:12 +01:00
parent 57f066442e
commit 1f5af5388b
2 changed files with 248 additions and 175 deletions

View file

@ -124,6 +124,7 @@
- (unsigned) skipToEndOfLine; - (unsigned) skipToEndOfLine;
- (unsigned) skipUnit; - (unsigned) skipUnit;
- (NSMutableArray*) sources; - (NSMutableArray*) sources;
- (NSString*) where;
@end @end
#endif #endif

View file

@ -3859,45 +3859,57 @@ countAttributes(NSSet *keys, NSDictionary *a)
{ {
NSString *directive = [self parseIdentifier]; NSString *directive = [self parseIdentifier];
if ([directive isEqual: @"define"] && inHeader) if ([directive isEqual: @"define"])
{ {
NSMutableDictionary *defn; if (inHeader)
defn = [self parseMacro];
if (defn != nil)
{ {
NSMutableDictionary *dict = [info objectForKey: @"Macros"]; NSMutableDictionary *defn;
NSString *name = [defn objectForKey: @"Name"];
NSMutableDictionary *odef;
odef = [dict objectForKey: name]; defn = [self parseMacro];
if (odef == nil) if (defn != nil)
{ {
if (dict == nil) NSMutableDictionary *dict = [info objectForKey: @"Macros"];
NSString *name = [defn objectForKey: @"Name"];
NSMutableDictionary *odef;
odef = [dict objectForKey: name];
if (odef == nil)
{ {
dict = [[NSMutableDictionary alloc] initWithCapacity: 8]; if (dict == nil)
[info setObject: dict forKey: @"Macros"]; {
RELEASE(dict); dict = [[NSMutableDictionary alloc]
initWithCapacity: 8];
[info setObject: dict forKey: @"Macros"];
RELEASE(dict);
}
[dict setObject: defn forKey: name];
} }
[dict setObject: defn forKey: name]; else
}
else
{
NSString *oc = [odef objectForKey: @"Comment"];
NSString *nc = [defn objectForKey: @"Comment"];
/*
* 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)
{ {
[self appendComment: nc to: odef]; NSString *oc = [odef objectForKey: @"Comment"];
NSString *nc = [defn objectForKey: @"Comment"];
/*
* 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)
{
[self appendComment: nc to: odef];
}
} }
} }
return pos;
}
else
{
/* Macro definition inside source is ignored since it is not
* visible to the outside world.
*/
return [self skipRemainderOfLine];
} }
} }
else if ([directive isEqual: @"endif"]) else if ([directive isEqual: @"endif"])
@ -3910,6 +3922,7 @@ countAttributes(NSSet *keys, NSDictionary *a)
{ {
[ifStack removeLastObject]; [ifStack removeLastObject];
} }
return [self skipRemainderOfLine];
} }
else if ([directive isEqual: @"elif"]) else if ([directive isEqual: @"elif"])
{ {
@ -3922,6 +3935,7 @@ countAttributes(NSSet *keys, NSDictionary *a)
[ifStack removeLastObject]; [ifStack removeLastObject];
[ifStack addObject: [ifStack lastObject]]; [ifStack addObject: [ifStack lastObject]];
} }
return [self skipRemainderOfLine];
} }
else if ([directive isEqual: @"else"]) else if ([directive isEqual: @"else"])
{ {
@ -3934,6 +3948,7 @@ countAttributes(NSSet *keys, NSDictionary *a)
[ifStack removeLastObject]; [ifStack removeLastObject];
[ifStack addObject: [ifStack lastObject]]; [ifStack addObject: [ifStack lastObject]];
} }
return [self skipRemainderOfLine];
} }
else if ([directive isEqual: @"if"]) else if ([directive isEqual: @"if"])
{ {
@ -3945,127 +3960,126 @@ countAttributes(NSSet *keys, NSDictionary *a)
top = [[ifStack lastObject] mutableCopy]; top = [[ifStack lastObject] mutableCopy];
while ((arg = [self parseIdentifier]) != nil) while ((arg = [self parseIdentifier]) != nil)
{ {
BOOL openstep; BOOL openstep;
NSString *ver; NSString *ver;
if ([arg isEqual: @"OS_API_VERSION"]) if ([arg isEqual: @"OS_API_VERSION"])
{ {
openstep = YES; openstep = YES;
if (hadOstep) if (hadOstep)
{ {
[self log: @"multiple grouped OS_API_VERSION() calls"]; [self log: @"multiple grouped OS_API_VERSION() calls"];
return [self skipRemainderOfLine]; return [self skipRemainderOfLine];
} }
hadOstep = YES; hadOstep = YES;
[top removeObjectForKey: @"ovadd"]; [top removeObjectForKey: @"ovadd"];
[top removeObjectForKey: @"ovdep"]; [top removeObjectForKey: @"ovdep"];
[top removeObjectForKey: @"ovrem"]; [top removeObjectForKey: @"ovrem"];
} }
else if ([arg isEqual: @"GS_API_VERSION"]) else if ([arg isEqual: @"GS_API_VERSION"])
{ {
openstep = NO; openstep = NO;
if (hadGstep) if (hadGstep)
{ {
[self log: @"multiple grouped GS_API_VERSION() calls"]; [self log: @"multiple grouped GS_API_VERSION() calls"];
return [self skipRemainderOfLine]; return [self skipRemainderOfLine];
} }
hadGstep = YES; hadGstep = YES;
[top removeObjectForKey: @"gvadd"]; [top removeObjectForKey: @"gvadd"];
[top removeObjectForKey: @"gvdep"]; [top removeObjectForKey: @"gvdep"];
[top removeObjectForKey: @"gvrem"]; [top removeObjectForKey: @"gvrem"];
} }
else else
{ {
break; break;
} }
[self parseSpace: spaces]; [self parseSpace: spaces];
if (pos < length && buffer[pos] == '(') if (pos < length && buffer[pos] == '(')
{ {
pos++; pos++;
} }
ver = [self parseVersion]; ver = [self parseVersion];
if ([ver length] == 0) if ([ver length] == 0)
{ {
ver = @"1.0.0"; ver = @"1.0.0";
} }
if (openstep) if (openstep)
{ {
[top setObject: ver forKey: @"ovadd"]; [top setObject: ver forKey: @"ovadd"];
} }
else else
{ {
[top setObject: ver forKey: @"gvadd"]; [top setObject: ver forKey: @"gvadd"];
} }
[self parseSpace: spaces]; [self parseSpace: spaces];
if (pos < length && buffer[pos] == ',') if (pos < length && buffer[pos] == ',')
{ {
pos++; pos++;
} }
ver = [self parseVersion]; ver = [self parseVersion];
if ([ver length] == 0) if ([ver length] == 0)
{ {
ver = @"99.99.99"; ver = @"99.99.99";
} }
if ([ver isEqualToString: @"99.99.99"] == NO) if ([ver isEqualToString: @"99.99.99"] == NO)
{ {
if (openstep) if (openstep)
{ {
[top setObject: ver forKey: @"ovrem"]; [top setObject: ver forKey: @"ovrem"];
} }
else else
{ {
[top setObject: ver forKey: @"gvrem"]; [top setObject: ver forKey: @"gvrem"];
} }
} }
[self parseSpace: spaces]; [self parseSpace: spaces];
if (pos < length && buffer[pos] == ',') if (pos < length && buffer[pos] == ',')
{ {
pos++; pos++;
ver = [self parseVersion]; ver = [self parseVersion];
if ([ver length] == 0) if ([ver length] == 0)
{ {
ver = @"99.99.99"; ver = @"99.99.99";
} }
if ([ver isEqualToString: @"99.99.99"] == NO) if ([ver isEqualToString: @"99.99.99"] == NO)
{ {
if (openstep) if (openstep)
{ {
[top setObject: ver forKey: @"ovdep"]; [top setObject: ver forKey: @"ovdep"];
} }
else else
{ {
[top setObject: ver forKey: @"gvdep"]; [top setObject: ver forKey: @"gvdep"];
} }
} }
[self parseSpace: spaces]; [self parseSpace: spaces];
} }
if (pos < length && buffer[pos] == ')') if (pos < length && buffer[pos] == ')')
{ {
pos++; pos++;
} }
[self parseSpace: spaces]; [self parseSpace: spaces];
if (pos < length-1 && buffer[pos] == '&' && buffer[pos+1] == '&') if (pos < length-1 && buffer[pos] == '&' && buffer[pos+1] == '&')
{ {
pos += 2; pos += 2;
} }
else else
{ {
break; // may only join version macros with && break; // may only join version macros with &&
} }
} }
[ifStack addObject: top]; [ifStack addObject: top];
RELEASE(top); RELEASE(top);
return [self skipRemainderOfLine];
} }
else if ([directive hasPrefix: @"if"]) else if ([directive isEqual: @"ifdef"])
{ {
BOOL isIfDef = [directive isEqual: @"ifdef"];
[self parseSpace: spaces]; [self parseSpace: spaces];
if (pos < length && buffer[pos] != '\n') if (pos < length && buffer[pos] != '\n')
{ {
@ -4076,47 +4090,64 @@ countAttributes(NSSet *keys, NSDictionary *a)
arg = [self parseIdentifier]; arg = [self parseIdentifier];
if ([arg isEqual: @"NO_GNUSTEP"]) if ([arg isEqual: @"NO_GNUSTEP"])
{ {
if (isIfDef) [self log: @"Unexpected #ifdef NO_GNUSTEP (nonsense)"];
{
[self log: @"Unexpected #ifdef NO_GNUSTEP (nonsense)"];
}
else
{
[top removeObjectForKey: @"MacOS-X"];
[top setObject: @"NotMacOS-X" forKey: @"NotMacOS-X"];
[top removeObjectForKey: @"OpenStep"];
[top setObject: @"NotOpenStep" forKey: @"NotOpenStep"];
}
} }
else if ([arg isEqual: @"STRICT_MACOS_X"]) else if ([arg isEqual: @"STRICT_MACOS_X"])
{ {
if (isIfDef) [top removeObjectForKey: @"NotMacOS-X"];
{ [top setObject: @"MacOS-X" forKey: @"MacOS-X"];
[top removeObjectForKey: @"NotMacOS-X"];
[top setObject: @"MacOS-X" forKey: @"MacOS-X"];
}
else
{
[top removeObjectForKey: @"MacOS-X"];
[top setObject: @"NotMacOS-X" forKey: @"NotMacOS-X"];
}
} }
else if ([arg isEqual: @"STRICT_OPENSTEP"]) else if ([arg isEqual: @"STRICT_OPENSTEP"])
{ {
if (isIfDef) [top removeObjectForKey: @"NotOpenStep"];
{ [top setObject: @"OpenStep" forKey: @"OpenStep"];
[top removeObjectForKey: @"NotOpenStep"];
[top setObject: @"OpenStep" forKey: @"OpenStep"];
}
else
{
[top removeObjectForKey: @"OpenStep"];
[top setObject: @"NotOpenStep" forKey: @"NotOpenStep"];
}
} }
[ifStack addObject: top]; [ifStack addObject: top];
RELEASE(top); RELEASE(top);
} }
return [self skipRemainderOfLine];
}
else if ([directive isEqual: @"ifndef"])
{
[self parseSpace: spaces];
if (pos < length && buffer[pos] != '\n')
{
NSMutableDictionary *top;
NSString *arg;
top = [[ifStack lastObject] mutableCopy];
arg = [self parseIdentifier];
if ([arg isEqual: @"NO_GNUSTEP"])
{
[top removeObjectForKey: @"MacOS-X"];
[top setObject: @"NotMacOS-X" forKey: @"NotMacOS-X"];
[top removeObjectForKey: @"OpenStep"];
[top setObject: @"NotOpenStep" forKey: @"NotOpenStep"];
}
else if ([arg isEqual: @"STRICT_MACOS_X"])
{
[top removeObjectForKey: @"MacOS-X"];
[top setObject: @"NotMacOS-X" forKey: @"NotMacOS-X"];
}
else if ([arg isEqual: @"STRICT_OPENSTEP"])
{
[top removeObjectForKey: @"OpenStep"];
[top setObject: @"NotOpenStep" forKey: @"NotOpenStep"];
}
[ifStack addObject: top];
RELEASE(top);
}
return [self skipRemainderOfLine];
}
else if ([directive isEqual: @"import"]
|| [directive isEqual: @"include"])
{
return [self skipRemainderOfLine];
}
else
{
[self log: @"Warning - unknown preprocessor directive %@", directive];
return [self skipRemainderOfLine];
} }
} }
return [self skipRemainderOfLine]; return [self skipRemainderOfLine];
@ -4840,7 +4871,7 @@ fail:
{ {
while (pos < length) while (pos < length)
{ {
if (buffer[pos++] == '\n') if ('\n' == buffer[pos++])
{ {
break; break;
} }
@ -4856,7 +4887,7 @@ fail:
if ([spaces characterIsMember: c] == NO) if ([spaces characterIsMember: c] == NO)
{ {
break; break;
} }
pos++; pos++;
} }
@ -4975,5 +5006,46 @@ fail:
{ {
return AUTORELEASE([source mutableCopy]); return AUTORELEASE([source mutableCopy]);
} }
- (NSString*) where
{
int index;
int start = 0;
int end;
NSString *l;
NSString *s;
for (index = [lines count] - 1; index >= 0; index--)
{
NSNumber *num = [lines objectAtIndex: index];
if ((start = [num intValue]) <= (int)pos)
{
break;
}
}
if (index >= [lines count] || index < 0)
{
start = 0;
index = -1;
}
if (index + 1 < [lines count])
{
end = [[lines objectAtIndex: index + 1] intValue];
}
else
{
end = length;
}
l = [[NSString alloc] initWithCharactersNoCopy: buffer + start
length: end - start
freeWhenDone: NO];
s = [NSString stringWithFormat: @"Character %d in line %d:%@",
pos - start, index + 2, l];
RELEASE(l);
return s;
}
@end @end