* EOControl/EOQualifier.m (cimSEL, spaceSet, alnumSet, digitSet)

(spaceCIM, alnumCIM, digitCIM): New static globals for unichar
	handling.
	([+initialize]): Initialize new variables.
	(getOperator, getKey, isNotQualifier, whichQualifier): Use
	unichar instead of char.
	([+qualifierWithQualifierFormat:varargList:]): Ditto.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@22124 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
David Ayers 2005-11-30 15:51:31 +00:00
parent f4651ff1a7
commit c1a9dc7ab1
2 changed files with 198 additions and 104 deletions

View file

@ -1,3 +1,13 @@
2005-11-30 David Ayers <d.ayers@inode.at>
* EOControl/EOQualifier.m (cimSEL, spaceSet, alnumSet, digitSet)
(spaceCIM, alnumCIM, digitCIM): New static globals for unichar
handling.
([+initialize]): Initialize new variables.
(getOperator, getKey, isNotQualifier, whichQualifier): Use
unichar instead of char.
([+qualifierWithQualifierFormat:varargList:]): Ditto.
2005-11-28 David Ayers <d.ayers@inode.at> 2005-11-28 David Ayers <d.ayers@inode.at>
* EOControl/EOSharedEditingContext.[hm]: New files. * EOControl/EOSharedEditingContext.[hm]: New files.

View file

@ -100,6 +100,32 @@ NSString *EOQualifierVariableSubstitutionException=@"EOQualifierVariableSubstitu
@end @end
@implementation EOQualifier @implementation EOQualifier
static SEL cimSEL = NULL;
static NSCharacterSet *spaceSet;
static NSCharacterSet *alnumSet;
static NSCharacterSet *digitSet;
static BOOL (*spaceCIM)(id,SEL,unichar);
static BOOL (*alnumCIM)(id,SEL,unichar);
static BOOL (*digitCIM)(id,SEL,unichar);
+ (void)initialize
{
if (cimSEL == NULL)
{
cimSEL = @selector(characterIsMember:);
spaceSet
= RETAIN([NSCharacterSet whitespaceAndNewlineCharacterSet]);
spaceCIM = (BOOL(*)(id,SEL,unichar))[spaceSet methodForSelector: cimSEL];
alnumSet
= RETAIN([NSCharacterSet alphanumericCharacterSet]);
alnumCIM = (BOOL(*)(id,SEL,unichar))[alnumSet methodForSelector: cimSEL];
digitSet
= RETAIN([NSCharacterSet decimalDigitCharacterSet]);
digitCIM = (BOOL(*)(id,SEL,unichar))[digitSet methodForSelector: cimSEL];
}
}
/** /**
* Returns an autoreleased qualifier which is constructed by calling * Returns an autoreleased qualifier which is constructed by calling
@ -146,53 +172,59 @@ NSString *EOQualifierVariableSubstitutionException=@"EOQualifierVariableSubstitu
#endif #endif
} }
static NSString *getOperator(const char **cFormat, const char **s) static NSString *getOperator(const unichar **cFormat, const unichar **s)
{ {
NSString *operator; NSString *operator;
while (**s && isspace(**s)) while (**s && spaceCIM(spaceSet,cimSEL,**s))
(*s)++; (*s)++;
*cFormat = *s; *cFormat = *s;
if (isalnum(**s)) if (alnumCIM(alnumSet,cimSEL,**s))
{ {
while (**s && !isspace(**s) && **s != '%' && **s != '\'') while (**s && !spaceCIM(spaceSet,cimSEL,**s)
&& **s != '%' && **s != '\'')
{ {
(*s)++; (*s)++;
} }
operator = [NSString stringWithCString: *cFormat length: *s - *cFormat]; operator = [NSString stringWithCharacters: *cFormat
length: *s - *cFormat];
} }
else else
{ {
while (**s && !isalnum(**s) && !isspace(**s) && **s != '%' && **s != '\'') while (**s && !alnumCIM(alnumSet, cimSEL, **s)
&& !spaceCIM(spaceSet, cimSEL, **s)
&& **s != '%' && **s != '\'')
{ {
NSDebugLog(@"avoid gcc 3.1.1 bug which optimizes to segfault", ""); NSDebugLog(@"avoid gcc 3.1.1 bug which optimizes to segfault",
@"avoid gcc 3.1.1 bug which optimizes to segfault");
(*s)++; (*s)++;
} }
operator = [NSString stringWithCString: *cFormat length: *s - *cFormat]; operator = [NSString stringWithCharacters: *cFormat
length: *s - *cFormat];
} }
*cFormat = *s; *cFormat = *s;
return operator; return operator;
} }
static id static id
getKey(const char **cFormat, getKey(const unichar **cFormat,
const char **s, const unichar **s,
BOOL *isKeyValue, BOOL *isKeyValue,
va_list *args) va_list *args)
{ {
NSMutableString *key; NSMutableString *key;
NSString *classString = nil; NSString *classString = nil;
char quoteChar; unichar quoteChar;
BOOL quoted = NO; BOOL quoted = NO;
BOOL literalNumber = NO; BOOL literalNumber = NO;
while (**s && isspace(**s)) while (**s && spaceCIM(spaceSet, cimSEL, **s))
(*s)++; (*s)++;
if (isKeyValue) if (isKeyValue)
@ -206,15 +238,15 @@ getKey(const char **cFormat,
NSCAssert(*s, @"Illegal Qualifer format missing bracket."); NSCAssert(*s, @"Illegal Qualifer format missing bracket.");
classString = [NSString stringWithCString: *cFormat classString = [NSString stringWithCharacters: *cFormat
length: *s - *cFormat]; length: *s - *cFormat];
(*s)++; *cFormat = *s; (*s)++; *cFormat = *s;
} }
if (!strncmp("nil", *s, 3)) if ((*s)[0] == 'n' && (*s)[1] == 'i' && (*s)[2] == 'l')
{ {
char value = *(*s+3); unichar value = *(*s+3);
if (value == 0 || value == ' ') if (value == 0 || value == ' ')
{ {
@ -239,7 +271,7 @@ getKey(const char **cFormat,
while (**s && **s != quoteChar) while (**s && **s != quoteChar)
(*s)++; (*s)++;
key = [NSString stringWithCString: *cFormat length: *s - *cFormat]; key = [NSString stringWithCharacters: *cFormat length: *s - *cFormat];
(*s)++; // skip closing quote (*s)++; // skip closing quote
} }
else else
@ -247,14 +279,16 @@ getKey(const char **cFormat,
key = [NSMutableString stringWithCapacity:8]; key = [NSMutableString stringWithCapacity:8];
if (classString == nil if (classString == nil
&& (isdigit(**s) || (**s == '-' && isdigit(*(*s+1))))) && (digitCIM(digitSet, cimSEL, **s)
|| (**s == '-' && digitCIM(digitSet, cimSEL, *(*s+1)))))
{ {
classString = @"NSNumber"; classString = @"NSNumber";
literalNumber = YES; literalNumber = YES;
} }
while (**s && (isalnum(**s) || **s == '@' || **s == '#' || **s == '_' while (**s && (alnumCIM(alnumSet,cimSEL,**s)
|| **s == '$' || **s == '%' || **s == '.' || **s == '-')) || **s == '@' || **s == '#' || **s == '_' || **s == '$'
|| **s == '%' || **s == '.' || **s == '-'))
{ {
if (**s == '%') if (**s == '%')
{ {
@ -263,8 +297,9 @@ getKey(const char **cFormat,
double argFloat; double argFloat;
/* 'float' is promoted to 'double' when passed through '...' /* 'float' is promoted to 'double' when passed through '...'
(so you should pass 'double' not 'float' to `va_arg') (so you should pass 'double' not 'float' to `va_arg')
Ayers: I believe the compiler should does promotion implicitly Ayers: I believe the compiler should do this promotion
but there are buggy compilers so cast to be safe. */ implicitly but there are buggy compilers so cast to
be safe. */
int argInt; int argInt;
@ -278,8 +313,8 @@ getKey(const char **cFormat,
case '@': case '@':
argObj = va_arg(*args, id); argObj = va_arg(*args, id);
if (isKeyValue && *isKeyValue == YES && quoted == NO if (isKeyValue && *isKeyValue == YES
&& classString == nil) && quoted == NO && classString == nil)
{ {
*cFormat = *s = *s+2; *cFormat = *s = *s+2;
return argObj; return argObj;
@ -287,8 +322,12 @@ getKey(const char **cFormat,
else else
{ {
if (*cFormat != *s) if (*cFormat != *s)
[key appendString: [NSString stringWithCString: *cFormat {
length: *s - *cFormat]]; NSString *str
= [NSString stringWithCharacters: *cFormat
length: *s - *cFormat];
[key appendString: str];
}
[key appendString: [argObj description]]; [key appendString: [argObj description]];
*cFormat = *s+2; *cFormat = *s+2;
@ -299,20 +338,25 @@ getKey(const char **cFormat,
case 's': case 's':
argString = va_arg(*args, const char *); argString = va_arg(*args, const char *);
if (isKeyValue && *isKeyValue == YES && quoted == NO if (isKeyValue && *isKeyValue == YES
&& classString == nil) && quoted == NO && classString == nil)
{ {
*cFormat = *s = *s + 2; *cFormat = *s = *s + 2;
return [NSString stringWithCString: argString]; return [NSString stringWithCString: argString];
} }
else else
{ {
NSString *str;
if (*cFormat != *s) if (*cFormat != *s)
[key appendString: [NSString stringWithCString: *cFormat {
length: *s - *cFormat]]; str = [NSString stringWithCharacters: *cFormat
length: *s - *cFormat];
[key appendString: str];
}
str = [NSString stringWithCString: argString];
[key appendString: str];
[key appendString: [NSString
stringWithCString: argString]];
*cFormat = *s + 2; *cFormat = *s + 2;
(*s)++; (*s)++;
} }
@ -321,27 +365,34 @@ getKey(const char **cFormat,
case 'd': case 'd':
argInt = va_arg(*args, int); argInt = va_arg(*args, int);
if (isKeyValue && *isKeyValue == YES && quoted == NO if (isKeyValue && *isKeyValue == YES
&& classString == nil) && quoted == NO && classString == nil)
{ {
*cFormat = *s = *s + 2; *cFormat = *s = *s + 2;
return [NSNumber numberWithInt: argInt]; return [NSNumber numberWithInt: argInt];
} }
else else
{ {
NSString *str;
if(*cFormat != *s) if(*cFormat != *s)
[key appendString: [NSString stringWithCString: *cFormat {
length: *s - *cFormat]]; str = [NSString stringWithCharacters: *cFormat
length: *s - *cFormat];
[key appendString: str];
}
str = [NSString stringWithFormat: @"%d", argInt];
[key appendString: str];
[key appendString: [NSString stringWithFormat: @"%d",
argInt]];
*cFormat = *s + 2; *cFormat = *s + 2;
(*s)++; (*s)++;
} }
break; break;
case 'f': case 'f':
argFloat = va_arg(*args, double);// `float' is promoted to `double' when passed through `...' (so you should pass `double' not `float' to `va_arg') /* 'float' is promoted to 'double' when passed through '...'
(so you should pass `double' not `float' to `va_arg') */
argFloat = va_arg(*args, double);
if (isKeyValue && *isKeyValue == YES && quoted == NO if (isKeyValue && *isKeyValue == YES && quoted == NO
&& classString == nil) && classString == nil)
@ -351,12 +402,18 @@ getKey(const char **cFormat,
} }
else else
{ {
if (*cFormat != *s) NSString *str;
[key appendString: [NSString stringWithCString: *cFormat
length: *s - *cFormat]]; if (*cFormat != *s)
{
str = [NSString stringWithCharacters: *cFormat
length: *s - *cFormat];
[key appendString: str];
}
str = [NSString stringWithFormat: @"%f", argFloat];
[key appendString: str];
[key appendString: [NSString stringWithFormat: @"%f",
argFloat]];
*cFormat = *s + 2; *cFormat = *s + 2;
(*s)++; (*s)++;
} }
@ -365,14 +422,21 @@ getKey(const char **cFormat,
case '%': case '%':
*cFormat = *s + 2; *cFormat = *s + 2;
(*s)++; (*s)++;
[key appendString: [NSString stringWithCString: *cFormat [key appendString: [NSString stringWithCharacters: *cFormat
length: *s - *cFormat]]; length: *s - *cFormat]];
break; break;
default: default:
[NSException raise: NSInvalidArgumentException {
format: @"%@ -- %@: unrecognized character (%c) in the conversion specification", @"qualifierParser", @"EOQualifier", *(*s + 1)]; NSString *fmt
break; = @"%@ -- %@: unrecognized character (%@) in the conversion specification";
NSString *specChar
= [NSString stringWithCharacters: (*s + 1) length: 1];
[NSException raise: NSInvalidArgumentException
format: fmt, @"EOQualifier",
@"qualifierParser", specChar];
break;
}
} }
} }
@ -380,8 +444,11 @@ getKey(const char **cFormat,
} }
if (*cFormat != *s) if (*cFormat != *s)
[key appendString: [NSString stringWithCString: *cFormat {
length: *s - *cFormat]]; NSString *str = [NSString stringWithCharacters: *cFormat
length: *s - *cFormat];
[key appendString: str];
}
} }
if (isKeyValue) if (isKeyValue)
@ -390,8 +457,8 @@ getKey(const char **cFormat,
if (classString) if (classString)
{ {
key = AUTORELEASE([[NSClassFromString(classString) alloc] Class cls = NSClassFromString(classString);
initWithString: key]); key = AUTORELEASE([[cls alloc] initWithString: key]);
} }
} }
@ -400,14 +467,16 @@ getKey(const char **cFormat,
return key; return key;
} }
static BOOL isNotQualifier(const char **cFormat, const char **s) static BOOL isNotQualifier(const unichar **cFormat, const unichar **s)
{ {
while (**s && isspace(**s)) while (**s && spaceCIM(spaceSet,cimSEL,**s))
(*s)++; (*s)++;
*cFormat = *s; *cFormat = *s;
if (!strncasecmp(*s, "not", 3)) if (((*s)[0]=='n' || (*s)[0]=='N')
&& ((*s)[1]=='o' || (*s)[1]=='O')
&& ((*s)[2]=='t' || (*s)[2]=='T'))
{ {
switch ((*s)[3]) switch ((*s)[3])
{ {
@ -422,14 +491,16 @@ static BOOL isNotQualifier(const char **cFormat, const char **s)
return NO; return NO;
} }
static Class whichQualifier(const char **cFormat, const char **s) static Class whichQualifier(const unichar **cFormat, const unichar **s)
{ {
while (**s && isspace(**s)) while (**s && spaceCIM(spaceSet,cimSEL,**s))
(*s)++; (*s)++;
*cFormat = *s; *cFormat = *s;
if (!strncasecmp(*s, "and", 3)) if (((*s)[0]=='a' || (*s)[0]=='A')
&& ((*s)[1]=='n' || (*s)[1]=='N')
&& ((*s)[2]=='d' || (*s)[2]=='D'))
{ {
switch ((*s)[3]) switch ((*s)[3])
{ {
@ -440,7 +511,8 @@ static Class whichQualifier(const char **cFormat, const char **s)
return [EOAndQualifier class]; return [EOAndQualifier class];
} }
} }
else if (!strncasecmp(*s, "or", 2)) else if (((*s)[0]=='o' || (*s)[0]=='O')
&& ((*s)[1]=='r' || (*s)[1]=='R'))
{ {
switch ((*s)[2]) switch ((*s)[2])
{ {
@ -458,8 +530,9 @@ static Class whichQualifier(const char **cFormat, const char **s)
+ (EOQualifier *)qualifierWithQualifierFormat: (NSString *)format + (EOQualifier *)qualifierWithQualifierFormat: (NSString *)format
varargList: (va_list)args varargList: (va_list)args
{ {
const char *s; unichar *s0;
const char *cFormat; const unichar *s;
const unichar *cFormat;
NSMutableArray *bracketStack = nil; NSMutableArray *bracketStack = nil;
NSMutableArray *qualifierArray = nil; NSMutableArray *qualifierArray = nil;
NSMutableArray *parentQualifiers = nil; NSMutableArray *parentQualifiers = nil;
@ -472,15 +545,21 @@ static Class whichQualifier(const char **cFormat, const char **s)
BOOL notQual; BOOL notQual;
Class lastQualifierClass = Nil; Class lastQualifierClass = Nil;
Class qualifierClass = Nil; Class qualifierClass = Nil;
unsigned formatLen;
bracketStack = [NSMutableArray array]; bracketStack = [NSMutableArray array];
parentQualifiers = [NSMutableArray array]; parentQualifiers = [NSMutableArray array];
cFormat = s = [format cString]; formatLen = [format length];
s0 = GSAutoreleasedBuffer((formatLen+1) * sizeof(unichar));
[format getCharacters: s0];
s0[formatLen] = '\0';
cFormat = s = s0;
while (*s) while (*s)
{ {
while (*s && isspace(*s)) while (*s && spaceCIM(spaceSet,cimSEL,*s))
(s)++; (s)++;
while (*s == '(' ) while (*s == '(' )
@ -488,10 +567,11 @@ static Class whichQualifier(const char **cFormat, const char **s)
NSMutableDictionary *state; NSMutableDictionary *state;
state = [NSMutableDictionary dictionaryWithCapacity:4]; state = [NSMutableDictionary dictionaryWithCapacity:4];
if (lastQualifierClass != NULL) if (lastQualifierClass != Nil)
{ {
[state setObject: lastQualifierClass forKey: @"lastQualifierClass"]; [state setObject: lastQualifierClass
lastQualifierClass = NULL; forKey: @"lastQualifierClass"];
lastQualifierClass = Nil;
} }
if (qualifierArray != nil) if (qualifierArray != nil)
{ {
@ -509,7 +589,7 @@ static Class whichQualifier(const char **cFormat, const char **s)
[bracketStack addObject:state]; [bracketStack addObject:state];
(s)++; // skip '(' (s)++; // skip '('
while (*s && isspace(*s)) while (*s && spaceCIM(spaceSet, cimSEL, *s))
(s)++; (s)++;
} }
@ -520,11 +600,14 @@ static Class whichQualifier(const char **cFormat, const char **s)
operatorSelector = [EOQualifier operatorSelectorForString: operator]; operatorSelector = [EOQualifier operatorSelectorForString: operator];
if (!operatorSelector) if (!operatorSelector)
[NSException raise: NSInvalidArgumentException {
format: @"%@ -- %@ 0x%x: no operator or unknown operator: '%@'", [NSException raise: NSInvalidArgumentException
NSStringFromSelector(_cmd), format: @"%@ -- %@ 0x%x: no operator or unknown operator: '%@'",
NSStringFromClass([self class]), self, NSStringFromClass([self class]),
operator]; NSStringFromSelector(_cmd),
self,
operator];
}
EOFLOGObjectLevelArgs(@"EOQualifier", EOFLOGObjectLevelArgs(@"EOQualifier",
@"leftKey=%@ operatorSelector=%s rightKey=%@ class=%@", @"leftKey=%@ operatorSelector=%s rightKey=%@ class=%@",
@ -554,49 +637,50 @@ static Class whichQualifier(const char **cFormat, const char **s)
@"qualifier=%@", @"qualifier=%@",
qualifier); qualifier);
while (*s && isspace(*s)) while (*s && spaceCIM(spaceSet,cimSEL,*s))
(s)++; (s)++;
while (*s == ')' ) while (*s == ')' )
{ {
NSMutableDictionary *state; NSMutableDictionary *state;
/* clean up inner qualifier */ /* clean up inner qualifier */
if (qualifierArray != nil) if (qualifierArray != nil)
{ {
[qualifierArray addObject:qualifier]; [qualifierArray addObject:qualifier];
qualifier = AUTORELEASE([[qualifierClass alloc] qualifier
initWithQualifierArray: qualifierArray]); = AUTORELEASE([[qualifierClass alloc]
qualifierArray = nil; initWithQualifierArray: qualifierArray]);
} qualifierArray = nil;
}
while ([parentQualifiers count] != 0) while ([parentQualifiers count] != 0)
{ {
id parent; id parent;
NSArray *quals; NSArray *quals;
parent = [parentQualifiers lastObject]; parent = [parentQualifiers lastObject];
quals = [[parent qualifiers] arrayByAddingObject: qualifier]; quals = [[parent qualifiers] arrayByAddingObject: qualifier];
qualifier = AUTORELEASE([[[parent class] alloc] qualifier = AUTORELEASE([[[parent class] alloc]
initWithQualifierArray: quals]); initWithQualifierArray: quals]);
[parentQualifiers removeLastObject]; [parentQualifiers removeLastObject];
} }
DESTROY(parentQualifiers); DESTROY(parentQualifiers);
/* pop bracketStack */ /* pop bracketStack */
state = [bracketStack lastObject]; state = [bracketStack lastObject];
qualifierArray = [state objectForKey:@"qualifierArray"]; qualifierArray = [state objectForKey:@"qualifierArray"];
lastQualifierClass = [state objectForKey:@"lastQualifierClass"]; lastQualifierClass = [state objectForKey:@"lastQualifierClass"];
qualifierClass = [state objectForKey:@"qualifierClass"]; qualifierClass = [state objectForKey:@"qualifierClass"];
parentQualifiers = [state objectForKey:@"parentQualifiers"]; parentQualifiers = [state objectForKey:@"parentQualifiers"];
[bracketStack removeLastObject]; [bracketStack removeLastObject];
(s)++; // skip ')' (s)++; // skip ')'
while (*s && isspace(*s)) while (*s && spaceCIM(spaceSet,cimSEL,*s))
(s)++; (s)++;
} }
qualifierClass = whichQualifier(&cFormat, &s); qualifierClass = whichQualifier(&cFormat, &s);
EOFLOGObjectLevelArgs(@"EOQualifier", @"qualifierClass=%@", EOFLOGObjectLevelArgs(@"EOQualifier", @"qualifierClass=%@",