summaryrefslogtreecommitdiff
path: root/src/xine-utils/xmllexer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-utils/xmllexer.c')
-rw-r--r--src/xine-utils/xmllexer.c140
1 files changed, 99 insertions, 41 deletions
diff --git a/src/xine-utils/xmllexer.c b/src/xine-utils/xmllexer.c
index fc75f0e73..a9fcd9e31 100644
--- a/src/xine-utils/xmllexer.c
+++ b/src/xine-utils/xmllexer.c
@@ -44,16 +44,19 @@
#endif
/* private constants*/
-#define NORMAL 0 /* normal lex mode */
-#define DATA 1 /* data lex mode */
/* private global variables */
static const char * lexbuf;
static int lexbuf_size = 0;
static int lexbuf_pos = 0;
-static int lex_mode = NORMAL;
static int in_comment = 0;
+static enum {
+ NORMAL,
+ DATA,
+ CDATA,
+} lex_mode = NORMAL;
+
void lexer_init(const char * buf, int size) {
lexbuf = buf;
lexbuf_size = size;
@@ -64,83 +67,102 @@ void lexer_init(const char * buf, int size) {
lprintf("buffer length %d\n", size);
}
+typedef enum {
+ STATE_UNKNOWN = -1,
+ STATE_IDLE,
+ STATE_EOL,
+ STATE_SEPAR,
+ STATE_T_M_START,
+ STATE_T_M_STOP_1,
+ STATE_T_M_STOP_2,
+ STATE_T_EQUAL,
+ STATE_T_STRING_SINGLE,
+ STATE_T_STRING_DOUBLE,
+ STATE_T_COMMENT,
+ STATE_T_TI_STOP,
+ STATE_T_DASHDASH,
+ STATE_T_C_STOP,
+ STATE_IDENT /* must be last */
+} lexer_state_t;
+
int lexer_get_token(char * tok, int tok_size) {
int tok_pos = 0;
- int state = 0;
+ lexer_state_t state = STATE_IDLE;
char c;
if (tok) {
while ((tok_pos < tok_size) && (lexbuf_pos < lexbuf_size)) {
c = lexbuf[lexbuf_pos];
- lprintf("c=%c, state=%d, in_comment=%d\n", c, state, in_comment);
+ lprintf("c=%c, state=%d, lex_mode=%d, in_comment=%d\n", c, state, lex_mode, in_comment);
- if (lex_mode == NORMAL) {
- /* normal mode */
+ switch (lex_mode) {
+ case NORMAL:
switch (state) {
/* init state */
- case 0:
+ case STATE_IDLE:
switch (c) {
case '\n':
case '\r':
- state = 1;
+ state = STATE_EOL;
tok[tok_pos] = c;
tok_pos++;
break;
case ' ':
case '\t':
- state = 2;
+ state = STATE_SEPAR;
tok[tok_pos] = c;
tok_pos++;
break;
case '<':
- state = 3;
+ state = STATE_T_M_START;
tok[tok_pos] = c;
tok_pos++;
break;
case '>':
- state = 4;
+ state = STATE_T_M_STOP_1;
tok[tok_pos] = c;
tok_pos++;
break;
case '/':
if (!in_comment)
- state = 5;
+ state = STATE_T_M_STOP_2;
tok[tok_pos] = c;
tok_pos++;
break;
case '=':
- state = 6;
+ state = STATE_T_EQUAL;
tok[tok_pos] = c;
tok_pos++;
break;
case '\"': /* " */
- state = 7;
+ state = STATE_T_STRING_DOUBLE;
break;
case '\'': /* " */
- state = 12;
+ state = STATE_T_STRING_SINGLE;
break;
case '-':
- state = 10;
+ state = STATE_T_DASHDASH;
tok[tok_pos] = c;
tok_pos++;
break;
case '?':
- state = 9;
+ if (!in_comment)
+ state = STATE_T_TI_STOP;
tok[tok_pos] = c;
tok_pos++;
break;
default:
- state = 100;
+ state = STATE_IDENT;
tok[tok_pos] = c;
tok_pos++;
break;
@@ -149,7 +171,7 @@ int lexer_get_token(char * tok, int tok_size) {
break;
/* end of line */
- case 1:
+ case STATE_EOL:
if (c == '\n' || (c == '\r')) {
tok[tok_pos] = c;
lexbuf_pos++;
@@ -161,7 +183,7 @@ int lexer_get_token(char * tok, int tok_size) {
break;
/* T_SEPAR */
- case 2:
+ case STATE_SEPAR:
if (c == ' ' || (c == '\t')) {
tok[tok_pos] = c;
lexbuf_pos++;
@@ -173,7 +195,7 @@ int lexer_get_token(char * tok, int tok_size) {
break;
/* T_M_START < or </ or <! or <? */
- case 3:
+ case STATE_T_M_START:
switch (c) {
case '/':
tok[tok_pos] = c;
@@ -186,7 +208,7 @@ int lexer_get_token(char * tok, int tok_size) {
tok[tok_pos] = c;
lexbuf_pos++;
tok_pos++;
- state = 8;
+ state = STATE_T_COMMENT;
break;
case '?':
tok[tok_pos] = c;
@@ -202,7 +224,7 @@ int lexer_get_token(char * tok, int tok_size) {
break;
/* T_M_STOP_1 */
- case 4:
+ case STATE_T_M_STOP_1:
tok[tok_pos] = '\0';
if (!in_comment)
lex_mode = DATA;
@@ -210,7 +232,7 @@ int lexer_get_token(char * tok, int tok_size) {
break;
/* T_M_STOP_2 */
- case 5:
+ case STATE_T_M_STOP_2:
if (c == '>') {
tok[tok_pos] = c;
lexbuf_pos++;
@@ -226,13 +248,13 @@ int lexer_get_token(char * tok, int tok_size) {
break;
/* T_EQUAL */
- case 6:
+ case STATE_T_EQUAL:
tok[tok_pos] = '\0';
return T_EQUAL;
break;
/* T_STRING */
- case 7:
+ case STATE_T_STRING_DOUBLE:
tok[tok_pos] = c;
lexbuf_pos++;
if (c == '\"') { /* " */
@@ -242,8 +264,8 @@ int lexer_get_token(char * tok, int tok_size) {
tok_pos++;
break;
- /* T_C_START or T_DOCTYPE_START */
- case 8:
+ /* T_C_START or T_DOCTYPE_START or T_CDATA_START */
+ case STATE_T_COMMENT:
switch (c) {
case '-':
lexbuf_pos++;
@@ -267,6 +289,17 @@ int lexer_get_token(char * tok, int tok_size) {
return T_ERROR;
}
break;
+ case '[':
+ lexbuf_pos++;
+ if (strncmp(lexbuf + lexbuf_pos, "CDATA[", 6) == 0) {
+ strncpy (tok + tok_pos, "[CDATA[", 7); /* FIXME */
+ lexbuf_pos += 6;
+ lex_mode = CDATA;
+ return T_CDATA_START;
+ } else{
+ return T_ERROR;
+ }
+ break;
default:
/* error */
return T_ERROR;
@@ -274,12 +307,14 @@ int lexer_get_token(char * tok, int tok_size) {
break;
/* T_TI_STOP */
- case 9:
+ case STATE_T_TI_STOP:
if (c == '>') {
tok[tok_pos] = c;
lexbuf_pos++;
tok_pos++; /* FIXME */
tok[tok_pos] = '\0';
+ if (!in_comment)
+ lex_mode = DATA;
return T_TI_STOP;
} else {
tok[tok_pos] = '\0';
@@ -288,24 +323,24 @@ int lexer_get_token(char * tok, int tok_size) {
break;
/* -- */
- case 10:
+ case STATE_T_DASHDASH:
switch (c) {
case '-':
tok[tok_pos] = c;
tok_pos++;
lexbuf_pos++;
- state = 11;
+ state = STATE_T_C_STOP;
break;
default:
tok[tok_pos] = c;
tok_pos++;
lexbuf_pos++;
- state = 100;
+ state = STATE_IDENT;
}
break;
/* --> */
- case 11:
+ case STATE_T_C_STOP:
switch (c) {
case '>':
tok[tok_pos] = c;
@@ -325,12 +360,12 @@ int lexer_get_token(char * tok, int tok_size) {
tok[tok_pos] = c;
tok_pos++;
lexbuf_pos++;
- state = 100;
+ state = STATE_IDENT;
}
break;
/* T_STRING (single quotes) */
- case 12:
+ case STATE_T_STRING_SINGLE:
tok[tok_pos] = c;
lexbuf_pos++;
if (c == '\'') { /* " */
@@ -341,7 +376,7 @@ int lexer_get_token(char * tok, int tok_size) {
break;
/* IDENT */
- case 100:
+ case STATE_IDENT:
switch (c) {
case '<':
case '>':
@@ -358,13 +393,13 @@ int lexer_get_token(char * tok, int tok_size) {
tok[tok_pos] = c;
tok_pos++;
lexbuf_pos++;
- state = 9;
+ state = STATE_T_TI_STOP;
break;
case '-':
tok[tok_pos] = c;
tok_pos++;
lexbuf_pos++;
- state = 10;
+ state = STATE_T_DASHDASH;
break;
default:
tok[tok_pos] = c;
@@ -376,8 +411,9 @@ int lexer_get_token(char * tok, int tok_size) {
lprintf("expected char \'%c\'\n", tok[tok_pos - 1]); /* FIX ME */
return T_ERROR;
}
- } else {
- /* data mode, stop if char equal '<' */
+ break;
+
+ case DATA: /* data mode, stop if char equal '<' */
switch (c)
{
case '<':
@@ -389,6 +425,28 @@ int lexer_get_token(char * tok, int tok_size) {
tok_pos++;
lexbuf_pos++;
}
+ break;
+
+ case CDATA: /* cdata mode, stop if next token is "]]>" */
+ switch (c)
+ {
+ case ']':
+ if (strncmp(lexbuf + lexbuf_pos, "]]>", 3) == 0) {
+ lexbuf_pos += 3;
+ lex_mode = DATA;
+ return T_CDATA_STOP;
+ } else {
+ tok[tok_pos] = c;
+ tok_pos++;
+ lexbuf_pos++;
+ }
+ break;
+ default:
+ tok[tok_pos] = c;
+ tok_pos++;
+ lexbuf_pos++;
+ }
+ break;
}
}
lprintf ("loop done tok_pos = %d, tok_size=%d, lexbuf_pos=%d, lexbuf_size=%d\n",