Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1331 lines
37 KiB

  1. /* dhi - When stable remove all #if DAN and #if FOR_WIN_TESTING sections
  2. and leave in #if FOR_WIN sections. Then get rid of these defines.
  3. */
  4. #define DEBUGOUTPUT 0
  5. #define FOR_WIN 1
  6. /*++
  7. Copyright (c) 1994 - 1996 Microsoft Corporation
  8. Module Name:
  9. PARSEPJL.C
  10. Abstract:
  11. Handles parsing of PJL printer response streams into token\value pairs.
  12. --*/
  13. /*
  14. Currently returns tokens for (see enum in parsepjl.h for token values):
  15. @PJL ECHO MSSYNC # ->#
  16. @PJL INFO MEMORY
  17. TOTAL=# ->#
  18. LARGEST=# ->#
  19. @PJL INFO STATUS
  20. CODE=# ->#
  21. DISPLAY=# (not returned)
  22. ONLINE=TRUE (or FALSE) -> 1 or 0 returned
  23. @PJL INQUIRE INTRAY?SIZE (? is 1,2,3 or 4)
  24. LEGAL(or other PJL paper size) ->constant from DM... list in PRINT.H
  25. @PJL INFO CONFIG
  26. MEMORY=# ->#
  27. @PJL USTATUS JOB
  28. END -> returns token with zero for value
  29. @PJL USTATUS JOB
  30. NAME="MSJOB #" ->#
  31. added
  32. @PJL USTATUS DEVICE
  33. CODE=# ->#
  34. DISPLAY=# (not returned)
  35. ONLINE=TRUE (or FALSE) -> 1 or 0 returned
  36. */
  37. #include "precomp.h"
  38. // VOID cdecl DbgMsg( LPSTR MsgFormat, ... );
  39. #define FF 12
  40. #define CR 13
  41. #define LF 10
  42. #define TAB 9
  43. #define SPACE 32
  44. #define OK_IF_FF_FOUND TRUE
  45. #define ERROR_IF_FF_FOUND FALSE
  46. #define TOKEN_BASE_NOT_USED 0
  47. #define ACTION_NOT_USED 0
  48. #define PARAM_NOT_USED 0
  49. /* returned as value for TOKEN_USTATUS_JOB_END */
  50. #define VALUE_RETURED_FOR_VALUELESS_TOKENS 0
  51. extern KeywordType readBackCommandKeywords[];
  52. extern KeywordType infoCatagoryKeywords[];
  53. extern KeywordType inquireVariableKeywords[];
  54. extern KeywordType traySizeKeywords[];
  55. extern KeywordType echoKeywords[];
  56. extern KeywordType infoConfigKeywords[];
  57. extern KeywordType ustatusKeywords[];
  58. extern KeywordType ustatusJobKeywords[];
  59. extern KeywordType ustatusDeviceKeywords[];
  60. /* Fuctions called when a string in keyword is found */
  61. void TokenFromParamValueFromNumberFF
  62. (ParseVarsType *pParseVars, ParamType);
  63. void SetNewList(ParseVarsType *pParseVars,
  64. ParamType);
  65. void GetTotalAndLargestFF(ParseVarsType *pParseVars,ParamType param);
  66. void GetCodeAndOnlineFF(ParseVarsType *pParseVars,ParamType param);
  67. void GetTokenFromIndexSetNewList(ParseVarsType *pParseVars,ParamType param);
  68. void SetValueFromParamFF(ParseVarsType *pParseVars,ParamType param);
  69. void SetValueFromParam(ParseVarsType *pParseVars,ParamType param);
  70. void GetTokenFromIndexValueFromNumberEOLFromParam(ParseVarsType *pParseVars,ParamType param);
  71. void GetTokenFromIndexValueFromBooleanEOL(ParseVarsType *pParseVars,ParamType param);
  72. void GetTokenFromIndexValueFromStringEOL(ParseVarsType *pParseVars,ParamType param);
  73. /* Fuctions called when no string in a keywords list is found */
  74. void ActionNotFoundSkipPastFF(ParseVarsType *pParseVars);
  75. void ActionNotFoundSkipCFLFandIndentedLines(ParseVarsType *pParseVars);
  76. /* Helper Functions */
  77. void StoreToken(ParseVarsType *pParseVars, DWORD dwToken);
  78. BOOL StoreTokenValueAndAdvancePointer
  79. (ParseVarsType *pParseVars, UINT_PTR dwValue);
  80. void ExpectFinalCRLFFF(ParseVarsType *pParseVars);
  81. BOOL SkipPastNextCRLF(ParseVarsType *pParseVars);
  82. int GetPositiveInteger(ParseVarsType *pParseVars);
  83. BOOL AdvancePointerPastString
  84. (ParseVarsType *pParseVars, LPSTR pString);
  85. BOOL SkipOverSpaces(ParseVarsType *pParseVars);
  86. int LookForKeyword(ParseVarsType *pParseVars);
  87. BOOL ExpectString(ParseVarsType *pParseVars, LPSTR pString);
  88. BOOL SkipPastFF(ParseVarsType *pParseVars);
  89. void ExpectFinalFF(ParseVarsType *pParseVars);
  90. /* Helper Strings */
  91. char lpCRLF[] = "\r\n";
  92. char lpQuoteCRLF[] = "\"\r\n";
  93. /*
  94. Below are the Lists that drive the parsing. The main loop of this
  95. parser looks through the keywords in the current list and tries to
  96. match the keyword string to the current input stream.
  97. If a keyword is found then the function corresponding to the Action in
  98. the keyword is called.
  99. If a FF is found in the input stream rather than a keyword, then the
  100. parser returns. The return value is determined using the bFormFeedOk
  101. element of the ListType structure.
  102. If no keyword from the list is found then the function corresponding
  103. to the notFoundAction is called.
  104. The tokenBaseValue element is a number to which the index in the
  105. keyword's list of strings will added to calculate the token number
  106. corresponding to the indexed string.
  107. */
  108. ListType readBackCommandList =
  109. {
  110. ERROR_IF_FF_FOUND,
  111. ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
  112. TOKEN_BASE_NOT_USED,
  113. readBackCommandKeywords /* INFO, ECHO, INQUIRE ... */
  114. };
  115. ListType infoCatagoryList =
  116. {
  117. ERROR_IF_FF_FOUND,
  118. ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
  119. TOKEN_BASE_NOT_USED,
  120. infoCatagoryKeywords /* MEMORY STATUS CONFIG ... */
  121. };
  122. ListType infoConfigList =
  123. {
  124. OK_IF_FF_FOUND,
  125. ACTION_IF_NOT_FOUND_SKIP_CFLF_AND_INDENTED_LINES,
  126. PJL_TOKEN_INFO_CONFIG_BASE,
  127. infoConfigKeywords /* MEMORY= ... */
  128. };
  129. ListType inquireVariableList =
  130. {
  131. ERROR_IF_FF_FOUND,
  132. ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
  133. PJL_TOKEN_INQUIRE_BASE,
  134. inquireVariableKeywords /* INTRAY1SIZE ...*/
  135. };
  136. ListType echoList =
  137. {
  138. OK_IF_FF_FOUND,
  139. ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
  140. TOKEN_BASE_NOT_USED,
  141. echoKeywords /* MSSYNC ...*/
  142. };
  143. ListType traySizeList =
  144. {
  145. ERROR_IF_FF_FOUND,
  146. ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
  147. TOKEN_BASE_NOT_USED,
  148. traySizeKeywords /* LEGAL, C5 ...*/
  149. };
  150. ListType ustatusList =
  151. {
  152. OK_IF_FF_FOUND,
  153. ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
  154. PJL_TOKEN_USTATUS_JOB_BASE,
  155. ustatusKeywords /* JOB ... */
  156. };
  157. ListType ustatusJobList =
  158. {
  159. OK_IF_FF_FOUND,
  160. ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
  161. PJL_TOKEN_USTATUS_JOB_BASE,
  162. ustatusJobKeywords /* END ... */
  163. };
  164. ListType ustatusDeviceList =
  165. {
  166. OK_IF_FF_FOUND,
  167. ACTION_IF_NOT_FOUND_SKIP_PAST_FF,
  168. PJL_TOKEN_USTATUS_DEVICE_BASE,
  169. ustatusDeviceKeywords /* END ... */
  170. };
  171. /* Command strings that can follow @PJL USTATUS */
  172. KeywordType ustatusKeywords[] =
  173. {
  174. {"JOB\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &ustatusJobList},
  175. {"DEVICE\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &ustatusDeviceList},
  176. // {"DEVICE\r\n", ACTION_GET_CODE_AND_ONLINE_FF, PARAM_NOT_USED},
  177. {"TIMED\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &ustatusDeviceList},
  178. NULL
  179. };
  180. /* Command strings that can follow @PJL USTATUS JOB */
  181. KeywordType ustatusJobKeywords[] =
  182. {
  183. {"END\r\n", ACTION_SET_VALUE_FROM_PARAM, VALUE_RETURED_FOR_VALUELESS_TOKENS},
  184. {"NAME=\"MSJOB ", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_NUMBER_EOL_FROM_PARAM, (struct ListTypeTag *)lpQuoteCRLF},
  185. NULL
  186. };
  187. /* command strings that can follow @PJL USTATUS DEVICE */
  188. KeywordType ustatusDeviceKeywords[] =
  189. {
  190. {"CODE=", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_NUMBER_EOL_FROM_PARAM, (struct ListTypeTag *)lpCRLF},
  191. {"DISPLAY=", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_STRING_EOL, (struct ListTypeTag *)lpCRLF},
  192. {"ONLINE=", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_BOOLEAN_EOL, (struct ListTypeTag *)lpCRLF},
  193. NULL
  194. };
  195. /* Command strings that can follow @PJL */
  196. KeywordType readBackCommandKeywords[] =
  197. {
  198. {"INFO", ACTION_SET_NEW_LIST, &infoCatagoryList},
  199. {"ECHO", ACTION_SET_NEW_LIST, &echoList},
  200. {"INQUIRE", ACTION_SET_NEW_LIST, &inquireVariableList},
  201. {"USTATUS", ACTION_SET_NEW_LIST, &ustatusList},
  202. NULL
  203. };
  204. /* Command strings that can follow @PJL ECHO (Microsoft specific-NOT PJL!) */
  205. KeywordType echoKeywords[] =
  206. {
  207. {"MSSYNC", ACTION_TOKEN_FROM_PARAM_VALUE_FROM_NUMBER_FF,
  208. (struct ListTypeTag *)TOKEN_ECHO_MSSYNC_NUMBER},
  209. NULL
  210. };
  211. /* Catagory strings that can follow @PJL INFO */
  212. KeywordType infoCatagoryKeywords[] =
  213. {
  214. {"MEMORY\r\n", ACTION_GET_TOTAL_AND_LARGEST_FF, PARAM_NOT_USED},
  215. {"STATUS\r\n", ACTION_GET_CODE_AND_ONLINE_FF, PARAM_NOT_USED},
  216. {"CONFIG\r\n", ACTION_SET_NEW_LIST, &infoConfigList},
  217. NULL
  218. };
  219. /* Catagory strings that can follow @PJL INFO */
  220. KeywordType infoConfigKeywords[] =
  221. {
  222. {"MEMORY=", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_NUMBER_EOL_FROM_PARAM, (struct ListTypeTag *)lpCRLF},
  223. {"MEMORY = ", ACTION_GET_TOKEN_FROM_INDEX_VALUE_FROM_NUMBER_EOL_FROM_PARAM, (struct ListTypeTag *)lpCRLF},
  224. {"DUPLEX", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)TRUE},
  225. NULL
  226. };
  227. /* TRUE or FALSE strings */
  228. KeywordType FALSEandTRUEKeywords[] =
  229. {
  230. {"FALSE", ACTION_NOT_USED, PARAM_NOT_USED},
  231. {"TRUE", ACTION_NOT_USED, PARAM_NOT_USED},
  232. NULL
  233. };
  234. /* strings that can follow @PJL INQUIRE */
  235. KeywordType inquireVariableKeywords[] =
  236. {
  237. {"INTRAY1SIZE\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &traySizeList},
  238. {"INTRAY2SIZE\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &traySizeList},
  239. {"INTRAY3SIZE\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &traySizeList},
  240. {"INTRAY4SIZE\r\n", ACTION_TOKEN_FROM_INDEX_SET_NEW_LIST, &traySizeList},
  241. NULL
  242. };
  243. /* strings that can follow @PJL INQUIRE INTRAY?SIZE */
  244. /* the parameters are the Microsoft defined token values for paper size */
  245. KeywordType traySizeKeywords[] =
  246. {
  247. {"LETTER", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_LETTER},
  248. {"LEGAL", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_LEGAL},
  249. {"A4", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_A4},
  250. {"EXECUTIVE", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_EXECUTIVE},
  251. {"COM10", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_ENV_10},
  252. {"MONARCH", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_ENV_MONARCH},
  253. {"C5", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_ENV_C5},
  254. {"DL", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_ENV_DL},
  255. {"B5", ACTION_SET_VALUE_FROM_PARAM_FF, (struct ListTypeTag *)DMPAPER_ENV_B5},
  256. NULL
  257. };
  258. void (*pfnNotFoundActions[])(ParseVarsType *pParseVars) =
  259. {
  260. ActionNotFoundSkipPastFF,
  261. ActionNotFoundSkipCFLFandIndentedLines
  262. };
  263. void (*pfnFoundActions[])(ParseVarsType *pParseVars, ParamType param) =
  264. {
  265. TokenFromParamValueFromNumberFF,
  266. SetNewList,
  267. GetTotalAndLargestFF,
  268. GetCodeAndOnlineFF,
  269. GetTokenFromIndexSetNewList,
  270. SetValueFromParamFF,
  271. GetTokenFromIndexValueFromNumberEOLFromParam,
  272. SetValueFromParam,
  273. GetTokenFromIndexValueFromBooleanEOL,
  274. GetTokenFromIndexValueFromStringEOL
  275. };
  276. PJLTOPRINTERSTATUS PJLToStatus[] =
  277. {
  278. { 10001,0x0 }, // clear status - printer is ready
  279. { 10002,0x0 }, // clear status - check ONLINE=TRUE or FALSE
  280. { 11002,0x0 }, // LJ4 sends this code for 00 READY
  281. { 40022,PORT_STATUS_PAPER_JAM },
  282. { 40034,PORT_STATUS_PAPER_PROBLEM},
  283. { 40079,PORT_STATUS_OFFLINE },
  284. { 40019,PORT_STATUS_OUTPUT_BIN_FULL},
  285. { 10003,PORT_STATUS_WARMING_UP },
  286. { 10006,PORT_STATUS_TONER_LOW },
  287. { 40038,PORT_STATUS_TONER_LOW },
  288. { 30016,PORT_STATUS_OUT_OF_MEMORY},
  289. { 40021,PORT_STATUS_DOOR_OPEN },
  290. { 30078,PORT_STATUS_POWER_SAVE },
  291. //
  292. // Entries added by MuhuntS
  293. //
  294. { 41002, PORT_STATUS_PAPER_PROBLEM}, // Load plain
  295. { 35078, PORT_STATUS_POWER_SAVE},
  296. {0, 0}
  297. };
  298. #if FOR_WIN
  299. #else
  300. /*
  301. test not enough room for tokens
  302. test no FF
  303. test zero before end
  304. */
  305. main ()
  306. {
  307. char pInString[] = "@PJL USTATUS DEVICE\r\nCODE=25008\r\n\f\
  308. @PJL USTATUS DEVICE\r\n\CODE=20020\r\n\f\
  309. @PJL ECHO MSSYNC 1234567\r\n\f\
  310. @PJL INFO CONFIG\r\n\
  311. IN TRAYS [1 ENUMERATED]\r\n\
  312. \tINTRAY1 PC\r\n\
  313. OUT TRAYS [1 ENUMERATED]\r\n\
  314. \tNORMAL FACEDOWN\r\n\
  315. PAPERS [10 ENUMERATED]\r\n\
  316. \tLETTER\r\n\
  317. \tLEGAL\r\n\
  318. \tA4\r\n\
  319. LANGUAGES [1 ENUMERATED]\r\n\
  320. \tPCL\r\n\
  321. MEMORY=2097152\r\n\
  322. DISPLAY LINES=1\r\n\
  323. DISPLAY CHARACTER SIZE=16\r\n\f\
  324. @PJL INQ";
  325. //char pInString[] = "@PJL USTATUS JOB\r\nEND\r\nNAME=\"MSJOB 3\"\r\nPAGES=3\r\n\f$"; //good command 1 token
  326. //char pInString[] = "@PJL USTATUS JOB\r\nEND\r\nNAME=\"JOB 14993\"\r\nPAGES=3\r\n\f$"; //good command 1 token
  327. /*
  328. char pInString[] = "@PJL INFO CONFIG\r\nINTRAYS [3 ENUMERATED]\r\n\tINTRAY1\
  329. MP\r\n\tINTRAY2 PC\r\n\tINTRAY3 LC\r\nENVELOPE TRAY\r\nMEMORY=2087152\r\n\
  330. DISPLAY LINES=1\r\n\f$"; //good command 1 token
  331. */
  332. //char pInString[] = "@PJL INQUIRE INTRAY3SIZE\r\nC5\r\n\f$"; //good command 1 token
  333. //char pInString[] = "@PJL INFO STATUS\r\nCODE=10001\r\n\DISPLAY=\"00 READY\"\r\nONLINE=TRUE\r\n\f$"; //good command 2 tokens
  334. //char pInString[] = "@PJL INFO MEMORY\r\nTOTAL=9876543\r\n\LARGEST=123456\r\n\f$"; //good command 2 tokens
  335. //char pInString[] = "@PJG INFO MEMORY\r\nTOTAL=9876543\r\n\LARGEST=123456\f$"; //bad command Fail
  336. //char pInString[] = "@PJG ECHO MSSYNC 12T4567\r\n\f$"; //bad command Fail
  337. //char pInString[] = "@PJL ECHO MSSYNC 12T4567\r\n\000\f$"; //bad command Fail
  338. //char pInString[] = "@PJL ECHO MSSYNC 12T4567\r\n\f$"; //bad MS command Fail
  339. //char pInString[] = "@PJL ECHO MSSYNC 1234567\r\n\f$"; //good command Success 1 token
  340. //char pInString[] = "@PJL ECHO 124567\r\n\f$"; //good command Success 0 token
  341. TokenPairType tokenPairs[20];
  342. DWORD nTokenParsedRet;
  343. LPSTR lpRet;
  344. DWORD i;
  345. DWORD status;
  346. status = GetPJLTokens(pInString, 20, tokenPairs, &nTokenParsedRet, &lpRet);
  347. switch (status)
  348. {
  349. case STATUS_REACHED_END_OF_COMMAND_OK:
  350. {
  351. printf("STATUS_REACHED_END_OF_COMMAND_OK\n");
  352. break;
  353. }
  354. case STATUS_CONTINUE:
  355. {
  356. printf("STATUS_CONTINUE\n");
  357. break;
  358. }
  359. case STATUS_REACHED_FF:
  360. {
  361. printf("STATUS_REACHED_FF\n");
  362. break;
  363. }
  364. case STATUS_END_OF_STRING;
  365. {
  366. printf("STATUS_END_OF_STRING\n");
  367. break;
  368. }
  369. case STATUS_SYNTAX_ERROR:
  370. {
  371. printf("STATUS_SYNTAX_ERROR\n");
  372. break;
  373. }
  374. case STATUS_ATPJL_NOT_FOUND:
  375. {
  376. printf("STATUS_ATPJL_NOT_FOUND\n");
  377. break;
  378. }
  379. case STATUS_NOT_ENOUGH_ROOM_FOR_TOKENS:
  380. {
  381. printf("STATUS_NOT_ENOUGH_ROOM_FOR_TOKENS\n");
  382. break;
  383. }
  384. default:
  385. {
  386. printf("INVALID STATUS RETURNED!!!!!!\n");
  387. break;
  388. }
  389. };
  390. printf(" length of command=%d, numberOfTokens=%d\n", lpRet-pInString, nTokenParsedRet);
  391. for (i=0; i<nTokenParsedRet; i++)
  392. {
  393. printf(" Token=0x%x, Value=%d\n", tokenPairs[i].token, tokenPairs[i].value);
  394. }
  395. if (*lpRet==0)
  396. {
  397. printf(" Next char is terminator\n");
  398. }
  399. else
  400. {
  401. printf(" Next char=%c\n", *lpRet);
  402. }
  403. exit(0);
  404. }
  405. #endif
  406. /* GetPJLTokens
  407. This function parses a single ASCII PJL command and returns token/value pairs.
  408. Complete PJL commands must begin with '@PJL' and end with a <FF>.
  409. The function result returns one of the following values:
  410. 0 = STATUS_REACHED_END_OF_COMMAND_OK
  411. 1 = STATUS_END_OF_STRING
  412. 2 = STATUS_SYNTAX_ERROR
  413. 3 = STATUS_ATPJL_NOT_FOUND,
  414. 4 = STATUS_NOT_ENOUGH_ROOM_FOR_TOKENS
  415. Also returned through the parameters are:
  416. 1] *plpInPJL:
  417. If STATUS_REACHED_END_OF_COMMAND_OK
  418. will point to the character past the first <FF> (FF = form feed).
  419. If STATUS_END_OF_STRING
  420. will point to the terminator that was found before any <FF>.
  421. Else
  422. undefined
  423. 2] *pnTokenParsed will contain the number of pairs returned in *pToken.
  424. 3] pToken will contain *pnTokenParsed token pairs
  425. If there are characters belonging to another command trailing the first
  426. then the caller should call again for the new command. If only part of
  427. the new command may be present, then the caller may want to copy the
  428. characters of the new command to the beginning of the buffer, and then read
  429. the necessary additional characters onto the end before resubmitting the
  430. complete command to this function for parsing. Note that the *plpInPJL
  431. tells the caller where the next command would begin.
  432. If the end of the string is encountered before the trailing <FF> is found then
  433. the function returns with *plpInPJL pointing to the terminator.
  434. If the caller wants the command parsed into
  435. token\value pairs it should resubmit the string once the characters
  436. which complete the command have been appended.
  437. Operation:
  438. ----------
  439. Lists drive the parsing. The main loop of this
  440. parser looks through the keywords of the current list and tries to
  441. match the keyword string to the current input stream.
  442. If a keyword is found then the function corresponding to the Action in
  443. the keyword is called.
  444. If no keyword from the list is found then the function corresponding
  445. to the notFoundAction is called.
  446. */
  447. DWORD GetPJLTokens(
  448. LPSTR lpInPJL,
  449. DWORD nTokenInBuffer,
  450. TokenPairType *pToken,
  451. DWORD *pnTokenParsed,
  452. LPSTR *plpInPJL
  453. )
  454. {
  455. /* The parseVars variables are put into a structure so that they can be
  456. passed efficiently to all the helper functions.
  457. */
  458. ParseVarsType parseVars;
  459. BOOL bFoundKeyword;
  460. DWORD i, keywordIndex;
  461. KeywordType *pKeyword;
  462. DWORD dwNotFoundAction;
  463. /* The first list to look for is the commands that can follow
  464. @PJL
  465. */
  466. parseVars.arrayOfLists[0] = &readBackCommandList;
  467. parseVars.arrayOfLists[1] = NULL;
  468. parseVars.pInPJL_Local = lpInPJL;
  469. parseVars.nTokenInBuffer_Local = 0;
  470. parseVars.nTokenLeft = nTokenInBuffer;
  471. parseVars.pToken_Local = pToken;
  472. parseVars.status = STATUS_CONTINUE;
  473. if (!AdvancePointerPastString(&parseVars, "@PJL"))
  474. {
  475. parseVars.status = STATUS_ATPJL_NOT_FOUND;
  476. }
  477. while (parseVars.status == STATUS_CONTINUE)
  478. {
  479. /* Look for next input keyword in currently valid lists.
  480. Sometimes may need to look for the next input keyword in more
  481. then one list.
  482. */
  483. bFoundKeyword = FALSE;
  484. for (i=0; (parseVars.pCurrentList = parseVars.arrayOfLists[i])!=NULL; i++)
  485. {
  486. dwNotFoundAction = parseVars.pCurrentList->dwNotFoundAction;
  487. /* Skip over spaces to start of next keyword string */
  488. if ( !SkipOverSpaces(&parseVars) )
  489. {
  490. /* Either the input stream has ended or FF was found */
  491. if (parseVars.status == STATUS_REACHED_FF)
  492. {
  493. /* Finding a FF here may or may not be an error,
  494. the field in the current list tells us which
  495. */
  496. if ( parseVars.pCurrentList->bFormFeedOK )
  497. {
  498. parseVars.status = STATUS_REACHED_END_OF_COMMAND_OK;
  499. }
  500. else
  501. {
  502. parseVars.status = STATUS_SYNTAX_ERROR;
  503. }
  504. }
  505. break;
  506. }
  507. /* Look for keyword in current keywords */
  508. parseVars.pCurrentKeywords = parseVars.pCurrentList->pListOfKeywords;
  509. keywordIndex = LookForKeyword(&parseVars);
  510. if ( keywordIndex!=-1 )
  511. {
  512. bFoundKeyword = TRUE;
  513. break;
  514. }
  515. }
  516. if ( parseVars.status!=STATUS_CONTINUE )
  517. {
  518. /* We are finished processing commands */
  519. break;
  520. }
  521. if ( bFoundKeyword )
  522. /* do action from keyword */
  523. {
  524. pKeyword = &parseVars.pCurrentKeywords[keywordIndex];
  525. (*pfnFoundActions[pKeyword->dwAction])(&parseVars, pKeyword->param);
  526. }
  527. else
  528. /* do not found action from list */
  529. {
  530. (*pfnNotFoundActions[dwNotFoundAction])(&parseVars);
  531. }
  532. }
  533. /* We are done parsing the input command, now we return the information */
  534. #if DEBUGOUTPUTDEBUG
  535. DbgMsg("ParseVars.status = %d\n", parseVars.status);
  536. #endif
  537. /* Fill in returned values and return with success */
  538. *pnTokenParsed = parseVars.nTokenInBuffer_Local;
  539. *plpInPJL = parseVars.pInPJL_Local;
  540. return(parseVars.status);
  541. }
  542. /*
  543. int LookForKeyword(ParseVarsType *pParseVars)
  544. This function looks through the current keyword list in search of a
  545. keyword that matches the characters in the input stream pointed to
  546. by pParseVars->pInPJL_Local.
  547. If a match is found:
  548. The index of the match in the pKeyword is returned.
  549. pParseVars->pInPJL_Local is advanced past the last matching character.
  550. pParseVars->dwKeywordIndex is set to item number in list
  551. If no match is found:
  552. The return value is -1.
  553. pParseVars->pInPJL_Local is unchanged.
  554. */
  555. int LookForKeyword(ParseVarsType *pParseVars)
  556. {
  557. LPSTR pInStart = pParseVars->pInPJL_Local;
  558. LPSTR pIn;
  559. DWORD dwKeywordIndex = 0;
  560. BOOL bFoundMatch = FALSE;
  561. BYTE c;
  562. KeywordType *pKeywords = pParseVars->pCurrentKeywords;
  563. LPSTR pKeywordString;
  564. while ( (pKeywordString=pKeywords[dwKeywordIndex++].lpsz)!=NULL )
  565. {
  566. #if DEBUGOUTPUT
  567. DbgMsg("LookForIn=%hs\n", pInStart);
  568. DbgMsg(" Keyword=%hs\n", pKeywordString);
  569. #endif
  570. pIn = pInStart;
  571. while ( (c=*pKeywordString++)!=0 )
  572. {
  573. if ( c!=*pIn++ )
  574. {
  575. break;
  576. }
  577. }
  578. if ( c==0 )
  579. {
  580. bFoundMatch = TRUE;
  581. pParseVars->pInPJL_Local = pIn;
  582. pParseVars->dwFoundIndex = dwKeywordIndex-1;
  583. break;
  584. }
  585. }
  586. #if DEBUGOUTPUT
  587. DbgMsg("LookForOut=%hs\n", pParseVars->pInPJL_Local);
  588. #endif
  589. return( (bFoundMatch)?dwKeywordIndex-1:-1 );
  590. }
  591. /*
  592. BOOL AdvancePointerPastString(ParseVarsType *pParseVars, LPSTR pString)
  593. This function looks through the input stream for a match with pString.
  594. If a match is found:
  595. pParseVars->pInPJL_Local is set to point just past the string.
  596. the return value is TRUE
  597. (pParseVars->status is unchanged)
  598. If the end of input is encountered before the string is found then
  599. pParseVars->pInPJL_Local is set to point to the terminating 0.
  600. the return value is FALSE
  601. pParseVars->status is set to STATUS_END_OF_STRING
  602. If an FF is encountered before the string is found then
  603. pParseVars->pInPJL_Local is set to point just past the FF.
  604. the return value is FALSE
  605. pParseVars->status is set to STATUS_REACHED_FF
  606. */
  607. BOOL AdvancePointerPastString(ParseVarsType *pParseVars, LPSTR pString)
  608. {
  609. LPSTR pIn = pParseVars->pInPJL_Local;
  610. LPSTR pS = pString;
  611. BYTE s, in;
  612. while ( ((s=*pS) != 0) && ((in=*pIn)!=0) && (in!=FF) )
  613. {
  614. if ( s==in )
  615. {
  616. pS++; /* point to next char in string to look for match */
  617. }
  618. else
  619. {
  620. pS = pString; /* start over looking for start of string */
  621. }
  622. pIn++;
  623. }
  624. if ( s==0 )
  625. {
  626. /* The whole string matched */
  627. /* point to character after string in input */
  628. pParseVars->pInPJL_Local = pIn;
  629. return(TRUE);
  630. }
  631. if ( in==FF )
  632. {
  633. pParseVars->status = STATUS_REACHED_FF;
  634. pParseVars->pInPJL_Local = pIn+1;
  635. }
  636. else
  637. {
  638. pParseVars->status = STATUS_END_OF_STRING;
  639. pParseVars->pInPJL_Local = pIn;
  640. }
  641. return(FALSE);
  642. }
  643. /*
  644. BOOL SkipOverSpaces(ParseVarsType &parseVars)
  645. This function skips over spaces in the input stream until a non-space
  646. character (FF and NULL are special cases) is found.
  647. If a non-space character is found then
  648. pParseVars->pInPJL_Local is set to point to the first non-space char.
  649. the return value is TRUE
  650. (pParseVars->status is unchanged)
  651. If the end of input is encountered before a non-space char is found then
  652. the return value is FALSE
  653. pParseVars->status is set to STATUS_END_OF_STRING_ENCOUNTERED
  654. pParseVars->pInPJL_Local is set to point to the terminating 0.
  655. If an FF is encountered before a non-space character is found then
  656. the return value is FALSE
  657. pParseVars->status is set to STATUS_REACHED_FF
  658. pParseVars->pInPJL_Local is set to point just past the FF.
  659. */
  660. BOOL SkipOverSpaces(ParseVarsType *pParseVars)
  661. {
  662. LPSTR pIn = pParseVars->pInPJL_Local;
  663. BYTE in;
  664. while ( ((in=*pIn)==SPACE)&&(in!=0)&&(in!=FF) )
  665. {
  666. pIn++;
  667. }
  668. switch (in)
  669. {
  670. case FF:
  671. {
  672. pParseVars->status = STATUS_REACHED_FF;
  673. pParseVars->pInPJL_Local = pIn+1;
  674. return(FALSE);
  675. }
  676. case 0:
  677. {
  678. pParseVars->status = STATUS_END_OF_STRING;
  679. pParseVars->pInPJL_Local = pIn;
  680. return(FALSE);
  681. }
  682. default:
  683. {
  684. /* point to character after string in input */
  685. pParseVars->pInPJL_Local = pIn;
  686. return(TRUE);
  687. }
  688. }
  689. }
  690. void TokenFromParamValueFromNumberFF(
  691. ParseVarsType *pParseVars,ParamType param)
  692. {
  693. int value;
  694. StoreToken(pParseVars, param.token);
  695. if ( (value=GetPositiveInteger(pParseVars))==-1 )
  696. {
  697. /* Not a valid number - status set by GetPositiveInteger() */
  698. return;
  699. }
  700. if ( !StoreTokenValueAndAdvancePointer(pParseVars, value) )
  701. {
  702. return;
  703. }
  704. ExpectFinalCRLFFF(pParseVars);
  705. return;
  706. }
  707. void ActionNotFoundSkipPastFF(ParseVarsType *pParseVars)
  708. {
  709. if ( SkipPastFF(pParseVars) )
  710. {
  711. pParseVars->status = STATUS_REACHED_END_OF_COMMAND_OK;
  712. }
  713. return;
  714. }
  715. /*
  716. BOOL SkipPastFF(ParseVarsType *pParseVars)
  717. This function skips over all characters until either a zero is found or
  718. FF is found.
  719. If the end of input is encountered before an FF char is found then
  720. the return value is FALSE
  721. pParseVars->status is set to STATUS_END_OF_STRING_ENCOUNTERED
  722. pParseVars->pInPJL_Local is set to point to the terminating 0.
  723. If an FF is encountered
  724. the return value is TRUE
  725. pParseVars->status is set to STATUS_REACHED_FF
  726. pParseVars->pInPJL_Local is set to point just past the FF.
  727. */
  728. BOOL SkipPastFF(ParseVarsType *pParseVars)
  729. {
  730. LPSTR pIn = pParseVars->pInPJL_Local;
  731. BYTE in;
  732. while ( ((in=*pIn)!=FF)&&(in!=0) )
  733. {
  734. pIn++;
  735. }
  736. if ( in==0 )
  737. {
  738. pParseVars->status = STATUS_END_OF_STRING;
  739. pParseVars->pInPJL_Local = pIn;
  740. return(FALSE);
  741. }
  742. pParseVars->pInPJL_Local = pIn+1;
  743. pParseVars->status = STATUS_REACHED_FF;
  744. return(TRUE);
  745. }
  746. void ExpectFinalCRLFFF(ParseVarsType *pParseVars)
  747. {
  748. char c;
  749. if ( pParseVars->status==STATUS_CONTINUE )
  750. {
  751. c=*pParseVars->pInPJL_Local;
  752. if ( c==0 )
  753. {
  754. pParseVars->status = STATUS_END_OF_STRING;
  755. return;
  756. }
  757. if ( !AdvancePointerPastString(pParseVars, lpCRLF) )
  758. {
  759. if ( pParseVars->status==STATUS_REACHED_FF )
  760. {
  761. pParseVars->status = STATUS_SYNTAX_ERROR;
  762. }
  763. return;
  764. }
  765. ExpectFinalFF(pParseVars);
  766. }
  767. return;
  768. }
  769. void ExpectFinalFF(ParseVarsType *pParseVars)
  770. {
  771. if ( pParseVars->status==STATUS_CONTINUE )
  772. {
  773. if ( *pParseVars->pInPJL_Local==FF )
  774. {
  775. pParseVars->status = STATUS_REACHED_END_OF_COMMAND_OK;
  776. pParseVars->pInPJL_Local++;
  777. }
  778. else
  779. {
  780. if ( *pParseVars->pInPJL_Local==0 )
  781. {
  782. pParseVars->status = STATUS_END_OF_STRING;
  783. }
  784. else
  785. {
  786. pParseVars->status = STATUS_SYNTAX_ERROR;
  787. }
  788. }
  789. }
  790. return;
  791. }
  792. /*
  793. int GetPositiveInteger(ParseVarsType *pParseVars)
  794. This function skips spaces and then interprets all the digits in input stream
  795. as a positive integer.
  796. If digits follow any spaces and they are not terminated by a zero then
  797. the return value is the positive integer.
  798. If the first character following spaces in not a digit or the end of
  799. string is encountered then
  800. -1 is returned as the value
  801. pParseVars->status is set to STATUS_SYNTAX_ERROR
  802. Note: does not check for overflow
  803. */
  804. int GetPositiveInteger(ParseVarsType *pParseVars)
  805. {
  806. int value;
  807. LPSTR pIn;
  808. BYTE c;
  809. if ( !SkipOverSpaces(pParseVars) )
  810. {
  811. if ( pParseVars->status == STATUS_REACHED_FF )
  812. {
  813. pParseVars->status = STATUS_SYNTAX_ERROR;
  814. }
  815. return(-1);
  816. }
  817. pIn = pParseVars->pInPJL_Local;
  818. for ( value=0; ((c=*pIn++)>='0')&&(c<='9'); value=value*10+(c-'0') );
  819. if ( (c==0)||(pIn==pParseVars->pInPJL_Local+1) )
  820. {
  821. /* either end of string encountered or no digits found */
  822. if ( c==0 )
  823. {
  824. pParseVars->status = STATUS_END_OF_STRING;
  825. }
  826. else
  827. {
  828. pParseVars->status = STATUS_SYNTAX_ERROR;
  829. }
  830. pParseVars->pInPJL_Local = pIn-1;
  831. return(-1);
  832. }
  833. pParseVars->pInPJL_Local = pIn-1;
  834. return(value);
  835. }
  836. void SetNewList(ParseVarsType *pParseVars, ParamType param)
  837. {
  838. pParseVars->arrayOfLists[0] = param.pList;
  839. pParseVars->arrayOfLists[1] = NULL;
  840. return;
  841. }
  842. void StoreToken(ParseVarsType *pParseVars, DWORD dwToken)
  843. {
  844. pParseVars->dwNextToken = dwToken;
  845. return;
  846. }
  847. BOOL StoreTokenValueAndAdvancePointer(ParseVarsType *pParseVars, UINT_PTR dwValue)
  848. {
  849. if ( pParseVars->nTokenLeft==0 )
  850. {
  851. pParseVars->status = STATUS_NOT_ENOUGH_ROOM_FOR_TOKENS;
  852. return(FALSE);
  853. }
  854. pParseVars->pToken_Local->token = pParseVars->dwNextToken;
  855. pParseVars->pToken_Local->value = dwValue;
  856. pParseVars->pToken_Local++;
  857. pParseVars->nTokenInBuffer_Local++;
  858. pParseVars->nTokenLeft--;
  859. return(TRUE);
  860. }
  861. void GetTotalAndLargestFF(ParseVarsType *pParseVars, ParamType param)
  862. {
  863. int value;
  864. param; /* to eliminate not used warning */
  865. if ( !ExpectString(pParseVars, "TOTAL=") )
  866. {
  867. return;
  868. }
  869. StoreToken(pParseVars, TOKEN_INFO_MEMORY_TOTAL);
  870. if ( (value=GetPositiveInteger(pParseVars))==-1 )
  871. {
  872. /* Not a valid number - status set by GetPositiveInteger() */
  873. return;
  874. }
  875. if ( !StoreTokenValueAndAdvancePointer(pParseVars, value) )
  876. {
  877. return;
  878. }
  879. if ( !ExpectString(pParseVars, "\r\nLARGEST=") )
  880. {
  881. return;
  882. }
  883. StoreToken(pParseVars, TOKEN_INFO_MEMORY_LARGEST);
  884. if ( (value=GetPositiveInteger(pParseVars))==-1 )
  885. {
  886. /* Not a valid number - status set by GetPositiveInteger() */
  887. return;
  888. }
  889. if ( !StoreTokenValueAndAdvancePointer(pParseVars, value) )
  890. {
  891. return;
  892. }
  893. ExpectFinalCRLFFF(pParseVars);
  894. return;
  895. }
  896. void GetCodeAndOnlineFF(ParseVarsType *pParseVars, ParamType param)
  897. {
  898. int value;
  899. param; /* to eliminate not used warning */
  900. if ( !ExpectString(pParseVars,"CODE=") )
  901. {
  902. return;
  903. }
  904. StoreToken(pParseVars, TOKEN_INFO_STATUS_CODE);
  905. if ( (value=GetPositiveInteger(pParseVars))==-1 )
  906. {
  907. /* Not a valid number - status set by GetPositiveInteger() */
  908. return;
  909. }
  910. if ( !StoreTokenValueAndAdvancePointer(pParseVars, value) )
  911. {
  912. return;
  913. }
  914. if ( !ExpectString(pParseVars, "\r\nDISPLAY=") )
  915. {
  916. return;
  917. }
  918. if ( !SkipPastNextCRLF(pParseVars) )
  919. {
  920. return;
  921. }
  922. if ( !ExpectString(pParseVars, "ONLINE=") )
  923. {
  924. return;
  925. }
  926. StoreToken(pParseVars, TOKEN_INFO_STATUS_ONLINE);
  927. pParseVars->pCurrentKeywords = FALSEandTRUEKeywords;
  928. if ( (value=LookForKeyword(pParseVars))==-1 )
  929. {
  930. /* Not TRUE or FALSE */
  931. pParseVars->status = STATUS_SYNTAX_ERROR;
  932. return;
  933. }
  934. if ( !StoreTokenValueAndAdvancePointer(pParseVars, value) )
  935. {
  936. return;
  937. }
  938. ExpectFinalCRLFFF(pParseVars);
  939. return;
  940. }
  941. /*
  942. BOOL ExpectString(ParseVarsType *pParseVars, LPSTR pString)
  943. This function looks for a match of the current stream
  944. position with pString.
  945. If a match is found:
  946. pParseVars->pInPJL_Local is set to point just past the string.
  947. the return value is TRUE
  948. (pParseVars->status is unchanged)
  949. If the end of input is encountered before the string is found then
  950. pParseVars->pInPJL_Local is set to point to the terminating 0.
  951. the return value is FALSE
  952. pParseVars->status is set to STATUS_END_OF_STRING
  953. If an FF is encountered before the string is found then
  954. pParseVars->pInPJL_Local is set to point just past the FF.
  955. the return value is FALSE
  956. pParseVars->status is set to STATUS_SYNTAX_ERROR
  957. */
  958. BOOL ExpectString(ParseVarsType *pParseVars, LPSTR pString)
  959. {
  960. LPSTR pIn = pParseVars->pInPJL_Local;
  961. LPSTR pS = pString;
  962. BYTE s, in;
  963. while ( ((s=*pS) != 0) && ((in=*pIn)!=0) && (in!=FF) && (s==in) )
  964. {
  965. pS++;
  966. pIn++;
  967. }
  968. if ( s==0 )
  969. {
  970. /* The whole string matched */
  971. /* point to character after string in input */
  972. pParseVars->pInPJL_Local = pIn;
  973. return(TRUE);
  974. }
  975. pParseVars->status = ( in!=0 )?
  976. STATUS_SYNTAX_ERROR:STATUS_END_OF_STRING;
  977. pParseVars->pInPJL_Local = pIn;
  978. return(FALSE);
  979. }
  980. /*
  981. BOOL SkipPastNextCRLF(ParseVarsType *pParseVars)
  982. This function positions the stream pointer past the next
  983. CRLF.
  984. If a CRLF is found:
  985. pParseVars->pInPJL_Local is set to point just past the CRLF.
  986. the return value is TRUE
  987. (pParseVars->status is unchanged)
  988. If the end of input is encountered before the CRLF is found then
  989. pParseVars->pInPJL_Local is set to point to the terminating 0.
  990. the return value is FALSE
  991. pParseVars->status is set to STATUS_END_OF_STRING
  992. If an FF is encountered before the CRLF is found then
  993. the return value is FALSE
  994. pParseVars->status is set to STATUS_SYNTAX_ERROR
  995. */
  996. BOOL SkipPastNextCRLF(ParseVarsType *pParseVars)
  997. {
  998. if ( !AdvancePointerPastString(pParseVars, "\r\n") )
  999. {
  1000. if ( pParseVars->status == STATUS_REACHED_FF)
  1001. {
  1002. pParseVars->status = STATUS_SYNTAX_ERROR;
  1003. }
  1004. return(FALSE);
  1005. }
  1006. return(TRUE);
  1007. }
  1008. void GetTokenFromIndexSetNewList(ParseVarsType *pParseVars, ParamType param)
  1009. {
  1010. StoreToken(pParseVars,
  1011. pParseVars->pCurrentList->tokenBaseValue+pParseVars->dwFoundIndex);
  1012. SetNewList(pParseVars, param);
  1013. return;
  1014. }
  1015. void SetValueFromParamFF(ParseVarsType *pParseVars, ParamType param)
  1016. {
  1017. if ( !StoreTokenValueAndAdvancePointer(pParseVars, param.value) )
  1018. {
  1019. return;
  1020. }
  1021. ExpectFinalCRLFFF(pParseVars);
  1022. return;
  1023. }
  1024. void SetValueFromParam(ParseVarsType *pParseVars, ParamType param)
  1025. {
  1026. if ( !StoreTokenValueAndAdvancePointer(pParseVars, param.value) )
  1027. {
  1028. return;
  1029. }
  1030. return;
  1031. }
  1032. void ActionNotFoundSkipCFLFandIndentedLines(ParseVarsType *pParseVars)
  1033. {
  1034. #if DEBUGOUTPUT
  1035. DbgMsg("ActionNotFoundSkipCRLF In=%hs\n", pParseVars->pInPJL_Local);
  1036. #endif
  1037. do
  1038. {
  1039. if ( !SkipPastNextCRLF(pParseVars) )
  1040. {
  1041. #if DEBUGOUTPUT
  1042. DbgMsg("ActionNotFoundSkipCRLF error skipping\n");
  1043. #endif
  1044. return;
  1045. }
  1046. } while (*pParseVars->pInPJL_Local==TAB);
  1047. #if DEBUGOUTPUT
  1048. DbgMsg("ActionNotFoundSkipCRLF Out=%hs\n", pParseVars->pInPJL_Local);
  1049. #endif
  1050. return;
  1051. }
  1052. void GetTokenFromIndexValueFromNumberEOLFromParam
  1053. (ParseVarsType *pParseVars,ParamType param)
  1054. {
  1055. int value;
  1056. param; /* to eliminate not used warning */
  1057. #if DEBUGOUTPUT
  1058. DbgMsg("GetTokenFromIndexValueFromNumberIn=%hs\n", pParseVars->pInPJL_Local);
  1059. #endif
  1060. StoreToken(pParseVars,
  1061. pParseVars->pCurrentList->tokenBaseValue+pParseVars->dwFoundIndex);
  1062. if ( (value=GetPositiveInteger(pParseVars))==-1 )
  1063. {
  1064. /* Not a valid number - status set by GetPositiveInteger() */
  1065. #if DEBUGOUTPUT
  1066. DbgMsg("error getting number\n");
  1067. #endif
  1068. return;
  1069. }
  1070. if ( !StoreTokenValueAndAdvancePointer(pParseVars, value) )
  1071. {
  1072. #if DEBUGOUTPUT
  1073. DbgMsg("error storing value\n");
  1074. #endif
  1075. return;
  1076. }
  1077. if ( !ExpectString(pParseVars, param.lpstr) )
  1078. {
  1079. return;
  1080. }
  1081. #if DEBUGOUTPUT
  1082. DbgMsg("GetTokenFromIndexValueFromNumberOut=%hs\n", pParseVars->pInPJL_Local);
  1083. #endif
  1084. return;
  1085. }
  1086. void GetTokenFromIndexValueFromBooleanEOL
  1087. (ParseVarsType *pParseVars,ParamType param)
  1088. {
  1089. int value;
  1090. param; /* to eliminate not used warning */
  1091. #if DEBUGOUTPUT
  1092. DbgMsg("GetTokenFromIndexValueFromBooleanEOLin=%hs\n", pParseVars->pInPJL_Local);
  1093. #endif
  1094. StoreToken(pParseVars,
  1095. pParseVars->pCurrentList->tokenBaseValue+pParseVars->dwFoundIndex);
  1096. pParseVars->pCurrentKeywords = FALSEandTRUEKeywords;
  1097. if ( (value=LookForKeyword(pParseVars))==-1 )
  1098. {
  1099. /* Not TRUE or FALSE */
  1100. pParseVars->status = STATUS_SYNTAX_ERROR;
  1101. return;
  1102. }
  1103. if ( !StoreTokenValueAndAdvancePointer(pParseVars, value) )
  1104. {
  1105. return;
  1106. }
  1107. if ( !ExpectString(pParseVars, param.lpstr) )
  1108. {
  1109. return;
  1110. }
  1111. #if DEBUGOUTPUT
  1112. DbgMsg("GetTokenFromIndexValueFromBooleanEOLout=%hs\n", pParseVars->pInPJL_Local);
  1113. #endif
  1114. return;
  1115. }
  1116. void GetTokenFromIndexValueFromStringEOL
  1117. (ParseVarsType *pParseVars,ParamType param)
  1118. {
  1119. param; /* to eliminate not used warning */
  1120. #if DEBUGOUTPUT
  1121. DbgMsg("GetTokenFromIndexValueFromStringEOLin=%hs\n", pParseVars->pInPJL_Local);
  1122. #endif
  1123. StoreToken(pParseVars,
  1124. pParseVars->pCurrentList->tokenBaseValue+pParseVars->dwFoundIndex);
  1125. if ( !StoreTokenValueAndAdvancePointer(pParseVars, (UINT_PTR)pParseVars->pInPJL_Local))
  1126. {
  1127. return;
  1128. }
  1129. SkipPastNextCRLF(pParseVars);
  1130. #if DEBUGOUTPUT
  1131. DbgMsg("GetTokenFromIndexValueFromStringEOLout=%hs\n", pParseVars->pInPJL_Local);
  1132. #endif
  1133. return;
  1134. }