C/C++

C/C++

C/C++

Your one-stop destination to learn and collaborate about the latest innovations in IBM C/C++ for z/OS compilers to develop high-performing C/C++ applications and system programs on z/OS while maximizing hardware use and improving application performance.

 View Only
  • 1.  XL C regcomp/regexec always returns 1 for search

    Posted Fri June 30, 2023 12:24 PM

    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
    ------------------------------


  • 2.  RE: XL C regcomp/regexec always returns 1 for search

    Posted Fri June 30, 2023 12:57 PM

    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
    ------------------------------



  • 3.  RE: XL C regcomp/regexec always returns 1 for search

    Posted Fri June 30, 2023 02:21 PM

    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. 



    ------------------------------
    Eric Erickson
    ------------------------------



  • 4.  RE: XL C regcomp/regexec always returns 1 for search

    Posted Fri June 30, 2023 02:59 PM

    I got an answer from over in the IBM-MAIN Listserv. I needed to change REG_NOSUB to REG_EXTENDED on the regcomp call. I thought the docs stated that if I used REG_NOSUB on the regcomp call that when I called regexec it would only report on success or failure, as implied in the docs. But apparently it don't work that way. Surprise, Surprise.



    ------------------------------
    Eric Erickson
    ------------------------------