make the parser recursive on a single scanner instead of using substrings

This commit is contained in:
Riccardo Mottola 2021-07-06 04:58:20 +02:00
parent 34a07aa4d5
commit 079467ccc1

View file

@ -167,84 +167,115 @@
[tView setNeedsDisplay:YES]; [tView setNeedsDisplay:YES];
} }
- (NSArray *) parseArray: (NSString *)stringInput - (NSString *) parseString: (NSScanner *)scanner
{ {
if (nil != stringInput) NSString *str;
[scanner scanString: @"\"" intoString: NULL];
[scanner scanUpToString: @"\"" intoString: &str];
[scanner scanString: @"\"" intoString: NULL];
return str;
}
- (NSArray *) parseArray: (NSScanner *)scanner
{ {
NSMutableArray *mArray; NSMutableArray *mArray;
NSScanner *stringScanner; id value;
NSString *value; NSString *string = [scanner string];
BOOL elementEnd;
NSLog(@"parseArray in: %@", [string substringFromIndex: [scanner scanLocation]]);
mArray = [[NSMutableArray alloc] init]; mArray = [[NSMutableArray alloc] init];
stringScanner = [NSScanner scannerWithString: stringInput];
while([stringScanner isAtEnd] == NO) [scanner scanString: @"[" intoString: NULL];
elementEnd = NO;
value = nil;
while([scanner isAtEnd] == NO && elementEnd == NO)
{ {
[stringScanner scanString: @"{" intoString: NULL]; if ([string characterAtIndex:[scanner scanLocation]] == '\"')
[stringScanner scanUpToString: @"}" intoString: &value]; {
[stringScanner scanString: @"}" intoString: NULL]; value = [self parseString: scanner];
}
else if ([string characterAtIndex:[scanner scanLocation]] == '{')
{
[scanner scanString: @"{" intoString: NULL];
value = [self parseKeyValue: scanner];
}
else if ([string characterAtIndex:[scanner scanLocation]] == ']')
{
[scanner scanString: @"]" intoString: NULL];
elementEnd = YES;
}
if (![scanner isAtEnd] && [string characterAtIndex:[scanner scanLocation]] == ',')
{
[scanner scanString: @"," intoString: NULL];
}
NSLog(@"Array Element: %@", value); NSLog(@"Array Element: %@", value);
if (value)
{
[mArray addObject: value]; [mArray addObject: value];
} }
return [mArray autorelease];
} }
return nil; return [mArray autorelease];
} }
/* /*
parse subpart of the MI reply which may look like this: parse subpart of the MI reply which may look like this:
bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x0804872c",func="main",file="main.m",fullname="/home/multix/code/gnustep-svc/DirectoryTest/main.m",line="23",thread-groups=["i1"],times="1",original-location="main.m:23"} bkpt={number="1",type="breakpoint",disp="keep",enabled="y",addr="0x0804872c",func="main",file="main.m",fullname="/home/multix/code/gnustep-svc/DirectoryTest/main.m",line="23",thread-groups=["i1"],times="1",original-location="main.m:23"}
*/ */
- (NSDictionary *) parseKeyValueString: (NSString *)stringInput - (NSDictionary *) parseKeyValue: (NSScanner *)scanner
{
if (nil != stringInput)
{ {
NSMutableDictionary *mdict; NSMutableDictionary *mdict;
NSScanner *stringScanner;
NSString *key = NULL; NSString *key = NULL;
id value = nil; id value;
NSString *string = [scanner string];
BOOL elementEnd;
NSLog(@"scanning KV: %@", stringInput); NSLog(@"scanning KV: %@", [[scanner string] substringFromIndex:[scanner scanLocation]]);
mdict = [[NSMutableDictionary alloc] init]; mdict = [[NSMutableDictionary alloc] init];
stringScanner = [NSScanner scannerWithString: stringInput];
while([stringScanner isAtEnd] == NO) value = nil;
elementEnd = NO;
while([scanner isAtEnd] == NO && elementEnd == NO)
{ {
[stringScanner scanUpToString: @"=" intoString: &key]; [scanner scanUpToString: @"=" intoString: &key];
[stringScanner scanString: @"=" intoString: NULL]; [scanner scanString: @"=" intoString: NULL];
NSLog(@"key found: %@", key); NSLog(@"KV key found: %@", key);
if ([stringInput characterAtIndex:[stringScanner scanLocation]] == '[') if ([string characterAtIndex:[scanner scanLocation]] == '\"')
{ {
[stringScanner scanString: @"[" intoString: NULL]; value = [self parseString: scanner];
[stringScanner scanUpToString: @"]" intoString: &value];
[stringScanner scanString: @"]" intoString: NULL];
[stringScanner scanString: @"," intoString: NULL];
value = [self parseArray: value];
} }
else if ([stringInput characterAtIndex:[stringScanner scanLocation]] == '{') else if ([string characterAtIndex:[scanner scanLocation]] == '[')
{ {
[stringScanner scanString: @"{" intoString: NULL]; value = [self parseArray: scanner];
[stringScanner scanUpToString: @"}" intoString: &value];
[stringScanner scanString: @"}" intoString: NULL];
[stringScanner scanString: @"," intoString: NULL];
value = [self parseKeyValueString: value];
} }
else else if ([string characterAtIndex:[scanner scanLocation]] == '{')
{ {
[stringScanner scanString: @"\"" intoString: NULL]; value = [self parseKeyValue: scanner];
[stringScanner scanUpToString: @"\"" intoString: &value];
[stringScanner scanString: @"\"" intoString: NULL];
[stringScanner scanString: @"," intoString: NULL];
} }
if (![scanner isAtEnd] && [string characterAtIndex:[scanner scanLocation]] == '}')
{
[scanner scanString: @"}" intoString: NULL];
elementEnd = YES;
}
if (![scanner isAtEnd] && [string characterAtIndex:[scanner scanLocation]] == ',')
{
[scanner scanString: @"," intoString: NULL];
}
if (key != nil && value != nil) if (key != nil && value != nil)
[mdict setObject:value forKey:key]; [mdict setObject:value forKey:key];
} }
return [mdict autorelease]; return [mdict autorelease];
} }
return nil;
}
/* /*
Parses a line coming from the debugger. It could be eiher a stanard output or it may come from the machine Parses a line coming from the debugger. It could be eiher a standard output or it may come from the machine
interface of gdb. interface of gdb.
*/ */
- (PCDebuggerOutputTypes) parseStringLine: (NSString *)stringInput - (PCDebuggerOutputTypes) parseStringLine: (NSString *)stringInput
@ -286,7 +317,7 @@
NSDictionary *dict; NSDictionary *dict;
[stringScanner scanString: @"," intoString: NULL]; [stringScanner scanString: @"," intoString: NULL];
dict = [self parseKeyValueString: [stringInput substringFromIndex:[stringScanner scanLocation]]]; dict = [self parseKeyValue: stringScanner];
NSLog(@"type %@ value %@", dictionaryName, dict); NSLog(@"type %@ value %@", dictionaryName, dict);
if([dict objectForKey:@"pid"] != nil && if([dict objectForKey:@"pid"] != nil &&
@ -336,10 +367,8 @@
if(dictionaryName != nil) if(dictionaryName != nil)
{ {
id value = nil;
[stringScanner scanString: @"," intoString: NULL]; [stringScanner scanString: @"," intoString: NULL];
value = [self parseKeyValueString: [stringInput substringFromIndex:[stringScanner scanLocation]]]; dict = [self parseKeyValue: stringScanner];
NSLog(@"type %@ value %@", dictionaryName, dict); NSLog(@"type %@ value %@", dictionaryName, dict);
} }
@ -474,7 +503,7 @@
return unescapedString; return unescapedString;
} }
- (void) parseString: (NSString *)inputString - (void) parseLine: (NSString *)inputString
{ {
NSArray *components; NSArray *components;
NSEnumerator *en; NSEnumerator *en;
@ -525,7 +554,7 @@
encoding:[NSString defaultCStringEncoding]]; encoding:[NSString defaultCStringEncoding]];
// if( ! // if( !
[self parseString: dataString]; // ) [self parseLine: dataString]; // )
// { // {
// [self logString: dataString newLine: NO withColor:debuggerColor]; // [self logString: dataString newLine: NO withColor:debuggerColor];
// } // }