private void ensure_gresource_to_file_map() { // map gresource paths to real file names if (gresource_to_file_map != null) { return; } gresource_to_file_map = new Dictionary <string, string>(); foreach (var gresource in context.gresources) { if (!File.Exists(gresource)) { Report.error(null, "GResources file `%s' does not exist".printf(gresource)); continue; } MarkupReader reader = new MarkupReader(gresource); int state = 0; string prefix = null; string alias = null; MarkupTokenType current_token = reader.read_token(); while (current_token != MarkupTokenType.EOF) { if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "gresource") { prefix = reader.get_attribute("prefix"); } else if (current_token == MarkupTokenType.START_ELEMENT && reader.name == "file") { alias = reader.get_attribute("alias"); state = 1; } else if (state == 1 && current_token == MarkupTokenType.TEXT) { var name = reader.content; var filename = context.get_gresource_path(gresource, name); if (alias != null) { gresource_to_file_map[Path.build_filename(prefix, alias)] = filename; } gresource_to_file_map[Path.build_filename(prefix, name)] = filename; state = 0; } current_token = reader.read_token(); } } }
public static string ToString(this MarkupTokenType @this) { switch (@this) { case MarkupTokenType.START_ELEMENT: return("start element"); case MarkupTokenType.END_ELEMENT: return("end element"); case MarkupTokenType.TEXT: return("text"); case MarkupTokenType.EOF: return("end of file"); default: return("unknown token type"); } }
private void process_current_ui_resource(string ui_resource, CodeNode node) { /* Scan a single gtkbuilder file for signal handlers in <object> elements, * and save an handler string -> Vala.Signal mapping for each of them */ ensure_cclass_to_vala_map(); ensure_gresource_to_file_map(); current_handler_to_signal_map = null; current_child_to_class_map = null; var ui_file = gresource_to_file_map[ui_resource]; if (ui_file == null || !File.Exists(ui_file)) { node.error = true; Report.error(node.source_reference, "UI resource not found: `%s'. Please make sure to specify the proper GResources xml files with --gresources and alternative search locations with --gresourcesdir.".printf(ui_resource)); return; } current_handler_to_signal_map = new Dictionary <string, Signal>(); current_child_to_class_map = new Dictionary <string, Class>(); MarkupReader reader = new MarkupReader(ui_file); Class current_class = null; bool template_tag_found = false; MarkupTokenType current_token = reader.read_token(); while (current_token != MarkupTokenType.EOF) { if (current_token == MarkupTokenType.START_ELEMENT && (reader.name == "template" || reader.name == "object")) { if (reader.name == "template") { template_tag_found = true; } var class_name = reader.get_attribute("class"); if (class_name != null) { current_class = cclass_to_vala_map[class_name]; var child_name = reader.get_attribute("id"); if (child_name != null) { current_child_to_class_map[child_name] = current_class; } } } else if (current_class != null && current_token == MarkupTokenType.START_ELEMENT && reader.name == "signal") { var signal_name = reader.get_attribute("name"); var handler_name = reader.get_attribute("handler"); if (current_class != null) { if (signal_name == null || handler_name == null) { Report.error(node.source_reference, "Invalid signal in ui file `%s'".printf(ui_file)); current_token = reader.read_token(); continue; } var sep_idx = signal_name.IndexOf("::"); if (sep_idx >= 0) { // detailed signal, we don't care about the detail signal_name = signal_name.Substring(0, sep_idx); } var sig = SemanticAnalyzer.symbol_lookup_inherited(current_class, signal_name.Replace("-", "_")) as Signal; if (sig != null) { current_handler_to_signal_map[handler_name] = sig; } } } current_token = reader.read_token(); } if (!template_tag_found) { Report.error(node.source_reference, "ui resource `%s' does not describe a valid composite template".printf(ui_resource)); } }
public MarkupTokenType read_token(out SourceLocation token_begin, out SourceLocation token_end) { attributes.Clear(); if (empty_element) { empty_element = false; token_begin = SourceLocation(begin, line, column); token_end = SourceLocation(begin, line, column); return(MarkupTokenType.END_ELEMENT); } space(); MarkupTokenType type = MarkupTokenType.NONE; char * begin = current; token_begin = SourceLocation(begin, line, column); if (current >= end) { type = MarkupTokenType.EOF; } else if (current[0] == '<') { current++; if (current >= end) { // error } else if (current[0] == '?') { // processing instruction } else if (current[0] == '!') { // comment or doctype current++; if (current < end - 1 && current[0] == '-' && current[1] == '-') { // comment current += 2; while (current < end - 2) { if (current[0] == '-' && current[1] == '-' && current[2] == '>') { // end of comment current += 3; break; } else if (current[0] == '\n') { line++; column = 0; } current++; } // ignore comment, read next token return(read_token(out token_begin, out token_end)); } } else if (current[0] == '/') { type = MarkupTokenType.END_ELEMENT; current++; name = read_name(); if (current >= end || current[0] != '>') { // error } current++; } else { type = MarkupTokenType.START_ELEMENT; name = read_name(); space(); while (current < end && current[0] != '>' && current[0] != '/') { string attr_name = read_name(); if (current >= end || current[0] != '=') { // error } current++; if (current >= end || current[0] != '"' || current[0] != '\'') { // error } char quote = current[0]; current++; string attr_value = text(quote, false); if (current >= end || current[0] != quote) { // error } current++; attributes[attr_name] = attr_value; space(); } if (current[0] == '/') { empty_element = true; current++; space(); } else { empty_element = false; } if (current >= end || current[0] != '>') { // error } current++; } } else { space(); if (current[0] != '<') { content = text('<', true); } else { // no text // read next token return(read_token(out token_begin, out token_end)); } type = MarkupTokenType.TEXT; } token_end = new SourceLocation(current, line, column - 1); return(type); }