Validate the supplied percent entity. The scope tests differ by percent entity class as follows:- X (%x) Standard system values: These are global so as long as the named entity exists it will be valid. U (%u) Standard user values: Must exist and be within a form accessible to logged in users. S (%s) User session variables: These are valid within any form as long as named variable has been created in an earlier <procdata> command. E (%e) Event values: These are tested against the fields known to exist in the supplied form. I (%i) In-situ values: Must be within a form and name members of the form's native data class. V (%v) Session object values: These are valid if the name members of a session object that an earlier <procdata> command has brought into focus. Returns The basetype if the entity is found and can be evaluated. BASTETYPE_UNDEF otherwise.

Return TypeFunction nameArguments
hdbBasetypehdsApp::PcEntTest(hzString&,hdsFormdef*,hdbClass*,hzString&,)

Declared in file: hzDissemino.h
Defined in file : hdsSystem.cpp

Function Logic:

0:START 1:items 2:unknown 3:err 4:Return BASETYPE_UNDEF 5:i 6:unknown 7:items err 8:Return BASETYPE_UNDEF 9:items srcInd 10:unknown 11:err 12:Return BASETYPE_UNDEF 13:items 14:unknown 15:err 16:Return BASETYPE_UNDEF 17:unknown 18:items 19:w items 20:unknown 21:unknown 22:items 23:extn items 24:unknown 25:items err 26:Return BASETYPE_UNDEF 27:items dt 28:unknown 29:unknown 30:pHost 31:srcInd 32:'x' 33:unknown 34:pRepos 35:unknown 36:rc items 37:dt

Function body:

hdbBasetype hdsApp::PcEntTest (hzString& err)hdsFormdef* pFormdef, hdbClass* pHost, hzString& pcntEnt, 
{
   //  Validate the supplied percent entity.
   //  
   //  The scope tests differ by percent entity class as follows:-
   //  
   //   X (%x) Standard system values: These are global so as long as the named entity exists it will be valid.
   //   U (%u) Standard user values: Must exist and be within a form accessible to logged in users.
   //   S (%s) User session variables: These are valid within any form as long as named variable has been created in an earlier <procdata> command.
   //   E (%e) Event values:   These are tested against the fields known to exist in the supplied form.
   //   I (%i) In-situ values:   Must be within a form and name members of the form's native data class.
   //   V (%v) Session object values: These are valid if the name members of a session object that an earlier <procdata> command has brought into focus.
   //  
   //  Arguments: 1) err   The error report string to be populated in the event of an error.
   //     2) pFormdef The host form where the percent entity is in (if any)
   //     3) pHost  Applicable data class. If this is not supplied it will be the host class of the supplied form (if any)
   //     4) pcntEnt  The string to tbe tested for validity as a percent entity
   //  
   //  Returns  The basetype if the entity is found and can be evaluated. BASTETYPE_UNDEF otherwise.
   _hzfunc("hdsApp::PcEntTest") ;
   const hdbClass*     pUC ;       //  User class (for checking %u: user entities
   const hdbMember*    pMbr ;      //  Class member
   hdbObjRepos*    pRepos = 0; //  Relevent cache (either the cache for the logged in user or the cache containing current object of interest)
   hdsPage*        pPage = 0;      //  Hostpage of form
   hdsField*       pFld ;          //  Field within the form definition
   hzChain         W ;             //  Variable name buffer
   hzChain         erep ;          //  Error report
   hzAtom          atom ;          //  For litteral values and type testing
   const char*     i ;             //  Used to iterate input value
   hzString        w ;             //  Constructed variable name
   hzString        extn ;          //  Variable extension for binaries and documents (eg ->addr, ->data)
   hzString        val ;           //  Variable value
   uint32_t        srcInd ;        //  Source indicator
   uint32_t        n ;             //  General iterator
   hdbBasetype     dt ;            //  Actual datatype of entity
   hzEcode         rc = E_OK ;     //  Return code
   err.Clear() ;
   if (!pcntEnt)
       { err = "null entity" ; return BASETYPE_UNDEF ; }
   i = *pcntEnt ;
   if (*i != CHAR_PERCENT)
   {
       erep.Printf("Literal value %s not allowed", *pcntEnt) ;
       err = erep ;
       return BASETYPE_UNDEF ;
   }
   i++ ;
   srcInd = *i ;
   if (srcInd != ''x''&&srcInd != ''u''&&srcInd != ''s''&&srcInd != ''e''&&srcInd != ''i''&&srcInd != ''v'')
       { err = "Invalid percent entity class" ; return BASETYPE_UNDEF ; }
   i++ ;
   if (*i != CHAR_COLON)
       { err = "Missing colon after percent entity class" ; return BASETYPE_UNDEF ; }
   //  Get the variable type and name component
   for (i++ ; *i && *i != CHAR_SCOLON && IsAlphanum(*i) ; i++)
       W.AddByte(*i) ;
   w = W ;
   W.Clear() ;
   if (*i == CHAR_PERIOD)
   {
       for (i++ ; *i && *i != CHAR_SCOLON && IsAlphanum(*i) ; i++)
           W.AddByte(*i) ;
       extn = W ;
       W.Clear() ;
   }
   if (*i != CHAR_SCOLON)
       { erep.Printf("PcEntTest: Missing semicolon after percent entity variable name (%s), char is [%c]", *pcntEnt, *i) ; err = erep ; return BASETYPE_UNDEF ; }
   i++ ;
   //  Lookup variable and determine its value
   dt = BASETYPE_UNDEF ;
   if (!pHost)
   {
       if (pFormdef)
           pHost = pFormdef->m_pClass ;
   }
   switch (srcInd)
   {
   case ''x'': //  System variables
       if (w == "count" || w == "objid")
       {
           //  Count is of objects in a class
           pRepos = m_ADP.GetObjRepos(extn) ;
           if (!pRepos)
               { rc = E_NOTFOUND ; erep.Printf("%s is not a declared repository", *extn) ; }
           else
               dt = BASETYPE_INT32 ;
           break ;
       }
       if (w == "date")        { dt = BASETYPE_SDATE ;     break ; }
       if (w == "time")        { dt = BASETYPE_TIME ;      break ; }
       if (w == "datetime")    { dt = BASETYPE_XDATE ;     break ; }
       if (w == "referer")     { dt = BASETYPE_URL ;       break ; }
       if (w == "usecs")       { dt = BASETYPE_UINT32 ;    break ; }
       if (w == "random")      { dt = BASETYPE_STRING ;    break ; }
       if (w == "uid")         { dt = BASETYPE_INT32 ;     break ; }
       if (w == "user")        { dt = BASETYPE_STRING ;    break ; }
       //  Also permitted are ....
       rc = E_RANGE ;
       erep.Printf("Invalid system entity (%s)", *w) ;
       break ;
   case ''u'': //  U-Class Percent Entities: For these to evaluate, the user must be logged in and the entity must name an atomic member of the applicable user class. However only
               //  the validity is being tested here, so user status is not important.
       if (!pFormdef)
           { rc = E_ARGUMENT ; erep.Printf("All user variables must occur within a form lying in a page accessable to logged on users") ; break ; }
       if (!m_ADP.m_pReposSubscriber)
           { rc = E_RANGE ; erep.Printf("Subscriber Repository not invoked - No users\n") ; break ; }
       pMbr = m_ADP.m_pClassSubscriber->GetMember(w) ;
       if (pMbr)
           { dt = pMbr->Basetype() ; break ; }
       for (n = 0; rc == E_OK && n < m_UserTypes.Count() ; n++)
       {
           val = m_UserTypes.GetKey(n) ;
           pUC = m_ADP.GetPureClass(val) ;
           if (!pUC)
               Fatal("No such user class as %s\n", *val) ;
           if (pPage->m_resAccess & m_UserTypes.GetObj(n))
           {
               pMbr = pUC->GetMember(w) ;
               if (pMbr)
                   dt = pMbr->Basetype() ;
               else
               {
                   rc = E_ARGUMENT ;
                   erep.Printf("User variable %s not a member of user class %s and yet this class of user can access the page", *w, pUC->txtType()) ;
               }
           }
       }
       break ;
   case ''s'': //  Session variables (explicitly set as part of this or a parent form) constrained by the same set as event variables
       if (!m_tmpVarsSess.Exists(w))
           { rc = E_RANGE ; erep.Printf("%s is not in scope", *w) ; }
       dt = m_tmpVarsSess[w] ;
       break ;
   case ''e'': //  Event variables. The entity is legal if the refered to variable is in scope (is within the supplied set of available variables)
       if (pFormdef)
       {
           if (!pFormdef->m_mapFlds.Exists(w))
               erep.Printf("Variable %s is not incident in form %s (%p)", *w, *pFormdef->m_Formname, pFormdef) ;
           else
           {
               pFld = pFormdef->m_mapFlds[w] ;
               if (pFld)
                   { dt = pFld->m_Fldspec.m_pType->Basetype() ; break ; }
           }
       }
       if (pHost)
       {
           pMbr = pHost->GetMember(w) ;
           if (pMbr)
               dt = pMbr->Basetype() ;
           else
               { rc = E_RANGE ; erep.Printf("%s is not a member of class %s", *w, pHost->txtType()) ; }
           break ;
       }
       if (!pFormdef && pHost)
           erep.Printf("Variable %s cannot be tested as there is neither a host form or class", *w) ;
       break ;
   case ''v'': //  Current object variables require the page they appear in to have a current object. This means there must be a current object class
               //  and a current object ID.
       if (!pHost)
           { rc = E_ARGUMENT ; erep.Printf("All user variables must occur within the context of a host user class") ; break ; }
       pMbr = pHost->GetMember(w) ;
       if (!pMbr)
           { rc = E_RANGE ; erep.Printf("%s is not a member of class %s and nor is it a freely declared variable", *w, pHost->txtType()) ; }
       else
           dt = pMbr->Basetype() ;
       break ;
   }
   err = erep ;
   return dt ;
}