⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wml_compiler.c

📁 The Kannel Open Source WAP and SMS gateway works as both an SMS gateway, for implementing keyword b
💻 C
📖 第 1 页 / 共 4 页
字号:
    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[] = "&nbsp;";    static char entity_shy[] = "&shy;";    static char nbsp[] = "&#160;";    static char shy[] = "&#173;";    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 + -