Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.
NORMALIZE()
We’re hard-pressed to come up with an explanation of how this little gem got added to the language. Its purpose is to validate an expression as legitimate VFP syntax, and it does an okay “first pass” job of it, but testing TYPE()
and EVAL() is just as accurate. Nonetheless, this is a cool function that makes it easier to compare user input to information you retrieve using FoxPro functions. NORMALIZE()
takes a string and converts it to a standard format like that returned by many of FoxPro’s built-in functions. FoxPro keywords get expanded to full length and converted to uppercase, and the “->” turns into a period. Plus, the syntax of the expression is checked.
cCleanExpr = NORMALIZE( cExpr )
Many FoxPro functions (like KEY()
, FILTER()
and so on) return expressions in a particular format. NORMALIZE()
lets you convert other expressions to the same format, making comparisons much easier.
NORMALIZE()
does some error checking of the expression. The key word here is “some.” If the expression isn’t syntactically valid, you get an error message. For example, if you pass “x and “, you get a “Missing Operand” error. (Make sure you’ve got an error handler in place to catch it.)
Don’t expect NORMALIZE()
to catch all the errors in input expressions, though. It only looks for the most basic syntax errors. The semantics of the expression aren’t checked at all, so if you, say, compare a character field to a date field, NORMALIZE()
won’t yell about it. Even a flaw as simple as ‘“abc”=37’ doesn’t trigger an error message.
In addition, NORMALIZE()
behaves like a number of FoxPro commands in ignoring anything following a valid expression. That is, NORMALIZE(“x y”) returns “X” rather than an error message. No doubt that’s because, until VFP 5, you could compile and run:
IF X Y
without an error message. The “Y” was seen as a comment. We wish the developers had made NORMALIZE()
’s test more stringent, though.
In spite of the error-checking weaknesses, we still think NORMALIZE()
is pretty cool. Just don’t count on it to find errors in input expressions. Even though it’s cool, we can’t see a lot of places we’re going to actually use NORMALIZE()
—let us know if you come up with some.
? NORMALIZE('upper(Region)="PA" and allt(Last_Name)="Grant"')
* Above returns
* 'UPPER(REGION)="PA".AND.ALLTRIM(LAST_NAME)="Grant"'
? NORMALIZE('Employee->Birth_date > {01/01/65}')
* Above returns
* 'EMPLOYEE.BIRTH_DATE>{01/01/1965}'
* You can apply NORMALIZE() to Expression Builder results
GETEXPR "Enter Filter" TO cFilt
cFilt = NORMALIZE(cFilt)
IF cFilt = FILTER()
* Do something
ELSE
* Do something different
ENDIF