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 047dbb1a6..bb03e5a79 100644
--- a/src/xine-utils/xmllexer.c
+++ b/src/xine-utils/xmllexer.c
@@ -43,14 +43,11 @@
#include "bswap.h"
/* 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 char *lex_malloc = NULL;
@@ -92,6 +89,12 @@ static void lex_convert (const char * buf, int size, enum utf utf)
lexbuf = lex_malloc = realloc (utf8, lexbuf_size + 1);
}
+static enum {
+ NORMAL,
+ DATA,
+ CDATA,
+} lex_mode = NORMAL;
+
void lexer_init(const char * buf, int size) {
static const char boms[] = { 0xFF, 0xFE, 0, 0, 0xFE, 0xFF },
bom_utf8[] = { 0xEF, 0xBB, 0xBF };
@@ -123,83 +126,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;
@@ -208,7 +230,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++;
@@ -220,7 +242,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++;
@@ -232,7 +254,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;
@@ -245,7 +267,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;
@@ -261,7 +283,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;
@@ -269,7 +291,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++;
@@ -285,13 +307,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 == '\"') { /* " */
@@ -301,8 +323,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++;
@@ -326,6 +348,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;
@@ -333,12 +366,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';
@@ -347,24 +382,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;
@@ -384,12 +419,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 == '\'') { /* " */
@@ -400,7 +435,7 @@ int lexer_get_token(char * tok, int tok_size) {
break;
/* IDENT */
- case 100:
+ case STATE_IDENT:
switch (c) {
case '<':
case '>':
@@ -417,13 +452,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;
@@ -435,8 +470,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 '<':
@@ -448,6 +484,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",