ldhtml.c
上传用户:aidanglao
上传日期:2007-01-07
资源大小:69k
文件大小:17k
源码类别:

Oracle数据库

开发平台:

Unix_Linux

  1. /* ldhtml.c - loads and HTML file
  2. /*
  3. /* Copyright (c) 1995-1999 Applied Information Technologies, Inc.
  4. /* All Rights Reserved.
  5. /*  
  6. /* Distributed uder the GNU General Public License which was included in
  7. /* the file named "LICENSE" in the package that you recieved.
  8. /* If not, write to:
  9. /* The Free Software Foundation, Inc.,
  10. /* 675 Mass Ave, Cambridge, MA 02139, USA.
  11.  */
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include <stdarg.h>
  16. #include <string.h>
  17. /*
  18. /* Local Includes 
  19.  */
  20. #include "sqlweb.h"
  21. /*
  22. /* TOKENS
  23.  */
  24. typedef enum {
  25.      OpenTag_t
  26.     ,OpenEndTag_t
  27.     ,OpenComment_t
  28.     ,EndTag_t
  29.     ,AttAssign_t
  30.     ,String_t
  31.     ,EndOfFile_t
  32. } eToken_t;
  33. /*
  34. /* STATES
  35.  */
  36. typedef enum {
  37.      Init_s
  38.     ,InBetween_s
  39.     ,InTag_s
  40.     ,InAtt_s
  41.     ,InAttAssign_s
  42.     ,InValue_s
  43.     ,InContents_s
  44.     ,InComment_s
  45.     ,InEndTag_s
  46.     ,InEndTag2_s
  47.     ,Err_s
  48.     ,EndOfFile_s
  49. } eParseState_t;
  50. /*
  51. /* Global Variables, basically, in a STATE MACHINE everything
  52. /* is global!
  53.  */
  54. static char gsStringBuf[MAX_BUFSIZ]; /* String from "TOKENIZER" */
  55. static char *gpStringBuf; /* Current Location in memory-
  56. /* mapped file */
  57. static eParseState_t gsParseState =Init_s; /* The STATE */
  58. static eToken_t gtToken; /* The TOKEN */
  59. static TAG *gpTAG; /* The TAG */
  60. static SYMBOL *gpSym; /* The Attribute */
  61. static PI *gpPI; /* The PageItem */
  62. static PAGE *gpPAGE; /* The PAGE */
  63. static LIST *galPI[MAX_TAG_LEVELS]; /* The PageItem List Array */
  64. static PI   *gaPI[MAX_TAG_LEVELS]; /* The PI Array (context) */
  65. static int giLevel /* The Level */
  66.   ,giErr = 0 /* Error counter */
  67.   ,giLineNbr = 1 /* Line Counter */
  68. ;
  69. static eBoolean_t
  70.    gbFatal = eFalse /* Fatal Errors */
  71. ;
  72. static TAG gNULLTag = 
  73.     {"NULL" /* pTagName */
  74.     ,"Y" /* pTagEmptyInd */
  75.     ,"" /* pTagDesc */
  76.     ,"A" /* pTagAfterInd(HIDDEN) */
  77.     ,"" /* pTagLinkDesc */
  78.     };
  79. #define EXACT_TOKENS 7
  80. #define EXACT_STATES 12
  81. /* #define MAX_PARSE_ERRORS 25
  82.  */
  83. /*
  84. /* State Transition Functions
  85.  */
  86. eParseState_t  f011(),f012(),f013(),f014(),f015(),f016()
  87. ,f021(),f022(),f023(),f024(),f025(),f026()
  88. ,f031(),f032(),f033(),f034(),f035(),f036()
  89. ,f041(),f042(),f043(),f044(),f045(),f046()
  90. ,f051(),f052(),f053(),f054(),f055(),f056()
  91. ,f061(),f062(),f063(),f064(),f065(),f066()
  92. ,f071(),f072(),f073(),f074(),f075(),f076()
  93. ,f081(),f082(),f083(),f084(),f085(),f086()
  94. ,f091(),f092(),f093(),f094(),f095(),f096()
  95. ,f101(),f102(),f103(),f104(),f105(),f106()
  96. ,f111(),f112(),f113(),f114(),f115(),f116()
  97. ,f_eof()/* end of file */
  98. ;
  99. /*
  100. /* The STATE MACHINE!
  101.  */
  102. typedef eParseState_t (*PFS_t)(); /* Pointer to Function returning STATE */
  103. PFS_t gaTransTab [ EXACT_STATES ] [ EXACT_TOKENS ]  = {
  104. /*    Open-  Open-   Open-           Att-
  105. /*    Tag    EndTag  Comment  EndTag Assign    STRING EOF
  106. /*    ===    ======  =======  ====== ======    ====== ===
  107. /* Init_s */ f011  ,f012   ,f013    ,f014  ,f015     ,f016  ,f_eof
  108. /* InBetween_s */,f021  ,f022   ,f023    ,f024  ,f025     ,f026  ,f_eof
  109. /* InTag_s */,f031  ,f032   ,f033    ,f034  ,f035     ,f036  ,f_eof
  110. /* InAtt_s */,f041  ,f042   ,f043    ,f044  ,f045     ,f046  ,f_eof
  111. /* InAttAssign_s*/,f051  ,f052   ,f053    ,f054  ,f055     ,f056  ,f_eof
  112. /* InValue_s */,f061  ,f062   ,f063    ,f064  ,f065     ,f066  ,f_eof
  113. /* InContents_s */,f071  ,f072   ,f073    ,f074  ,f075     ,f076  ,f_eof
  114. /* InComment_s */,f081  ,f082   ,f083    ,f084  ,f085     ,f086  ,f_eof
  115. /* InEndTag_s */,f091  ,f092   ,f093    ,f094  ,f095     ,f096  ,f_eof
  116. /* InEndTag2_s */,f101  ,f102   ,f103    ,f104  ,f105     ,f106  ,f_eof
  117. /* Err_s */,f111  ,f112   ,f113    ,f114  ,f115     ,f116  ,f_eof
  118. };
  119. static eBoolean_t ParseStream();
  120. static eToken_t GetNextToken();
  121. static eBoolean_t mk_PI(char *pTagName, char *pPiContents);
  122. static void ParseErr(const char *pFmt, ...);
  123. /*
  124. /* Routines for processing input characters
  125.  */
  126. static int EatSpaces(int c);
  127. static int GetC();
  128. static void unGetC(int c);
  129. /*
  130. /*  Here we go.....
  131.  */
  132. /* The main interface routine.  This function takes the SQLweb HTML
  133. /* file and builds the in-memory PAGE / PI Tree that is represented
  134. /* by it.
  135.  */
  136. eBoolean_t
  137. LoadHTML(char *pFilename
  138. ,PAGE **pout_Page)
  139. {
  140.     eBoolean_t bParseRet;
  141.     PI PI; /* temporary PI for loading File Text */
  142.     char sBuf[BUFSIZ]; /* for dumping ERRStack */
  143.     RETeFalse2(LoadTEXT(pFilename,"HTML",&PI)
  144.      ,"LoadHTML Failed on %s"
  145.      ,pFilename
  146.      );
  147.     (*pout_Page) = (PAGE*)malloc(sizeof(PAGE));
  148.     if(!(*pout_Page)){
  149. ParseErr("malloc failed in parser");
  150. return(eFalse);
  151.     }
  152.     (void)memset((*pout_Page),0,sizeof(PAGE));
  153.     (*pout_Page)->lPI = galPI[0] = l_create("QUEUE"); /* Level 0:Page List*/
  154.     (*pout_Page)->pFileText = gpStringBuf = PI.pPiContents;
  155.     bParseRet = ParseStream();
  156.     /* This method, pop's off ALL Parse Errors
  157.     /* and if we are NOT COOKING the page it
  158.     /* displays the errors as HTML Comments
  159.     /* are silently ignored.....
  160.      */
  161.     while( MsgPop(sBuf) ) {
  162. if(ISCOOKED) {
  163.     DebugHTML(__FILE__,__LINE__,0,"%s",sBuf);
  164. } else {
  165.     fprintf(stderr,"%sn",sBuf);
  166. }
  167.     }
  168.     return(bParseRet);
  169. }
  170. /*
  171. /* The file parser.  runs "The State Machine"
  172.  */
  173. static eBoolean_t
  174. ParseStream()
  175. {
  176.     giErr=0; /* Global Error Count */
  177.     gbFatal=eFalse; /* Fatal Error Flag */
  178.     giLevel=0; /* Global PageItem Level */
  179.     giLineNbr=1; /* Line Number */
  180.     gsParseState = Init_s;
  181.     do {
  182. gtToken = GetNextToken();
  183. gsParseState = (gaTransTab[gsParseState][gtToken])();
  184.     } while( gsParseState != EndOfFile_s);
  185.     return( ISeTrue(gbFatal) ? eFalse : eTrue );
  186. }
  187. /*
  188. /* The Tokenizer
  189.  */
  190. static eToken_t
  191. GetNextToken()
  192. {
  193.     int c;
  194.     char *pBuf=gsStringBuf;
  195.     eBoolean_t bQuote=eFalse;
  196.     /*
  197.     /* Get the first character
  198.      */
  199.     c=GetC();
  200.     /*
  201.     /* Initialize the global STRING BUFFER 
  202.      */
  203.     *pBuf=0;
  204.     if(c==EOF){
  205. return(EndOfFile_t);
  206.     }
  207.     if(gsParseState==InAttAssign_s && c=='=') {
  208. return( AttAssign_t );
  209.     }
  210.     if(c == '<'){
  211. c=GetC();
  212. if(c=='!') {
  213.     return(OpenComment_t);
  214. } if(c=='/') {
  215.     return(OpenEndTag_t);
  216. unGetC(c);
  217. return(OpenTag_t);
  218.     }
  219.     if(c == '>') {
  220. return(EndTag_t);
  221.     }
  222.     for( ;c!=EOF && (pBuf-gsStringBuf)<sizeof(gsStringBuf);c=GetC()){
  223. /*
  224. /* Deal with Quotes (excluding InContents_s and InComments_s)
  225.  */
  226. if(c == '"'
  227.     && (  gsParseState==InAtt_s
  228. ||gsParseState==InAttAssign_s
  229. ||gsParseState==InValue_s))
  230. {
  231.      bQuote = ISeTrue(bQuote) ? eFalse :eTrue;
  232.     /* Toggle Quote Flag
  233.      */
  234.      continue; /* And eat it! */
  235. }
  236. if(c == '\' && ISeTrue(bQuote)) {
  237.     int c2 = GetC();
  238.     if(c2=='"'){
  239. *pBuf++ = (char) c2;
  240. continue;
  241.     }
  242.     unGetC(c2);
  243. }
  244. /* Deal with < and > 'tings
  245.  */
  246. if((c == '<' || c == '>')
  247.     && ISeFalse(bQuote))
  248. {
  249.     unGetC(c);
  250.     *pBuf = 0;
  251.     return(String_t);
  252. }
  253. /*
  254. /* The Attribute Assignment
  255.  */
  256. if(c == '=' && ISeFalse(bQuote)
  257.     && (gsParseState==InAtt_s || gsParseState==InAttAssign_s))
  258. {
  259.     unGetC(c);
  260.     *pBuf = 0;
  261.     return(String_t);
  262. }
  263. /*
  264. /* White space separator within <> pairs...
  265.  */
  266. if(isspace(c) 
  267.     && ISeFalse(bQuote)
  268.     &&( gsParseState==InTag_s
  269.      || gsParseState==InAtt_s
  270.      || gsParseState==InAttAssign_s
  271.      || gsParseState==InValue_s))
  272. {
  273.     *pBuf=0;
  274.     c=EatSpaces(c);
  275.     unGetC(c);
  276.     if( pBuf==gsStringBuf )
  277. continue;
  278.     return(String_t);
  279. }
  280. /* Fillin the Buffer....
  281.  */
  282. *pBuf++ = (char) c;
  283.     }
  284.     if( pBuf==gsStringBuf )
  285. return(EndOfFile_t);
  286.     *pBuf=0;
  287.     unGetC(c);
  288.     return(String_t);
  289. }
  290. /*
  291. /* Eat Spaces between TAGS
  292.  */
  293. static int
  294. EatSpaces(int c)
  295. {
  296.     do{ c=GetC();
  297.       } while(isspace(c));
  298.     return(c);
  299. }
  300. eParseState_t f_eof(){ return(EndOfFile_s); }
  301. /*
  302. /* The Init_s State
  303.  */
  304. eParseState_t f011(){return(InTag_s);}
  305. eParseState_t f012(){return(Init_s);}
  306. eParseState_t f013(){return(InComment_s);}
  307. eParseState_t f014(){return(Init_s);}
  308. eParseState_t f015(){return(Init_s);}
  309. eParseState_t f016(){return(Init_s);}
  310. /*
  311. /* The InBetween State
  312.  */
  313. eParseState_t f021(){return(InTag_s);}
  314. eParseState_t f022(){return(InEndTag_s);}
  315. eParseState_t f023(){return(InComment_s);}
  316. eParseState_t f024(){ParseErr("Encountered unmatched 'gt'");return(Err_s); }
  317. eParseState_t f025(){ParseErr("Internal error got '=' inBTWN");return(Err_s);}
  318. eParseState_t f026()
  319. {
  320. /*
  321. /*    int iWLen = strspn(gsStringBuf," tnr");
  322. /*    if(iWLen=iStrLen(gsStringBuf))
  323. /* return(InBetween_s);
  324.  */
  325.     if(ISeFalse(mk_PI("NULL",gsStringBuf))) {
  326. ParseErr("FATAL Error:mk_PI(NULL,%%s) failed");
  327. gbFatal=eTrue;
  328. return(Err_s);
  329.     }
  330.     return(InBetween_s);
  331. }
  332. /*
  333. /* The InTag State
  334.  */
  335. eParseState_t f031(){ParseErr("Got 'lt' within a tag")   ;return(Err_s);}
  336. eParseState_t f032(){ParseErr("Got 'lt+/' within a tag") ;return(Err_s);}
  337. eParseState_t f033(){ParseErr("Got 'lt+!' within a tag") ;return(Err_s);}
  338. eParseState_t f034(){ParseErr("Got 'lt' before tag name");return(Err_s);}
  339. eParseState_t f035(){ParseErr("Got '=' before tag name") ;return(Err_s);}
  340. eParseState_t f036()
  341. {
  342.     if(ISeFalse(mk_PI(gsStringBuf,0))) {
  343. ParseErr("ERR:InTag:mk_PI(%s,null) failed",gsStringBuf);
  344. gbFatal=eTrue;
  345. return(Err_s);
  346.     }
  347.     return(InAtt_s);
  348. }
  349. /*
  350. /* The InAtt State
  351.  */
  352. eParseState_t f041(){ParseErr("Got 'lt' within tag, "%s"",gpTAG->pTagName);
  353.     return(Err_s); 
  354.     }
  355. eParseState_t f042(){ParseErr("Got 'lt+/' within tag, "%s"",gpTAG->pTagName);
  356.     return(Err_s); 
  357.     }
  358. eParseState_t f043(){ParseErr("Got 'lt+!' within tag, "%s"",gpTAG->pTagName);
  359.     return(Err_s); 
  360.     }
  361. /*eParseState_t f044(){if(!isEmpty((gpPI))) return(InContents_s);
  362. /*      else   return(InBetween_s);
  363. /*     }
  364.  */
  365. eParseState_t f044(){if(!isEmpty((gpPI))) {
  366. /* giLevel++;
  367. /* galPI[giLevel] = gpPI->lPI;
  368.  */
  369. return(InBetween_s);
  370.     }
  371.      else return(InContents_s);
  372.     }
  373. eParseState_t f045(){ParseErr("Got '=' within tag, "%s"",gpTAG->pTagName);
  374.     return(Err_s); 
  375.     }
  376. eParseState_t f046()
  377. {
  378.     gpSym = NewPIA();
  379.     if(!gpSym){
  380. ParseErr("NewPIA Failed in parser");
  381. gbFatal=eTrue;
  382. return(Err_s);
  383.     }
  384.     /* (void)memset(gpSym,0,sizeof(SYMBOL));
  385.      */
  386.     gpSym->iType = PIA_SYMBOL;
  387.     gpSym->pName = DupBuf(gsStringBuf);
  388.     gpSym->pValue= 0;
  389.     ENQ(gpPI->lPIA,gpSym);
  390.     return(InAttAssign_s);
  391. }
  392. /*
  393. /* The InAttAssign State
  394.  */
  395. eParseState_t f051(){ParseErr("Got 'lt' within tag, "%s"",gpTAG->pTagName);
  396.     return(Err_s); 
  397.     }
  398. eParseState_t f052(){ParseErr("Got 'lt+/' within tag, "%s"",gpTAG->pTagName);
  399.     return(Err_s); 
  400.     }
  401. eParseState_t f053(){ParseErr("Got 'lt+!' within tag, "%s"",gpTAG->pTagName);
  402.     return(Err_s); 
  403.     }
  404. /* eParseState_t f054(){if(!isEmpty((gpPI))) return(InContents_s);
  405. /*       else   return(InBetween_s);
  406. /*      }
  407.  */
  408. eParseState_t f054(){if(!isEmpty((gpPI))) {
  409. /* giLevel++;
  410. /* galPI[giLevel] = gpPI->lPI;
  411.  */
  412. return(InBetween_s);
  413.     }
  414.      else return(InContents_s);
  415.     }
  416. eParseState_t f055(){return(InValue_s);}
  417. eParseState_t f056()
  418. {
  419.     gpSym = NewPIA();
  420.     if(!gpSym){
  421. ParseErr("NewPIA Failed to parser");
  422. gbFatal=eTrue;
  423. return(Err_s);
  424.     }
  425.     (void)memset(gpSym,0,sizeof(SYMBOL));
  426.     gpSym->iType = PIA_SYMBOL;
  427.     gpSym->pName = DupBuf(gsStringBuf);
  428.     gpSym->pValue= 0;
  429.     ENQ(gpPI->lPIA,gpSym);
  430.     return(InAttAssign_s);
  431. }
  432. /*
  433. /* The InValue State
  434.  */
  435. eParseState_t f061(){ParseErr("Got 'lt' within tag, "%s"" ,gpTAG->pTagName);
  436.     return(Err_s);
  437.     }
  438. eParseState_t f062(){ParseErr("Got 'lt+/' within tag, "%s"" ,gpTAG->pTagName);
  439.     return(Err_s);
  440.     }
  441. eParseState_t f063(){ParseErr("Got 'lt+!' within tag, "%s"" ,gpTAG->pTagName);
  442.     return(Err_s);
  443.     }
  444. eParseState_t f064(){ParseErr("Got 'gt' within attribute assign of tag, "%s""
  445.     ,gpTAG->pTagName);
  446.     return(Err_s);
  447.     }
  448. eParseState_t f065(){ParseErr("Got '= =' within tag, "%s"" ,gpTAG->pTagName);
  449.     return(Err_s);
  450.     }
  451. eParseState_t f066(){
  452.     gpSym->pValue = DupBuf(gsStringBuf);
  453.     return(InAtt_s);
  454.     }
  455. /*
  456. /* The InContents State
  457.  */
  458. eParseState_t f071(){return(InTag_s); }
  459. eParseState_t f072(){return(InEndTag_s); }
  460. eParseState_t f073(){return(InComment_s); }
  461. eParseState_t f074(){ParseErr("Got 'gt' after tag, "%s"",gpTAG->pTagName);
  462.     return(Err_s);
  463.     }
  464. eParseState_t f075(){ParseErr("Got '=' after tag, "%s"",gpTAG->pTagName);
  465.     return(Err_s);
  466.     }
  467. eParseState_t f076(){
  468.     gpPI->pPiContents = DupBuf(gsStringBuf);
  469.     return(InBetween_s); 
  470.     }
  471. /*
  472. /* The InComment State
  473.  */
  474. eParseState_t f081(){return(InComment_s); }
  475. eParseState_t f082(){return(InComment_s); }
  476. eParseState_t f083(){return(InComment_s); }
  477. eParseState_t f084(){return(InBetween_s); }
  478. eParseState_t f085(){return(InComment_s); }
  479. eParseState_t f086(){
  480.     int iSize = iStrLen(gsStringBuf);
  481.     gsStringBuf[iSize+3]=0; /* NULL */
  482.     gsStringBuf[iSize+2]='>'; /* Closing of Tag '>' */
  483.     while( --iSize>=0 ) /* The Contents */
  484. gsStringBuf[iSize+2] = gsStringBuf[iSize];
  485.     gsStringBuf[1] = '!'; /* Comment identifier */
  486.     gsStringBuf[0] = '<'; /* Starting TAG symbol */
  487.     if(*gsStringBuf && ISeFalse(mk_PI("!",gsStringBuf))) {
  488. ParseErr("ERR:InComment:Failed to make COMMENT");
  489. gbFatal=eTrue;
  490. return(Err_s);
  491.     }
  492.     return(InComment_s);
  493. } /* was InEndTag2 */
  494. /*
  495. /* The InEndTag State, just got '</' now looking for TAG-NAME
  496.  */
  497. eParseState_t f091(){ParseErr("missing tag name in trailer");return(Err_s); }
  498. eParseState_t f092(){ParseErr("missing tag name in trailer");return(Err_s); }
  499. eParseState_t f093(){ParseErr("missing tag name in trailer");return(Err_s); }
  500. eParseState_t f094(){ParseErr("missing tag name in trailer");return(Err_s); }
  501. eParseState_t f095(){ParseErr("missing tag name in trailer");return(Err_s); }
  502. eParseState_t f096()
  503. {
  504.     int iLevel = giLevel;
  505.     TAG *pTAG;
  506.     /* Make sure Tag was non-empty...
  507.      */
  508.     if(ISeFalse(GetTAGByName(gsStringBuf,&pTAG))) {
  509.     /*
  510.     /* May want to use NULL, here???
  511.      */
  512. MsgPush("Unknown tag, "%s"", gsStringBuf);
  513. return(Err_s);
  514.     }
  515.     if(is_casematch(pTAG->pTagEmptyInd,"Y")) {
  516. /* Empty TAG with end tag, WARNING...
  517.  */
  518. MsgPush("WARN(%s):Empty Tag w/END-TAG ignored, "%s" near line %d"
  519. ,pTAG->pTagEmptyInd
  520. ,gsStringBuf
  521. ,giLineNbr
  522.         ,gaPI[(giLevel>0)?giLevel-1:0]->pTagName
  523.         ,(giLevel>0)?giLevel-1:0
  524. );
  525. return(InEndTag2_s);
  526.     }
  527.     
  528.     /*
  529.     /* OK, Tag was non-empty, let's find it on the stack
  530.      */
  531.     while(--giLevel>=0
  532. && !is_casematch(gaPI[giLevel]->pTagName,gsStringBuf))
  533.     {
  534. /*
  535. DebugHTML(__FILE__,__LINE__,1
  536. ,"WARN(%s): Possible missing END-TAG, "%s" near line %d"
  537.        ,gaPI[giLevel]->pTag->pTagEmptyInd
  538.        ,gaPI[giLevel]->pTagName
  539.        ,giLineNbr
  540.        );
  541.  */
  542. MsgPush("WARN(%s): Possible missing END-TAG, "%s" near line %d"
  543.        ,gaPI[giLevel]->pTag->pTagEmptyInd
  544.        ,gaPI[giLevel]->pTagName
  545.        ,giLineNbr
  546.        );
  547.     }
  548.     if(giLevel<0) {
  549. MsgPush("Failed to find matching TAG for END-TAG, "%s" at line %d"
  550.        ,gsStringBuf
  551.        ,giLineNbr
  552.        );
  553. /* giLevel = iLevel-1;
  554.  */
  555. giLevel = iLevel; /* Couldn't find it; don't pop */
  556. return(Err_s);
  557.     }
  558.     return(InEndTag2_s);
  559. }
  560. /*
  561. /* The InEndTag2 State (looking for '>')
  562.  */
  563. eParseState_t f101(){ParseErr("Failed to find 'gt'");return(Err_s);}
  564. eParseState_t f102(){ParseErr("Failed to find 'gt'");return(Err_s);}
  565. eParseState_t f103(){ParseErr("Failed to find 'gt'");return(Err_s);}
  566. eParseState_t f104(){return(InBetween_s);}
  567. eParseState_t f105(){ParseErr("Failed to find 'gt'");return(Err_s);}
  568. eParseState_t f106(){ParseErr("Failed to find 'gt'");return(Err_s);}
  569. /*
  570. /* The inErr State
  571.  */
  572. eParseState_t f111(){return(ISeTrue(gbFatal)?EndOfFile_s:InTag_s);}
  573. eParseState_t f112(){return(ISeTrue(gbFatal)?EndOfFile_s:InEndTag_s);}
  574. eParseState_t f113(){return(ISeTrue(gbFatal)?EndOfFile_s:InComment_s);}
  575. eParseState_t f114(){return(ISeTrue(gbFatal)?EndOfFile_s:InBetween_s);}
  576. eParseState_t f115(){return(ISeTrue(gbFatal)?EndOfFile_s:Err_s);}
  577. eParseState_t f116(){return(ISeTrue(gbFatal)?EndOfFile_s:InBetween_s);}
  578. static eBoolean_t
  579. mk_PI(char *pTagName
  580.      ,char *pPiContents
  581.      )
  582. {
  583.     DebugHTML(__FILE__,__LINE__,4
  584. ,"mk_PI(%s,%s) line=%d"
  585. ,pTagName
  586. ,pPiContents?pPiContents:"**Null**"
  587. ,giLineNbr
  588. );
  589.     (gpPI) = NewPI();
  590.     if(!gpPI) {
  591. ParseErr("NewPI Failed in parser");
  592. gbFatal=eTrue;
  593. return(Err_s);
  594.     }
  595.     (gpPI)->iLevel = giLevel;
  596.     (gpPI)->pTagName = DupBuf(pTagName);
  597.     (gpPI)->pPage = gpPAGE;
  598.     (gpPI)->pTag = gpTAG;
  599.     (gpPI)->lPI = l_create("QUEUE");
  600.     (gpPI)->lPIA= l_create("INORDER");
  601.     (gpPI)->iLineNbr = giLineNbr;
  602.     if(is_casematch(pTagName,"NULL")){
  603. gpTAG = &gNULLTag;
  604.     } else {
  605. if(ISeFalse(GetTAGByName(pTagName,&gpTAG))) {
  606. /*
  607. /* May want to use NULL, here???
  608.  */
  609.     ParseErr("Unknown tag, "%s"", gsStringBuf);
  610.     return(eFalse);
  611. }
  612.     }
  613.     (gpPI)->pTag = gpTAG;
  614.     ENQ(galPI[giLevel], gpPI); /* Put PI in correct PI List */
  615.     gaPI[giLevel] = gpPI; /* Store pPI in PI Array */
  616.     gpPI->pPIContext = giLevel>0 ? gaPI[giLevel-1]: 0;
  617. /* Build the CONTEXT pointer */
  618.     (gpPI)->pPiContents = DupBuf(pPiContents);
  619.     if(!isEmpty((gpPI))) {
  620. giLevel++;
  621. galPI[giLevel] = gpPI->lPI;
  622.     }
  623.     return(eTrue);
  624. }
  625. /*
  626. /* Report a Parse Error
  627.  */
  628. static void
  629. ParseErr
  630.     (
  631.     const char *pFmt
  632.     ,...
  633.     )
  634. {
  635.     va_list pParms;
  636.     char sBuf[BUFSIZ];
  637.     /*
  638.     /* Build PrintF style buffer
  639.      */
  640.     va_start(pParms,pFmt);
  641.     vsprintf(sBuf,pFmt,pParms);
  642.     /* Add Line Number information
  643.      */
  644.     MsgPush("ParseErr line: %.4d: %s",giLineNbr,sBuf);
  645. }
  646. static int
  647. GetC()
  648. {
  649.     int c;
  650.     c= (int) *gpStringBuf++;
  651.     if(c=='n') giLineNbr++;
  652.     if(c=='') return(EOF);
  653.     return(c);
  654. }
  655. static void
  656. unGetC(int c)
  657. {
  658.     *(--gpStringBuf) = (char)c;
  659. }