📄 parsepjl.c
字号:
/* dhi - When stable remove all #if DAN and #if FOR_WIN_TESTING sections
and leave in #if FOR_WIN sections. Then get rid of these defines.
*/
#define DEBUGOUTPUT 0
#define FOR_WIN 1
/*++
Copyright (c) 1994 - 1996 Microsoft Corporation
Module Name:
PARSEPJL.C
Abstract:
Handles parsing of PJL printer response streams into token\value pairs.
--*/
/*
Currently returns tokens for (see enum in parsepjl.h for token values):
@PJL ECHO MSSYNC # ->#
@PJL INFO MEMORY
TOTAL=# ->#
LARGEST=# ->#
@PJL INFO STATUS
CODE=# ->#
DISPLAY=# (not returned)
ONLINE=TRUE (or FALSE) -> 1 or 0 returned
@PJL INQUIRE INTRAY?SIZE (? is 1,2,3 or 4)
LEGAL(or other PJL paper size) ->constant from DM... list in PRINT.H
@PJL INFO CONFIG
MEMORY=# ->#
@PJL USTATUS JOB
END -> returns token with zero for value
@PJL USTATUS JOB
NAME="MSJOB #" ->#
added
@PJL USTATUS DEVICE
CODE=# ->#
DISPLAY=# (not returned)
ONLINE=TRUE (or FALSE) -> 1 or 0 returned
*/
#include "precomp.h"
// VOID cdecl DbgMsg( LPSTR MsgFormat, ... );
#define FF 12
#define CR 13
#define LF 10
#define TAB 9
#define SPACE 32
#define OK_IF_FF_FOUND TRUE
#define ERROR_IF_FF_FOUND FALSE
#define TOKEN_BASE_NOT_USED 0
#define ACTION_NOT_USED 0
#define PARAM_NOT_USED 0
/* returned as value for TOKEN_USTATUS_JOB_END */
#define VALUE_RETURED_FOR_VALUELESS_TOKENS 0
extern KeywordType readBackCommandKeywords[];
extern KeywordType infoCatagoryKeywords[];
extern KeywordType inquireVariableKeywords[];
extern KeywordType traySizeKeywords[];
extern KeywordType echoKeywords[];
extern KeywordType infoConfigKeywords[];
extern KeywordType ustatusKeywords[];
extern KeywordType ustatusJobKeywords[];
extern KeywordType ustatusDeviceKeywords[];
/* Fuctions called when a string in keyword is found */
void TokenFromParamValueFromNumberFF
(ParseVarsType *pParseVars, ParamType);
void SetNewList(ParseVarsType *pParseVars,
ParamType);
void GetTotalAndLargestFF(ParseVarsType *pParseVars,ParamType param);
void GetCodeAndOnlineFF(ParseVarsType *pParseVars,ParamType param);
void GetTokenFromIndexSetNewList(ParseVarsType *pParseVars,ParamType param);
void SetValueFromParamFF(ParseVarsType *pParseVars,ParamType param);
void SetValueFromParam(ParseVarsType *pParseVars,ParamType param);
void GetTokenFromIndexValueFromNumberEOLFromParam(ParseVarsType *pParseVars,ParamType param);
void GetTokenFromIndexValueFromBooleanEOL(ParseVarsType *pParseVars,ParamType param);
void GetTokenFromIndexValueFromStringEOL(ParseVarsType *pParseVars,ParamType param);
/* Fuctions called when no string in a keywords list is found */
void ActionNotFoundSkipPastFF(ParseVarsType *pParseVars);
void ActionNotFoundSkipCFLFandIndentedLines(ParseVarsType *pParseVars);
/* Helper Functions */
void StoreToken(ParseVarsType *pParseVars, DWORD dwToken);
BOOL StoreTokenValueAndAdvancePointer
(ParseVarsType *pParseVars, UINT_PTR dwValue);
void ExpectFinalCRLFFF(ParseVarsType *pParseVars);
BOOL SkipPastNextCRLF(ParseVarsType *pParseVars);
int GetPositiveInteger(ParseVarsType *pParseVars);
BOOL AdvancePointerPastString
(ParseVarsType *pParseVars, LPSTR pString);
BOOL SkipOverSpaces(ParseVarsType *pParseVars);
int LookForKeyword(ParseVarsType *pParseVars);
BOOL ExpectString(ParseVarsType *pParseVars, LPSTR pString);
BOOL SkipPastFF(ParseVarsType *pParseVars);
void ExpectFinalFF(ParseVarsType *pParseVars);
/* Helper Strings */
char lpCRLF[] = "\r\n";
char lpQuoteCRLF[] = "\"\r\n";
/*
Below are the Lists that drive the parsing. The main loop of this
parser looks through the keywords in 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 a FF is found in the input stream rather than a keyword, then the
parser returns. The return value is determined using the bFormFeedOk
element of the ListType structure.
If no keyword from the list is found then the function corresponding
to the notFoundAction is called.
The tokenBaseValue element is a number to which the index in the
keyword's list of strings will added to calculate the token number
corresponding to the indexed string.
*/
ListType readBackCommandList =
{
ERROR_IF_FF_FOUND,
ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
TOKEN_BASE_NOT_USED,
readBackCommandKeywords /* INFO, ECHO, INQUIRE ... */
};
ListType infoCatagoryList =
{
ERROR_IF_FF_FOUND,
ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
TOKEN_BASE_NOT_USED,
infoCatagoryKeywords /* MEMORY STATUS CONFIG ... */
};
ListType infoConfigList =
{
OK_IF_FF_FOUND,
ACTION_IF_NOT_FOUND_SKIP_CFLF_AND_INDENTED_LINES,
PJL_TOKEN_INFO_CONFIG_BASE,
infoConfigKeywords /* MEMORY= ... */
};
ListType inquireVariableList =
{
ERROR_IF_FF_FOUND,
ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
PJL_TOKEN_INQUIRE_BASE,
inquireVariableKeywords /* INTRAY1SIZE ...*/
};
ListType echoList =
{
OK_IF_FF_FOUND,
ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
TOKEN_BASE_NOT_USED,
echoKeywords /* MSSYNC ...*/
};
ListType traySizeList =
{
ERROR_IF_FF_FOUND,
ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
TOKEN_BASE_NOT_USED,
traySizeKeywords /* LEGAL, C5 ...*/
};
ListType ustatusList =
{
OK_IF_FF_FOUND,
ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
PJL_TOKEN_USTATUS_JOB_BASE,
ustatusKeywords /* JOB ... */
};
ListType ustatusJobList =
{
OK_IF_FF_FOUND,
ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
PJL_TOKEN_USTATUS_JOB_BASE,
ustatusJobKeywords /* END ... */
};
ListType ustatusDeviceList =
{
OK_IF_FF_FOUND,
ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
PJL_TOKEN_USTATUS_DEVICE_BASE,
ustatusDeviceKeywords /* END ... */
};
/* Command strings that can follow @PJL USTATUS */
KeywordType ustatusKeywords[] =
{
{"JOB\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &ustatusJobList},
{"DEVICE\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &ustatusDeviceList},
// {"DEVICE\r\n", ACTION_GET_CODE_AND_ONLINE_FF, PARAM_NOT_USED},
{"TIMED\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &ustatusDeviceList},
NULL
};
/* Command strings that can follow @PJL USTATUS JOB */
KeywordType ustatusJobKeywords[] =
{
{"END\r\n", ACTION_SET_VALUE_FROM_PARAM, VALUE_RETURED_FOR_VALUELESS_TOKENS},
{"NAME=\"MSJOB ", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_NUMBER_EOL_FROM_PARAM, (struct ListTypeTag *)lpQuoteCRLF},
NULL
};
/* command strings that can follow @PJL USTATUS DEVICE */
KeywordType ustatusDeviceKeywords[] =
{
{"CODE=", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_NUMBER_EOL_FROM_PARAM, (struct ListTypeTag *)lpCRLF},
{"DISPLAY=", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_STRING_EOL, (struct ListTypeTag *)lpCRLF},
{"ONLINE=", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_BOOLEAN_EOL, (struct ListTypeTag *)lpCRLF},
NULL
};
/* Command strings that can follow @PJL */
KeywordType readBackCommandKeywords[] =
{
{"INFO", ACTION_SET_NEW_LIST, &infoCatagoryList},
{"ECHO", ACTION_SET_NEW_LIST, &echoList},
{"INQUIRE", ACTION_SET_NEW_LIST, &inquireVariableList},
{"USTATUS", ACTION_SET_NEW_LIST, &ustatusList},
NULL
};
/* Command strings that can follow @PJL ECHO (Microsoft specific-NOT PJL!) */
KeywordType echoKeywords[] =
{
{"MSSYNC", ACTION_TOKEN_FROM_PARAM_VALUE_FROM_NUMBER_FF,
(struct ListTypeTag *)TOKEN_ECHO_MSSYNC_NUMBER},
NULL
};
/* Catagory strings that can follow @PJL INFO */
KeywordType infoCatagoryKeywords[] =
{
{"MEMORY\r\n", ACTION_GET_TOTAL_AND_LARGEST_FF, PARAM_NOT_USED},
{"STATUS\r\n", ACTION_GET_CODE_AND_ONLINE_FF, PARAM_NOT_USED},
{"CONFIG\r\n", ACTION_SET_NEW_LIST, &infoConfigList},
NULL
};
/* Catagory strings that can follow @PJL INFO */
KeywordType infoConfigKeywords[] =
{
{"MEMORY=", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_NUMBER_EOL_FROM_PARAM, (struct ListTypeTag *)lpCRLF},
{"MEMORY = ", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_NUMBER_EOL_FROM_PARAM, (struct ListTypeTag *)lpCRLF},
NULL
};
/* TRUE or FALSE strings */
KeywordType FALSEandTRUEKeywords[] =
{
{"FALSE", ACTION_NOT_USED, PARAM_NOT_USED},
{"TRUE", ACTION_NOT_USED, PARAM_NOT_USED},
NULL
};
/* strings that can follow @PJL INQUIRE */
KeywordType inquireVariableKeywords[] =
{
{"INTRAY1SIZE\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &traySizeList},
{"INTRAY2SIZE\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &traySizeList},
{"INTRAY3SIZE\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &traySizeList},
{"INTRAY4SIZE\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &traySizeList},
NULL
};
/* strings that can follow @PJL INQUIRE INTRAY?SIZE */
/* the parameters are the Microsoft defined token values for paper size */
KeywordType traySizeKeywords[] =
{
{"LETTER", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_LETTER},
{"LEGAL", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_LEGAL},
{"A4", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_A4},
{"EXECUTIVE", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_EXECUTIVE},
{"COM10", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_ENV_10},
{"MONARCH", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_ENV_MONARCH},
{"C5", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_ENV_C5},
{"DL", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_ENV_DL},
{"B5", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_ENV_B5},
NULL
};
void (*pfnNotFoundActions[])(ParseVarsType *pParseVars) =
{
ActionNotFoundSkipPastFF,
ActionNotFoundSkipCFLFandIndentedLines
};
void (*pfnFoundActions[])(ParseVarsType *pParseVars, ParamType param) =
{
TokenFromParamValueFromNumberFF,
SetNewList,
GetTotalAndLargestFF,
GetCodeAndOnlineFF,
GetTokenFromIndexSetNewList,
SetValueFromParamFF,
GetTokenFromIndexValueFromNumberEOLFromParam,
SetValueFromParam,
GetTokenFromIndexValueFromBooleanEOL,
GetTokenFromIndexValueFromStringEOL
};
PJLTOPRINTERSTATUS PJLToStatus[] =
{
{ 10001,0x0 }, // clear status - printer is ready
{ 10002,0x0 }, // clear status - check ONLINE=TRUE or FALSE
{ 11002,0x0 }, // LJ4 sends this code for 00 READY
{ 40022,PORT_STATUS_PAPER_JAM },
{ 40034,PORT_STATUS_PAPER_PROBLEM},
{ 40079,PORT_STATUS_OFFLINE },
{ 40019,PORT_STATUS_OUTPUT_BIN_FULL},
{ 10003,PORT_STATUS_WARMING_UP },
{ 10006,PORT_STATUS_TONER_LOW },
{ 40038,PORT_STATUS_TONER_LOW },
{ 30016,PORT_STATUS_OUT_OF_MEMORY},
{ 40021,PORT_STATUS_DOOR_OPEN },
{ 30078,PORT_STATUS_POWER_SAVE },
//
// Entries added by MuhuntS
//
{ 41002, PORT_STATUS_PAPER_PROBLEM}, // Load plain
{ 35078, PORT_STATUS_POWER_SAVE},
{0, 0}
};
#if FOR_WIN
#else
/*
test not enough room for tokens
test no FF
test zero before end
*/
main ()
{
char pInString[] = "@PJL USTATUS DEVICE\r\nCODE=25008\r\n\f\
@PJL USTATUS DEVICE\r\n\CODE=20020\r\n\f\
@PJL ECHO MSSYNC 1234567\r\n\f\
@PJL INFO CONFIG\r\n\
IN TRAYS [1 ENUMERATED]\r\n\
\tINTRAY1 PC\r\n\
OUT TRAYS [1 ENUMERATED]\r\n\
\tNORMAL FACEDOWN\r\n\
PAPERS [10 ENUMERATED]\r\n\
\tLETTER\r\n\
\tLEGAL\r\n\
\tA4\r\n\
LANGUAGES [1 ENUMERATED]\r\n\
\tPCL\r\n\
MEMORY=2097152\r\n\
DISPLAY LINES=1\r\n\
DISPLAY CHARACTER SIZE=16\r\n\f\
@PJL INQ";
//char pInString[] = "@PJL USTATUS JOB\r\nEND\r\nNAME=\"MSJOB 3\"\r\nPAGES=3\r\n\f$"; //good command 1 token
//char pInString[] = "@PJL USTATUS JOB\r\nEND\r\nNAME=\"JOB 14993\"\r\nPAGES=3\r\n\f$"; //good command 1 token
/*
char pInString[] = "@PJL INFO CONFIG\r\nINTRAYS [3 ENUMERATED]\r\n\tINTRAY1\
MP\r\n\tINTRAY2 PC\r\n\tINTRAY3 LC\r\nENVELOPE TRAY\r\nMEMORY=2087152\r\n\
DISPLAY LINES=1\r\n\f$"; //good command 1 token
*/
//char pInString[] = "@PJL INQUIRE INTRAY3SIZE\r\nC5\r\n\f$"; //good command 1 token
//char pInString[] = "@PJL INFO STATUS\r\nCODE=10001\r\n\DISPLAY=\"00 READY\"\r\nONLINE=TRUE\r\n\f$"; //good command 2 tokens
//char pInString[] = "@PJL INFO MEMORY\r\nTOTAL=9876543\r\n\LARGEST=123456\r\n\f$"; //good command 2 tokens
//char pInString[] = "@PJG INFO MEMORY\r\nTOTAL=9876543\r\n\LARGEST=123456\f$"; //bad command Fail
//char pInString[] = "@PJG ECHO MSSYNC 12T4567\r\n\f$"; //bad command Fail
//char pInString[] = "@PJL ECHO MSSYNC 12T4567\r\n\000\f$"; //bad command Fail
//char pInString[] = "@PJL ECHO MSSYNC 12T4567\r\n\f$"; //bad MS command Fail
//char pInString[] = "@PJL ECHO MSSYNC 1234567\r\n\f$"; //good command Success 1 token
//char pInString[] = "@PJL ECHO 124567\r\n\f$"; //good command Success 0 token
TokenPairType tokenPairs[20];
DWORD nTokenParsedRet;
LPSTR lpRet;
DWORD i;
DWORD status;
status = GetPJLTokens(pInString, 20, tokenPairs, &nTokenParsedRet, &lpRet);
switch (status)
{
case STATUS_REACHED_END_OF_COMMAND_OK:
{
printf("STATUS_REACHED_END_OF_COMMAND_OK\n");
break;
}
case STATUS_CONTINUE:
{
printf("STATUS_CONTINUE\n");
break;
}
case STATUS_REACHED_FF:
{
printf("STATUS_REACHED_FF\n");
break;
}
case STATUS_END_OF_STRING;
{
printf("STATUS_END_OF_STRING\n");
break;
}
case STATUS_SYNTAX_ERROR:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -