70 #include <sys/types.h> 78 #include <libxml/xmlmemory.h> 79 #include <libxml/tree.h> 80 #include <libxml/debugXML.h> 81 #include <libxml/encoding.h> 82 #include <libxml/parser.h> 83 #include <libxml/xmlerror.h> 103 #define NUMBERED(name, strings) \ 104 static const wml_externalid_t name##_strings[] = { strings }; 105 #define ASSIGN(string, number) { string, number }, 108 #define NUMBER_OF_WML_EXTERNALID ((long) sizeof(public_ids_strings)/sizeof(public_ids_strings[0])) 125 #define NUMBER_OF_WBXML_VERSION sizeof(wbxml_version)/sizeof(wbxml_version[0]) 296 static int hash_cmp(
void *hash1,
void *hash2);
340 if ((err = xmlGetLastError()) == NULL)
346 error(0,
"XML error: code: %d, level: %d, line: %d, %s",
365 xmlDocPtr pDoc = NULL;
385 error(0,
"WML compiler: Compiling error: " 386 "\\0 character found in the middle of the WML source.");
409 error(0,
"WML compiler: Compiling error: " 410 "libxml2 returned a NULL pointer");
438 for (i = 0; i < len; i++) {
452 for (i = 0; i < len; i++) {
462 for (i = 0; i < len; i++) {
469 (XML_PARSE_NOERROR | XML_PARSE_NONET) :
470 (XML_PARSE_RECOVER | XML_PARSE_NOERROR | XML_PARSE_NONET);
507 switch (node->type) {
508 case XML_ELEMENT_NODE:
514 case XML_CDATA_SECTION_NODE:
517 case XML_COMMENT_NODE:
526 error(0,
"WML compiler: Unknown XML node in the WML source.");
538 if (node->children != NULL)
543 if (node->children != NULL)
553 "WML compiler: undefined return value in a parse function.");
558 if (node->next != NULL)
575 Octstr *externalID = NULL;
578 if (document == NULL) {
579 error(0,
"WML compiler: XML parsing failed, no parsed document.");
580 error(0,
"Most probably an error in the WML source.");
585 if (version == NULL) {
586 (*wbxml)->wbxml_version = 0x01;
587 info(0,
"WBXML: No wbxml version given, assuming 1.1");
592 debug(
"parse_document",0,
"WBXML: Encoding with wbxml version <%s>",
598 (*wbxml)->wbxml_version = 0x01;
599 warning(0,
"WBXML: Unknown wbxml version, assuming 1.1 (<%s> is unknown)",
605 if ((document->intSubset != NULL) && (document->intSubset->ExternalID != NULL))
606 externalID =
octstr_create((
char *)document->intSubset->ExternalID);
607 if (externalID == NULL) {
608 (*wbxml)->wml_public_id = 0x04;
609 warning(0,
"WBXML: WML without ExternalID, assuming 1.1");
613 (*wbxml)->wml_public_id = public_ids_strings[i].value;
614 debug(
"parse_document",0,
"WBXML: WML with ExternalID <%s>",
620 (*wbxml)->wml_public_id = 0x04;
621 warning(0,
"WBXML: WML with unknown ExternalID, assuming 1.1 " 628 (*wbxml)->string_table_length = 0x00;
634 (*wbxml)->character_set =
charset ?
637 node = xmlDocGetRootElement(document);
640 error(0,
"WML compiler: XML parsing failed, no document root element.");
641 error(0,
"Most probably an error in the WML source.");
663 unsigned char wbxml_hex = 0, status_bits;
664 xmlAttrPtr attribute;
675 if (wbxml_hex == 0x27 ||
679 error(0,
"WML compiler: Two or more do elements with same" 680 " name in a card or template element.");
684 if (wbxml_hex == 0x3E)
690 wbxml_hex = wbxml_hex | status_bits;
703 wbxml_hex = wbxml_hex | status_bits;
711 warning(0,
"WML compiler: Unknown tag in WML source: <%s>",
718 if(node->properties != NULL) {
719 attribute = node->properties;
720 while (attribute != NULL) {
722 attribute = attribute->next;
743 int coded_length = 0;
744 unsigned char wbxml_hex = 0x00;
747 Octstr *
name = NULL, *pattern = NULL, *p = NULL;
751 if (attr->children != NULL)
759 if (attr->children == NULL ||
762 if(attribute->
binary == 0x00) {
763 warning(0,
"WML compiler: can't compile attribute %s%s%s%s",
765 (attr->children != NULL ?
"=\"":
""),
767 (attr->children != NULL ?
"\"":
""));
772 wbxml_hex = attribute->
binary;
787 warning(0,
"WML compiler: Unknown attribute in WML source: <%s>",
797 if (pattern != NULL &&
799 if (coded_length == 0)
807 wbxml, attr->doc->charset, default_esc);
810 wbxml, attr->doc->charset, default_esc);
813 "WML compiler: could not output attribute " 814 "value as a string.");
837 int i, pos, wbxml_hex;
848 tmp = (
char*) xmlGetCharEncodingName(
charset);
849 if (
charset != XML_CHAR_ENCODING_UTF8 &&
852 error(0,
"Failed to convert XML attribute value from charset " 853 "<%s> to <%s>, will leave as is.",
"UTF-8",
854 tmp ? tmp :
"(undef)");
954 tmp = (
char*) xmlGetCharEncodingName(node->doc->charset);
955 if (node->doc->charset != XML_CHAR_ENCODING_UTF8 &&
958 error(0,
"Failed to convert XML text entity from charset " 959 "<%s> to <%s>, will leave as is.",
"UTF-8",
960 tmp ? tmp :
"(undef)");
1024 if (variable == NULL)
1067 }
else if (ch ==
'(') {
1071 error(0,
"WML compiler: braces opened, but not closed for a " 1073 else if (end -
start == 0)
1074 error(0,
"WML compiler: empty braces without variable.");
1119 error(0,
"WML compiler: syntax error in variable escaping.");
1128 if (!(isalpha((
int)ch)) && ch !=
'_') {
1129 error(0,
"WML compiler: syntax error in variable; name starting " 1133 for (i = 1; i < (int)
octstr_len(variable); i++)
1136 warning(0,
"WML compiler: syntax error in variable.");
1154 Octstr *output, *var, *temp = NULL;
1156 int start = 0, pos = 0, len;
1178 if ((var_len =
parse_variable(ostr, pos, default_esc, &var, wbxml)) > 0) {
1200 pos = pos + var_len;
1239 static char entity_nbsp[] =
" ";
1240 static char entity_shy[] =
"­";
1241 static char nbsp[] =
" ";
1242 static char shy[] =
"­";
1302 if (wbxml != NULL) {
1433 else if (strcmp(attributes[i].text1, attributes[i-1].text1) != 0) {
1439 if (attributes[i].text2 == NULL)
1446 }
while (attributes[i].text1 != NULL);
1501 gw_assert(item != NULL && pattern != NULL);
1522 List *name_list = NULL;
1526 if ((child = node->children) != NULL) {
1527 while (child != NULL) {
1528 if (child->name && strcmp((
char *)child->name,
"do") == 0) {
1532 error(0,
"WML compiler: no name or type in a do element");
1547 child = child->next;
1569 if ((attr = node->properties) != NULL) {
1570 while (attr != NULL) {
1571 if (attr->name && strcmp((
char *)attr->name,
"name") == 0) {
1580 error(0,
"WML compiler: no name in a setvar element");
1603 if ((attr = node->properties) != NULL) {
1604 while (attr != NULL) {
1605 if (attr->name && strcmp((
char *)attr->name,
"name") == 0) {
1613 attr = node->properties;
1614 while (attr != NULL) {
1615 if (attr->name && strcmp((
char *)attr->name,
"type") == 0) {
1636 switch ((
unsigned char) hex) {
1637 case 0x4A:
case 0x4B:
case 0x4C:
1638 case 0x32:
case 0x58:
case 0x59:
1654 if (node == NULL || node->name == NULL)
1657 if (strcmp((
char *)node->name,
"b") == 0)
1659 if (strcmp((
char *)node->name,
"big") == 0)
1661 if (strcmp((
char *)node->name,
"em") == 0)
1663 if (strcmp((
char *)node->name,
"i") == 0)
1665 if (strcmp((
char *)node->name,
"small") == 0)
1667 if (strcmp((
char *)node->name,
"strong") == 0)
1669 if (strcmp((
char *)node->name,
"u") == 0)
1700 while (
table[i].text1 != NULL)
1818 xmlAttrPtr attribute;
1820 switch (node->type) {
1834 case XML_ELEMENT_NODE:
1835 if(node->properties != NULL) {
1836 attribute = node->properties;
1837 while (attribute != NULL) {
1838 if (attribute->children != NULL)
1840 attribute = attribute->next;
1848 if (node->children != NULL)
1851 if (node->next != NULL)
1868 List *sorted = NULL;
1886 if (
string != NULL) {
1939 List *list = NULL, *temp_list = NULL;
1975 unsigned long i, offset = 0;
1978 for (i = 0; i < (
unsigned long)
gwlist_len((*wbxml)->string_table); i++) {
1979 item =
gwlist_get((*wbxml)->string_table, i);
1987 offset = (*wbxml)->string_table_length;
1991 (*wbxml)->string_table_length =
1992 (*wbxml)->string_table_length +
octstr_len(ostr) + 1;
2010 long i = 0, word_s = 0, str_e = 0;
2014 for (i = 0; i <
gwlist_len((*wbxml)->string_table); i++) {
2015 item =
gwlist_get((*wbxml)->string_table, i);
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
void error(int err, const char *fmt,...)
void info(int err, const char *fmt,...)
static wml_attribute_t * attribute_create(void)
static void parse_st_end(wml_binary_t **wbxml)
static int parse_cdata(xmlNodePtr node, wml_binary_t **wbxml)
void octstr_replace(Octstr *haystack, Octstr *needle, Octstr *repl)
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
static wml_table_t wml_URL_values[]
unsigned char element_check_content(xmlNodePtr node)
unsigned char wbxml_version
void octstr_convert_range(Octstr *ostr, long pos, long len, octstr_func_t map)
static int check_if_url(int hex)
static int parse_document(xmlDocPtr document, Octstr *charset, wml_binary_t **wbxml, Octstr *version)
gw_assert(wtls_machine->packet_to_send !=NULL)
void dict_put(Dict *dict, Octstr *key, void *value)
void gwlist_append(List *list, void *item)
static string_table_t * string_table_create(int offset, Octstr *ostr)
static void xml_error(void)
long gwlist_len(List *list)
void * gwlist_get(List *list, long pos)
unsigned long wml_public_id
static wbxml_version_t wbxml_version[]
void octstr_append_char(Octstr *ostr, int ch)
static wml_binary_t * wml_binary_create(void)
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
static void attr_dict_construct(wml_table3_t *attributes, Dict *attr_dict)
static void string_table_apply(Octstr *ostr, wml_binary_t **wbxml)
static int parse_attr_value(Octstr *attr_value, List *tokens, wml_binary_t **wbxml, int charset, var_esc_t default_esc)
void octstr_strip_blanks(Octstr *text)
#define octstr_get_cstr(ostr)
static void output_st_octet_string(Octstr *ostr, wml_binary_t **wbxml)
#define octstr_copy(ostr, from, len)
#define WBXML_STRING_TABLE_MIN
long octstr_search_char(const Octstr *ostr, int ch, long pos)
static void hash_destroy(void *p)
static void attribute_destroy(void *p)
static int parse_node(xmlNodePtr node, wml_binary_t **wbxml)
static string_table_proposal_t * string_table_proposal_create(Octstr *ostr)
static wml_hash_t * hash_create(char *text, unsigned char token)
static void output_st_char(int byte, wml_binary_t **wbxml)
static int parse_variable(Octstr *text, int start, var_esc_t default_esc, Octstr **output, wml_binary_t **wbxml)
static void wml_binary_output(Octstr *ostr, wml_binary_t *wbxml)
void octstr_strip_nonalphanums(Octstr *text)
Octstr * octstr_imm(const char *cstr)
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
int parse_charset(Octstr *os)
void * gwlist_extract_first(List *list)
static var_esc_t check_variable_name(xmlNodePtr node)
void * dict_get(Dict *dict, Octstr *key)
static void string_table_proposal_destroy(string_table_proposal_t *node)
void octstr_delete(Octstr *ostr1, long pos, long len)
static void string_table_collect_strings(xmlNodePtr node, List *strings)
List * wml_attr_values_list
static int hash_cmp(void *hash1, void *hash2)
unsigned long string_table_length
static List * string_table_collect_words(List *strings)
#define octstr_duplicate(ostr)
static void string_table_destroy(string_table_t *node)
static int wml_table3_len(wml_table3_t *table)
#define NUMBER_OF_WBXML_VERSION
int wml_compile(Octstr *wml_text, Octstr *charset, Octstr **wml_binary, Octstr *version)
void warning(int err, const char *fmt,...)
List * octstr_split_words(const Octstr *ostr)
static int check_do_elements(xmlNodePtr node)
static List * string_table_sort_list(List *start)
Octstr * octstr_format(const char *fmt,...)
void octstr_destroy(Octstr *ostr)
#define octstr_create(cstr)
static wml_table_t wml_elements[]
void octstr_destroy_item(void *os)
Dict * wml_attributes_dict
static int wml_table_len(wml_table_t *table)
static void output_variable(Octstr *variable, Octstr **output, var_esc_t escaped, wml_binary_t **wbxml)
static Octstr * get_variable(Octstr *text, int start)
static wml_table_t wml_attribute_values[]
unsigned long character_set
long octstr_len(const Octstr *ostr)
void dict_destroy(Dict *dict)
void octstr_append_uintvar(Octstr *ostr, unsigned long value)
static int parse_st_octet_string(Octstr *ostr, int cdata, var_esc_t default_esc, wml_binary_t **wbxml)
static var_esc_t check_variable_syntax(Octstr *variable, var_esc_t default_esc)
#define NUMBER_OF_WML_EXTERNALID
void debug(const char *place, int err, const char *fmt,...)
int octstr_str_compare(const Octstr *ostr, const char *str)
static int parse_text(xmlNodePtr node, wml_binary_t **wbxml)
static int wml_xml_strict
static int parse_element(xmlNodePtr node, wml_binary_t **wbxml)
void octstr_truncate(Octstr *ostr, int new_len)
static void parse_entities(Octstr *wml_source)
static int parse_attribute(xmlAttrPtr attr, wml_binary_t **wbxml)
#define WBXML_CONTENT_BIT
static Octstr * get_do_element_name(xmlNodePtr node)
static List * string_table_add_many(List *sorted, wml_binary_t **wbxml)
List * wml_URL_values_list
#define create_octstr_from_node(node)
static int check_if_emphasis(xmlNodePtr node)
int octstr_get_char(const Octstr *ostr, long pos)
void octstr_shrink_blanks(Octstr *text)
static void wml_binary_destroy(wml_binary_t *wbxml)
static XMLRPCDocument * msg
void wml_init(int wml_xml_strict)
static void string_table_output(Octstr *ostr, wml_binary_t **wbxml)
static void string_table_build(xmlNodePtr node, wml_binary_t **wbxml)
static wml_table3_t wml_attributes[]
static unsigned long string_table_add(Octstr *ostr, wml_binary_t **wbxml)
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)