示例#1
0
ast_expression *fold_constgen_string(fold_t *fold, const char *str, bool translate) {
    hash_table_t *table = (translate) ? fold->imm_string_untranslate : fold->imm_string_dotranslate;
    ast_value    *out   = NULL;
    size_t        hash  = util_hthash(table, str);

    if ((out = (ast_value*)util_htgeth(table, str, hash)))
        return (ast_expression*)out;

    if (translate) {
        char name[32];
        util_snprintf(name, sizeof(name), "dotranslate_%lu", (unsigned long)(fold->parser->translated++));
        out                    = ast_value_new(parser_ctx(fold->parser), name, TYPE_STRING);
        out->expression.flags |= AST_FLAG_INCLUDE_DEF; /* def needs to be included for translatables */
    } else
        out                    = ast_value_new(fold_ctx(fold), "#IMMEDIATE", TYPE_STRING);

    out->cvq              = CV_CONST;
    out->hasvalue         = true;
    out->isimm            = true;
    out->constval.vstring = parser_strdup(str);

    vec_push(fold->imm_string, out);
    util_htseth(table, str, hash, out);

    return (ast_expression*)out;
}
示例#2
0
/**
 * Initializes a configuration element. Reports an error if memory allocation fails.
 * 
 * @param context the parser context
 * @param ce the configuration element to be initialized
 * @param name the element name
 * @param atts the element attributes
 * @param parent the parent element
 */
static void init_cfg_element(ploader_context_t *plcontext, cp_cfg_element_t *ce,
	const XML_Char *name, const XML_Char * const *atts, cp_cfg_element_t *parent) {
	
	// Initialize the configuration element 
	memset(ce, 0, sizeof(cp_cfg_element_t));
	ce->name = parser_strdup(plcontext, name);
	ce->atts = parser_attsdup(plcontext, atts, &(ce->num_atts));
	ce->value = NULL;
	plcontext->value = NULL;
	plcontext->value_size = 0;
	plcontext->value_length = 0;
	ce->parent = parent;
	ce->children = NULL;	
}
示例#3
0
/**
 * Processes the start of element events while parsing.
 * 
 * @param userData the parsing context
 * @param name the element name
 * @param atts the element attributes
 */
static void CP_XMLCALL start_element_handler(
	void *userData, const XML_Char *name, const XML_Char **atts) {
	static const XML_Char * const req_plugin_atts[] = { "id", NULL };
	static const XML_Char * const opt_plugin_atts[] = { "name", "version", "provider-name", NULL };
	static const XML_Char * const req_bwcompatibility_atts[] = { NULL };
	static const XML_Char * const opt_bwcompatibility_atts[] = { "abi", "api", NULL };
	static const XML_Char * const req_cpluff_atts[] = { "version", NULL };
	static const XML_Char * const opt_cpluff_atts[] = { NULL };
	static const XML_Char * const req_import_atts[] = { "plugin", NULL };
	static const XML_Char * const opt_import_atts[] = { "version", "optional", NULL };
	static const XML_Char * const req_runtime_atts[] = { "library", NULL };
	static const XML_Char * const opt_runtime_atts[] = { "funcs", NULL };
	static const XML_Char * const req_ext_point_atts[] = { "id", NULL };
	static const XML_Char * const opt_ext_point_atts[] = { "name", "schema", NULL };
	static const XML_Char * const req_extension_atts[] = { "point", NULL };
	//static const XML_Char * const opt_extension_atts[] = { "id", "name", NULL };
	ploader_context_t *plcontext = userData;
	unsigned int i;

	// Process element start 
	switch (plcontext->state) {

		case PARSER_BEGIN:
			if (!strcmp(name, "plugin")) {
				plcontext->state = PARSER_PLUGIN;
				if (!check_attributes(plcontext, name, atts,
						req_plugin_atts, opt_plugin_atts)) {
					break;
				}
				for (i = 0; atts[i] != NULL; i += 2) {
					if (!strcmp(atts[i], "name")) {
						plcontext->plugin->name
							= parser_strdup(plcontext, atts[i+1]);
					} else if (!strcmp(atts[i], "id")) {
						plcontext->plugin->identifier
							= parser_strdup(plcontext, atts[i+1]);
					} else if (!strcmp(atts[i], "version")) {
						plcontext->plugin->version
							= parser_strdup(plcontext, atts[i+1]);
					} else if (!strcmp(atts[i], "provider-name")) {
						plcontext->plugin->provider_name
							= parser_strdup(plcontext, atts[i+1]);
					} else if(!strcmp(atts[i],"url")){
						plcontext->plugin->url = parser_strdup(plcontext, atts[i+1]);
					} else if(!strcmp(atts[i],"resourcetype")){
						plcontext->plugin->resourcetype = parser_strdup(plcontext, atts[i+1]);
					}
				}
			} else {
				unexpected_element(plcontext, name);
			}
			break;

		case PARSER_PLUGIN:
			if (!strcmp(name, "backwards-compatibility")) {
				if (check_attributes(plcontext, name, atts,
						req_bwcompatibility_atts, opt_bwcompatibility_atts)) {
					for (i = 0; atts[i] != NULL; i += 2) {
						if (!strcmp(atts[i], "abi")) {
							plcontext->plugin->abi_bw_compatibility = parser_strdup(plcontext, atts[i+1]);
						} else if (!strcmp(atts[i], "api")) {
							plcontext->plugin->api_bw_compatibility = parser_strdup(plcontext, atts[i+1]);
						}
					}
				}
			} else if (!strcmp(name, "requires")) {
				plcontext->state = PARSER_REQUIRES;
			} else if (!strcmp(name, "runtime")) {
				if (check_attributes(plcontext, name, atts,
						req_runtime_atts, opt_runtime_atts)) {
					for (i = 0; atts[i] != NULL; i += 2) {
						if (!strcmp(atts[i], "library")) {
							plcontext->plugin->runtime_lib_name
								= parser_strdup(plcontext, atts[i+1]);
						} else if (!strcmp(atts[i], "funcs")) {
							plcontext->plugin->runtime_funcs_symbol
								= parser_strdup(plcontext, atts[i+1]);
						}
					}
				}
			} else if (!strcmp(name, "extension-point")) {
				if (check_attributes(plcontext, name, atts,
						req_ext_point_atts, opt_ext_point_atts)) {
					cp_ext_point_t *ext_point;
					
					// Allocate space for extension points, if necessary 
					if (plcontext->plugin->num_ext_points == plcontext->ext_points_size) {
						cp_ext_point_t *nep;
						size_t ns;
						
						if (plcontext->ext_points_size == 0) {
							ns = 4;
						} else {
							ns = plcontext->ext_points_size * 2;
						}
						if ((nep = realloc(plcontext->plugin->ext_points,
								ns * sizeof(cp_ext_point_t))) == NULL) {
							resource_error(plcontext);
							break;
						}
						plcontext->plugin->ext_points = nep;
						plcontext->ext_points_size = ns;
					}
					
					// Parse extension point specification 
					ext_point = plcontext->plugin->ext_points
						+ plcontext->plugin->num_ext_points;
					memset(ext_point, 0, sizeof(cp_ext_point_t));
					ext_point->plugin = plcontext->plugin;
					ext_point->name = NULL;
					ext_point->local_id = NULL;
					ext_point->identifier = NULL;
					ext_point->schema_path = NULL;
					for (i = 0; atts[i] != NULL; i += 2) {
						if (!strcmp(atts[i], "name")) {
							ext_point->name
								= parser_strdup(plcontext, atts[i+1]);
						} else if (!strcmp(atts[i], "id")) {
							ext_point->local_id
								= parser_strdup(plcontext, atts[i+1]);
							ext_point->identifier
								= parser_strscat(plcontext,
									plcontext->plugin->identifier, ".", atts[i+1], NULL);
						} else if (!strcmp(atts[i], "schema")) {
							ext_point->schema_path
								= parser_strdup(plcontext, atts[i+1]);
						}
					}
					plcontext->plugin->num_ext_points++;
					
				}
			} else if (!(strcmp(name, "extension"))) {
				plcontext->state = PARSER_EXTENSION;
				plcontext->depth = 0;
				if (check_req_attributes(
					plcontext, name, atts, req_extension_atts)) {
					cp_extension_t *extension;
				
					// Allocate space for extensions, if necessary 
					if (plcontext->plugin->num_extensions == plcontext->extensions_size) {
						cp_extension_t *ne;
						size_t ns;
						
						if (plcontext->extensions_size == 0) {
							ns = 16;
						} else {
							ns = plcontext->extensions_size * 2;
						}
						if ((ne = realloc(plcontext->plugin->extensions,
								ns * sizeof(cp_extension_t))) == NULL) {
							resource_error(plcontext);
							break;
						}
						plcontext->plugin->extensions = ne;
						plcontext->extensions_size = ns;
					}
					
					// Parse extension attributes 
					extension = plcontext->plugin->extensions
						+ plcontext->plugin->num_extensions;
					memset(extension, 0, sizeof(cp_extension_t));
					extension->plugin = plcontext->plugin;
					extension->name = NULL;
					extension->local_id = NULL;
					extension->identifier = NULL;
					extension->ext_point_id = NULL;
					extension->configuration = NULL;
					for (i = 0; atts[i] != NULL; i += 2) {
						if (!strcmp(atts[i], "point")) {
							extension->ext_point_id
								= parser_strdup(plcontext, atts[i+1]);
						} else if (!strcmp(atts[i], "id")) {
							extension->local_id
								= parser_strdup(plcontext, atts[i+1]);
							extension->identifier
								= parser_strscat(plcontext,
									plcontext->plugin->identifier, ".", atts[i+1], NULL);
						} else if (!strcmp(atts[i], "name")) {
							extension->name
								= parser_strdup(plcontext, atts[i+1]);
						}
					}
					plcontext->plugin->num_extensions++;
					
					// Initialize configuration parsing 
					if ((extension->configuration = plcontext->configuration
						= parser_malloc(plcontext, sizeof(cp_cfg_element_t))) != NULL) {
						init_cfg_element(plcontext, plcontext->configuration, name, atts, NULL);
					}
					XML_SetCharacterDataHandler(plcontext->parser, character_data_handler);
				}
			} else {
				unexpected_element(plcontext, name);
			}
			break;

		case PARSER_REQUIRES:
			if (!strcmp(name, "c-pluff")) {
				if (check_attributes(plcontext, name, atts,
						req_cpluff_atts, opt_cpluff_atts)) {
					for (i = 0; atts[i] != NULL; i += 2) {
						if (!strcmp(atts[i], "version")) {
							plcontext->plugin->req_cpluff_version = parser_strdup(plcontext, atts[i+1]);
						}
					}
				}
			} else if (!strcmp(name, "import")) {
				if (check_attributes(plcontext, name, atts,
						req_import_atts, opt_import_atts)) {
					cp_plugin_import_t *import = NULL;
				
					// Allocate space for imports, if necessary 
					if (plcontext->plugin->num_imports == plcontext->imports_size) {
						cp_plugin_import_t *ni;
						size_t ns;
					
						if (plcontext->imports_size == 0) {
							ns = 16;
						} else {
							ns = plcontext->imports_size * 2;
						}
						if ((ni = realloc(plcontext->plugin->imports,
								ns * sizeof(cp_plugin_import_t))) == NULL) {
							resource_error(plcontext);
							break;
						}
						plcontext->plugin->imports = ni;
						plcontext->imports_size = ns;
					}
				
					// Parse import specification 
					import = plcontext->plugin->imports
						+ plcontext->plugin->num_imports;
					memset(import, 0, sizeof(cp_plugin_import_t));
					import->plugin_id = NULL;
					import->version = NULL;
					for (i = 0; atts[i] != NULL; i += 2) {
						if (!strcmp(atts[i], "plugin")) {
							import->plugin_id
								= parser_strdup(plcontext, atts[i+1]);
						} else if (!strcmp(atts[i], "version")) {
							import->version = parser_strdup(plcontext, atts[i+1]);
						} else if (!strcmp(atts[i], "optional")) {
							if (!strcmp(atts[i+1], "true")
								|| !strcmp(atts[i+1], "1")) {
								import->optional = 1;
							} else if (strcmp(atts[i+1], "false")
								&& strcmp(atts[i+1], "0")) {
								descriptor_errorf(plcontext, 0, _("unknown boolean value: %s"), atts[i+1]);
							}
						}
					}
					plcontext->plugin->num_imports++;
				}
			} else {
				unexpected_element(plcontext, name);
			}
			break;

		case PARSER_EXTENSION:
			plcontext->depth++;
			if (plcontext->configuration != NULL && plcontext->skippedCEs == 0) {
				cp_cfg_element_t *ce;
				
				// Allocate more space for children, if necessary 
				if (plcontext->configuration->num_children == plcontext->configuration->index) {
					cp_cfg_element_t *nce;
					size_t ns;
						
					if (plcontext->configuration->index == 0) {
						ns = 16;
					} else {
						ns = plcontext->configuration->index * 2;
					}
					if ((nce = realloc(plcontext->configuration->children,
							ns * sizeof(cp_cfg_element_t))) == NULL) {
						plcontext->skippedCEs++;
						resource_error(plcontext);
						break;
					}
					plcontext->configuration->children = nce;
					plcontext->configuration->index = ns;
				}
				
				// Save possible value 
				if (plcontext->value != NULL) {
					plcontext->value[plcontext->value_length] = '\0';
					plcontext->configuration->value = plcontext->value;
				}
				
				ce = plcontext->configuration->children + plcontext->configuration->num_children;
				init_cfg_element(plcontext, ce, name, atts, plcontext->configuration);
				plcontext->configuration->num_children++;
				plcontext->configuration = ce;
			}
			break;
			
		case PARSER_UNKNOWN:
			plcontext->depth++;
			break;
		default:
			unexpected_element(plcontext, name);
			break;
	}
}