I know I could drop into assembler to do this, but would like to keep it all C. The regex way should work, as the web tool used to build the expression, works as expected for my test strings. Its just when I move the expression into my C program that I always get a rc of 1.
Original Message:
Sent: Fri June 30, 2023 12:56 PM
From: Scott Fagen
Subject: XL C regcomp/regexec always returns 1 for search
This really isn't an answer to your question, but in Z assembler, there are "translate" instructions (TR, TRT) which would allow for this process to be done much more simply. In one implementation, a programmer would create a translate table that has zeros in the "right places" (valid characters) and something else in the wrong places. The program would TRanslate the set of characters that should contain a DSN qualifier against this translate table. If the resultant set of bytes is all zero, then you know that the input set of characters were all in your set of valid characters.
I am not sure how you might do this in XL/C, but someone with more experience coding with it might have some more/better advice.
Scott
------------------------------
Scott Fagen
Mainframe Evangelist
CDW
www.cdw.com
Original Message:
Sent: Fri June 30, 2023 12:24 PM
From: Eric Erickson
Subject: XL C regcomp/regexec always returns 1 for search
I'm having an issue with trying to use a regular expression to validate an z/OS Dataset Name Qualifier. I traverse the DSN using strtok to extract a pointer to each qualifier. I built a regular expression that works using a web tool to identify any invalid characters. The string I build using the web tool is "[^A-Z0-9@#\$\}\-]+" which when I bring that up the mainframe I change to "[^A-Z0-9@#\\$\\}\\-]+" as I have to double the escape (\) otherwise the compiler issues a message.
Even when I shorted the regex to ""[^A-Z0-9]+" is returns a 1 for both strings (SCHEMA or SCH!MA) where I would expect the first to return 1 and second to return 0.
Basically I'm trying to validate that a string does not contain any lower case characters or any of the symbols except ($, @, #, -, or }).
Here is a subset of the code.
if (regcomp(&pRegExp, pszDsnPattern, REG_NOSUB) == 0)
{
printf("ZDP2999T: RegEx compiled %s.\n", pszDsnPattern);
/*
** Regular Expression compiled, make a copy of the buffer, as strtok
** is going to destroy it during tokenization.
*/
strcpy(cBuffer, pszKeyValue);
/*
** Get the first token in the string.
*/
pszToken = strtok(cBuffer, ".");
/*
** And loop through the string processing each returned string.
*/
do
{
/*
** Perform z/OS Dataset Name Validation. Check the qualifier length
** and first character for validity.
*/
printf("ZDP2999T: Qualifier \"%s\".\n", pszToken);
if (strlen(pszToken) <= 8 && (isupper(pszToken[0]) || pszToken[0] == '$' ||
pszToken[0] == '@' || pszToken[0] == '#'))
{
printf("ZDP2999T: Valid first char %c.\n", pszToken[0]);
if ((iRc = regexec(&pRegExp, pszToken, 0, NULL, 0)) == 0)
{
bValidDbHlq = FALSE;
}
}
else{
bValidDbHlq = FALSE;
}
} while ((pszToken = strtok(NULL, ".")) && bValidDbHlq);
/*
** Free the regex allocated storage.
*/
regfree(&pRegExp);
Note: I do handle the special case of the first character via a separate test, but don't want to iterate through the remaining characters in a loop.
This is all under XL C under z/OS 2.5.
------------------------------
Eric Erickson
------------------------------