// ----------------------------------------------------------------------------- // Reads a colour configuration from text data [mc] // ----------------------------------------------------------------------------- bool ColourConfiguration::readConfiguration(MemChunk& mc) { // Parse text Parser parser; parser.parseText(mc); // Get 'colours' block auto colours = parser.parseTreeRoot()->childPTN("colours"); if (colours) { // Read all colour definitions for (unsigned a = 0; a < colours->nChildren(); a++) { auto def = colours->childPTN(a); // Read properties for (unsigned b = 0; b < def->nChildren(); b++) { auto prop = def->childPTN(b); auto& col = cc_colours[def->name()]; col.exists = true; // Colour name if (prop->name() == "name") col.name = prop->stringValue(); // Colour group (for config ui) else if (prop->name() == "group") col.group = prop->stringValue(); // Colour else if (prop->name() == "rgb") col.colour.set(prop->intValue(0), prop->intValue(1), prop->intValue(2)); // Alpha else if (prop->name() == "alpha") col.colour.a = prop->intValue(); // Additive else if (prop->name() == "additive") col.blend_additive = prop->boolValue(); else Log::warning(fmt::format("Unknown colour definition property \"{}\"", prop->name())); } } } // Get 'theme' block auto theme = parser.parseTreeRoot()->childPTN("theme"); if (theme) { // Read all theme definitions for (unsigned a = 0; a < theme->nChildren(); a++) { auto prop = theme->childPTN(a); if (prop->name() == "line_hilight_width") line_hilight_width = prop->floatValue(); else if (prop->name() == "line_selection_width") line_selection_width = prop->floatValue(); else if (prop->name() == "flat_alpha") flat_alpha = prop->floatValue(); else Log::warning(fmt::format("Unknown theme property \"{}\"", prop->name())); } } return true; }
// ----------------------------------------------------------------------------- // Reads in a text definition of a language. See slade.pk3 for // formatting examples // ----------------------------------------------------------------------------- bool TextLanguage::readLanguageDefinition(MemChunk& mc, string_view source) { Tokenizer tz; // Open the given text data if (!tz.openMem(mc, source)) { Log::warning("Unable to open language definition {}", source); return false; } // Parse the definition text ParseTreeNode root; if (!root.parse(tz)) return false; // Get parsed data for (unsigned a = 0; a < root.nChildren(); a++) { auto node = root.childPTN(a); // Create language auto lang = new TextLanguage(node->name()); // Check for inheritance if (!node->inherit().empty()) { auto inherit = fromId(node->inherit()); if (inherit) inherit->copyTo(lang); else Log::warning("Warning: Language {} inherits from undefined language {}", node->name(), node->inherit()); } // Parse language info for (unsigned c = 0; c < node->nChildren(); c++) { auto child = node->childPTN(c); auto pn_lower = StrUtil::lower(child->name()); // Language name if (pn_lower == "name") lang->setName(child->stringValue()); // Comment begin else if (pn_lower == "comment_begin") { lang->setCommentBeginList(child->stringValues()); } // Comment end else if (pn_lower == "comment_end") { lang->setCommentEndList(child->stringValues()); } // Line comment else if (pn_lower == "comment_line") { lang->setLineCommentList(child->stringValues()); } // Preprocessor else if (pn_lower == "preprocessor") lang->setPreprocessor(child->stringValue()); // Case sensitive else if (pn_lower == "case_sensitive") lang->setCaseSensitive(child->boolValue()); // Doc comment else if (pn_lower == "comment_doc") lang->setDocComment(child->stringValue()); // Keyword lookup link else if (pn_lower == "keyword_link") lang->word_lists_[WordType::Keyword].lookup_url = child->stringValue(); // Constant lookup link else if (pn_lower == "constant_link") lang->word_lists_[WordType::Constant].lookup_url = child->stringValue(); // Function lookup link else if (pn_lower == "function_link") lang->f_lookup_url_ = child->stringValue(); // Jump blocks else if (pn_lower == "blocks") { for (unsigned v = 0; v < child->nValues(); v++) lang->jump_blocks_.push_back(child->stringValue(v)); } else if (pn_lower == "blocks_ignore") { for (unsigned v = 0; v < child->nValues(); v++) lang->jb_ignore_.push_back(child->stringValue(v)); } // Block begin else if (pn_lower == "block_begin") lang->block_begin_ = child->stringValue(); // Block end else if (pn_lower == "block_end") lang->block_end_ = child->stringValue(); // Preprocessor block begin else if (pn_lower == "pp_block_begin") { for (unsigned v = 0; v < child->nValues(); v++) lang->pp_block_begin_.push_back(child->stringValue(v)); } // Preprocessor block end else if (pn_lower == "pp_block_end") { for (unsigned v = 0; v < child->nValues(); v++) lang->pp_block_end_.push_back(child->stringValue(v)); } // Word block begin else if (pn_lower == "word_block_begin") { for (unsigned v = 0; v < child->nValues(); v++) lang->word_block_begin_.push_back(child->stringValue(v)); } // Word block end else if (pn_lower == "word_block_end") { for (unsigned v = 0; v < child->nValues(); v++) lang->word_block_end_.push_back(child->stringValue(v)); } // Keywords else if (pn_lower == "keywords") { // Go through values for (unsigned v = 0; v < child->nValues(); v++) { auto val = child->stringValue(v); // Check for '$override' if (StrUtil::equalCI(val, "$override")) { // Clear any inherited keywords lang->clearWordList(WordType::Keyword); } // Not a special symbol, add as keyword else lang->addWord(WordType::Keyword, val); } } // Constants else if (pn_lower == "constants") { // Go through values for (unsigned v = 0; v < child->nValues(); v++) { auto val = child->stringValue(v); // Check for '$override' if (StrUtil::equalCI(val, "$override")) { // Clear any inherited constants lang->clearWordList(WordType::Constant); } // Not a special symbol, add as constant else lang->addWord(WordType::Constant, val); } } // Types else if (pn_lower == "types") { // Go through values for (unsigned v = 0; v < child->nValues(); v++) { auto val = child->stringValue(v); // Check for '$override' if (StrUtil::equalCI(val, "$override")) { // Clear any inherited constants lang->clearWordList(WordType::Type); } // Not a special symbol, add as constant else lang->addWord(WordType::Type, val); } } // Properties else if (pn_lower == "properties") { // Go through values for (unsigned v = 0; v < child->nValues(); v++) { auto val = child->stringValue(v); // Check for '$override' if (StrUtil::equalCI(val, "$override")) { // Clear any inherited constants lang->clearWordList(WordType::Property); } // Not a special symbol, add as constant else lang->addWord(WordType::Property, val); } } // Functions else if (pn_lower == "functions") { bool lang_has_void = lang->isWord(Keyword, "void") || lang->isWord(Type, "void"); if (lang->id_ != "zscript") { // Go through children (functions) for (unsigned f = 0; f < child->nChildren(); f++) { auto child_func = child->childPTN(f); string params; // Simple definition if (child_func->nChildren() == 0) { if (child_func->stringValue(0).empty()) { if (lang_has_void) params = "void"; else params = ""; } else { params = child_func->stringValue(0); } // Add function lang->addFunction( child_func->name(), params, "", "", !StrUtil::contains(child_func->name(), '.'), child_func->type()); // Add args for (unsigned v = 1; v < child_func->nValues(); v++) lang->addFunction(child_func->name(), child_func->stringValue(v)); } // Full definition else { string name = child_func->name(); vector<string> args; string desc; string deprecated; for (unsigned p = 0; p < child_func->nChildren(); p++) { auto child_prop = child_func->childPTN(p); if (child_prop->name() == "args") { for (unsigned v = 0; v < child_prop->nValues(); v++) args.push_back(child_prop->stringValue(v)); } else if (child_prop->name() == "description") desc = child_prop->stringValue(); else if (child_prop->name() == "deprecated") deprecated = child_prop->stringValue(); } if (args.empty() && lang_has_void) args.emplace_back("void"); for (unsigned as = 0; as < args.size(); as++) lang->addFunction(name, args[as], desc, deprecated, as == 0, child_func->type()); } } } // ZScript function info which cannot be parsed from (g)zdoom.pk3 else { ZFuncExProp ex_prop; for (unsigned f = 0; f < child->nChildren(); f++) { auto child_func = child->childPTN(f); for (unsigned p = 0; p < child_func->nChildren(); ++p) { auto child_prop = child_func->childPTN(p); if (child_prop->name() == "description") ex_prop.description = child_prop->stringValue(); else if (child_prop->name() == "deprecated_f") ex_prop.deprecated_f = child_prop->stringValue(); } lang->zfuncs_ex_props_.emplace(child_func->name(), ex_prop); } } } } } return true; }