📄 wml_compiler.c
字号:
int ch; gw_assert(text != NULL); gw_assert(start >= 0 && start <= (int) octstr_len(text)); ch = octstr_get_char(text, start); if (ch == '$') { var = octstr_create("$"); } else if (ch == '(') { start ++; end = octstr_search_char(text, ')', start); if (end == -1) error(0, "WML compiler: braces opened, but not closed for a " "variable."); else if (end - start == 0) error(0, "WML compiler: empty braces without variable."); else var = octstr_copy(text, start, end - start); } else { end = start + 1; while (isalnum(ch = octstr_get_char(text, end)) || (ch == '_')) end ++; var = octstr_copy(text, start, end - start); } return var;}/* * check_variable_syntax - checks the variable syntax and the possible * escape mode it has. Octstr *variable contains the variable string. */static var_esc_t check_variable_syntax(Octstr *variable, var_esc_t default_esc){ Octstr *escape; char ch; int pos, len, i; var_esc_t ret; if ((pos = octstr_search_char(variable, ':', 0)) > 0) { len = octstr_len(variable) - pos; escape = octstr_copy(variable, pos + 1, len - 1); octstr_truncate(variable, pos); octstr_truncate(escape, len); octstr_convert_range(escape, 0, octstr_len(escape), tolower); if (octstr_str_compare(escape, "noesc") == 0 || octstr_str_compare(escape, "n") == 0 ) ret = NOESC; else if (octstr_str_compare(escape, "unesc") == 0 || octstr_str_compare(escape, "u") == 0 ) ret = UNESC; else if (octstr_str_compare(escape, "escape") == 0 || octstr_str_compare(escape, "e") == 0 ) ret = ESC; else { error(0, "WML compiler: syntax error in variable escaping."); octstr_destroy(escape); return FAILED; } octstr_destroy(escape); } else ret = default_esc; ch = octstr_get_char(variable, 0); if (!(isalpha((int)ch)) && ch != '_') { error(0, "WML compiler: syntax error in variable; name starting " "with %c.", ch); return FAILED; } else for (i = 1; i < (int) octstr_len(variable); i++) if (!isalnum((int)(ch = octstr_get_char(variable, 0))) && ch != '_') { warning(0, "WML compiler: syntax error in variable."); return FAILED; } return ret;}/* * parse_st_octet_string - parse an octet string into wbxml_string, the string * is checked for variables. If string is string table applicable, it will * be checked for string insrtances that are in the string table, otherwise * not. Returns 0 for success, -1 for error. */static int parse_st_octet_string(Octstr *ostr, int cdata, var_esc_t default_esc, wml_binary_t **wbxml){ Octstr *output, *var, *temp = NULL; int var_len; int start = 0, pos = 0, len; /* No variables? Ok, let's take the easy way... (CDATA never contains variables.) */ if ((pos = octstr_search_char(ostr, '$', 0)) < 0 || cdata == 1) { string_table_apply(ostr, wbxml); return 0; } len = octstr_len(ostr); output = octstr_create(""); var = octstr_create(""); while (pos < len) { if (octstr_get_char(ostr, pos) == '$') { if (pos > start) { temp = octstr_copy(ostr, start, pos - start); octstr_insert(output, temp, octstr_len(output)); octstr_destroy(temp); } if ((var_len = parse_variable(ostr, pos, default_esc, &var, wbxml)) > 0) { if (octstr_len(var) > 0) { if (octstr_get_char(var, 0) == '$') /* * No, it's not actually variable, but $-character * escaped as "$$". So everything should be packed * into one string. */ octstr_insert(output, var, octstr_len(output)); else { /* * The string is output as a inline string and the * variable as a string table variable reference. */ if (octstr_len(output) > 0) string_table_apply(output, wbxml); octstr_truncate(output, 0); output_st_octet_string(var, wbxml); } /* Variable had a syntax error, so it's skipped. */ } pos = pos + var_len; start = pos; } else return -1; } else pos ++; } /* Was there still something after the last variable? */ if (start < pos) { if (octstr_len(output) == 0) { octstr_destroy(output); output = octstr_copy(ostr, start, pos - start); } else { temp = octstr_copy(ostr, start, pos - start); octstr_insert(output, temp, octstr_len(output)); octstr_destroy(temp); } } if (octstr_len(output) > 0) string_table_apply(output, wbxml); octstr_destroy(output); octstr_destroy(var); return 0;}/* * parse_entities - replaces WML entites in the WML source with equivalent * numerical entities. A fast patch for WAP 1.1 compliance. */static void parse_entities(Octstr *wml_source){ static char entity_nbsp[] = " "; static char entity_shy[] = "­"; static char nbsp[] = " "; static char shy[] = "­"; int pos = 0; Octstr *temp; if ((pos = octstr_search(wml_source, octstr_imm(entity_nbsp), pos)) >= 0) { temp = octstr_create(nbsp); while (pos >= 0) { octstr_delete(wml_source, pos, strlen(entity_nbsp)); octstr_insert(wml_source, temp, pos); pos = octstr_search(wml_source, octstr_imm(entity_nbsp), pos); } octstr_destroy(temp); } pos = 0; if ((pos = octstr_search(wml_source, octstr_imm(entity_shy), pos)) >= 0) { temp = octstr_create(shy); while (pos >= 0) { octstr_delete(wml_source, pos, strlen(entity_shy)); octstr_insert(wml_source, temp, pos); pos = octstr_search(wml_source, octstr_imm(entity_shy), pos); } octstr_destroy(temp); } }/* * wml_binary_create - reserves memory for the wml_binary_t and sets the * fields to zeros and NULLs. */static wml_binary_t *wml_binary_create(void){ wml_binary_t *wbxml; wbxml = gw_malloc(sizeof(wml_binary_t)); wbxml->wbxml_version = 0x00; wbxml->wml_public_id = 0x00; wbxml->character_set = 0x00; wbxml->string_table_length = 0x00; wbxml->string_table = list_create(); wbxml->wbxml_string = octstr_create(""); return wbxml;}/* * wml_binary_destroy - frees the memory allocated for the wml_binary_t. */static void wml_binary_destroy(wml_binary_t *wbxml){ if (wbxml != NULL) { list_destroy(wbxml->string_table, NULL); octstr_destroy(wbxml->wbxml_string); gw_free(wbxml); }}/* * wml_binary_output - outputs all the fiels of wml_binary_t into ostr. */static void wml_binary_output(Octstr *ostr, wml_binary_t *wbxml){ octstr_append_char(ostr, wbxml->wbxml_version); octstr_append_char(ostr, wbxml->wml_public_id); octstr_append_uintvar(ostr, wbxml->character_set); octstr_append_uintvar(ostr, wbxml->string_table_length); if (wbxml->string_table_length > 0) string_table_output(ostr, &wbxml); octstr_insert(ostr, wbxml->wbxml_string, octstr_len(ostr));}/* * output_st_char - output a character into wbxml_string. * Returns 0 for success, -1 for error. */static void output_st_char(int byte, wml_binary_t **wbxml){ octstr_append_char((*wbxml)->wbxml_string, byte);}/* * output_st_octet_string - output an octet string into wbxml. * Returns 0 for success, -1 for an error. No conversions. */static void output_st_octet_string(Octstr *ostr, wml_binary_t **wbxml){ octstr_insert((*wbxml)->wbxml_string, ostr, octstr_len((*wbxml)->wbxml_string));}/* * output_variable - output a variable reference into the string table. */static void output_variable(Octstr *variable, Octstr **output, var_esc_t escaped, wml_binary_t **wbxml){ switch (escaped) { case ESC: octstr_append_char(*output, WBXML_EXT_T_0); break; case UNESC: octstr_append_char(*output, WBXML_EXT_T_1); break; default: octstr_append_char(*output, WBXML_EXT_T_2); break; } octstr_append_uintvar(*output, string_table_add(variable, wbxml));}/* * hash_create - allocates memory for a 2 field hash table node. */static wml_hash_t *hash_create(char *text, unsigned char token){ wml_hash_t *table_node; table_node = gw_malloc(sizeof(wml_hash_t)); table_node->item = octstr_create(text); table_node->binary = token; return table_node;}/* * attribute_create - allocates memory for the attributes hash table node * that contains the attribute, the binary for it and a list of binary values * tied with the attribute. */static wml_attribute_t *attribute_create(void){ wml_attribute_t *attr; attr = gw_malloc(sizeof(wml_attribute_t)); attr->attribute = NULL; attr->binary = 0; attr->value_list = list_create(); return attr;}/* * attr_dict_construct - takes a table of attributes and their values and * inputs these into a dictionary. */static void attr_dict_construct(wml_table3_t *attributes, Dict *attr_dict){ int i = 0; wml_attribute_t *node = NULL; wml_hash_t *temp = NULL; node = attribute_create(); do { if (node->attribute == NULL) node->attribute = octstr_create(attributes[i].text1); else if (strcmp(attributes[i].text1, attributes[i-1].text1) != 0) { dict_put(attr_dict, node->attribute, node); node = attribute_create(); node->attribute = octstr_create(attributes[i].text1); } if (attributes[i].text2 == NULL) node->binary = attributes[i].token; else { temp = hash_create(attributes[i].text2, attributes[i].token); list_append(node->value_list, (void *)temp); } i++; } while (attributes[i].text1 != NULL); dict_put(attr_dict, node->attribute, node);}/* * hash_destroy - deallocates memory of a 2 field hash table node. */static void hash_destroy(void *p){ wml_hash_t *node; if (p == NULL) return; node = p; octstr_destroy(node->item); gw_free(node);}/* * attribute_destroy - deallocates memory of a attribute hash table node. */static void attribute_destroy(void *p){ wml_attribute_t *node; if (p == NULL) return; node = p; octstr_destroy(node->attribute); list_destroy(node->value_list, hash_destroy); gw_free(node);}/* * hash_cmp - compares pattern against item and if the pattern matches the * item returns 1, else 0. */static int hash_cmp(void *item, void *pattern){ int ret = 0; gw_assert(item != NULL && pattern != NULL); gw_assert(((wml_hash_t *)item)->item != NULL); if (octstr_search(pattern, ((wml_hash_t *)item)->item, 0) == 0) ret = 1; return ret;}/* * check_do_elements - a helper function for parse_element for checking if a * card or template element has two or more do elements of the same name. * Returns 0 for OK and -1 for an error (== do elements with same name found). */static int check_do_elements(xmlNodePtr node){ xmlNodePtr child; int i, status = 0; Octstr *name = NULL; List *name_list = NULL; name_list = list_create(); if ((child = node->children) != NULL) { while (child != NULL) { if (strcmp(child->name, "do") == 0) { name = get_do_element_name(child); if (name == NULL) { error(0, "WML compiler: no name or type in a do element"); return -1; } for (i = 0; i < list_len(name_list); i ++) if (octstr_compare(list_get(name_list, i), name) == 0) { octstr_destroy(name); status = -1; break; } if (status != -1) list_append(name_list, name); else break; } child = child->next; } } list_destroy(name_list, octstr_destroy_item); return status;}/* * check_variable_name - checks the name for variable in a setvar element. * If the name has syntax error, -1 is returned, else 0. */static var_esc_t check_variable_name(xmlNodePtr node){ Octstr *name = NULL; xmlAttrPtr attr; var_esc_t ret = FAILED; if ((attr = node->properties) != NULL) { while (attr != NULL) { if (strcmp(attr->name, "name") == 0) { name = create_octstr_from_node(attr->children); break; } attr = attr->next; } } if (attr == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -