Purpose: Check if a test string contains a date and is of the form implied by a control string The control string is interpreted as a simplfied regular expression. The method is aimed primarily at filtering filenames which are expected to contain dates and is not intended as a formal regular expression interpreter. The ? will match to any one character and the * will match to a series of zero or more characters as per the standards. However treatment of the [] constructs is more limited.

Return TypeFunction nameArguments
boolFormCheckDate(hzXDate&,const char*,const char*,)

Declared in file: hzTextproc.h
Defined in file : hzRegex.cpp

Function Logic:

0:START 1:items 2:unknown 3:Return true 4:unknown 5:Return false 6:test ctrl 7:unknown 8:unknown 9:unknown 10:unknown 11:unknown 12:Return true 13:Return false 14:unknown 15:items items 16:unknown 17:unknown 18:Return false 19:unknown 20:unknown 21:unknown 22:items ctrl 23:unknown 24:unknown 25:items ctrl 26:unknown 27:unknown 28:items ctrl 29:unknown 30:unknown 31:items ctrl 32:unknown 33:unknown 34:unknown 35:items ctrl 36:unknown 37:unknown 38:items ctrl 39:unknown 40:items ctrl 41:unknown 42:unknown 43:unknown 44:items ctrl 45:unknown 46:unknown 47:items ctrl 48:unknown 49:unknown 50:items ctrl 51:unknown 52:items ctrl 53:unknown 54:items items 55:Return false 56:unknown 57:unknown 58:items 59:pd.Y&&pd.M&&!pd.D 60:items 61:pd.Y&&!pd.M&&pd.D 62:items 63:pd.Y&&!pd.M&&!pd.D 64:items 65:!pd.Y&&pd.M&&pd.D 66:unknown 67:pd 68:items pd 69:items 70:!pd.Y&&pd.M&&!pd.D 71:items 72:!pd.Y&&!pd.M&&pd.D 73:items 74:!pd.Y&&!pd.M&&!pd.D 75:items 76:unknown 77:Return false 78:Return true

Function body:

bool FormCheckDate (hzXDate& xdate)const char* cpTest, const char* cpCtrl, 
{
   //  Category: Regular Expression
   //  
   //  Purpose: Check if a test string contains a date and is of the form implied by a control string
   //  
   //  The control string is interpreted as a simplfied regular expression. The method is aimed primarily at filtering filenames which are expected to contain
   //  dates and is not intended as a formal regular expression interpreter. The ? will match to any one character and the * will match to a series of zero or
   //  more characters as per the standards. However treatment of the [] constructs is more limited.
   //  
   //  Arguments: 1) xdate The hzXDate instance to be populated in the event of HadronZoo date forms in the control being met in the test.
   //     2) cpTest The test string
   //     3) cpCtrl The control or 'form' string
   //  
   //  Returns: True If the test string is of the form specified in the control
   //     False Otherwise. Note that this may be because the test string contains an invalid date or partial date.
   //  
   _hzfunc(__func__) ;
   _psudoDate  pd ;        //  For showing that anticipated date or partial date in the test string are valid
   const char* ctrl ;      //  For processing ctrl string into parts
   const char* test ;      //  Progressive ptr for test string
   uint32_t    val ;       //  For Hex number read
   xdate.Clear() ;
   if (!cpCtrl || !cpCtrl[0])  return true ;
   if (!cpTest || !cpTest[0])  return false ;
   test = cpTest ;
   ctrl = cpCtrl ;
   //  Perform the test
   for (; *test && *ctrl ;)
   {
       if (*ctrl == ''*'')
       {
           //  Because we don't know how many chars this pertains to, we recursivly call this function in a loop. We start with test
           //  where it is and advance it one place for each call. The control string for all these calls is set to one place beyond
           //  the asterisk(s).
           for (; *ctrl == ''*'';ctrl++) ;
           for (; *test ; test++)
           {
               if (FormCheckDate(xdate, test, ctrl))
                   return true ;
           }
           return false ;
       }
       if (*ctrl == ''?'')
           { test++ ; ctrl++ ; continue ; }
       if (*ctrl == ''{'')
       {
           if (!_set_psudo_date(pd, &test, &ctrl))
               return false ;
           continue ;
       }
       if (*ctrl == CHAR_BKSLASH)
       {
           //  This will be treated only as a backslash if followed by another backslash
           if (ctrl[1]== CHAR_BKSLASH)
               if (*test == CHAR_BKSLASH)
                   { test++ ; ctrl += 2; continue ; }
           if (ctrl[1]== ''n'')
               if (*test == CHAR_NL)
                   { test++ ; ctrl += 2; continue ; }
           //  Whitespace
           if (ctrl[1]== ''s'')
               if (*test == CHAR_CTRLL || *test == CHAR_NL || *test == CHAR_CR || *test == CHAR_TAB || *test == CHAR_CTRLK)
                   { test++ ; ctrl += 2; continue ; }
           //  Non white space
           if (ctrl[1]== ''S'')
               if (*test > CHAR_SPACE)
                   { test++ ; ctrl += 2; continue ; }
           if (ctrl[1]== ''c'')
           {
               //  \cx
               //  Matches the control character indicated by x. For example, \cM matches a Control-M or carriage return character.
               //  The value of x must be in the range of A-Z or a-z. If not, c is assumed to be a literal c character.
               if (ctrl[2]>&eq; ''a''&&ctrl[2]<&eq; ''z'')
                   if (*test == (ctrl[2]-''a''))
                       { test++ ; ctrl += 3; continue ; }
               if (ctrl[2]>&eq; ''A''&&ctrl[2]<&eq; ''Z'')
                   if (*test == (ctrl[2]-''A''))
                       { test++ ; ctrl += 3; continue ; }
               if (*test == ''c'')
                   { test++ ; ctrl += 2; continue ; }
           }
           if (ctrl[1]== ''x'')
               if (IsHexnum(val, ctrl+1))
                   if (*test == (uchar) (val & 0xff))
                       { test++ ; ctrl += 4; continue ; }
           if (ctrl[1]== ''t'')
               if (*test == CHAR_TAB)
                   { test++ ; ctrl += 2; continue ; }
           //  Cope with vertical tab
           if (ctrl[1]== ''v'')
               if (*test == CHAR_CTRLI)
                   { test++ ; ctrl += 2; continue ; }
           //  Cope with \f, \r, \n
           if (*test == ctrl[1])
               { test++ ; ctrl += 2; continue ; }
           //  Drop thru and just test for the backslash
       }
       //  No we have ordinary char in ctrl
       if (*test == *ctrl)
           { test++ ; ctrl++ ; continue ; }
       return false ;
   }
   if (pd.Y || pd.M || pd.D)
   {
       if ( pd.Y &&  pd.M &&  pd.D)
           xdate.SetDate(pd.Y, pd.M, pd.D) ;
       else if ( pd.Y &&  pd.M && !pd.D)
           xdate.SetDate(pd.Y, pd.M, 1);
       else if ( pd.Y && !pd.M &&  pd.D)   xdate.Clear() ; //  invalid
       else if ( pd.Y && !pd.M && !pd.D)   xdate.Clear() ; //  invalid
       else if (!pd.Y &&  pd.M &&  pd.D)
       {
           if (xdate.IsSet())
               pd.Y = xdate.Year() ;
           else
               { xdate.SysDateTime() ; pd.Y = xdate.Year() ; }
           xdate.SetDate(pd.Y, pd.M, pd.D) ;
       }
       else if (!pd.Y &&  pd.M && !pd.D)   xdate.Clear() ; //  invalid
       else if (!pd.Y && !pd.M &&  pd.D)   xdate.Clear() ; //  invalid
       else if (!pd.Y && !pd.M && !pd.D)   xdate.Clear() ; //  invalid
       //  if (!pd.Y || !pd.M || !pd.D)
       //   xdate.SysDateTime() ;
       //  if (!pd.Y) pd.Y = xdate.Year() ;
       //  if (!pd.M) pd.M = xdate.Month() ;
       //  if (!pd.D) pd.D = xdate.Day() ;
       //  xdate.SetDate(pd.Y, pd.M, pd.D) ;
       if (!xdate.IsSet())
           return false ;
   }
   return true ;
}