Log in

View Full Version : Is FindStr() intentionally case sensitive?


Robert Martens
17th February 2011, 19:37
At Gavino's suggestion (http://forum.doom9.org/showthread.php?p=1478732#post1478732), I'm starting a thread here to get some clarification.

While testing a recent update to a script of mine, I traced some unexpected behavior to the apparent case sensitivity of FindStr(). While I'd think such a feature might be useful to some people, it seems inconsistent with the other string functions (LeftStr, MidStr, RightStr, all case insensitive) and, as Gavino noted, the logical operators as applied to strings.

Beyond that, the example in the documentation, calling FindStr("AviSynth","syn") and getting a return value of 4, doesn't work; the function returns 0, unless I capitalize the 's' in "syn". I've found this happens in 2.5.6, 2.5.7, 2.5.8, SEt's 2.5.8MT, and the September 27th, 2009 2.6.0 alpha.

I've been able to avoid the issue in my own script by way of calling LCase() on strings before comparing them, but I'm still curious: is this sensitivity by design, and only a mixup in the docs, or is it an actual bug?

IanB
17th February 2011, 22:05
FindStr() has always used strstr so I guess it is by design. Some libc support the strcasestr() function, but it is a non-standard extension.

Functions like LeftStr are case agnostic rather than insensitive.

I guess the doco example was a typo, I have fixed it in CVS.

I am more concerned that == is case insensitive and there is no case sensitive alternative, but no-one has had an issue until now.

Given the tools LCase() or UCase() you can build case insensitive versions from case sensitive comparisons, but give case insensitive comparisons you cannot build case sensitive ones.AVSValue FindStr(AVSValue args, void*, IScriptEnvironment* env)
{ const char *pdest;
int result;

pdest = strstr( args[0].AsString(),args[1].AsString() );
result = pdest - args[0].AsString() +1;
if (pdest == NULL) result = 0;
return result;
}AVSValue ExpEqual::Evaluate(IScriptEnvironment* env)
{
AVSValue x = a->Evaluate(env);
AVSValue y = b->Evaluate(env);
...
else if (x.IsString() && y.IsString()) {
return !lstrcmpi(x.AsString(), y.AsString());
}
...

Robert Martens
17th February 2011, 22:58
... but no-one has had an issue until now.

Oh, I'm not really affected by it, I was only wondering. I just happened to realize that in all of my testing for previous releases of SimpleSlugUpscale, I'd been typing strings the way I'd intended them to be typed. "DVwidepNTSC", for example. Something compelled me to try it all lowercase this time, and when I did I got output that wasn't sized correctly, ultimately leading me to my use of FindStr().

I haven't gotten any complaints about it from users, but I made sure with version 1.10 to convert to lower case before checking the strings, just in case.

I'm sure it's nothing to worry about, if no one else has said anything, but thank you for clearing that up and updating the documentation!

Gavino
18th February 2011, 00:31
I am more concerned that == is case insensitive and there is no case sensitive alternative
Given that FindStr() is case-sensitive, you can do a case-sensitive equality test of strings A and B with
StrLen(A) == StrLen(B) && FindStr(A, B) == 1

Not-equals is obviously the converse, but case-sensitive comparisons like "<" are still impossible.