⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parsepjl.c

📁 A language monitor provides a full duplex communications path between the print spooler and bi-direc
💻 C
📖 第 1 页 / 共 3 页
字号:
      {
      printf("STATUS_SYNTAX_ERROR\n");
      break;
      }
   case STATUS_ATPJL_NOT_FOUND:
      {
      printf("STATUS_ATPJL_NOT_FOUND\n");
      break;
      }
   case STATUS_NOT_ENOUGH_ROOM_FOR_TOKENS:
      {
      printf("STATUS_NOT_ENOUGH_ROOM_FOR_TOKENS\n");
      break;
      }
   default:
      {
      printf("INVALID STATUS RETURNED!!!!!!\n");
      break;
      }
   };

printf(" length of command=%d, numberOfTokens=%d\n", lpRet-pInString, nTokenParsedRet);
for (i=0; i<nTokenParsedRet; i++)
   {
   printf("  Token=0x%x, Value=%d\n", tokenPairs[i].token, tokenPairs[i].value);
   }

if (*lpRet==0)
   {
   printf(" Next char is terminator\n");
   }
else
   {
   printf(" Next char=%c\n", *lpRet);
   }

exit(0);
}
#endif


/* GetPJLTokens 
This function parses a single ASCII PJL command and returns token/value pairs.
Complete PJL commands must begin with '@PJL' and end with a <FF>.

The function result returns one of the following values:
   0 = STATUS_REACHED_END_OF_COMMAND_OK
   1 = STATUS_END_OF_STRING
   2 = STATUS_SYNTAX_ERROR
   3 = STATUS_ATPJL_NOT_FOUND,
   4 = STATUS_NOT_ENOUGH_ROOM_FOR_TOKENS

Also returned through the parameters are:
 1] *plpInPJL:
    If STATUS_REACHED_END_OF_COMMAND_OK
      will point to the character past the first <FF> (FF = form feed).
    If STATUS_END_OF_STRING
      will point to the terminator that was found before any <FF>.
    Else
      undefined 
  
 2] *pnTokenParsed will contain the number of pairs returned in *pToken.

 3] pToken will contain *pnTokenParsed  token pairs  

If there are characters belonging to another command trailing the first
then the caller should call again for the new command.  If only part of
the new command may be present, then the caller may want to copy the 
characters of the new command to the beginning of the buffer, and then read 
the necessary additional characters onto the end before resubmitting the
complete command to this function for parsing.  Note that the *plpInPJL
tells the caller where the next command would begin.


If the end of the string is encountered before the trailing <FF> is found then
the function returns with *plpInPJL pointing to the terminator.
If the caller wants the command parsed into
token\value pairs it should resubmit the string once the characters 
which complete the command have been appended.


Operation:
----------
Lists drive the parsing.  The main loop of this 
parser looks through the keywords of the current list and tries to
match the keyword string to the current input stream.  

If a keyword is found then the function corresponding to the Action in 
the keyword is called.  

If no keyword from the list is found then the function corresponding
to the notFoundAction is called.

*/

DWORD GetPJLTokens(
    LPSTR lpInPJL,
    DWORD nTokenInBuffer,
    TokenPairType *pToken, 
    DWORD *pnTokenParsed,
    LPSTR *plpInPJL
)
{
   /* The parseVars variables are put into a structure so that they can be
      passed efficiently to all the helper functions.
    */
   ParseVarsType parseVars;
   BOOL bFoundKeyword;
   DWORD i, keywordIndex;
   KeywordType *pKeyword;
   DWORD dwNotFoundAction;

   /* The first list to look for is the commands that can follow
      @PJL
    */
   parseVars.arrayOfLists[0] = &readBackCommandList;
   parseVars.arrayOfLists[1] = NULL;      

   parseVars.pInPJL_Local = lpInPJL;
   parseVars.nTokenInBuffer_Local = 0;
   parseVars.nTokenLeft = nTokenInBuffer;
   parseVars.pToken_Local = pToken;
   parseVars.status = STATUS_CONTINUE;

   if (!AdvancePointerPastString(&parseVars, "@PJL"))
      {
      parseVars.status = STATUS_ATPJL_NOT_FOUND;
      }
                     
   while (parseVars.status == STATUS_CONTINUE)
      {
      /* Look for next input keyword in currently valid lists.
         Sometimes may need to look for the next input keyword in more
         then one list.
       */
      bFoundKeyword = FALSE;
      for (i=0; (parseVars.pCurrentList = parseVars.arrayOfLists[i])!=NULL; i++)
         {
         dwNotFoundAction = parseVars.pCurrentList->dwNotFoundAction;
         /* Skip over spaces to start of next keyword string */
         if ( !SkipOverSpaces(&parseVars) )
            {
            /* Either the input stream has ended or FF was found */
            if (parseVars.status == STATUS_REACHED_FF)
               {
               /* Finding a FF here may or may not be an error,
                  the field in the current list tells us which
                */  

               if ( parseVars.pCurrentList->bFormFeedOK )
                  {
                  parseVars.status = STATUS_REACHED_END_OF_COMMAND_OK;
                  }
               else
                  {
                  parseVars.status = STATUS_SYNTAX_ERROR;
                  }
               }
            break;
            }
         /* Look for keyword in current keywords */
         parseVars.pCurrentKeywords = parseVars.pCurrentList->pListOfKeywords;
         keywordIndex = LookForKeyword(&parseVars);
         if ( keywordIndex!=-1 )
            {
            bFoundKeyword = TRUE;
            break;
            }
         }

      if ( parseVars.status!=STATUS_CONTINUE )
         {
         /* We are finished processing commands */
         break;
         }

      if ( bFoundKeyword )
         /* do action from keyword */
         {
         pKeyword = &parseVars.pCurrentKeywords[keywordIndex];
         (*pfnFoundActions[pKeyword->dwAction])(&parseVars, pKeyword->param);
         }
      else
         /* do not found action from list */
         {
         (*pfnNotFoundActions[dwNotFoundAction])(&parseVars);
         }
      } 

   /* We are done parsing the input command, now we return the information */
#if DEBUGOUTPUTDEBUG
 DbgMsg("ParseVars.status = %d\n", parseVars.status);
#endif

   /* Fill in returned values and return with success */
   *pnTokenParsed = parseVars.nTokenInBuffer_Local;
   *plpInPJL = parseVars.pInPJL_Local;

   return(parseVars.status);
}


/* 
int LookForKeyword(ParseVarsType *pParseVars)

This function looks through the current keyword list in search of a 
keyword that matches the characters in the input stream pointed to 
by pParseVars->pInPJL_Local.

If a match is found:
        The index of the match in the pKeyword is returned.
        pParseVars->pInPJL_Local is advanced past the last matching character.
        pParseVars->dwKeywordIndex is set to item number in list

If no match is found:
        The return value is -1.
        pParseVars->pInPJL_Local is unchanged.
*/
int LookForKeyword(ParseVarsType *pParseVars)
{
LPSTR   pInStart = pParseVars->pInPJL_Local;
LPSTR   pIn;
DWORD   dwKeywordIndex = 0;
BOOL    bFoundMatch = FALSE;
BYTE    c;
KeywordType *pKeywords = pParseVars->pCurrentKeywords;
LPSTR   pKeywordString;

while ( (pKeywordString=pKeywords[dwKeywordIndex++].lpsz)!=NULL )
   {
#if DEBUGOUTPUT
 DbgMsg("LookForIn=%hs\n", pInStart);
 DbgMsg(" Keyword=%hs\n", pKeywordString);
#endif
   pIn = pInStart;
   while ( (c=*pKeywordString++)!=0 )
      {
      if ( c!=*pIn++ )
         {
         break;
         }
      }

   if ( c==0 )
      {
      bFoundMatch = TRUE;
      pParseVars->pInPJL_Local = pIn;
      pParseVars->dwFoundIndex = dwKeywordIndex-1;
      break;
      }
   }
#if DEBUGOUTPUT
 DbgMsg("LookForOut=%hs\n", pParseVars->pInPJL_Local);
#endif
return( (bFoundMatch)?dwKeywordIndex-1:-1 );
}


/*
BOOL AdvancePointerPastString(ParseVarsType *pParseVars, LPSTR pString)

This function looks through the input stream for a match with pString.

If a match is found:
   pParseVars->pInPJL_Local is set to point just past the string.
   the return value is TRUE
   (pParseVars->status is unchanged)

If the end of input is encountered before the string is found then
   pParseVars->pInPJL_Local is set to point to the terminating 0.
   the return value is FALSE
   pParseVars->status is set to STATUS_END_OF_STRING

If an FF is encountered before the string is found then
   pParseVars->pInPJL_Local is set to point just past the FF.
   the return value is FALSE
   pParseVars->status is set to STATUS_REACHED_FF
*/
BOOL AdvancePointerPastString(ParseVarsType *pParseVars, LPSTR pString)
{
LPSTR pIn = pParseVars->pInPJL_Local;
LPSTR pS = pString;
BYTE  s, in;

   while ( ((s=*pS) != 0) && ((in=*pIn)!=0) && (in!=FF) )
      {
      if ( s==in )
         {
         pS++; /* point to next char in string to look for match */
         }
      else
         {
         pS = pString; /* start over looking for start of string */
         }
      pIn++;
      }
   
   if ( s==0 )
      {
      /* The whole string matched  */
      /* point to character after string in input */
      pParseVars->pInPJL_Local = pIn;
      return(TRUE);
      }

   if ( in==FF )
      {
      pParseVars->status = STATUS_REACHED_FF;
      pParseVars->pInPJL_Local = pIn+1;
      }
   else
      {
      pParseVars->status = STATUS_END_OF_STRING;
      pParseVars->pInPJL_Local = pIn;
      } 

   return(FALSE);
}



/*
BOOL SkipOverSpaces(ParseVarsType &parseVars) 
This function skips over spaces in the input stream until a non-space
character (FF and NULL are special cases) is found.

If a non-space character is found then 
   pParseVars->pInPJL_Local is set to point to the first non-space char.
   the return value is TRUE
   (pParseVars->status is unchanged)

If the end of input is encountered before a non-space char is found then
   the return value is FALSE
   pParseVars->status is set to STATUS_END_OF_STRING_ENCOUNTERED
   pParseVars->pInPJL_Local is set to point to the terminating 0.

If an FF is encountered before a non-space character is found then
   the return value is FALSE
   pParseVars->status is set to STATUS_REACHED_FF
   pParseVars->pInPJL_Local is set to point just past the FF.
*/
BOOL SkipOverSpaces(ParseVarsType *pParseVars) 
{
LPSTR pIn = pParseVars->pInPJL_Local;
BYTE  in;

   while ( ((in=*pIn)==SPACE)&&(in!=0)&&(in!=FF) )
      {
      pIn++;
      }
   
   switch (in)
      {
      case FF:
         {
         pParseVars->status = STATUS_REACHED_FF;
         pParseVars->pInPJL_Local = pIn+1;
         return(FALSE);
         }
      case 0:
         {
         pParseVars->status = STATUS_END_OF_STRING;
         pParseVars->pInPJL_Local = pIn;
         return(FALSE);
         }
      default:
         {
         /* point to character after string in input */
         pParseVars->pInPJL_Local = pIn;
         return(TRUE);
         }
      }
}


void TokenFromParamValueFromNumberFF(
   ParseVarsType *pParseVars,ParamType param)
{
   int value;

   StoreToken(pParseVars, param.token);
   if ( (value=GetPositiveInteger(pParseVars))==-1 )
      {
      /* Not a valid number - status set by GetPositiveInteger() */
      return;
      }
   if ( !StoreTokenValueAndAdvancePointer(pParseVars, value) )
      {
      return;
      }
   ExpectFinalCRLFFF(pParseVars);
   return;
}

void ActionNotFoundSkipPastFF(ParseVarsType *pParseVars)
{
   if ( SkipPastFF(pParseVars) )
      {
      pParseVars->status = STATUS_REACHED_END_OF_COMMAND_OK;
      }
   return;
}

/*
BOOL SkipPastFF(ParseVarsType *pParseVars)
This function skips over all characters until either a zero is found or
FF is found.

If the end of input is encountered before an FF char is found then
   the return value is FALSE
   pParseVars->status is set to STATUS_END_OF_STRING_ENCOUNTERED
   pParseVars->pInPJL_Local is set to point to the terminating 0.

If an FF is encountered 
   the return value is TRUE
   pParseVars->status is set to STATUS_REACHED_FF
   pParseVars->pInPJL_Local is set to point just past the FF.
*/
BOOL SkipPastFF(ParseVarsType *pParseVars)
{
LPSTR pIn = pParseVars->pInPJL_Local;
BYTE  in;

   while ( ((in=*pIn)!=FF)&&(in!=0) )
      {
      pIn++;
      }
   
   if ( in==0 )
      {
      pParseVars->status = STATUS_END_OF_STRING;
      pParseVars->pInPJL_Local = pIn;
      return(FALSE);
      }
   pParseVars->pInPJL_Local = pIn+1;
   pParseVars->status = STATUS_REACHED_FF;
   return(TRUE);
}

void ExpectFinalCRLFFF(ParseVarsType *pParseVars)
{
   char c;

   if ( pParseVars->status==STATUS_CONTINUE )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -