📄 parser.c
字号:
int Parser_setLastElem(Parser *pParser, const char*s) { if (*s == '\0') { membuffer_assign(&(pParser->lastElem),NULL,0); return 0; } if (membuffer_assign_str(&(pParser->lastElem),s)!=0) return -1; return 0;}char* Parser_getTokBuf(Parser *pParser) { if (pParser->tokBuf.buf) return pParser->tokBuf.buf; else return "";}int Parser_getTokBufLength(Parser *pParser) { return pParser->tokBuf.length;}int Parser_clearTokBuf(Parser *pParser) { membuffer_assign(&(pParser->tokBuf),NULL,0); return 0;}int Parser_appendTokBuf_string(Parser *pParser, const char *s) { if (*s == '\0') return 0; if (membuffer_append_str(&(pParser->tokBuf) ,s)!=0) return -1; return 0;}int Parser_appendTokBuf_char(Parser *pParser, char c) { if (membuffer_append(&(pParser->tokBuf),&c,1)!=0) return -1; return 0;}void Parser_IgnoreWhiteSpaces(Parser *pParser){ while(char_match (*(pParser->CurrPtr), WHITESPACE)) Parser_getNextToken(pParser);}//Rewinds Current Ptr by n bytesvoid Parser_rewindCurrentPtr(Parser *pParser, int n){ pParser->CurrPtr=pParser->CurrPtr - n;}//Finds the Next Match//Finds the next character in strSearch that contains strMatch.char * Parser_findNextMatch (char *strSearch, const char *strMatch){ char *strIndex; // Current character match position if ((strSearch == NULL) || (strMatch == NULL)) return NULL; strIndex = strSearch; while (!(char_match (*strIndex, strMatch)) && (*strIndex != '\0')) strIndex++; return strIndex;}int get_char(char *src, int*clen){ char *pnum; int count; int sum; char c; *clen=0; if (!src || !clen) return -1; if (*src!='&'){ if (*src>0 &&isxmlch(*src)){ *clen=1; return *src; } int i, len; i=toint(src,&len); if (!isxmlch(i))return -1; *clen=len; return i; } if (!strncasecmp(src,QUOT,strlen(QUOT))){ *clen=strlen(QUOT); return '"'; } if (!strncasecmp(src,LT,strlen(LT))){ *clen=strlen(LT); return '<'; } if (!strncasecmp(src,GT,strlen(GT))){ *clen=strlen(GT); return '>'; } if (!strncasecmp(src,APOS,strlen(APOS))){ *clen=strlen(APOS); return '\''; } if (!strncasecmp(src,AMP,strlen(AMP))){ *clen=strlen(AMP); return '&'; } // Read in escape characters of type &#xnn where nn is a hexadecimal value if (!strncasecmp(src,ESC_HEX,strlen(ESC_HEX))){ count=0; pnum=src+strlen(ESC_HEX); sum=0; while (char_match(pnum[count],HEX_NUMBERS)){ c=pnum[count]; if (c<='9') sum = sum * 16+(c-'0'); else if(c<='F') sum = sum*16+(c-'A'+10); else sum = sum*16+(c-'a'+10); count++; } if (count<=0||pnum[count]!=';'||!isxmlch(sum)) return -1; *clen=strlen(ESC_HEX)+count+1; return sum; } // Read in escape characters of type &#nn where nn is a decimal value if (!strncasecmp(src,ESC_DEC,strlen(ESC_DEC))){ count=0; pnum=src+strlen(ESC_DEC); sum=0; while (char_match(pnum[count],DEC_NUMBERS)) sum=sum*10+(pnum[count++]-'0'); if (count<=0||pnum[count]!=';'||!isxmlch(sum)) return -1; *clen=strlen(ESC_DEC)+count+1; return sum; } return -1;}short int Parser_copy_token(Parser *pParser, char *src, int len){ int i,c, cl; char *psrc, *pend; utf8char uch; if (!src||len <= 0) return 0; psrc=src; pend=src+len; while (psrc<pend){ if ((c=get_char(psrc, &cl))<=0) { //*dest=0; //clearTokBuf(); return 0; } if (cl==1){ //*dest++=c; Parser_appendTokBuf_char(pParser, c); psrc++; } else { //i=toutf8(c, dest); i=toutf8(c, uch); //if (i<0) {*dest=0; return false;} if (i<0) { return 0;} //dest+=i; Parser_appendTokBuf_char(pParser, uch); psrc+=cl; } } //*dest=0; if (psrc>pend) return 0; return 1; // success}//Skip String//Skips all characters in the fragment string that are contained within//strSkipChars until some other character is found. Useful for skipping//over whitespace.long Parser_skipString (char **pstrFragment, const char *strSkipChars){ if (!pstrFragment || !strSkipChars) return -1; while ((**pstrFragment != '\0') && (char_match (**pstrFragment, strSkipChars))) { (*pstrFragment)++; } return 0; //success}//Skip Until String//Skips all characters in the string until it finds the skip key.//Then it skips the skip key and returns.long Parser_skipUntilString (char **pstrSource, const char *strSkipKey){ if (!pstrSource || !strSkipKey) return -1; while (**pstrSource && strncmp (*pstrSource, strSkipKey, strlen(strSkipKey))) (*pstrSource)++; *pstrSource = *pstrSource + strlen (strSkipKey); return 0; //success}//This will return the string of the next token in the TokenBuffint Parser_getNextToken(Parser *pParser){ int TokenLength=0; int temp, tlen; Parser_clearTokBuf(pParser); // Check for white space if(*(pParser->CurrPtr)=='\0') { //TokenBuff[0]='\0'; return 0; } // Attribute value logic must come first, since all text untokenized until end-quote if (pParser->inAttrib && (!char_match (*(pParser->CurrPtr), QUOTE))) { char *strEndQuote = Parser_findNextMatch (pParser->CurrPtr, QUOTE); if (strEndQuote == NULL) { TokenLength = 1; //*TokenBuff = '\0'; // return a single space for whitespace //if (!copy_token (TokenBuff, pParser->CurrPtr, TokenLength)) if (!Parser_copy_token (pParser, pParser->CurrPtr, TokenLength)) return 1; return 0; // serious problem - no matching end-quote found for attribute } TokenLength = strEndQuote - pParser->CurrPtr; // BUGBUG: conversion issue if using more than simple strings //if (!copy_token (TokenBuff, CurrPtr, TokenLength)) if (!Parser_copy_token (pParser, pParser->CurrPtr, TokenLength)) return 1; pParser->CurrPtr = pParser->CurrPtr+TokenLength; return 0; // must return now, so it doesn't go into name processing } if (char_match (*(pParser->CurrPtr), WHITESPACE)) { TokenLength = 1; //if (!copy_token (TokenBuff, " ", TokenLength)) // return a single space for whitespace if (!Parser_copy_token (pParser, " ", TokenLength)) // return a single space for whitespace return 1; pParser->CurrPtr = pParser->CurrPtr+TokenLength; return 0; } // Skip <? .. ?> , <! .. >, <!-- .. --> while (!strncmp (pParser->CurrPtr, BEGIN_COMMENT, strlen(BEGIN_COMMENT)) // <!-- || !strncmp (pParser->CurrPtr, BEGIN_PROCESSING, strlen(BEGIN_PROCESSING)) // <? || !strncmp (pParser->CurrPtr, BEGIN_DOCTYPE, strlen(BEGIN_DOCTYPE))) // <! { if (!strncmp (pParser->CurrPtr, BEGIN_COMMENT, strlen(BEGIN_COMMENT))) Parser_skipUntilString (&(pParser->CurrPtr), END_COMMENT); else if (!strncmp (pParser->CurrPtr, BEGIN_PROCESSING, strlen(BEGIN_PROCESSING))) Parser_skipUntilString (&(pParser->CurrPtr), END_PROCESSING); else Parser_skipUntilString (&(pParser->CurrPtr), GREATERTHAN); Parser_skipString (&(pParser->CurrPtr), WHITESPACE); pParser->TagVal=0; } // Check for start tags if (char_match (*(pParser->CurrPtr), LESSTHAN)) { temp = toint((pParser->CurrPtr)+1, &tlen); if (temp == '/') TokenLength = 2; // token is '</' end tag else if(isnamech(temp,0)) TokenLength=1; // Begin tag found, so return '<' token else{ //strcpy(TokenBuff,"\0"); return 1; //error } pParser->TagVal=0; } // Check for opening/closing attribute value quotation mark if (char_match (*(pParser->CurrPtr), QUOTE) && !(pParser->TagVal)) { // Quote found, so return it as token TokenLength = strlen(QUOTE); } // Check for '=' token if (char_match (*(pParser->CurrPtr), EQUALS) && !(pParser->TagVal)) { // Equals found, so return it as a token TokenLength = strlen(EQUALS); } // Check for '/>' token if (char_match (*(pParser->CurrPtr), SLASH)) { if (char_match (*(pParser->CurrPtr + 1), GREATERTHAN)) { // token '/>' found TokenLength = 2; pParser->TagVal=1; } //Content may begin with a / else if (pParser->TagVal) { pParser->TagVal=0; pParser->CurrPtr=pParser->SavePtr+1;//SavePtr whould not have have already moved. char *pEndContent = pParser->CurrPtr; // Read content until a < is found that is not a comment <!-- short int bReadContent = 1; while (bReadContent) { while (!char_match (*pEndContent, LESSTHAN) && *pEndContent) pEndContent++; if (!strncmp (pEndContent, BEGIN_COMMENT, strlen (BEGIN_COMMENT)))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -