Kannel: Open Source WAP and SMS gateway  svn-r5335
wml_compiler.c File Reference
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <inttypes.h>
#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/debugXML.h>
#include <libxml/encoding.h>
#include <libxml/parser.h>
#include <libxml/xmlerror.h>
#include "gwlib/gwlib.h"
#include "wml_compiler.h"
#include "xml_definitions.h"
#include "wbxml_tokens.def"
#include "xml_shared.h"
#include "wml_definitions.h"

Go to the source code of this file.

Data Structures

struct  wml_externalid_t
 
struct  wbxml_version_t
 
struct  wml_table_t
 
struct  wml_table3_t
 
struct  wml_binary_t
 
struct  string_table_t
 
struct  string_table_proposal_t
 
struct  wml_hash_t
 
struct  wml_attribute_t
 

Macros

#define NUMBERED(name, strings)   static const wml_externalid_t name##_strings[] = { strings };
 
#define ASSIGN(string, number)   { string, number },
 
#define NUMBER_OF_WML_EXTERNALID   ((long) sizeof(public_ids_strings)/sizeof(public_ids_strings[0]))
 
#define NUMBER_OF_WBXML_VERSION   sizeof(wbxml_version)/sizeof(wbxml_version[0])
 

Typedefs

typedef struct wml_externalid_t wml_externalid_t
 
typedef struct wbxml_version_t wbxml_version_t
 

Enumerations

enum  var_esc_t { NOESC, ESC, UNESC, FAILED }
 

Functions

static int parse_document (xmlDocPtr document, Octstr *charset, wml_binary_t **wbxml, Octstr *version)
 
static int parse_node (xmlNodePtr node, wml_binary_t **wbxml)
 
static int parse_element (xmlNodePtr node, wml_binary_t **wbxml)
 
static int parse_attribute (xmlAttrPtr attr, 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)
 
static int parse_text (xmlNodePtr node, wml_binary_t **wbxml)
 
static int parse_cdata (xmlNodePtr node, wml_binary_t **wbxml)
 
static int parse_st_octet_string (Octstr *ostr, int cdata, var_esc_t default_esc, wml_binary_t **wbxml)
 
static void parse_st_end (wml_binary_t **wbxml)
 
static void parse_entities (Octstr *wml_source)
 
static int parse_variable (Octstr *text, int start, var_esc_t default_esc, Octstr **output, wml_binary_t **wbxml)
 
static Octstrget_variable (Octstr *text, int start)
 
static var_esc_t check_variable_syntax (Octstr *variable, var_esc_t default_esc)
 
static wml_binary_twml_binary_create (void)
 
static void wml_binary_destroy (wml_binary_t *wbxml)
 
static void wml_binary_output (Octstr *ostr, wml_binary_t *wbxml)
 
static void output_st_char (int byte, wml_binary_t **wbxml)
 
static void output_st_octet_string (Octstr *ostr, wml_binary_t **wbxml)
 
static void output_variable (Octstr *variable, Octstr **output, var_esc_t escaped, wml_binary_t **wbxml)
 
static wml_hash_thash_create (char *text, unsigned char token)
 
static wml_attribute_tattribute_create (void)
 
static void attr_dict_construct (wml_table3_t *attributes, Dict *attr_dict)
 
static void hash_destroy (void *p)
 
static void attribute_destroy (void *p)
 
static int hash_cmp (void *hash1, void *hash2)
 
static int check_do_elements (xmlNodePtr node)
 
static var_esc_t check_variable_name (xmlNodePtr node)
 
static Octstrget_do_element_name (xmlNodePtr node)
 
static int check_if_url (int hex)
 
static int check_if_emphasis (xmlNodePtr node)
 
static int wml_table_len (wml_table_t *table)
 
static int wml_table3_len (wml_table3_t *table)
 
static string_table_tstring_table_create (int offset, Octstr *ostr)
 
static void string_table_destroy (string_table_t *node)
 
static string_table_proposal_tstring_table_proposal_create (Octstr *ostr)
 
static void string_table_proposal_destroy (string_table_proposal_t *node)
 
static void string_table_build (xmlNodePtr node, wml_binary_t **wbxml)
 
static void string_table_collect_strings (xmlNodePtr node, List *strings)
 
static Liststring_table_collect_words (List *strings)
 
static Liststring_table_sort_list (List *start)
 
static Liststring_table_add_many (List *sorted, wml_binary_t **wbxml)
 
static unsigned long string_table_add (Octstr *ostr, wml_binary_t **wbxml)
 
static void string_table_apply (Octstr *ostr, wml_binary_t **wbxml)
 
static void string_table_output (Octstr *ostr, wml_binary_t **wbxml)
 
static void xml_error (void)
 
int wml_compile (Octstr *wml_text, Octstr *charset, Octstr **wml_binary, Octstr *version)
 
void wml_init (int wml_xml_strict)
 
void wml_shutdown ()
 

Variables

static wbxml_version_t wbxml_version []
 
Dictwml_elements_dict
 
Dictwml_attributes_dict
 
Listwml_attr_values_list
 
Listwml_URL_values_list
 
int wml_xml_parser_opt
 

Macro Definition Documentation

◆ ASSIGN

#define ASSIGN (   string,
  number 
)    { string, number },

Definition at line 105 of file wml_compiler.c.

◆ NUMBER_OF_WBXML_VERSION

#define NUMBER_OF_WBXML_VERSION   sizeof(wbxml_version)/sizeof(wbxml_version[0])

Definition at line 125 of file wml_compiler.c.

Referenced by parse_document().

◆ NUMBER_OF_WML_EXTERNALID

#define NUMBER_OF_WML_EXTERNALID   ((long) sizeof(public_ids_strings)/sizeof(public_ids_strings[0]))

Definition at line 108 of file wml_compiler.c.

Referenced by parse_document().

◆ NUMBERED

#define NUMBERED (   name,
  strings 
)    static const wml_externalid_t name##_strings[] = { strings };

Definition at line 103 of file wml_compiler.c.

Typedef Documentation

◆ wbxml_version_t

Definition at line 115 of file wml_compiler.c.

◆ wml_externalid_t

Definition at line 101 of file wml_compiler.c.

Enumeration Type Documentation

◆ var_esc_t

enum var_esc_t
Enumerator
NOESC 
ESC 
UNESC 
FAILED 

Definition at line 128 of file wml_compiler.c.

Function Documentation

◆ attr_dict_construct()

static void attr_dict_construct ( wml_table3_t attributes,
Dict attr_dict 
)
static

Definition at line 1422 of file wml_compiler.c.

References wml_attribute_t::attribute, attribute_create(), wml_attribute_t::binary, dict_put(), gwlist_append(), hash_create(), octstr_create, wml_table3_t::token, token, and wml_attribute_t::value_list.

Referenced by wml_init().

1423 {
1424  int i = 0;
1425  wml_attribute_t *node = NULL;
1426  wml_hash_t *temp = NULL;
1427 
1428  node = attribute_create();
1429 
1430  do {
1431  if (node->attribute == NULL)
1432  node->attribute = octstr_create(attributes[i].text1);
1433  else if (strcmp(attributes[i].text1, attributes[i-1].text1) != 0) {
1434  dict_put(attr_dict, node->attribute, node);
1435  node = attribute_create();
1436  node->attribute = octstr_create(attributes[i].text1);
1437  }
1438 
1439  if (attributes[i].text2 == NULL)
1440  node->binary = attributes[i].token;
1441  else {
1442  temp = hash_create(attributes[i].text2, attributes[i].token);
1443  gwlist_append(node->value_list, (void *)temp);
1444  }
1445  i++;
1446  } while (attributes[i].text1 != NULL);
1447 
1448  dict_put(attr_dict, node->attribute, node);
1449 }
static wml_attribute_t * attribute_create(void)
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
void gwlist_append(List *list, void *item)
Definition: list.c:179
unsigned char binary
Definition: wml_compiler.c:206
static wml_hash_t * hash_create(char *text, unsigned char token)
int token
Definition: wslexer.c:159
#define octstr_create(cstr)
Definition: octstr.h:125
Octstr * attribute
Definition: wml_compiler.c:205
unsigned char token
Definition: wml_compiler.c:148

◆ attribute_create()

static wml_attribute_t * attribute_create ( void  )
static

Definition at line 1403 of file wml_compiler.c.

References wml_attribute_t::attribute, wml_attribute_t::binary, gwlist_create, and wml_attribute_t::value_list.

Referenced by attr_dict_construct().

1404 {
1405  wml_attribute_t *attr;
1406 
1407  attr = gw_malloc(sizeof(wml_attribute_t));
1408  attr->attribute = NULL;
1409  attr->binary = 0;
1410  attr->value_list = gwlist_create();
1411 
1412  return attr;
1413 }
unsigned char binary
Definition: wml_compiler.c:206
Octstr * attribute
Definition: wml_compiler.c:205
#define gwlist_create()
Definition: list.h:136

◆ attribute_destroy()

static void attribute_destroy ( void *  p)
static

Definition at line 1476 of file wml_compiler.c.

References wml_attribute_t::attribute, gwlist_destroy(), hash_destroy(), octstr_destroy(), and wml_attribute_t::value_list.

Referenced by wml_init().

1477 {
1478  wml_attribute_t *node;
1479 
1480  if (p == NULL)
1481  return;
1482 
1483  node = p;
1484 
1485  octstr_destroy(node->attribute);
1487  gw_free(node);
1488 }
static void hash_destroy(void *p)
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Octstr * attribute
Definition: wml_compiler.c:205
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ check_do_elements()

static int check_do_elements ( xmlNodePtr  node)
static

Definition at line 1517 of file wml_compiler.c.

References error(), get_do_element_name(), gwlist_append(), gwlist_create, gwlist_destroy(), gwlist_get(), gwlist_len(), name, octstr_compare(), octstr_destroy(), and octstr_destroy_item().

Referenced by parse_element().

1518 {
1519  xmlNodePtr child;
1520  int i, status = 0;
1521  Octstr *name = NULL;
1522  List *name_list = NULL;
1523 
1524  name_list = gwlist_create();
1525 
1526  if ((child = node->children) != NULL) {
1527  while (child != NULL) {
1528  if (child->name && strcmp((char *)child->name, "do") == 0) {
1529  name = get_do_element_name(child);
1530 
1531  if (name == NULL) {
1532  error(0, "WML compiler: no name or type in a do element");
1533  return -1;
1534  }
1535 
1536  for (i = 0; i < gwlist_len(name_list); i ++)
1537  if (octstr_compare(gwlist_get(name_list, i), name) == 0) {
1539  status = -1;
1540  break;
1541  }
1542  if (status != -1)
1543  gwlist_append(name_list, name);
1544  else
1545  break;
1546  }
1547  child = child->next;
1548  }
1549  }
1550 
1551  gwlist_destroy(name_list, octstr_destroy_item);
1552 
1553  return status;
1554 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
char * name
Definition: smsc_cimd2.c:212
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void octstr_destroy_item(void *os)
Definition: octstr.c:336
Definition: octstr.c:118
#define gwlist_create()
Definition: list.h:136
static Octstr * get_do_element_name(xmlNodePtr node)
Definition: list.c:102
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ check_if_emphasis()

static int check_if_emphasis ( xmlNodePtr  node)
static

Definition at line 1652 of file wml_compiler.c.

Referenced by parse_text().

1653 {
1654  if (node == NULL || node->name == NULL)
1655  return 0;
1656 
1657  if (strcmp((char *)node->name, "b") == 0)
1658  return 1;
1659  if (strcmp((char *)node->name, "big") == 0)
1660  return 1;
1661  if (strcmp((char *)node->name, "em") == 0)
1662  return 1;
1663  if (strcmp((char *)node->name, "i") == 0)
1664  return 1;
1665  if (strcmp((char *)node->name, "small") == 0)
1666  return 1;
1667  if (strcmp((char *)node->name, "strong") == 0)
1668  return 1;
1669  if (strcmp((char *)node->name, "u") == 0)
1670  return 1;
1671 
1672  return 0;
1673 }

◆ check_if_url()

static int check_if_url ( int  hex)
static

Definition at line 1634 of file wml_compiler.c.

Referenced by parse_attribute().

1635 {
1636  switch ((unsigned char) hex) {
1637  case 0x4A: case 0x4B: case 0x4C: /* href, href http://, href https:// */
1638  case 0x32: case 0x58: case 0x59: /* src, src http://, src https:// */
1639  return 1;
1640  break;
1641  }
1642  return 0;
1643 }

◆ check_variable_name()

static var_esc_t check_variable_name ( xmlNodePtr  node)
static

Definition at line 1563 of file wml_compiler.c.

References check_variable_syntax(), create_octstr_from_node, error(), FAILED, name, NOESC, and octstr_destroy().

Referenced by parse_element().

1564 {
1565  Octstr *name = NULL;
1566  xmlAttrPtr attr;
1567  var_esc_t ret = FAILED;
1568 
1569  if ((attr = node->properties) != NULL) {
1570  while (attr != NULL) {
1571  if (attr->name && strcmp((char *)attr->name, "name") == 0) {
1572  name = create_octstr_from_node((char *)attr->children);
1573  break;
1574  }
1575  attr = attr->next;
1576  }
1577  }
1578 
1579  if (attr == NULL) {
1580  error(0, "WML compiler: no name in a setvar element");
1581  return FAILED;
1582  }
1583 
1586 
1587  return ret;
1588 }
void error(int err, const char *fmt,...)
Definition: log.c:648
var_esc_t
Definition: wml_compiler.c:128
char * name
Definition: smsc_cimd2.c:212
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
static var_esc_t check_variable_syntax(Octstr *variable, var_esc_t default_esc)
#define create_octstr_from_node(node)

◆ check_variable_syntax()

static var_esc_t check_variable_syntax ( Octstr variable,
var_esc_t  default_esc 
)
static

Definition at line 1095 of file wml_compiler.c.

References error(), ESC, FAILED, NOESC, octstr_convert_range(), octstr_copy, octstr_destroy(), octstr_get_char(), octstr_len(), octstr_search_char(), octstr_str_compare(), octstr_truncate(), UNESC, and warning().

Referenced by check_variable_name(), and parse_variable().

1096 {
1097  Octstr *escape;
1098  char ch;
1099  int pos, len, i;
1100  var_esc_t ret;
1101 
1102  if ((pos = octstr_search_char(variable, ':', 0)) > 0) {
1103  len = octstr_len(variable) - pos;
1104  escape = octstr_copy(variable, pos + 1, len - 1);
1105  octstr_truncate(variable, pos);
1106  octstr_truncate(escape, len);
1107  octstr_convert_range(escape, 0, octstr_len(escape), tolower);
1108 
1109  if (octstr_str_compare(escape, "noesc") == 0 ||
1110  octstr_str_compare(escape, "n") == 0 )
1111  ret = NOESC;
1112  else if (octstr_str_compare(escape, "unesc") == 0 ||
1113  octstr_str_compare(escape, "u") == 0 )
1114  ret = UNESC;
1115  else if (octstr_str_compare(escape, "escape") == 0 ||
1116  octstr_str_compare(escape, "e") == 0 )
1117  ret = ESC;
1118  else {
1119  error(0, "WML compiler: syntax error in variable escaping.");
1120  octstr_destroy(escape);
1121  return FAILED;
1122  }
1123  octstr_destroy(escape);
1124  } else
1125  ret = default_esc;
1126 
1127  ch = octstr_get_char(variable, 0);
1128  if (!(isalpha((int)ch)) && ch != '_') {
1129  error(0, "WML compiler: syntax error in variable; name starting "
1130  "with %c.", ch);
1131  return FAILED;
1132  } else
1133  for (i = 1; i < (int) octstr_len(variable); i++)
1134  if (!isalnum((int)(ch = octstr_get_char(variable, 0))) &&
1135  ch != '_') {
1136  warning(0, "WML compiler: syntax error in variable.");
1137  return FAILED;
1138  }
1139 
1140  return ret;
1141 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void octstr_convert_range(Octstr *ostr, long pos, long len, octstr_func_t map)
Definition: octstr.c:836
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
var_esc_t
Definition: wml_compiler.c:128
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:973
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1327
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406

◆ get_do_element_name()

static Octstr * get_do_element_name ( xmlNodePtr  node)
static

Definition at line 1598 of file wml_compiler.c.

References create_octstr_from_node, and name.

Referenced by check_do_elements().

1599 {
1600  Octstr *name = NULL;
1601  xmlAttrPtr attr;
1602 
1603  if ((attr = node->properties) != NULL) {
1604  while (attr != NULL) {
1605  if (attr->name && strcmp((char *)attr->name, "name") == 0) {
1606  name = create_octstr_from_node((char *)attr->children);
1607  break;
1608  }
1609  attr = attr->next;
1610  }
1611 
1612  if (attr == NULL) {
1613  attr = node->properties;
1614  while (attr != NULL) {
1615  if (attr->name && strcmp((char *)attr->name, "type") == 0) {
1616  name = create_octstr_from_node((char *)attr->children);
1617  break;
1618  }
1619  attr = attr->next;
1620  }
1621  }
1622  }
1623 
1624  return name;
1625 }
char * name
Definition: smsc_cimd2.c:212
Definition: octstr.c:118
#define create_octstr_from_node(node)

◆ get_variable()

static Octstr * get_variable ( Octstr text,
int  start 
)
static

Definition at line 1054 of file wml_compiler.c.

References error(), gw_assert(), octstr_copy, octstr_create, octstr_get_char(), octstr_len(), octstr_search_char(), start, and text.

Referenced by parse_variable().

1055 {
1056  Octstr *var = NULL;
1057  long end;
1058  int ch;
1059 
1060  gw_assert(text != NULL);
1061  gw_assert(start >= 0 && start <= (int) octstr_len(text));
1062 
1063  ch = octstr_get_char(text, start);
1064 
1065  if (ch == '$') {
1066  var = octstr_create("$");
1067  } else if (ch == '(') {
1068  start ++;
1069  end = octstr_search_char(text, ')', start);
1070  if (end == -1)
1071  error(0, "WML compiler: braces opened, but not closed for a "
1072  "variable.");
1073  else if (end - start == 0)
1074  error(0, "WML compiler: empty braces without variable.");
1075  else
1076  var = octstr_copy(text, start, end - start);
1077  } else {
1078  end = start + 1;
1079  while (isalnum(ch = octstr_get_char(text, end)) || (ch == '_'))
1080  end ++;
1081 
1082  var = octstr_copy(text, start, end - start);
1083  }
1084 
1085  return var;
1086 }
void error(int err, const char *fmt,...)
Definition: log.c:648
gw_assert(wtls_machine->packet_to_send !=NULL)
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
char * text
Definition: smsc_cimd2.c:921
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static int start

◆ hash_cmp()

static int hash_cmp ( void *  hash1,
void *  hash2 
)
static

Definition at line 1497 of file wml_compiler.c.

References gw_assert(), and octstr_search().

Referenced by parse_attribute().

1498 {
1499  int ret = 0;
1500 
1501  gw_assert(item != NULL && pattern != NULL);
1502  gw_assert(((wml_hash_t *)item)->item != NULL);
1503 
1504  if (octstr_search(pattern, ((wml_hash_t *)item)->item, 0) == 0)
1505  ret = 1;
1506 
1507  return ret;
1508 }
gw_assert(wtls_machine->packet_to_send !=NULL)
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070

◆ hash_create()

static wml_hash_t * hash_create ( char *  text,
unsigned char  token 
)
static

Definition at line 1384 of file wml_compiler.c.

References wml_hash_t::binary, wml_hash_t::item, octstr_create, text, and token.

Referenced by attr_dict_construct(), and wml_init().

1385 {
1386  wml_hash_t *table_node;
1387 
1388  table_node = gw_malloc(sizeof(wml_hash_t));
1389  table_node->item = octstr_create(text);
1390  table_node->binary = token;
1391 
1392  return table_node;
1393 }
unsigned char binary
Definition: wml_compiler.c:196
Octstr * item
Definition: wml_compiler.c:195
int token
Definition: wslexer.c:159
char * text
Definition: smsc_cimd2.c:921
#define octstr_create(cstr)
Definition: octstr.h:125

◆ hash_destroy()

static void hash_destroy ( void *  p)
static

Definition at line 1457 of file wml_compiler.c.

References wml_hash_t::item, and octstr_destroy().

Referenced by attribute_destroy(), wml_init(), and wml_shutdown().

1458 {
1459  wml_hash_t *node;
1460 
1461  if (p == NULL)
1462  return;
1463 
1464  node = p;
1465 
1466  octstr_destroy(node->item);
1467  gw_free(node);
1468 }
Octstr * item
Definition: wml_compiler.c:195
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324

◆ output_st_char()

static void output_st_char ( int  byte,
wml_binary_t **  wbxml 
)
static

Definition at line 1335 of file wml_compiler.c.

References octstr_append_char().

Referenced by parse_attr_value(), parse_attribute(), parse_element(), parse_st_end(), and string_table_apply().

1336 {
1337  octstr_append_char((*wbxml)->wbxml_string, byte);
1338 }
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517

◆ output_st_octet_string()

static void output_st_octet_string ( Octstr ostr,
wml_binary_t **  wbxml 
)
static

Definition at line 1347 of file wml_compiler.c.

References octstr_insert(), and octstr_len().

Referenced by parse_st_octet_string(), and string_table_apply().

1348 {
1349  octstr_insert((*wbxml)->wbxml_string, ostr,
1350  octstr_len((*wbxml)->wbxml_string));
1351 }
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ output_variable()

static void output_variable ( Octstr variable,
Octstr **  output,
var_esc_t  escaped,
wml_binary_t **  wbxml 
)
static

Definition at line 1359 of file wml_compiler.c.

References ESC, octstr_append_char(), octstr_append_uintvar(), string_table_add(), UNESC, WBXML_EXT_T_0, WBXML_EXT_T_1, and WBXML_EXT_T_2.

Referenced by parse_variable().

1361 {
1362  switch (escaped)
1363  {
1364  case ESC:
1366  break;
1367  case UNESC:
1369  break;
1370  default:
1372  break;
1373  }
1374 
1375  octstr_append_uintvar(*output, string_table_add(variable, wbxml));
1376 }
#define WBXML_EXT_T_2
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
#define WBXML_EXT_T_0
void octstr_append_uintvar(Octstr *ostr, unsigned long value)
Definition: octstr.c:1931
#define WBXML_EXT_T_1
static unsigned long string_table_add(Octstr *ostr, wml_binary_t **wbxml)

◆ parse_attr_value()

static int parse_attr_value ( Octstr attr_value,
List tokens,
wml_binary_t **  wbxml,
int  charset,
var_esc_t  default_esc 
)
static

Definition at line 834 of file wml_compiler.c.

References wml_hash_t::binary, charset, charset_convert(), error(), gw_assert(), gwlist_get(), gwlist_len(), wml_hash_t::item, octstr_copy, octstr_delete(), octstr_destroy(), octstr_len(), octstr_search(), octstr_search_char(), output_st_char(), and parse_st_octet_string().

Referenced by parse_attribute().

836 {
837  int i, pos, wbxml_hex;
838  wml_hash_t *temp = NULL;
839  Octstr *cut_text = NULL;
840  char *tmp;
841 
842  /*
843  * Beware that libxml2 does internal encoding in UTF-8 while parsing.
844  * So if our original WML source had a different encoding set, we have
845  * to transcode at least here. Only transcode if target encoding differs
846  * from libxml2's internal encoding (UTF-8).
847  */
848  tmp = (char*) xmlGetCharEncodingName(charset);
849  if (charset != XML_CHAR_ENCODING_UTF8 &&
850  charset_convert(attr_value, "UTF-8",
851  tmp) != 0) {
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)");
855  }
856 
857 
858  /*
859  * The attribute value is search for text strings that can be replaced
860  * with one byte codes. Note that the algorith is not foolproof; seaching
861  * is done in an order and the text before first hit is not checked for
862  * those tokens that are after the hit in the order. Most likely it would
863  * be waste of time anyway. String table is not used here, since at least
864  * Nokia 7110 doesn't seem to understand string table references here.
865  */
866 
867  /* A fast patch to allow reserved names to be variable names. May produce
868  a little longer binary at some points. --tuo */
869  if (octstr_search_char(attr_value, '$', 0) >= 0) {
870  if (parse_st_octet_string(attr_value, 0, default_esc, wbxml) != 0)
871  return -1;
872  } else {
873 
874  for (i = 0; i < gwlist_len(tokens); i++) {
875  temp = gwlist_get(tokens, i);
876  pos = octstr_search(attr_value, temp->item, 0);
877  switch (pos) {
878  case -1:
879  break;
880  case 0:
881  wbxml_hex = temp->binary;
882  output_st_char(wbxml_hex, wbxml);
883  octstr_delete(attr_value, 0, octstr_len(temp->item));
884  break;
885  default:
886  /*
887  * There is some text before the first hit, that has to
888  * be handled too.
889  */
890  gw_assert(pos <= octstr_len(attr_value));
891 
892  cut_text = octstr_copy(attr_value, 0, pos);
893  if (parse_st_octet_string(cut_text, 0, default_esc, wbxml) != 0)
894  return -1;
895  octstr_destroy(cut_text);
896 
897  wbxml_hex = temp->binary;
898  output_st_char(wbxml_hex, wbxml);
899 
900  octstr_delete(attr_value, 0, pos + octstr_len(temp->item));
901  break;
902  }
903  }
904 
905  /*
906  * If no hits, then the attr_value is handled as a normal text,
907  * otherwise the remaining part is searched for other hits too.
908  */
909 
910  if ((int) octstr_len(attr_value) > 0) {
911  if (i < gwlist_len(tokens))
912  parse_attr_value(attr_value, tokens, wbxml, charset, default_esc);
913  else
914  if (parse_st_octet_string(attr_value, 0, default_esc, wbxml) != 0)
915  return -1;
916  }
917  }
918 
919  return 0;
920 }
void error(int err, const char *fmt,...)
Definition: log.c:648
gw_assert(wtls_machine->packet_to_send !=NULL)
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
unsigned char binary
Definition: wml_compiler.c:196
static int parse_attr_value(Octstr *attr_value, List *tokens, wml_binary_t **wbxml, int charset, var_esc_t default_esc)
Definition: wml_compiler.c:834
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
Octstr * charset
Definition: test_ota.c:68
Octstr * item
Definition: wml_compiler.c:195
static void output_st_char(int byte, wml_binary_t **wbxml)
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
static int parse_st_octet_string(Octstr *ostr, int cdata, var_esc_t default_esc, wml_binary_t **wbxml)
Definition: octstr.c:118
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589

◆ parse_attribute()

static int parse_attribute ( xmlAttrPtr  attr,
wml_binary_t **  wbxml 
)
static

Definition at line 740 of file wml_compiler.c.

References wml_attribute_t::attribute, wml_hash_t::binary, wml_attribute_t::binary, check_if_url(), create_octstr_from_node, dict_get(), error(), ESC, gwlist_search(), hash_cmp(), wml_hash_t::item, name, NOESC, octstr_append_uintvar(), octstr_copy, octstr_create, octstr_destroy(), octstr_duplicate, octstr_get_cstr, octstr_len(), octstr_str_compare(), output_st_char(), parse_attr_value(), string_table_add(), wml_attribute_t::value_list, warning(), WBXML_LITERAL, wml_attr_values_list, wml_attributes_dict, and wml_URL_values_list.

Referenced by parse_element().

741 {
742  int status = 0;
743  int coded_length = 0;
744  unsigned char wbxml_hex = 0x00;
745  wml_hash_t *hit = NULL;
746  wml_attribute_t *attribute = NULL;
747  Octstr *name = NULL, *pattern = NULL, *p = NULL;
748 
749  name = octstr_create((char *)attr->name);
750 
751  if (attr->children != NULL)
752  pattern = create_octstr_from_node((char *)attr->children);
753  else
754  pattern = NULL;
755 
756  /* Check if the attribute is found on the code page. */
757 
758  if ((attribute = dict_get(wml_attributes_dict, name)) != NULL) {
759  if (attr->children == NULL ||
760  (hit = gwlist_search(attribute->value_list, (void *)pattern,
761  hash_cmp)) == NULL) {
762  if(attribute->binary == 0x00) {
763  warning(0, "WML compiler: can't compile attribute %s%s%s%s",
764  octstr_get_cstr(attribute->attribute),
765  (attr->children != NULL ? "=\"": ""),
766  (attr->children != NULL ? octstr_get_cstr(pattern) : ""),
767  (attr->children != NULL ? "\"": ""));
768  wbxml_hex = WBXML_LITERAL;
769  output_st_char(wbxml_hex, wbxml);
771  } else {
772  wbxml_hex = attribute->binary;
773  output_st_char(wbxml_hex, wbxml);
774  }
775  } else if (hit->binary) {
776  wbxml_hex = hit->binary;
777  coded_length = octstr_len(hit->item);
778  output_st_char(wbxml_hex, wbxml);
779  } else
780  status = -1;
781  } else {
782  /* The attribute was not on the code page, it has to be encoded as a
783  string. */
784  wbxml_hex = WBXML_LITERAL;
785  output_st_char(wbxml_hex, wbxml);
786  octstr_append_uintvar((*wbxml)->wbxml_string,string_table_add(octstr_duplicate(name), wbxml));
787  warning(0, "WML compiler: Unknown attribute in WML source: <%s>",
789  }
790 
791  if (status >= 0) {
792  var_esc_t default_esc;
793 
794  default_esc = (octstr_str_compare (name, "href") == 0) ? ESC : NOESC;
795 
796  /* The rest of the attribute is coded as a inline string. */
797  if (pattern != NULL &&
798  coded_length < (int) octstr_len(pattern)) {
799  if (coded_length == 0)
800  p = create_octstr_from_node((char *)attr->children);
801  else
802  p = octstr_copy(pattern, coded_length,
803  octstr_len(pattern) - coded_length);
804 
805  if (check_if_url(wbxml_hex))
807  wbxml, attr->doc->charset, default_esc);
808  else
810  wbxml, attr->doc->charset, default_esc);
811  if (status != 0)
812  error(0,
813  "WML compiler: could not output attribute "
814  "value as a string.");
815  octstr_destroy(p);
816  }
817  }
818 
819  /* Memory cleanup. */
821 
822  if (pattern != NULL)
823  octstr_destroy(pattern);
824 
825  return status;
826 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
static int check_if_url(int hex)
unsigned char binary
Definition: wml_compiler.c:206
unsigned char binary
Definition: wml_compiler.c:196
static int parse_attr_value(Octstr *attr_value, List *tokens, wml_binary_t **wbxml, int charset, var_esc_t default_esc)
Definition: wml_compiler.c:834
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
var_esc_t
Definition: wml_compiler.c:128
Octstr * item
Definition: wml_compiler.c:195
static void output_st_char(int byte, wml_binary_t **wbxml)
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
#define WBXML_LITERAL
List * wml_attr_values_list
Definition: wml_compiler.c:222
static int hash_cmp(void *hash1, void *hash2)
#define octstr_duplicate(ostr)
Definition: octstr.h:187
char * name
Definition: smsc_cimd2.c:212
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
Dict * wml_attributes_dict
Definition: wml_compiler.c:220
Octstr * attribute
Definition: wml_compiler.c:205
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
void octstr_append_uintvar(Octstr *ostr, unsigned long value)
Definition: octstr.c:1931
Definition: octstr.c:118
int octstr_str_compare(const Octstr *ostr, const char *str)
Definition: octstr.c:973
List * wml_URL_values_list
Definition: wml_compiler.c:224
#define create_octstr_from_node(node)
static unsigned long string_table_add(Octstr *ostr, wml_binary_t **wbxml)

◆ parse_cdata()

static int parse_cdata ( xmlNodePtr  node,
wml_binary_t **  wbxml 
)
static

Definition at line 986 of file wml_compiler.c.

References create_octstr_from_node, NOESC, octstr_destroy(), and parse_st_octet_string().

Referenced by parse_node().

987 {
988  int ret = 0;
989  Octstr *temp;
990 
991  temp = create_octstr_from_node((char *)node);
992 
993  parse_st_octet_string(temp, 1, NOESC, wbxml);
994 
995  /* Memory cleanup. */
996  octstr_destroy(temp);
997 
998  return ret;
999 }
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static int parse_st_octet_string(Octstr *ostr, int cdata, var_esc_t default_esc, wml_binary_t **wbxml)
Definition: octstr.c:118
#define create_octstr_from_node(node)

◆ parse_document()

static int parse_document ( xmlDocPtr  document,
Octstr charset,
wml_binary_t **  wbxml,
Octstr version 
)
static

Definition at line 571 of file wml_compiler.c.

References charset, debug(), error(), info(), NUMBER_OF_WBXML_VERSION, NUMBER_OF_WML_EXTERNALID, octstr_compare(), octstr_create, octstr_destroy(), octstr_get_cstr, octstr_imm(), parse_charset(), parse_node(), string_table_build(), wbxml_version_t::value, warning(), wbxml_version, and xml_error().

Referenced by wml_compile().

573 {
574  xmlNodePtr node;
575  Octstr *externalID = NULL;
576  long i;
577 
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.");
581  return -1;
582  }
583 
584  /* Return WBXML version dependent on device given Encoding-Version */
585  if (version == NULL) {
586  (*wbxml)->wbxml_version = 0x01; /* WBXML Version number 1.1 */
587  info(0, "WBXML: No wbxml version given, assuming 1.1");
588  } else {
589  for (i = 0; i < NUMBER_OF_WBXML_VERSION; i++) {
590  if (octstr_compare(version, octstr_imm(wbxml_version[i].string)) == 0) {
591  (*wbxml)->wbxml_version = wbxml_version[i].value;
592  debug("parse_document",0,"WBXML: Encoding with wbxml version <%s>",
593  octstr_get_cstr(version));
594  break;
595  }
596  }
597  if (i == NUMBER_OF_WBXML_VERSION) {
598  (*wbxml)->wbxml_version = 0x01; /* WBXML Version number 1.1 */
599  warning(0, "WBXML: Unknown wbxml version, assuming 1.1 (<%s> is unknown)",
600  octstr_get_cstr(version));
601  }
602  }
603 
604  /* Return WML Version dependent on xml ExternalID string */
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; /* WML 1.1 Public ID */
609  warning(0, "WBXML: WML without ExternalID, assuming 1.1");
610  } else {
611  for (i = 0; i < NUMBER_OF_WML_EXTERNALID; i++) {
612  if (octstr_compare(externalID, octstr_imm(public_ids_strings[i].string)) == 0) {
613  (*wbxml)->wml_public_id = public_ids_strings[i].value;
614  debug("parse_document",0,"WBXML: WML with ExternalID <%s>",
615  octstr_get_cstr(externalID));
616  break;
617  }
618  }
619  if (i == NUMBER_OF_WML_EXTERNALID) {
620  (*wbxml)->wml_public_id = 0x04; /* WML 1.1 Public ID */
621  warning(0, "WBXML: WML with unknown ExternalID, assuming 1.1 "
622  "(<%s> is unknown)",
623  octstr_get_cstr(externalID));
624  }
625  }
626  octstr_destroy(externalID);
627 
628  (*wbxml)->string_table_length = 0x00; /* String table length=0 */
629 
630  /*
631  * Make sure we set the charset encoding right. If none is given
632  * then set UTF-8 as default.
633  */
634  (*wbxml)->character_set = charset ?
636 
637  node = xmlDocGetRootElement(document);
638 
639  if (node == NULL) {
640  error(0, "WML compiler: XML parsing failed, no document root element.");
641  error(0, "Most probably an error in the WML source.");
642  xml_error();
643  return -1;
644  }
645 
646  string_table_build(node, wbxml);
647 
648  return parse_node(node, wbxml);
649 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
static void xml_error(void)
Definition: wml_compiler.c:334
static wbxml_version_t wbxml_version[]
Definition: wml_compiler.c:117
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * charset
Definition: test_ota.c:68
static int parse_node(xmlNodePtr node, wml_binary_t **wbxml)
Definition: wml_compiler.c:502
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
int parse_charset(Octstr *os)
Definition: xml_shared.c:189
#define NUMBER_OF_WBXML_VERSION
Definition: wml_compiler.c:125
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118
#define NUMBER_OF_WML_EXTERNALID
Definition: wml_compiler.c:108
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static void string_table_build(xmlNodePtr node, wml_binary_t **wbxml)
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ parse_element()

static int parse_element ( xmlNodePtr  node,
wml_binary_t **  wbxml 
)
static

Definition at line 660 of file wml_compiler.c.

References check_do_elements(), check_variable_name(), dict_get(), element_check_content(), error(), FAILED, name, octstr_append_uintvar(), octstr_create, octstr_destroy(), octstr_duplicate, octstr_get_cstr, output_st_char(), parse_attribute(), parse_st_end(), string_table_add(), warning(), WBXML_CONTENT_BIT, WBXML_LITERAL, and wml_elements_dict.

Referenced by parse_node().

661 {
662  int add_end_tag = 0;
663  unsigned char wbxml_hex = 0, status_bits;
664  xmlAttrPtr attribute;
665  Octstr *name;
667 
668  name = octstr_create((char *)node->name);
669 
670  /* Check, if the tag can be found from the code page. */
671  if ((element = dict_get(wml_elements_dict, name)) != NULL) {
672  wbxml_hex = element->binary;
673  /* A conformance patch: no do-elements of same name in a card or
674  template. An extremely ugly patch. --tuo */
675  if (wbxml_hex == 0x27 || /* Card */
676  wbxml_hex == 0x3B) /* Template */
677  if (check_do_elements(node) == -1) {
678  add_end_tag = -1;
679  error(0, "WML compiler: Two or more do elements with same"
680  " name in a card or template element.");
681  }
682  /* A conformance patch: if variable in setvar has a bad name, it's
683  ignored. */
684  if (wbxml_hex == 0x3E) /* Setvar */
685  if (check_variable_name(node) == FAILED) {
687  return add_end_tag;
688  }
689  if ((status_bits = element_check_content(node)) > 0) {
690  wbxml_hex = wbxml_hex | status_bits;
691  /* If this node has children, the end tag must be added after
692  them. */
693  if ((status_bits & WBXML_CONTENT_BIT) == WBXML_CONTENT_BIT)
694  add_end_tag = 1;
695  }
696 
697  output_st_char(wbxml_hex, wbxml);
698  } else {
699  /* The tag was not on the code page, it has to be encoded as a
700  string. */
701  wbxml_hex = WBXML_LITERAL;
702  if ((status_bits = element_check_content(node)) > 0) {
703  wbxml_hex = wbxml_hex | status_bits;
704  /* If this node has children, the end tag must be added after
705  them. */
706  if ((status_bits & WBXML_CONTENT_BIT) == WBXML_CONTENT_BIT)
707  add_end_tag = 1;
708  }
709  output_st_char(wbxml_hex, wbxml);
710  octstr_append_uintvar((*wbxml)->wbxml_string,string_table_add(octstr_duplicate(name), wbxml));
711  warning(0, "WML compiler: Unknown tag in WML source: <%s>",
713  }
714 
715  /* Encode the attribute list for this node and add end tag after the
716  list. */
717 
718  if(node->properties != NULL) {
719  attribute = node->properties;
720  while (attribute != NULL) {
721  parse_attribute(attribute, wbxml);
722  attribute = attribute->next;
723  }
724  parse_st_end(wbxml);
725  }
726 
728  return add_end_tag;
729 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static void parse_st_end(wml_binary_t **wbxml)
Definition: wml_compiler.c:928
unsigned char element_check_content(xmlNodePtr node)
Definition: xml_shared.c:242
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static void output_st_char(int byte, wml_binary_t **wbxml)
static var_esc_t check_variable_name(xmlNodePtr node)
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
#define WBXML_LITERAL
#define octstr_duplicate(ostr)
Definition: octstr.h:187
char * name
Definition: smsc_cimd2.c:212
void warning(int err, const char *fmt,...)
Definition: log.c:660
static int check_do_elements(xmlNodePtr node)
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
Dict * wml_elements_dict
Definition: wml_compiler.c:218
void octstr_append_uintvar(Octstr *ostr, unsigned long value)
Definition: octstr.c:1931
Definition: octstr.c:118
static int parse_attribute(xmlAttrPtr attr, wml_binary_t **wbxml)
Definition: wml_compiler.c:740
#define WBXML_CONTENT_BIT
static unsigned long string_table_add(Octstr *ostr, wml_binary_t **wbxml)

◆ parse_entities()

static void parse_entities ( Octstr wml_source)
static

Definition at line 1237 of file wml_compiler.c.

References octstr_create, octstr_delete(), octstr_destroy(), octstr_imm(), octstr_insert(), and octstr_search().

Referenced by wml_compile().

1238 {
1239  static char entity_nbsp[] = "&nbsp;";
1240  static char entity_shy[] = "&shy;";
1241  static char nbsp[] = "&#160;";
1242  static char shy[] = "&#173;";
1243  int pos = 0;
1244  Octstr *temp;
1245 
1246  if ((pos = octstr_search(wml_source, octstr_imm(entity_nbsp),
1247  pos)) >= 0) {
1248  temp = octstr_create(nbsp);
1249  while (pos >= 0) {
1250  octstr_delete(wml_source, pos, strlen(entity_nbsp));
1251  octstr_insert(wml_source, temp, pos);
1252  pos = octstr_search(wml_source,
1253  octstr_imm(entity_nbsp), pos);
1254  }
1255  octstr_destroy(temp);
1256  }
1257 
1258  pos = 0;
1259  if ((pos = octstr_search(wml_source, octstr_imm(entity_shy),
1260  pos)) >= 0) {
1261  temp = octstr_create(shy);
1262  while (pos >= 0) {
1263  octstr_delete(wml_source, pos, strlen(entity_shy));
1264  octstr_insert(wml_source, temp, pos);
1265  pos = octstr_search(wml_source,
1266  octstr_imm(entity_shy), pos);
1267  }
1268  octstr_destroy(temp);
1269  }
1270 }
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
Definition: octstr.c:118

◆ parse_node()

static int parse_node ( xmlNodePtr  node,
wml_binary_t **  wbxml 
)
static

Definition at line 502 of file wml_compiler.c.

References error(), parse_cdata(), parse_element(), parse_st_end(), and parse_text().

Referenced by parse_document().

503 {
504  int status = 0;
505 
506  /* Call for the parser function of the node type. */
507  switch (node->type) {
508  case XML_ELEMENT_NODE:
509  status = parse_element(node, wbxml);
510  break;
511  case XML_TEXT_NODE:
512  status = parse_text(node, wbxml);
513  break;
514  case XML_CDATA_SECTION_NODE:
515  status = parse_cdata(node, wbxml);
516  break;
517  case XML_COMMENT_NODE:
518  case XML_PI_NODE:
519  /* Comments and PIs are ignored. */
520  break;
521  /*
522  * XML has also many other node types, these are not needed with
523  * WML. Therefore they are assumed to be an error.
524  */
525  default:
526  error(0, "WML compiler: Unknown XML node in the WML source.");
527  return -1;
528  break;
529  }
530 
531  /*
532  * If node is an element with content, it will need an end tag after it's
533  * children. The status for it is returned by parse_element.
534  */
535  switch (status) {
536  case 0:
537 
538  if (node->children != NULL)
539  if (parse_node(node->children, wbxml) == -1)
540  return -1;
541  break;
542  case 1:
543  if (node->children != NULL)
544  if (parse_node(node->children, wbxml) == -1)
545  return -1;
546  parse_st_end(wbxml);
547  break;
548 
549  case -1: /* Something went wrong in the parsing. */
550  return -1;
551  default:
552  error(0,
553  "WML compiler: undefined return value in a parse function.");
554  return -1;
555  break;
556  }
557 
558  if (node->next != NULL)
559  if (parse_node(node->next, wbxml) == -1)
560  return -1;
561 
562  return 0;
563 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static void parse_st_end(wml_binary_t **wbxml)
Definition: wml_compiler.c:928
static int parse_cdata(xmlNodePtr node, wml_binary_t **wbxml)
Definition: wml_compiler.c:986
static int parse_node(xmlNodePtr node, wml_binary_t **wbxml)
Definition: wml_compiler.c:502
static int parse_text(xmlNodePtr node, wml_binary_t **wbxml)
Definition: wml_compiler.c:940
static int parse_element(xmlNodePtr node, wml_binary_t **wbxml)
Definition: wml_compiler.c:660

◆ parse_st_end()

static void parse_st_end ( wml_binary_t **  wbxml)
static

Definition at line 928 of file wml_compiler.c.

References output_st_char(), and WBXML_END.

Referenced by parse_element(), and parse_node().

929 {
930  output_st_char(WBXML_END, wbxml);
931 }
static void output_st_char(int byte, wml_binary_t **wbxml)
#define WBXML_END

◆ parse_st_octet_string()

static int parse_st_octet_string ( Octstr ostr,
int  cdata,
var_esc_t  default_esc,
wml_binary_t **  wbxml 
)
static

Definition at line 1152 of file wml_compiler.c.

References octstr_copy, octstr_create, octstr_destroy(), octstr_get_char(), octstr_insert(), octstr_len(), octstr_search_char(), octstr_truncate(), output_st_octet_string(), parse_variable(), start, and string_table_apply().

Referenced by parse_attr_value(), parse_cdata(), and parse_text().

1153 {
1154  Octstr *output, *var, *temp = NULL;
1155  int var_len;
1156  int start = 0, pos = 0, len;
1157 
1158  /* No variables? Ok, let's take the easy way... (CDATA never contains
1159  variables.) */
1160 
1161  if ((pos = octstr_search_char(ostr, '$', 0)) < 0 || cdata == 1) {
1162  string_table_apply(ostr, wbxml);
1163  return 0;
1164  }
1165 
1166  len = octstr_len(ostr);
1167  output = octstr_create("");
1168  var = octstr_create("");
1169 
1170  while (pos < len) {
1171  if (octstr_get_char(ostr, pos) == '$') {
1172  if (pos > start) {
1173  temp = octstr_copy(ostr, start, pos - start);
1174  octstr_insert(output, temp, octstr_len(output));
1175  octstr_destroy(temp);
1176  }
1177 
1178  if ((var_len = parse_variable(ostr, pos, default_esc, &var, wbxml)) > 0) {
1179  if (octstr_len(var) > 0) {
1180  if (octstr_get_char(var, 0) == '$')
1181  /*
1182  * No, it's not actually variable, but $-character
1183  * escaped as "$$". So everything should be packed
1184  * into one string.
1185  */
1186  octstr_insert(output, var, octstr_len(output));
1187  else {
1188  /*
1189  * The string is output as a inline string and the
1190  * variable as a string table variable reference.
1191  */
1192  if (octstr_len(output) > 0)
1193  string_table_apply(output, wbxml);
1194  octstr_truncate(output, 0);
1195  output_st_octet_string(var, wbxml);
1196  }
1197  /* Variable had a syntax error, so it's skipped. */
1198  }
1199 
1200  pos = pos + var_len;
1201  start = pos;
1202  } else
1203  return -1;
1204  } else
1205  pos ++;
1206  }
1207 
1208  /* Was there still something after the last variable? */
1209  if (start < pos) {
1210  if (octstr_len(output) == 0) {
1211  octstr_destroy(output);
1212  output = octstr_copy(ostr, start, pos - start);
1213  } else {
1214  temp = octstr_copy(ostr, start, pos - start);
1215  octstr_insert(output, temp, octstr_len(output));
1216  octstr_destroy(temp);
1217  }
1218  }
1219 
1220  if (octstr_len(output) > 0)
1221  string_table_apply(output, wbxml);
1222 
1223  octstr_destroy(output);
1224  octstr_destroy(var);
1225 
1226  return 0;
1227 }
static void string_table_apply(Octstr *ostr, wml_binary_t **wbxml)
static void output_st_octet_string(Octstr *ostr, wml_binary_t **wbxml)
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
static int parse_variable(Octstr *text, int start, var_esc_t default_esc, Octstr **output, wml_binary_t **wbxml)
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1327
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static int start

◆ parse_text()

static int parse_text ( xmlNodePtr  node,
wml_binary_t **  wbxml 
)
static

Definition at line 940 of file wml_compiler.c.

References charset_convert(), check_if_emphasis(), create_octstr_from_node, error(), NOESC, octstr_destroy(), octstr_len(), octstr_shrink_blanks(), octstr_strip_blanks(), and parse_st_octet_string().

Referenced by parse_node().

941 {
942  int ret;
943  Octstr *temp;
944  char* tmp;
945 
946  temp = create_octstr_from_node((char *)node); /* returns string in UTF-8 */
947 
948  /*
949  * Beware that libxml2 does internal encoding in UTF-8 while parsing.
950  * So if our original WML source had a different encoding set, we have
951  * to transcode at least here. Only transcode if target encoding differs
952  * from libxml2's internal encoding (UTF-8).
953  */
954  tmp = (char*) xmlGetCharEncodingName(node->doc->charset);
955  if (node->doc->charset != XML_CHAR_ENCODING_UTF8 &&
956  charset_convert(temp, "UTF-8",
957  tmp) != 0) {
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)");
961  }
962 
963  octstr_shrink_blanks(temp);
964  if (!check_if_emphasis(node->prev) && !check_if_emphasis(node->next))
965  octstr_strip_blanks(temp);
966 
967  if (octstr_len(temp) == 0)
968  ret = 0;
969  else
970  ret = parse_st_octet_string(temp, 0, NOESC, wbxml);
971 
972  /* Memory cleanup. */
973  octstr_destroy(temp);
974 
975  return ret;
976 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
static int parse_st_octet_string(Octstr *ostr, int cdata, var_esc_t default_esc, wml_binary_t **wbxml)
Definition: octstr.c:118
#define create_octstr_from_node(node)
static int check_if_emphasis(xmlNodePtr node)
void octstr_shrink_blanks(Octstr *text)
Definition: octstr.c:1433
int charset_convert(Octstr *string, char *charset_from, char *charset_to)
Definition: charset.c:589

◆ parse_variable()

static int parse_variable ( Octstr text,
int  start,
var_esc_t  default_esc,
Octstr **  output,
wml_binary_t **  wbxml 
)
static

Definition at line 1014 of file wml_compiler.c.

References check_variable_syntax(), FAILED, get_variable(), octstr_append_char(), octstr_destroy(), octstr_get_char(), octstr_len(), octstr_truncate(), output_variable(), start, and text.

Referenced by parse_st_octet_string().

1016 {
1017  var_esc_t esc;
1018  int ret;
1019  Octstr *variable;
1020 
1021  variable = get_variable(text, start + 1);
1022  octstr_truncate(*output, 0);
1023 
1024  if (variable == NULL)
1025  return 0;
1026 
1027  if (octstr_get_char(variable, 0) == '$') {
1028  octstr_append_char(*output, '$');
1029  octstr_destroy(variable);
1030  ret = 2;
1031  } else {
1032  if (octstr_get_char(text, start + 1) == '(')
1033  ret = octstr_len(variable) + 3;
1034  else
1035  ret = octstr_len(variable) + 1;
1036 
1037  if ((esc = check_variable_syntax(variable, default_esc)) != FAILED)
1038  output_variable(variable, output, esc, wbxml);
1039  else
1040  octstr_destroy(variable);
1041  }
1042 
1043  return ret;
1044 }
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
var_esc_t
Definition: wml_compiler.c:128
char * text
Definition: smsc_cimd2.c:921
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static void output_variable(Octstr *variable, Octstr **output, var_esc_t escaped, wml_binary_t **wbxml)
static Octstr * get_variable(Octstr *text, int start)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
static var_esc_t check_variable_syntax(Octstr *variable, var_esc_t default_esc)
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1327
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
static int start

◆ string_table_add()

static unsigned long string_table_add ( Octstr ostr,
wml_binary_t **  wbxml 
)
static

Definition at line 1972 of file wml_compiler.c.

References gwlist_append(), gwlist_get(), gwlist_len(), octstr_compare(), octstr_destroy(), octstr_len(), string_table_t::offset, string_table_t::string, and string_table_create().

Referenced by output_variable(), parse_attribute(), parse_element(), and string_table_add_many().

1973 {
1974  string_table_t *item = NULL;
1975  unsigned long i, offset = 0;
1976 
1977  /* Check whether the string is unique. */
1978  for (i = 0; i < (unsigned long)gwlist_len((*wbxml)->string_table); i++) {
1979  item = gwlist_get((*wbxml)->string_table, i);
1980  if (octstr_compare(item->string, ostr) == 0) {
1981  octstr_destroy(ostr);
1982  return item->offset;
1983  }
1984  }
1985 
1986  /* Create a new list item for the string table. */
1987  offset = (*wbxml)->string_table_length;
1988 
1989  item = string_table_create(offset, ostr);
1990 
1991  (*wbxml)->string_table_length =
1992  (*wbxml)->string_table_length + octstr_len(ostr) + 1;
1993  gwlist_append((*wbxml)->string_table, item);
1994 
1995  return offset;
1996 }
unsigned long offset
Definition: wml_compiler.c:175
void gwlist_append(List *list, void *item)
Definition: list.c:179
static string_table_t * string_table_create(int offset, Octstr *ostr)
long gwlist_len(List *list)
Definition: list.c:166
Octstr * string
Definition: wml_compiler.c:176
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ string_table_add_many()

static List * string_table_add_many ( List sorted,
wml_binary_t **  wbxml 
)
static

Definition at line 1905 of file wml_compiler.c.

References string_table_proposal_t::count, gwlist_append(), gwlist_create, gwlist_destroy(), gwlist_extract_first(), gwlist_len(), octstr_duplicate, octstr_len(), string_table_proposal_t::string, string_table_add(), string_table_proposal_destroy(), and WBXML_STRING_TABLE_MIN.

Referenced by string_table_build().

1906 {
1907  string_table_proposal_t *item = NULL;
1908  List *list = NULL;
1909 
1910  list = gwlist_create();
1911 
1912  while (gwlist_len(sorted)) {
1913  item = gwlist_extract_first(sorted);
1914 
1915  if (item->count > 1 && octstr_len(item->string) >
1917  string_table_add(octstr_duplicate(item->string), wbxml);
1919  } else
1920  gwlist_append(list, item);
1921  }
1922 
1923  gwlist_destroy(sorted, NULL);
1924 
1925  return list;
1926 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
#define WBXML_STRING_TABLE_MIN
void * gwlist_extract_first(List *list)
Definition: list.c:305
static void string_table_proposal_destroy(string_table_proposal_t *node)
#define octstr_duplicate(ostr)
Definition: octstr.h:187
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
#define gwlist_create()
Definition: list.h:136
Definition: list.c:102
static unsigned long string_table_add(Octstr *ostr, wml_binary_t **wbxml)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ string_table_apply()

static void string_table_apply ( Octstr ostr,
wml_binary_t **  wbxml 
)
static

Definition at line 2006 of file wml_compiler.c.

References gwlist_get(), gwlist_len(), octstr_append_char(), octstr_append_uintvar(), octstr_compare(), octstr_create, octstr_delete(), octstr_destroy(), octstr_get_char(), octstr_insert(), octstr_len(), octstr_search(), octstr_truncate(), string_table_t::offset, output_st_char(), output_st_octet_string(), string_table_t::string, WBXML_STR_END, WBXML_STR_I, WBXML_STR_T, and WBXML_STRING_TABLE_MIN.

Referenced by parse_st_octet_string().

2007 {
2008  Octstr *input = NULL;
2009  string_table_t *item = NULL;
2010  long i = 0, word_s = 0, str_e = 0;
2011 
2012  input = octstr_create("");
2013 
2014  for (i = 0; i < gwlist_len((*wbxml)->string_table); i++) {
2015  item = gwlist_get((*wbxml)->string_table, i);
2016 
2018  /* No use to replace 1 to 3 character substring, the reference
2019  will eat the saving up. A variable will be in the string table
2020  even though it's only 1 character long. */
2021  if ((word_s = octstr_search(ostr, item->string, 0)) >= 0) {
2022  /* Check whether the octet string are equal if they are equal
2023  in length. */
2024  if (octstr_len(ostr) == octstr_len(item->string)) {
2025  if ((word_s = octstr_compare(ostr, item->string)) == 0)
2026  {
2027  octstr_truncate(ostr, 0);
2029  octstr_append_uintvar(ostr, item->offset);
2030  str_e = 1;
2031  }
2032  }
2033  /* Check the possible substrings. */
2034  else if (octstr_len(ostr) > octstr_len(item->string))
2035  {
2036  if (word_s + octstr_len(item->string) == octstr_len(ostr))
2037  str_e = 1;
2038 
2039  octstr_delete(ostr, word_s, octstr_len(item->string));
2040 
2041  octstr_truncate(input, 0);
2042  /* Substring in the start? No STR_END then. */
2043  if (word_s > 0)
2045 
2047  octstr_append_uintvar(input, item->offset);
2048 
2049  /* Subtring the end? No need to start a new one. */
2050  if ( word_s < octstr_len(ostr))
2052 
2053  octstr_insert(ostr, input, word_s);
2054  }
2055  /* If te string table entry is longer than the string, it can
2056  be skipped. */
2057  }
2058  }
2059 
2060  octstr_destroy(input);
2061 
2062  if (octstr_get_char(ostr, 0) != WBXML_STR_T)
2063  output_st_char(WBXML_STR_I, wbxml);
2064  if (!str_e)
2066 
2067  output_st_octet_string(ostr, wbxml);
2068 }
unsigned long offset
Definition: wml_compiler.c:175
long gwlist_len(List *list)
Definition: list.c:166
Octstr * string
Definition: wml_compiler.c:176
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
Definition: octstr.c:1070
static void output_st_octet_string(Octstr *ostr, wml_binary_t **wbxml)
#define WBXML_STR_END
#define WBXML_STRING_TABLE_MIN
static void output_st_char(int byte, wml_binary_t **wbxml)
#define WBXML_STR_I
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
void octstr_append_uintvar(Octstr *ostr, unsigned long value)
Definition: octstr.c:1931
Definition: octstr.c:118
void octstr_truncate(Octstr *ostr, int new_len)
Definition: octstr.c:1327
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
#define WBXML_STR_T
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ string_table_build()

static void string_table_build ( xmlNodePtr  node,
wml_binary_t **  wbxml 
)
static

Definition at line 1780 of file wml_compiler.c.

References gwlist_create, gwlist_destroy(), gwlist_extract_first(), gwlist_len(), string_table_add_many(), string_table_collect_strings(), string_table_collect_words(), string_table_proposal_destroy(), and string_table_sort_list().

Referenced by parse_document().

1781 {
1782  string_table_proposal_t *item = NULL;
1783  List *list = NULL;
1784 
1785  list = gwlist_create();
1786 
1787  string_table_collect_strings(node, list);
1788 
1789  list = string_table_add_many(string_table_sort_list(list), wbxml);
1790 
1791  list = string_table_collect_words(list);
1792 
1793  /* Don't add strings if there aren't any. (no NULLs please) */
1794  if (list) {
1795  list = string_table_add_many(string_table_sort_list(list), wbxml);
1796  }
1797 
1798  /* Memory cleanup. */
1799  while (gwlist_len(list)) {
1800  item = gwlist_extract_first(list);
1802  }
1803 
1804  gwlist_destroy(list, NULL);
1805 }
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_extract_first(List *list)
Definition: list.c:305
static void string_table_proposal_destroy(string_table_proposal_t *node)
static void string_table_collect_strings(xmlNodePtr node, List *strings)
static List * string_table_collect_words(List *strings)
static List * string_table_sort_list(List *start)
#define gwlist_create()
Definition: list.h:136
static List * string_table_add_many(List *sorted, wml_binary_t **wbxml)
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ string_table_collect_strings()

static void string_table_collect_strings ( xmlNodePtr  node,
List strings 
)
static

Definition at line 1815 of file wml_compiler.c.

References create_octstr_from_node, gwlist_append(), octstr_destroy(), octstr_len(), octstr_shrink_blanks(), octstr_strip_blanks(), octstr_strip_nonalphanums(), and WBXML_STRING_TABLE_MIN.

Referenced by string_table_build().

1816 {
1817  Octstr *string;
1818  xmlAttrPtr attribute;
1819 
1820  switch (node->type) {
1821  case XML_TEXT_NODE:
1822  string = create_octstr_from_node((char *)node);
1823 
1824  octstr_shrink_blanks(string);
1825  octstr_strip_blanks(string);
1826  if (octstr_len(string) > WBXML_STRING_TABLE_MIN)
1827  octstr_strip_nonalphanums(string);
1828 
1829  if (octstr_len(string) > WBXML_STRING_TABLE_MIN)
1830  gwlist_append(strings, string);
1831  else
1832  octstr_destroy(string);
1833  break;
1834  case XML_ELEMENT_NODE:
1835  if(node->properties != NULL) {
1836  attribute = node->properties;
1837  while (attribute != NULL) {
1838  if (attribute->children != NULL)
1839  string_table_collect_strings(attribute->children, strings);
1840  attribute = attribute->next;
1841  }
1842  }
1843  break;
1844  default:
1845  break;
1846  }
1847 
1848  if (node->children != NULL)
1849  string_table_collect_strings(node->children, strings);
1850 
1851  if (node->next != NULL)
1852  string_table_collect_strings(node->next, strings);
1853 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#define WBXML_STRING_TABLE_MIN
void octstr_strip_nonalphanums(Octstr *text)
Definition: octstr.c:1405
static void string_table_collect_strings(xmlNodePtr node, List *strings)
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
#define create_octstr_from_node(node)
void octstr_shrink_blanks(Octstr *text)
Definition: octstr.c:1433

◆ string_table_collect_words()

static List * string_table_collect_words ( List strings)
static

Definition at line 1935 of file wml_compiler.c.

References gwlist_append(), gwlist_destroy(), gwlist_extract_first(), gwlist_len(), octstr_split_words(), string_table_proposal_t::string, and string_table_proposal_destroy().

Referenced by string_table_build().

1936 {
1937  Octstr *word = NULL;
1938  string_table_proposal_t *item = NULL;
1939  List *list = NULL, *temp_list = NULL;
1940 
1941  while (gwlist_len(strings)) {
1942  item = gwlist_extract_first(strings);
1943 
1944  if (list == NULL) {
1945  list = octstr_split_words(item->string);
1947  } else {
1948  temp_list = octstr_split_words(item->string);
1949 
1950  while ((word = gwlist_extract_first(temp_list)) != NULL)
1951  gwlist_append(list, word);
1952 
1953  gwlist_destroy(temp_list, NULL);
1955  }
1956  }
1957 
1958  gwlist_destroy(strings, NULL);
1959 
1960  return list;
1961 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_extract_first(List *list)
Definition: list.c:305
static void string_table_proposal_destroy(string_table_proposal_t *node)
List * octstr_split_words(const Octstr *ostr)
Definition: octstr.c:1602
Definition: octstr.c:118
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ string_table_create()

static string_table_t * string_table_create ( int  offset,
Octstr ostr 
)
static

Definition at line 1713 of file wml_compiler.c.

References string_table_t::offset, and string_table_t::string.

Referenced by string_table_add().

1714 {
1715  string_table_t *node;
1716 
1717  node = gw_malloc(sizeof(string_table_t));
1718  node->offset = offset;
1719  node->string = ostr;
1720 
1721  return node;
1722 }
unsigned long offset
Definition: wml_compiler.c:175
Octstr * string
Definition: wml_compiler.c:176

◆ string_table_destroy()

static void string_table_destroy ( string_table_t node)
static

Definition at line 1730 of file wml_compiler.c.

References octstr_destroy(), and string_table_t::string.

Referenced by string_table_output().

1731 {
1732  if (node != NULL) {
1733  octstr_destroy(node->string);
1734  gw_free(node);
1735  }
1736 }
Octstr * string
Definition: wml_compiler.c:176
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324

◆ string_table_output()

static void string_table_output ( Octstr ostr,
wml_binary_t **  wbxml 
)
static

Definition at line 2077 of file wml_compiler.c.

References gwlist_extract_first(), octstr_append_char(), octstr_insert(), octstr_len(), string_table_t::string, string_table_destroy(), and WBXML_STR_END.

Referenced by wml_binary_output().

2078 {
2079  string_table_t *item;
2080 
2081  while ((item = gwlist_extract_first((*wbxml)->string_table)) != NULL) {
2082  octstr_insert(ostr, item->string, octstr_len(ostr));
2084  string_table_destroy(item);
2085  }
2086 }
Octstr * string
Definition: wml_compiler.c:176
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
#define WBXML_STR_END
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
void * gwlist_extract_first(List *list)
Definition: list.c:305
static void string_table_destroy(string_table_t *node)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ string_table_proposal_create()

static string_table_proposal_t * string_table_proposal_create ( Octstr ostr)
static

Definition at line 1745 of file wml_compiler.c.

References string_table_proposal_t::count, and string_table_proposal_t::string.

Referenced by string_table_sort_list().

1746 {
1748 
1749  node = gw_malloc(sizeof(string_table_proposal_t));
1750  node->count = 1;
1751  node->string = ostr;
1752 
1753  return node;
1754 }

◆ string_table_proposal_destroy()

static void string_table_proposal_destroy ( string_table_proposal_t node)
static

Definition at line 1763 of file wml_compiler.c.

References octstr_destroy(), and string_table_proposal_t::string.

Referenced by string_table_add_many(), string_table_build(), and string_table_collect_words().

1764 {
1765  if (node != NULL) {
1766  octstr_destroy(node->string);
1767  gw_free(node);
1768  }
1769 }
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324

◆ string_table_sort_list()

static List * string_table_sort_list ( List start)
static

Definition at line 1863 of file wml_compiler.c.

References string_table_proposal_t::count, gwlist_append(), gwlist_create, gwlist_destroy(), gwlist_extract_first(), gwlist_get(), gwlist_len(), octstr_compare(), octstr_destroy(), start, string_table_proposal_t::string, and string_table_proposal_create().

Referenced by string_table_build().

1864 {
1865  int i;
1866  Octstr *string = NULL;
1867  string_table_proposal_t *item = NULL;
1868  List *sorted = NULL;
1869 
1870  sorted = gwlist_create();
1871 
1872  while (gwlist_len(start)) {
1873  string = gwlist_extract_first(start);
1874 
1875  /* Check whether the string is unique. */
1876  for (i = 0; i < gwlist_len(sorted); i++) {
1877  item = gwlist_get(sorted, i);
1878  if (octstr_compare(item->string, string) == 0) {
1879  octstr_destroy(string);
1880  string = NULL;
1881  item->count ++;
1882  break;
1883  }
1884  }
1885 
1886  if (string != NULL) {
1887  item = string_table_proposal_create(string);
1888  gwlist_append(sorted, item);
1889  }
1890  }
1891 
1892  gwlist_destroy(start, NULL);
1893 
1894  return sorted;
1895 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
static string_table_proposal_t * string_table_proposal_create(Octstr *ostr)
void * gwlist_extract_first(List *list)
Definition: list.c:305
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
#define gwlist_create()
Definition: list.h:136
Definition: list.c:102
static int start
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ wml_binary_create()

static wml_binary_t * wml_binary_create ( void  )
static

Definition at line 1279 of file wml_compiler.c.

References wml_binary_t::character_set, gwlist_create, octstr_create, wml_binary_t::string_table, wml_binary_t::string_table_length, wml_binary_t::wbxml_string, wml_binary_t::wbxml_version, and wml_binary_t::wml_public_id.

Referenced by wml_compile().

1280 {
1281  wml_binary_t *wbxml;
1282 
1283  wbxml = gw_malloc(sizeof(wml_binary_t));
1284  wbxml->wbxml_version = 0x00;
1285  wbxml->wml_public_id = 0x00;
1286  wbxml->character_set = 0x00;
1287  wbxml->string_table_length = 0x00;
1288  wbxml->string_table = gwlist_create();
1289  wbxml->wbxml_string = octstr_create("");
1290 
1291  return wbxml;
1292 }
unsigned char wbxml_version
Definition: wml_compiler.c:161
Octstr * wbxml_string
Definition: wml_compiler.c:166
unsigned long wml_public_id
Definition: wml_compiler.c:162
unsigned long string_table_length
Definition: wml_compiler.c:164
#define octstr_create(cstr)
Definition: octstr.h:125
unsigned long character_set
Definition: wml_compiler.c:163
List * string_table
Definition: wml_compiler.c:165
#define gwlist_create()
Definition: list.h:136

◆ wml_binary_destroy()

static void wml_binary_destroy ( wml_binary_t wbxml)
static

Definition at line 1300 of file wml_compiler.c.

References gwlist_destroy(), octstr_destroy(), wml_binary_t::string_table, and wml_binary_t::wbxml_string.

Referenced by wml_compile().

1301 {
1302  if (wbxml != NULL) {
1303  gwlist_destroy(wbxml->string_table, NULL);
1304  octstr_destroy(wbxml->wbxml_string);
1305  gw_free(wbxml);
1306  }
1307 }
Octstr * wbxml_string
Definition: wml_compiler.c:166
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
List * string_table
Definition: wml_compiler.c:165
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ wml_binary_output()

static void wml_binary_output ( Octstr ostr,
wml_binary_t wbxml 
)
static

Definition at line 1315 of file wml_compiler.c.

References wml_binary_t::character_set, octstr_append_char(), octstr_append_uintvar(), octstr_insert(), octstr_len(), wml_binary_t::string_table_length, string_table_output(), wml_binary_t::wbxml_string, wml_binary_t::wbxml_version, and wml_binary_t::wml_public_id.

Referenced by wml_compile().

1316 {
1317  octstr_append_char(ostr, wbxml->wbxml_version);
1318  octstr_append_uintvar(ostr, wbxml->wml_public_id);
1319  octstr_append_uintvar(ostr, wbxml->character_set);
1321 
1322  if (wbxml->string_table_length > 0)
1323  string_table_output(ostr, &wbxml);
1324 
1325  octstr_insert(ostr, wbxml->wbxml_string, octstr_len(ostr));
1326 }
unsigned char wbxml_version
Definition: wml_compiler.c:161
Octstr * wbxml_string
Definition: wml_compiler.c:166
unsigned long wml_public_id
Definition: wml_compiler.c:162
void octstr_append_char(Octstr *ostr, int ch)
Definition: octstr.c:1517
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
unsigned long string_table_length
Definition: wml_compiler.c:164
unsigned long character_set
Definition: wml_compiler.c:163
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
void octstr_append_uintvar(Octstr *ostr, unsigned long value)
Definition: octstr.c:1931
static void string_table_output(Octstr *ostr, wml_binary_t **wbxml)

◆ wml_compile()

int wml_compile ( Octstr wml_text,
Octstr charset,
Octstr **  wml_binary,
Octstr version 
)

Definition at line 360 of file wml_compiler.c.

References charset, debug(), error(), octstr_create, octstr_get_cstr, octstr_len(), octstr_search_char(), octstr_strip_blanks(), parse_document(), parse_entities(), size, wml_binary_create(), wml_binary_destroy(), wml_binary_output(), wml_xml_parser_opt, and xml_error().

Referenced by convert_wml_to_wmlc(), and main().

362 {
363  int ret = 0;
364  size_t size;
365  xmlDocPtr pDoc = NULL;
366  char *wml_c_text;
367  wml_binary_t *wbxml = NULL;
368 
369  *wml_binary = octstr_create("");
370  wbxml = wml_binary_create();
371 
372  /* Remove the extra space from start and the end of the WML Document. */
373  octstr_strip_blanks(wml_text);
374 
375  /* Check the WML-code for \0-characters and for WML entities. Fast patch.
376  -- tuo */
377  parse_entities(wml_text);
378 
379  size = octstr_len(wml_text);
380  wml_c_text = octstr_get_cstr(wml_text);
381 
382  debug("wml_compile",0, "WML: Given charset: %s", octstr_get_cstr(charset));
383 
384  if (octstr_search_char(wml_text, '\0', 0) != -1) {
385  error(0, "WML compiler: Compiling error: "
386  "\\0 character found in the middle of the WML source.");
387  ret = -1;
388  } else {
389  /*
390  * An empty octet string for the binary output is created, the wml
391  * source is parsed into a parsing tree and the tree is then compiled
392  * into binary.
393  */
394 
395  pDoc = xmlReadMemory(wml_c_text, size, NULL, octstr_get_cstr(charset),
397 
398  if (pDoc != NULL) {
399  /*
400  * If we have a set internal encoding, then apply this information
401  * to the XML parsing tree document for later transcoding ability.
402  */
403  if (charset)
404  pDoc->charset = xmlParseCharEncoding(octstr_get_cstr(charset));
405 
406  ret = parse_document(pDoc, charset, &wbxml, version);
407  wml_binary_output(*wml_binary, wbxml);
408  } else {
409  error(0, "WML compiler: Compiling error: "
410  "libxml2 returned a NULL pointer");
411  xml_error();
412  ret = -1;
413  }
414  }
415 
416  wml_binary_destroy(wbxml);
417 
418  if (pDoc)
419  xmlFreeDoc(pDoc);
420 
421  return ret;
422 }
void error(int err, const char *fmt,...)
Definition: log.c:648
int size
Definition: wsasm.c:84
static int parse_document(xmlDocPtr document, Octstr *charset, wml_binary_t **wbxml, Octstr *version)
Definition: wml_compiler.c:571
static void xml_error(void)
Definition: wml_compiler.c:334
static wml_binary_t * wml_binary_create(void)
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
Octstr * charset
Definition: test_ota.c:68
static void wml_binary_output(Octstr *ostr, wml_binary_t *wbxml)
#define octstr_create(cstr)
Definition: octstr.h:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static void parse_entities(Octstr *wml_source)
static void wml_binary_destroy(wml_binary_t *wbxml)
int wml_xml_parser_opt
Definition: wml_compiler.c:226

◆ wml_init()

void wml_init ( int  wml_xml_strict)

Definition at line 429 of file wml_compiler.c.

References attr_dict_construct(), attribute_destroy(), dict_create(), dict_put(), gwlist_append(), gwlist_create, hash_create(), hash_destroy(), wml_hash_t::item, text, token, wml_attr_values_list, wml_attribute_values, wml_attributes, wml_attributes_dict, wml_elements, wml_elements_dict, wml_table3_len(), wml_table_len(), wml_URL_values, wml_URL_values_list, wml_xml_parser_opt, and wml_xml_strict.

Referenced by main().

430 {
431  int i = 0, len = 0;
432  wml_hash_t *temp = NULL;
433 
434  /* The wml elements into a hash table. */
437 
438  for (i = 0; i < len; i++) {
440  dict_put(wml_elements_dict, temp->item, temp);
441  }
442 
443  /* Attributes. */
447 
448  /* Attribute values. */
451 
452  for (i = 0; i < len; i++) {
456  }
457 
458  /* URL values. */
461 
462  for (i = 0; i < len; i++) {
465  }
466 
467  /* Strict XML parsing. */
469  (XML_PARSE_NOERROR | XML_PARSE_NONET) :
470  (XML_PARSE_RECOVER | XML_PARSE_NOERROR | XML_PARSE_NONET);
471 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
static wml_table_t wml_URL_values[]
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
void gwlist_append(List *list, void *item)
Definition: list.c:179
static void attr_dict_construct(wml_table3_t *attributes, Dict *attr_dict)
static void hash_destroy(void *p)
static void attribute_destroy(void *p)
static wml_hash_t * hash_create(char *text, unsigned char token)
Octstr * item
Definition: wml_compiler.c:195
int token
Definition: wslexer.c:159
List * wml_attr_values_list
Definition: wml_compiler.c:222
char * text
Definition: smsc_cimd2.c:921
static int wml_table3_len(wml_table3_t *table)
static wml_table_t wml_elements[]
Dict * wml_attributes_dict
Definition: wml_compiler.c:220
static int wml_table_len(wml_table_t *table)
static wml_table_t wml_attribute_values[]
Dict * wml_elements_dict
Definition: wml_compiler.c:218
static int wml_xml_strict
Definition: wapbox.c:108
#define gwlist_create()
Definition: list.h:136
List * wml_URL_values_list
Definition: wml_compiler.c:224
static wml_table3_t wml_attributes[]
int wml_xml_parser_opt
Definition: wml_compiler.c:226

◆ wml_shutdown()

void wml_shutdown ( void  )

Definition at line 479 of file wml_compiler.c.

References dict_destroy(), gwlist_destroy(), hash_destroy(), wml_attr_values_list, wml_attributes_dict, wml_elements_dict, and wml_URL_values_list.

Referenced by main().

480 {
485 }
static void hash_destroy(void *p)
List * wml_attr_values_list
Definition: wml_compiler.c:222
Dict * wml_attributes_dict
Definition: wml_compiler.c:220
Dict * wml_elements_dict
Definition: wml_compiler.c:218
void dict_destroy(Dict *dict)
Definition: dict.c:215
List * wml_URL_values_list
Definition: wml_compiler.c:224
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ wml_table3_len()

static int wml_table3_len ( wml_table3_t table)
static

Definition at line 1696 of file wml_compiler.c.

Referenced by wml_init().

1697 {
1698  int i = 0;
1699 
1700  while (table[i].text1 != NULL)
1701  i++;
1702 
1703  return i;
1704 }

◆ wml_table_len()

static int wml_table_len ( wml_table_t table)
static

Definition at line 1680 of file wml_compiler.c.

References text.

Referenced by wml_init().

1681 {
1682  int i = 0;
1683 
1684  while (table[i].text != NULL)
1685  i++;
1686 
1687  return i;
1688 }
char * text
Definition: smsc_cimd2.c:921

◆ xml_error()

static void xml_error ( void  )
static

Definition at line 334 of file wml_compiler.c.

References error(), msg, octstr_destroy(), octstr_format(), octstr_get_cstr, octstr_imm(), and octstr_replace().

Referenced by parse_document(), and wml_compile().

335 {
336  xmlErrorPtr err;
337  Octstr *msg;
338 
339  /* we should have an error, but be more sensitive */
340  if ((err = xmlGetLastError()) == NULL)
341  return;
342 
343  /* replace annoying line feeds */
344  msg = octstr_format("%s", err->message);
345  octstr_replace(msg, octstr_imm("\n"), octstr_imm(" "));
346  error(0,"XML error: code: %d, level: %d, line: %d, %s",
347  err->code, err->level, err->line, octstr_get_cstr(msg));
349 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void octstr_replace(Octstr *haystack, Octstr *needle, Octstr *repl)
Definition: octstr.c:2649
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

Variable Documentation

◆ wbxml_version

wbxml_version_t wbxml_version[]
static
Initial value:
= {
{ "1.1", 0x01 },
{ "1.2", 0x02 },
{ "1.3", 0x03 },
{ "1.4", 0x04 },
{ "1.5", 0x05 }
}

Definition at line 117 of file wml_compiler.c.

Referenced by parse_document().

◆ wml_attr_values_list

List* wml_attr_values_list

Definition at line 222 of file wml_compiler.c.

Referenced by parse_attribute(), wml_init(), and wml_shutdown().

◆ wml_attributes_dict

Dict* wml_attributes_dict

Definition at line 220 of file wml_compiler.c.

Referenced by parse_attribute(), wml_init(), and wml_shutdown().

◆ wml_elements_dict

Dict* wml_elements_dict

Definition at line 218 of file wml_compiler.c.

Referenced by parse_element(), wml_init(), and wml_shutdown().

◆ wml_URL_values_list

List* wml_URL_values_list

Definition at line 224 of file wml_compiler.c.

Referenced by parse_attribute(), wml_init(), and wml_shutdown().

◆ wml_xml_parser_opt

int wml_xml_parser_opt

Definition at line 226 of file wml_compiler.c.

Referenced by wml_compile(), and wml_init().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.