Index: include/mxml.h =================================================================== RCS file: /usr/local/cvsroot/rome/include/mxml.h,v retrieving revision 1.7 diff -u -r1.7 mxml.h --- include/mxml.h 12 Jul 2005 09:04:15 -0000 1.7 +++ include/mxml.h 6 Oct 2005 21:53:13 -0000 @@ -43,6 +43,10 @@ #define PROCESSING_INSTRUCTION_NODE 3 #define COMMENT_NODE 4 #define DOCUMENT_NODE 5 +#define ENTITY_NODE 6 + +#define INTERNAL_ENTITY 0 +#define EXTERNAL_ENTITY 1 typedef struct { int fh; @@ -115,6 +119,7 @@ PMXML_NODE mxml_create_root_node(); PMXML_NODE mxml_parse_file(char *file_name, char *error, int error_size); PMXML_NODE mxml_parse_buffer(char *buffer, char *error, int error_size); +PMXML_NODE mxml_parse_entity(char *buf, char *error, int error_size); int mxml_write_tree(char *file_name, PMXML_NODE tree); void mxml_debug_tree(PMXML_NODE tree, int level); void mxml_free_tree(PMXML_NODE tree); Index: src/mxml.c =================================================================== RCS file: /usr/local/cvsroot/rome/src/mxml.c,v retrieving revision 1.8 diff -u -r1.8 mxml.c --- src/mxml.c 11 May 2005 12:50:02 -0000 1.8 +++ src/mxml.c 6 Oct 2005 21:53:13 -0000 @@ -1209,6 +1209,30 @@ p += 2; + } else if (strncmp(p, "!ENTITY", 7) == 0) { + + /* found !ENTITY element */ + pnew = mxml_add_special_node(ptree, ENTITY_NODE, "ENTYTY", NULL); + pv = p+1; + + p++; + if (strstr(p, ">") == NULL) + return read_error(HERE, "Unterminated !ENTITY element"); + + while (*p != '>') { + if (*p == '\n') + line_number++; + p++; + } + + len = (size_t)p - (size_t)pv; + pnew->value = (char *)malloc(len+1); + memcpy(pnew->value, pv, len); + pnew->value[len] = 0; + mxml_decode(pnew->value); + + p ++; + } else { /* found normal element */ @@ -1407,6 +1431,249 @@ /*------------------------------------------------------------------*/ +PMXML_NODE mxml_parse_entity(char *buf, char *error, int error_size) +/* parse !ENTYTY entries of XML files and replace with references. Return NULL + in case of error, return error description. Optional file_name is used + for error reporting if called from mxml_parse_file() */ +{ + char *p; + char *pv; + char delimiter; + int i,j,k, line_number; + char replacement[1000]; + char entity_name[256][256]; + char entity_reference_name[256][256]; + char *entity_value[256]; + int entity_type[256]; /* internal or external */ + int nentity; + int fh, length,len; + char *buffer; + PMXML_NODE root = mxml_create_root_node(); // dummy for 'HERE' + char *file_name = NULL; // dummy for 'HERE' + + /* copy string to temporary space */ + buffer = (char *)malloc(strlen(buf)+1); + strcpy(buffer,buf); + free(buf); + + p = buffer; + line_number = 1; + nentity = -1; + + /* search !ENTITY */ + do { + if (*p == '<') { + + /* found new entity */ + p++; + while (*p && isspace(*p)) { + if (*p == '\n') + line_number++; + p++; + } + if (!*p) + return read_error(HERE, "Unexpected end of file"); + + if (strncmp(p, "!ENTITY", 7) == 0) { + + /* found entity */ + nentity++; + if(nentity>=1000) + return read_error(HERE, "Too much entities"); + + pv = p+7; + while (*pv == ' ') + pv++; + + /* extract entity name */ + p = pv; + + while (*p && isspace(*p) && *p != '<' && *p != '>') { + if (*p == '\n') + line_number++; + p++; + } + if (!*p) + return read_error(HERE, "Unexpected end of file"); + if (*p == '<' || *p == '>') + return read_error(HERE, "Unexpected \'%c\' inside !ENTITY", *p); + + pv = p; + while (*pv && !isspace(*pv) && *pv != '<' && *pv != '>') + pv++; + + if (!*pv) + return read_error(HERE, "Unexpected end of file"); + if (*pv == '<' || *pv == '>' ) + return read_error(HERE, "Unexpected \'%c\' inside entity \"%s\"", *pv, &entity_name[nentity][1]); + + len = (size_t)pv - (size_t)p; + if (len > (int)sizeof(replacement)-1) + len = sizeof(replacement)-1; + memcpy(replacement, p, len); + replacement[len] = 0; + mxml_decode(replacement); + + entity_name[nentity][0] = '&'; + i = 1; + entity_name[nentity][i] = 0; + while (*p && !isspace(*p) && *p != '/' && *p != '>' && *p != '<' && i<253) + entity_name[nentity][i++] = *p++; + entity_name[nentity][i++] = ';'; + entity_name[nentity][i] = 0; + + if (!*p) + return read_error(HERE, "Unexpected end of file"); + if (*p == '<') + return read_error(HERE, "Unexpected \'<\' inside entity \"%s\"", &entity_name[nentity][1]); + + /* extract replacement or SYSTEM*/ + while (*p && isspace(*p)) { + if (*p == '\n') + line_number++; + p++; + } + if (!*p) + return read_error(HERE, "Unexpected end of file"); + if (*p == '>') + return read_error(HERE, "Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]); + + /* check if SYSTEM */ + if(strncmp(p, "SYSTEM", 6) == 0){ + entity_type[nentity] = EXTERNAL_ENTITY; + p += 6; + } + else{ + entity_type[nentity] = INTERNAL_ENTITY; + } + + /* extract replacement */ + while (*p && isspace(*p)) { + if (*p == '\n') + line_number++; + p++; + } + if (!*p) + return read_error(HERE, "Unexpected end of file"); + if (*p == '>') + return read_error(HERE, "Unexpected \'>\' inside entity \"%s\"", &entity_name[nentity][1]); + + if (*p != '\"' && *p != '\'') + return read_error(HERE, "Replacement was not found for entity \"%s\"", &entity_name[nentity][1]); + delimiter = *p; + p++; + if (!*p) + return read_error(HERE, "Unexpected end of file"); + pv = p; + while (*pv && *pv != delimiter ) + pv++; + + if (!*pv) + return read_error(HERE, "Unexpected end of file"); + if (*pv == '<' ) + return read_error(HERE, "Unexpected \'%c\' inside entity \"%s\"", *pv, &entity_name[nentity][1]); + + len = (size_t)pv - (size_t)p; + if (len > (int)sizeof(replacement)-1) + len = sizeof(replacement)-1; + memcpy(replacement, p, len); + replacement[len] = 0; + + if(entity_type[nentity] == EXTERNAL_ENTITY){ + strcpy(entity_reference_name[nentity],replacement); + } + else{ + entity_value[nentity] = (char *)malloc(strlen(replacement)); + strcpy(entity_value[nentity],replacement); + } + + p = pv; + while (*p && isspace(*p)) { + if (*p == '\n') + line_number++; + p++; + } + if (!*p) + return read_error(HERE, "Unexpected end of file"); + } + } + + /* go to next element */ + while (*p && *p != '<') { + if (*p == '\n') + line_number++; + p++; + } + } while (*p); + nentity++; + + /* read external file */ + for(i=0;i