/****************************************************************************** * The copyright string is composed of three parts: * 1) A copyright notice, "Copyright ©" * 2) One or more years or year ranges, e.g., "2004,2006-2008" * 3) A rights reserved notice, "Apple Inc. All Rights Reserved." * We check the validity of the string by searching for both the copyright * notice and the rights reserved notice. If both are found, we then check that * the text between the two notices contains only valid years and year ranges. ******************************************************************************/ boolean_t kxld_validate_copyright_string(const char *str) { boolean_t result = FALSE; const char *copyright = NULL; const char *rights = NULL; char *date_str = NULL; u_long len = 0; copyright = kxld_strstr(str, kCopyrightToken); rights = kxld_strstr(str, kRightsToken); if (!copyright || !rights || copyright > rights) goto finish; str = copyright + const_strlen(kCopyrightToken); len = rights - str; date_str = kxld_alloc(len+1); if (!date_str) goto finish; strncpy(date_str, str, len); date_str[len] = '\0'; if (!dates_are_valid(date_str, len)) goto finish; result = TRUE; finish: if (date_str) kxld_free(date_str, len+1); return result; }
static auto calculate_checksum(const DataType& data, const char *prefix = nullptr) { auto encoder = ripemd160::encoder(); encoder.write((const char *)&data, sizeof(DataType)); if (prefix != nullptr) { encoder.write(prefix, const_strlen(prefix)); } return encoder.result()._hash[0]; }
static kern_return_t patch_vtables(KXLDKext *kext, KXLDDict *patched_vtables, const KXLDDict *defined_symbols) { kern_return_t rval = KERN_FAILURE; KXLDSymtabIterator iter; const KXLDSymtab *symtab = NULL; const KXLDSym *metaclass = NULL; KXLDSym *super_metaclass_pointer = NULL; KXLDSym *final_sym = NULL; KXLDVTable *vtable = NULL; KXLDVTable *super_vtable = NULL; char class_name[KXLD_MAX_NAME_LEN]; char super_class_name[KXLD_MAX_NAME_LEN]; char vtable_name[KXLD_MAX_NAME_LEN]; char super_vtable_name[KXLD_MAX_NAME_LEN]; char final_sym_name[KXLD_MAX_NAME_LEN]; char *demangled_name1 = NULL; char *demangled_name2 = NULL; size_t demangled_length1 = 0;; size_t demangled_length2 = 0; size_t len = 0; u_int nvtables = 0; u_int npatched = 0; u_int nprogress = 0; boolean_t failure = FALSE; check(kext); check(patched_vtables); symtab = kxld_object_get_symtab(kext->kext); rval = create_vtable_index(kext); require_noerr(rval, finish); /* Find each super meta class pointer symbol */ kxld_symtab_iterator_init(&iter, symtab, kxld_sym_is_super_metaclass_pointer, FALSE); nvtables = kxld_symtab_iterator_get_num_remaining(&iter); while (npatched < nvtables) { npatched = 0; nprogress = 0; kxld_symtab_iterator_reset(&iter); while((super_metaclass_pointer = kxld_symtab_iterator_get_next(&iter))) { /* Get the class name from the smc pointer */ rval = kxld_sym_get_class_name_from_super_metaclass_pointer( super_metaclass_pointer, class_name, sizeof(class_name)); require_noerr(rval, finish); /* Get the vtable name from the class name */ rval = kxld_sym_get_vtable_name_from_class_name(class_name, vtable_name, sizeof(vtable_name)); require_noerr(rval, finish); /* Get the vtable and make sure it hasn't been patched */ vtable = kxld_dict_find(&kext->vtable_index, vtable_name); require_action(vtable, finish, rval=KERN_FAILURE; kxld_log(kKxldLogPatching, kKxldLogErr, kKxldLogMissingVtable, vtable_name, class_name)); if (!vtable->is_patched) { /* Find the SMCP's meta class symbol */ metaclass = get_metaclass_symbol_from_super_meta_class_pointer_symbol( kext, super_metaclass_pointer); require_action(metaclass, finish, rval=KERN_FAILURE); /* Get the super class name from the super metaclass */ rval = kxld_sym_get_class_name_from_metaclass(metaclass, super_class_name, sizeof(super_class_name)); require_noerr(rval, finish); /* Get the super vtable name from the class name */ rval = kxld_sym_get_vtable_name_from_class_name(super_class_name, super_vtable_name, sizeof(super_vtable_name)); require_noerr(rval, finish); /* Get the super vtable if it's been patched */ super_vtable = kxld_dict_find(patched_vtables, super_vtable_name); if (failure) { const KXLDVTable *unpatched_super_vtable; unpatched_super_vtable = kxld_dict_find(&kext->vtable_index, super_vtable_name); /* If the parent's vtable hasn't been patched, warn that * this vtable is unpatchable because of the parent. */ if (!super_vtable) { kxld_log(kKxldLogPatching, kKxldLogErr, "The %s was not patched because its parent, " "the %s, was not %s.", kxld_demangle(vtable_name, &demangled_name1, &demangled_length1), kxld_demangle(super_vtable_name, &demangled_name2, &demangled_length2), (unpatched_super_vtable) ? "patchable" : "found"); } continue; } if (!super_vtable) continue; /* Get the final symbol's name from the super vtable */ rval = kxld_sym_get_final_sym_name_from_class_name(super_class_name, final_sym_name, sizeof(final_sym_name)); require_noerr(rval, finish); /* Verify that the final symbol does not exist. First check * all the externally defined symbols, then check locally. */ final_sym = kxld_dict_find(defined_symbols, final_sym_name); if (!final_sym) { final_sym = kxld_symtab_get_locally_defined_symbol_by_name( symtab, final_sym_name); } if (final_sym) { kxld_log(kKxldLogPatching, kKxldLogErr, "Class '%s' is a subclass of final class '%s'.", kxld_demangle(class_name, &demangled_name1, &demangled_length1), kxld_demangle(super_class_name, &demangled_name2, &demangled_length2)); continue; } /* Patch the class's vtable */ rval = kxld_vtable_patch(vtable, super_vtable, kext->kext); if (rval) continue; /* Add the class's vtable to the set of patched vtables */ rval = kxld_dict_insert(patched_vtables, vtable->name, vtable); require_noerr(rval, finish); /* Get the meta vtable name from the class name */ rval = kxld_sym_get_meta_vtable_name_from_class_name(class_name, vtable_name, sizeof(vtable_name)); require_noerr(rval, finish); /* Get the meta vtable. Whether or not it should exist has already * been tested in create_vtables(), so if it doesn't exist and we're * still running, we can safely skip it. */ vtable = kxld_dict_find(&kext->vtable_index, vtable_name); if (!vtable) { ++nprogress; ++npatched; continue; } require_action(!vtable->is_patched, finish, rval=KERN_FAILURE); /* There is no way to look up a metaclass vtable at runtime, but * we know that every class's metaclass inherits directly from * OSMetaClass, so we just hardcode that vtable name here. */ len = strlcpy(super_vtable_name, kOSMetaClassVTableName, sizeof(super_vtable_name)); require_action(len == const_strlen(kOSMetaClassVTableName), finish, rval=KERN_FAILURE); /* Get the super meta vtable */ super_vtable = kxld_dict_find(patched_vtables, super_vtable_name); require_action(super_vtable && super_vtable->is_patched, finish, rval=KERN_FAILURE); /* Patch the meta class's vtable */ rval = kxld_vtable_patch(vtable, super_vtable, kext->kext); require_noerr(rval, finish); /* Add the MetaClass's vtable to the set of patched vtables */ rval = kxld_dict_insert(patched_vtables, vtable->name, vtable); require_noerr(rval, finish); ++nprogress; } ++npatched; } require_action(!failure, finish, rval=KERN_FAILURE); failure = (nprogress == 0); } rval = KERN_SUCCESS; finish: if (demangled_name1) kxld_free(demangled_name1, demangled_length1); if (demangled_name2) kxld_free(demangled_name2, demangled_length2); return rval; }
bool BindingsConfiguration::read(const std::string &file) { enum class InProgress { None, Command, Key }; bool result = true; std::ifstream f(file); if (!f.is_open()) return result; // shared variables InProgress in_progress = InProgress::None; size_t line_no = 0; std::string line; Binding::ActionChain actions; // def_key specific variables NC::Key::Type key = NC::Key::None; std::string strkey; // def_command specific variables bool cmd_immediate = false; std::string cmd_name; auto error = [&]() -> std::ostream & { std::cerr << file << ":" << line_no << ": error: "; in_progress = InProgress::None; result = false; return std::cerr; }; auto bind_in_progress = [&]() -> bool { if (in_progress == InProgress::Command) { if (!actions.empty()) { m_commands.insert(std::make_pair(cmd_name, Command(std::move(actions), cmd_immediate))); actions.clear(); return true; } else { error() << "definition of command '" << cmd_name << "' cannot be empty\n"; return false; } } else if (in_progress == InProgress::Key) { if (!actions.empty()) { bind(key, actions); actions.clear(); return true; } else { error() << "definition of key '" << strkey << "' cannot be empty\n"; return false; } } return true; }; const char def_command[] = "def_command"; const char def_key[] = "def_key"; while (!f.eof() && ++line_no) { getline(f, line); if (line.empty() || line[0] == '#') continue; // beginning of command definition if (!line.compare(0, const_strlen(def_command), def_command)) { if (!bind_in_progress()) break; in_progress = InProgress::Command; cmd_name = getEnclosedString(line, '"', '"', 0); if (cmd_name.empty()) { error() << "command must have non-empty name\n"; break; } if (m_commands.find(cmd_name) != m_commands.end()) { error() << "redefinition of command '" << cmd_name << "'\n"; break; } std::string cmd_type = getEnclosedString(line, '[', ']', 0); if (cmd_type == "immediate") cmd_immediate = true; else if (cmd_type == "deferred") cmd_immediate = false; else { error() << "invalid type of command: '" << cmd_type << "'\n"; break; } } // beginning of key definition else if (!line.compare(0, const_strlen(def_key), def_key)) { if (!bind_in_progress()) break; in_progress = InProgress::Key; strkey = getEnclosedString(line, '"', '"', 0); key = stringToKey(strkey); if (key == NC::Key::None) { error() << "invalid key: '" << strkey << "'\n"; break; } } else if (isspace(line[0])) // name of action to be bound { boost::trim(line); auto action = parseActionLine(line, error); if (action) actions.push_back(action); else { error() << "unknown action: '" << line << "'\n"; break; } } else { error() << "invalid line: '" << line << "'\n"; break; } } bind_in_progress(); f.close(); return result; }
static kern_return_t init_predicates(KXLDSym *sym, u_char n_type, u_short n_desc) { kern_return_t rval = KERN_FAILURE; check(sym); /* The type field is interpreted differently for normal symbols and stabs */ if (n_type & N_STAB) { sym->predicates.is_stab = 1; switch (n_type) { /* Labeled as NO_SECT in stab.h */ case N_GSYM: case N_FNAME: case N_RSYM: case N_SSYM: case N_LSYM: case N_BINCL: case N_PARAMS: case N_VERSION: case N_OLEVEL: case N_PSYM: case N_EINCL: case N_EXCL: case N_BCOMM: case N_LENG: case N_OPT: case N_OSO: sym->predicates.is_absolute = 1; break; /* Labeled as n_sect in stab.h */ case N_FUN: case N_STSYM: case N_LCSYM: case N_BNSYM: case N_SLINE: case N_ENSYM: case N_SO: case N_SOL: case N_ENTRY: case N_ECOMM: case N_ECOML: /* These are labeled as NO_SECT in stab.h, but they are actually * section-based on OS X. We must mark them as such so they get * relocated. */ case N_LBRAC: case N_RBRAC: sym->predicates.is_section = 1; break; default: rval = KERN_FAILURE; kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO "Invalid N_STAB symbol type: %u.", n_type); goto finish; } /* Don't care about the C++ predicates for stabs */ } else { u_char type = n_type & N_TYPE; /* Set the type-independent fields */ if ((n_type & N_EXT) && !(n_type & N_PEXT)) { sym->predicates.is_external = 1; } if (n_desc & N_DESC_DISCARDED) { sym->predicates.is_obsolete = 1; } if (n_desc & N_WEAK_REF) { sym->predicates.is_weak = 1; } if (n_desc & N_ARM_THUMB_DEF) { sym->predicates.is_thumb = 1; } /* The first set of type fields are mutually exclusive, so they can be * set with a switch statement. */ switch (type) { case N_ABS: sym->predicates.is_absolute = 1; break; case N_SECT: sym->predicates.is_section = 1; break; case N_UNDF: if (sym->base_addr) { sym->predicates.is_common = 1; } else { sym->predicates.is_undefined = 1; } break; case N_INDR: sym->predicates.is_indirect = 1; break; default: rval = KERN_FAILURE; kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO "Invalid symbol type: %u.", type); goto finish; } /* Set the C++-specific fields */ if ((0 == strncmp(CXX_PREFIX, sym->name, const_strlen(CXX_PREFIX)))) { sym->predicates.is_cxx = 1; if (0 == strncmp(sym->name, METACLASS_VTABLE_PREFIX, const_strlen(METACLASS_VTABLE_PREFIX))) { sym->predicates.is_meta_vtable = 1; } else if (0 == strncmp(sym->name, VTABLE_PREFIX, const_strlen(VTABLE_PREFIX))) { sym->predicates.is_class_vtable = 1; } else if (kxld_strstr(sym->name, RESERVED_TOKEN)) { sym->predicates.is_padslot = 1; } else if (kxld_strstr(sym->name, METACLASS_TOKEN)) { sym->predicates.is_metaclass = 1; } else if (kxld_strstr(sym->name, SUPER_METACLASS_POINTER_TOKEN)) { sym->predicates.is_super_metaclass_pointer = 1; } } else if (streq_safe(CXX_PURE_VIRTUAL, sym->name, sizeof(CXX_PURE_VIRTUAL))) { sym->predicates.is_cxx = 1; sym->predicates.is_pure_virtual = 1; } } rval = KERN_SUCCESS; finish: return rval; }
constexpr uint64_t combine(const char* s) { return combine(s, const_strlen(s)); }
constexpr std::size_t const_strlen(const char* s, std::size_t sz = 0) { return (sz == 8 || !s[sz] || s[sz] == ' ') ? sz : const_strlen(s, sz + 1); }
void CSAORI::exec(const CSAORIInput& in,CSAORIOutput& out) { if (in.args.size() == 0) { out.result_code = SAORIRESULT_OK; out.result = (CInetHelper::checkInternet()) ? L"1" : L"0"; } else { chttpc_conf *cc = new chttpc_conf; cc->url = SAORI_FUNC::UnicodeToMultiByte(in.args[0], CP_UTF8); if(strnicmp(cc->url.c_str(),"file:",5) == 0) { string_t fileW = checkAndModifyPathW(in.args[0].substr(5)); cc->url = "file:"+SAORI_FUNC::UnicodeToMultiByte(fileW, CP_UTF8); // cc->url = checkAndModifyPath(cc->url.substr(5)); cc->isLocalFile = true; } cc->codepage = in.codepage; cc->module_path = getModulePath(); UINT idx; for(UINT i = 1; i < in.args.size(); i++) { if((idx = in.args[i].find(L"codepage=")) != string::npos) { cc->charset = in.args[i].substr(idx + const_strlen(L"codepage=")); } else if((idx = in.args[i].find(L"save=")) != string::npos) { cc->saveOrginal = in.args[i].substr(idx + const_strlen(L"save=")); } else if((idx = in.args[i].find(L"saveUtf8=")) != string::npos) { cc->saveUtf8 = in.args[i].substr(idx + const_strlen(L"saveUtf8=")); } else if((idx = in.args[i].find(L"saveParsed=")) != string::npos) { cc->saveParsed = in.args[i].substr(idx + const_strlen(L"saveParsed=")); } else if((idx = in.args[i].find(L"start=")) != string::npos) { cc->searchStart = in.args[i].substr(idx + const_strlen(L"start=")); } else if((idx = in.args[i].find(L"end=")) != string::npos) { cc->searchEnd = in.args[i].substr(idx + const_strlen(L"end=")); } else if((idx = in.args[i].find(L"id=")) != string::npos) { cc->id = in.args[i].substr(idx + const_strlen(L"id=")); } else if((idx = in.args[i].find(L"hwnd=")) != string::npos) { cc->hwnd = reinterpret_cast<HWND>(_wtol(in.args[i].substr(idx + const_strlen(L"hwnd=")).c_str())); } else if((idx = in.args[i].find(L"strip")) != string::npos) { cc->isStripTag = true; } else if((idx = in.args[i].find(L"multiSearch")) != string::npos) { cc->isMultiSearch = true; } else if((idx = in.args[i].find(L"translate")) != string::npos) { cc->isTranslateTag = true; } else if((idx = in.args[i].find(L"noOutput")) != string::npos) { cc->isNoOutput = true; } else if((idx = in.args[i].find(L"removeTags=")) != string::npos) { string tags = SAORI_FUNC::UnicodeToMultiByte(in.args[i].substr(idx + const_strlen(L"removeTags="))); int cutAt; while( (cutAt = tags.find_first_of(",")) != string::npos ) { if(cutAt > 0) { cc->stripTags[tags.substr(0,cutAt)] = true; } tags = tags.substr(cutAt+1); } if(tags.length() > 0) { cc->stripTags[tags] = true; } } } if(cc->hwnd != NULL && !cc->id.empty()) { (new chttpcThread(cc))->create(); out.result_code = SAORIRESULT_NO_CONTENT; } else { wstring result; int crresult = chttpc_runner::run(cc, result); delete cc; out.result_code = crresult ? SAORIRESULT_INTERNAL_SERVER_ERROR : SAORIRESULT_OK; out.result = result; } } }
bool Satori::system_variable_operation(string key, string value, string* result) { // mapにしようよ。 if ( key == "喋り間隔" ) { talk_interval = zen2int(value); if ( talk_interval<3 ) talk_interval=0; // 3未満は喋らない // 喋りカウント初期化 int dist = static_cast<int>(talk_interval*(talk_interval_random/100.0)); talk_interval_count = ( dist==0 ) ? talk_interval : (talk_interval-dist)+(random(dist*2)); return true; } if ( key == "喋り間隔誤差" ) { talk_interval_random = zen2int(value); if ( talk_interval_random>100 ) talk_interval_random=100; if ( talk_interval_random<0 ) talk_interval_random=0; // 喋りカウント初期化 int dist = int(talk_interval*(talk_interval_random/100.0)); talk_interval_count = ( dist==0 ) ? talk_interval : (talk_interval-dist)+(random(dist*2)); return true; } if ( key =="見切れてても喋る" ) { is_call_ontalk_at_mikire= (value=="有効"); return true; } if ( key == "今回は喋らない" ) { return_empty=(value=="有効"); return true; } if ( key == "スクリプトの一番頭" ) { header_script = value; return true; } if ( key == "呼び出し回数制限" ) { m_nest_limit = zen2int(value); if ( m_nest_limit < 0 ) { m_nest_limit = 0; } return true; } if ( key == "ジャンプ回数制限" ) { m_jump_limit = zen2int(value); if ( m_jump_limit < 0 ) { m_jump_limit = 0; } return true; } if ( key == "スコープ切り換え時" ) { append_at_scope_change = zen2han(value); return true; } if ( key == "さくらスクリプトによるスコープ切り換え時" ) { append_at_scope_change_with_sakura_script = zen2han(value); return true; } if ( key == "トーク開始時" ) { append_at_talk_start = zen2han(value); return true; } if ( key == "トーク終了時" ) { append_at_talk_end = zen2han(value); return true; } if ( key == "選択肢開始時" ) { append_at_choice_start = zen2han(value); return true; } if ( key == "選択肢終了時" ) { append_at_choice_end = zen2han(value); return true; } if ( key == "会話時サーフェス戻し" || key == "会話時サーフィス戻し" ) { if ( value == "有効" ) { surface_restore_at_talk = SR_NORMAL; } else if ( value == "強制" ) { surface_restore_at_talk = SR_FORCE; } else { surface_restore_at_talk = SR_NONE; } return true; } if ( key == "今回は会話時サーフェス戻し" || key == "今回は会話時サーフィス戻し" ) { if ( value == "有効" ) { surface_restore_at_talk_onetime = SR_NORMAL; } else if ( value == "強制" ) { surface_restore_at_talk_onetime = SR_FORCE; } else { surface_restore_at_talk_onetime = SR_NONE; } return true; } if ( key == "自動アンカー" ) { if ( value == "有効" ) { auto_anchor_enable = true; auto_anchor_enable_onetime = auto_anchor_enable; } else { auto_anchor_enable = false; auto_anchor_enable_onetime = auto_anchor_enable; } return true; } if ( key == "今回は自動アンカー" ) { if ( value == "有効" ) { auto_anchor_enable_onetime = true; } else { auto_anchor_enable_onetime = false; } return true; } if ( compare_head(key, "サーフェス加算値") && aredigits(key.c_str() + const_strlen("サーフェス加算値")) ) { int n = zen2int(key.c_str() + const_strlen("サーフェス加算値")); surface_add_value[n]= zen2int(value); variables[string()+"デフォルトサーフェス"+itos(n)] = value; next_default_surface[n] = zen2int(value); if ( !is_speaked_anybody() ) default_surface[n]=next_default_surface[n]; return true; } if ( compare_head(key, "デフォルトサーフェス") && aredigits(key.c_str() + const_strlen("デフォルトサーフェス")) ) { int n = zen2int(key.c_str() + const_strlen("デフォルトサーフェス")); next_default_surface[n]= zen2int(value); if ( !is_speaked_anybody() ) default_surface[n]=next_default_surface[n]; return true; } if ( compare_head(key, "BalloonOffset") && aredigits(key.c_str() + const_strlen("BalloonOffset")) ) { int n = stoi(key.c_str() + const_strlen("BalloonOffset")); BalloonOffset[n] = value; validBalloonOffset[n] = true; return true; } if ( key == "トーク中のなでられ反応") { insert_nade_talk_at_other_talk= (value=="有効"); return true; } if ( key == "なでられ持続秒数") { nade_valid_time_initializer = zen2int(value); return true; } if ( key == "なでられ反応回数") { nade_sensitivity = zen2int(value); return true; } if ( key == "デバッグ" ) { fDebugMode = (value=="有効"); return true; } if ( key == "Log" ) { Sender::validate(value=="有効"); return true; } if ( key == "RequestLog" ) { fRequestLog = (value=="有効"); return true; } if ( key == "OperationLog" ) { fOperationLog = (value=="有効"); return true; } if ( key == "ResponseLog" ) { fResponseLog = (value=="有効"); return true; } if ( key == "自動挿入ウェイトの倍率" ) { rate_of_auto_insert_wait= zen2int(value); rate_of_auto_insert_wait = min(1000, max(0, rate_of_auto_insert_wait)); variables["自動挿入ウェイトの倍率"] = int2zen(rate_of_auto_insert_wait); return true; } if ( key == "自動挿入ウェイトタイプ" ) { if ( value == "一般" ) { type_of_auto_insert_wait = 2; variables["自動挿入ウェイトタイプ"] = "一般"; } else if ( value == "無効" ) { type_of_auto_insert_wait = 0; variables["自動挿入ウェイトタイプ"] = "無効"; } else /* if ( value == "里々" ) */ { type_of_auto_insert_wait = 1; variables["自動挿入ウェイトタイプ"] = "里々"; } return true; } if ( key == "辞書フォルダ" ) { strvec words; split(value, ",",dic_folder); reload_flag=true; return true; } if ( key == "セーブデータ暗号化" ) { fEncodeSavedata = (value=="有効"); return true; } if ( compare_head(key,"単語群「") && compare_tail(key,"」の重複回避") ) { variables.erase(key); words.setOC( string(key.c_str()+8, key.length()-8-12), value ); return true; } if ( compare_head(key,"文「") && compare_tail(key,"」の重複回避") ) { variables.erase(key); talks.setOC( string(key.c_str()+4, key.length()-4-12), value ); return true; } if ( key == "次のトーク" ) { variables.erase(key); int count=1; while ( reserved_talk.find(count) != reserved_talk.end() ) ++count; reserved_talk[count] = value; sender << "次回のランダムトークが「" << value << "」に予\x96\xf1されました。" << endl; return true; } if ( compare_head(key,"次から") && compare_tail(key,"回目のトーク") ) { variables.erase(key); int count = zen2int( string(key.c_str()+6, key.length()-6-12) ); if ( count<=0 ) { sender << "トーク予\x96\xf1、設定値がヘンです。" << endl; } else { while ( reserved_talk.find(count) != reserved_talk.end() ) ++count; reserved_talk[count] = value; sender << count << "回後のランダムトークが「" << value << "」に予\x96\xf1されました。" << endl; } return true; } if ( key=="トーク予\x96\xf1のキャンセル" ) { if ( value=="*" ) reserved_talk.clear(); else for (map<int, string>::iterator it=reserved_talk.begin(); it!=reserved_talk.end() ; ) if ( value == it->second ) reserved_talk.erase(it++); else ++it; return true; } if ( key == "SAORI引数の計算" ) { if (value=="有効") mSaoriArgumentCalcMode = SACM_ON; else if (value=="無効") mSaoriArgumentCalcMode = SACM_OFF; else mSaoriArgumentCalcMode = SACM_AUTO; return true; } if ( key == "辞書リロード" && value=="実行") { variables.erase(key); reload_flag=true; return true; } if ( key == "手動セーブ" && value=="実行") { variables.erase(key); if ( is_dic_loaded ) { this->Save(); } return true; } if ( key == "自動セーブ間隔" ) { mAutoSaveInterval = zen2int(value); mAutoSaveCurrentCount = mAutoSaveInterval; if ( mAutoSaveInterval > 0 ) sender << "" << itos(mAutoSaveInterval) << "秒間隔で自動セーブを行います。" << endl; else sender << "自動セーブは行いません。" << endl; return true; } if ( key == "全タイマ解除" && value=="実行") { variables.erase(key); for (strintmap::const_iterator i=timer.begin();i!=timer.end();++i) variables.erase(i->first + "タイマ"); timer.clear(); return true; } if ( key == "教わること" ) { variables.erase(key); teach_genre=value; if ( result != NULL ) *result += "\\![open,teachbox]"; return true; } if ( key.size()>6 && compare_tail(key, "タイマ") ) { string name(key.c_str(), strlen(key.c_str())-6); /*if ( sentences.find(name) == sentences.end() ) { result = string("※ タイマ終了時のジャンプ先 *")+name+" がありません ※"; // セーブデータ復帰時を考慮 } else */{ int sec = zen2int(value); if ( sec < 1 ) { variables.erase(key); if ( timer.find(name)!=timer.end() ) { timer.erase(name); sender << "タイマ「" << name << "」の予\x96\xf1がキャンセルされました。" << endl; } else sender << "タイマ「" << name << "」は元から予\x96\xf1されていません。" << endl; } else { timer[name] = sec; sender << "タイマ「" << name << "」が" << sec << "秒後に予\x96\xf1されました。" << endl; } } return true; } if ( key == "引数区切り追加" && value.size()>0 ) { variables.erase(key); mDelimiters.insert(value); return true; } if ( key == "引数区切り削除" && value.size()>0 ) { variables.erase(key); mDelimiters.erase(value); return true; } if ( compare_head(key, "Value") && aredigits(key.c_str() + 5) ) { variables.erase(key); if(value!=""){ mResponseMap[string()+"Reference"+key.substr(5)] = value; }else{ mResponseMap.erase(string()+"Reference"+key.substr(5)); } return true; } return false; }
bool Configuration::read(const std::vector<std::string> &config_paths, bool ignore_errors) { option_parser p; p.add<void>("visualizer_sample_multiplier", nullptr, "", [](std::string v) { if (!v.empty()) deprecated( "visualizer_sample_multiplier", 0.9, "visualizer scales automatically"); }); p.add<void>("progressbar_boldness", nullptr, "", [](std::string v) { if (!v.empty()) deprecated( "progressbar_boldness", 0.9, "use extended progressbar_color and progressbar_elapsed_color instead"); }); // keep the same order of variables as in configuration file p.add("ncmpcpp_directory", &ncmpcpp_directory, "~/.ncmpcpp/", adjust_directory); p.add("lyrics_directory", &lyrics_directory, "~/.lyrics/", adjust_directory); p.add<void>("mpd_host", nullptr, "localhost", [](std::string host) { expand_home(host); Mpd.SetHostname(host); }); p.add<void>("mpd_port", nullptr, "6600", [](std::string port) { Mpd.SetPort(verbose_lexical_cast<unsigned>(port)); }); p.add("mpd_music_dir", &mpd_music_dir, "~/music", adjust_directory); p.add("mpd_connection_timeout", &mpd_connection_timeout, "5"); p.add("mpd_crossfade_time", &crossfade_time, "5"); p.add("visualizer_fifo_path", &visualizer_fifo_path, "/tmp/mpd.fifo", adjust_path); p.add("visualizer_output_name", &visualizer_output_name, "Visualizer feed"); p.add("visualizer_in_stereo", &visualizer_in_stereo, "yes", yes_no); p.add("visualizer_sync_interval", &visualizer_sync_interval, "30", [](std::string v) { unsigned sync_interval = verbose_lexical_cast<unsigned>(v); lowerBoundCheck<unsigned>(sync_interval, 10); return boost::posix_time::seconds(sync_interval); }); p.add("visualizer_type", &visualizer_type, "wave"); p.add("visualizer_look", &visualizer_chars, "●▮", [](std::string s) { auto result = ToWString(std::move(s)); boundsCheck<std::wstring::size_type>(result.size(), 2, 2); return result; }); p.add("visualizer_color", &visualizer_colors, "blue, cyan, green, yellow, magenta, red", list_of<NC::FormattedColor>); p.add("system_encoding", &system_encoding, "", [](std::string encoding) { #ifdef HAVE_LANGINFO_H // try to autodetect system encoding if (encoding.empty()) { encoding = nl_langinfo(CODESET); if (encoding == "UTF-8") // mpd uses utf-8 by default so no need to convert encoding.clear(); } #endif // HAVE_LANGINFO_H return encoding; }); p.add("playlist_disable_highlight_delay", &playlist_disable_highlight_delay, "5", [](std::string v) { return boost::posix_time::seconds(verbose_lexical_cast<unsigned>(v)); }); p.add("message_delay_time", &message_delay_time, "5"); p.add("song_list_format", &song_list_format, "{%a - }{%t}|{$8%f$9}$R{$3(%l)$9}", [](std::string v) { return Format::parse(v); }); p.add("song_status_format", &song_status_format, "{{%a{ \"%b\"{ (%y)}} - }{%t}}|{%f}", [this](std::string v) { auto flags = Format::Flags::All ^ Format::Flags::OutputSwitch; // precompute wide format for status display song_status_wformat = Format::parse(ToWString(v), flags); return Format::parse(v, flags); }); p.add("song_library_format", &song_library_format, "{%n - }{%t}|{%f}", [](std::string v) { return Format::parse(v); }); p.add("alternative_header_first_line_format", &new_header_first_line, "$b$1$aqqu$/a$9 {%t}|{%f} $1$atqq$/a$9$/b", [](std::string v) { return Format::parse(ToWString(std::move(v)), Format::Flags::All ^ Format::Flags::OutputSwitch); }); p.add("alternative_header_second_line_format", &new_header_second_line, "{{$4$b%a$/b$9}{ - $7%b$9}{ ($4%y$9)}}|{%D}", [](std::string v) { return Format::parse(ToWString(std::move(v)), Format::Flags::All ^ Format::Flags::OutputSwitch); }); p.add("now_playing_prefix", &now_playing_prefix, "$b", [this](std::string v) { NC::Buffer result = buffer(v); now_playing_prefix_length = wideLength(ToWString(result.str())); return result; }); p.add("now_playing_suffix", &now_playing_suffix, "$/b", [this](std::string v) { NC::Buffer result = buffer(v); now_playing_suffix_length = wideLength(ToWString(result.str())); return result; }); p.add("browser_playlist_prefix", &browser_playlist_prefix, "$2playlist$9 ", buffer); p.add("selected_item_prefix", &selected_item_prefix, "$6", [this](std::string v) { NC::Buffer result = buffer(v); selected_item_prefix_length = wideLength(ToWString(result.str())); return result; }); p.add("selected_item_suffix", &selected_item_suffix, "$9", [this](std::string v) { NC::Buffer result = buffer(v); selected_item_suffix_length = wideLength(ToWString(result.str())); return result; }); p.add("modified_item_prefix", &modified_item_prefix, "$3>$9 ", buffer); p.add("song_window_title_format", &song_window_title_format, "{%a - }{%t}|{%f}", [](std::string v) { return Format::parse(v, Format::Flags::Tag); }); p.add("browser_sort_mode", &browser_sort_mode, "name"); p.add("browser_sort_format", &browser_sort_format, "{%a - }{%t}|{%f} {(%l)}", [](std::string v) { return Format::parse(v, Format::Flags::Tag); }); p.add("song_columns_list_format", &song_columns_mode_format, "(20)[]{a} (6f)[green]{NE} (50)[white]{t|f:Title} (20)[cyan]{b} (7f)[magenta]{l}", [this](std::string v) { columns = generate_columns(v); return columns_to_format(columns); }); p.add("execute_on_song_change", &execute_on_song_change, "", adjust_path); p.add("execute_on_player_state_change", &execute_on_player_state_change, "", adjust_path); p.add("playlist_show_mpd_host", &playlist_show_mpd_host, "no", yes_no); p.add("playlist_show_remaining_time", &playlist_show_remaining_time, "no", yes_no); p.add("playlist_shorten_total_times", &playlist_shorten_total_times, "no", yes_no); p.add("playlist_separate_albums", &playlist_separate_albums, "no", yes_no); p.add("playlist_display_mode", &playlist_display_mode, "columns"); p.add("browser_display_mode", &browser_display_mode, "classic"); p.add("search_engine_display_mode", &search_engine_display_mode, "classic"); p.add("playlist_editor_display_mode", &playlist_editor_display_mode, "classic"); p.add("discard_colors_if_item_is_selected", &discard_colors_if_item_is_selected, "yes", yes_no); p.add("show_duplicate_tags", &MPD::Song::ShowDuplicateTags, "yes", yes_no); p.add("incremental_seeking", &incremental_seeking, "yes", yes_no); p.add("seek_time", &seek_time, "1"); p.add("volume_change_step", &volume_change_step, "2"); p.add("autocenter_mode", &autocenter_mode, "no", yes_no); p.add("centered_cursor", ¢ered_cursor, "no", yes_no); p.add("progressbar_look", &progressbar, "=>", [](std::string v) { auto result = ToWString(std::move(v)); boundsCheck<std::wstring::size_type>(result.size(), 2, 3); // If two characters were specified, fill \0 as the third one. result.resize(3); return result; }); p.add("default_place_to_search_in", &search_in_db, "database", [](std::string v) { if (v == "database") return true; else if (v == "playlist") return false; else invalid_value(v); }); p.add("user_interface", &design, "classic"); p.add("data_fetching_delay", &data_fetching_delay, "yes", yes_no); p.add("media_library_primary_tag", &media_lib_primary_tag, "artist", [](std::string v) { if (v == "artist") return MPD_TAG_ARTIST; else if (v == "album_artist") return MPD_TAG_ALBUM_ARTIST; else if (v == "date") return MPD_TAG_DATE; else if (v == "genre") return MPD_TAG_GENRE; else if (v == "composer") return MPD_TAG_COMPOSER; else if (v == "performer") return MPD_TAG_PERFORMER; else invalid_value(v); }); p.add("default_find_mode", &wrapped_search, "wrapped", [](std::string v) { if (v == "wrapped") return true; else if (v == "normal") return false; else invalid_value(v); }); p.add("default_tag_editor_pattern", &pattern, "%n - %t"); p.add("header_visibility", &header_visibility, "yes", yes_no); p.add("statusbar_visibility", &statusbar_visibility, "yes", yes_no); p.add("titles_visibility", &titles_visibility, "yes", yes_no); p.add("header_text_scrolling", &header_text_scrolling, "yes", yes_no); p.add("cyclic_scrolling", &use_cyclic_scrolling, "no", yes_no); p.add("lines_scrolled", &lines_scrolled, "2"); p.add("lyrics_fetchers", &lyrics_fetchers, "lyricwiki, azlyrics, genius, sing365, lyricsmania, metrolyrics, justsomelyrics, tekstowo, internet", list_of<LyricsFetcher_>); p.add("follow_now_playing_lyrics", &now_playing_lyrics, "no", yes_no); p.add("fetch_lyrics_for_current_song_in_background", &fetch_lyrics_in_background, "no", yes_no); p.add("store_lyrics_in_song_dir", &store_lyrics_in_song_dir, "no", yes_no); p.add("generate_win32_compatible_filenames", &generate_win32_compatible_filenames, "yes", yes_no); p.add("allow_for_physical_item_deletion", &allow_for_physical_item_deletion, "no", yes_no); p.add("lastfm_preferred_language", &lastfm_preferred_language, "en"); p.add("space_add_mode", &space_add_mode, "add_remove"); p.add("show_hidden_files_in_local_browser", &local_browser_show_hidden_files, "no", yes_no); p.add<void>( "screen_switcher_mode", nullptr, "playlist, browser", [this](std::string v) { if (v == "previous") screen_switcher_previous = true; else { screen_switcher_previous = false; screen_sequence = list_of<ScreenType>(v, [](std::string s) { auto screen = stringtoStartupScreenType(s); if (screen == ScreenType::Unknown) invalid_value(s); return screen; }); } }); p.add("startup_screen", &startup_screen_type, "playlist", [](std::string v) { auto screen = stringtoStartupScreenType(v); if (screen == ScreenType::Unknown) invalid_value(v); return screen; }); p.add("startup_slave_screen", &startup_slave_screen_type, "", [](std::string v) { boost::optional<ScreenType> screen; if (!v.empty()) { screen = stringtoStartupScreenType(v); if (screen == ScreenType::Unknown) invalid_value(v); } return screen; }); p.add("startup_slave_screen_focus", &startup_slave_screen_focus, "no", yes_no); p.add("locked_screen_width_part", &locked_screen_width_part, "50", [](std::string v) { return verbose_lexical_cast<double>(v) / 100; }); p.add("ask_for_locked_screen_width_part", &ask_for_locked_screen_width_part, "yes", yes_no); p.add("jump_to_now_playing_song_at_start", &jump_to_now_playing_song_at_start, "yes", yes_no); p.add("ask_before_clearing_playlists", &ask_before_clearing_playlists, "yes", yes_no); p.add("ask_before_shuffling_playlists", &ask_before_shuffling_playlists, "yes", yes_no); p.add("clock_display_seconds", &clock_display_seconds, "no", yes_no); p.add("display_volume_level", &display_volume_level, "yes", yes_no); p.add("display_bitrate", &display_bitrate, "no", yes_no); p.add("display_remaining_time", &display_remaining_time, "no", yes_no); p.add("regular_expressions", ®ex_type, "perl", [](std::string v) { if (v == "none") return boost::regex::icase | boost::regex::literal; else if (v == "basic") return boost::regex::icase | boost::regex::basic; else if (v == "extended") return boost::regex::icase | boost::regex::extended; else if (v == "perl") return boost::regex::icase | boost::regex::perl; else invalid_value(v); }); p.add("ignore_leading_the", &ignore_leading_the, "no", yes_no); p.add("block_search_constraints_change_if_items_found", &block_search_constraints_change, "yes", yes_no); p.add("mouse_support", &mouse_support, "yes", yes_no); p.add("mouse_list_scroll_whole_page", &mouse_list_scroll_whole_page, "yes", yes_no); p.add("empty_tag_marker", &empty_tag, "<empty>"); p.add("tags_separator", &MPD::Song::TagsSeparator, " | "); p.add("tag_editor_extended_numeration", &tag_editor_extended_numeration, "no", yes_no); p.add("media_library_sort_by_mtime", &media_library_sort_by_mtime, "no", yes_no); p.add("enable_window_title", &set_window_title, "yes", [](std::string v) { // Consider this variable only if TERM variable is available and we're not // in emacs terminal nor tty (through any wrapper like screen). auto term = getenv("TERM"); if (term != nullptr && strstr(term, "linux") == nullptr && strncmp(term, "eterm", const_strlen("eterm"))) return yes_no(v); else { std::clog << "Terminal doesn't support window title, skipping 'enable_window_title'.\n"; return false; } }); p.add("search_engine_default_search_mode", &search_engine_default_search_mode, "1", [](std::string v) { auto mode = verbose_lexical_cast<unsigned>(v); boundsCheck<unsigned>(mode, 1, 3); return --mode; }); p.add("external_editor", &external_editor, "nano", adjust_path); p.add("use_console_editor", &use_console_editor, "yes", yes_no); p.add("colors_enabled", &colors_enabled, "yes", yes_no); p.add("empty_tag_color", &empty_tags_color, "cyan"); p.add("header_window_color", &header_color, "default"); p.add("volume_color", &volume_color, "default"); p.add("state_line_color", &state_line_color, "default"); p.add("state_flags_color", &state_flags_color, "default:b"); p.add("main_window_color", &main_color, "yellow"); p.add("color1", &color1, "white"); p.add("color2", &color2, "green"); p.add("main_window_highlight_color", &main_highlight_color, "yellow"); p.add("progressbar_color", &progressbar_color, "black:b"); p.add("progressbar_elapsed_color", &progressbar_elapsed_color, "green:b"); p.add("statusbar_color", &statusbar_color, "default"); p.add("statusbar_time_color", &statusbar_time_color, "default:b"); p.add("player_state_color", &player_state_color, "default:b"); p.add("alternative_ui_separator_color", &alternative_ui_separator_color, "black:b"); p.add("active_column_color", &active_column_color, "red"); p.add("window_border_color", &window_border, "green", verbose_lexical_cast<NC::Color>); p.add("active_window_border", &active_window_border, "red", verbose_lexical_cast<NC::Color>); return std::all_of( config_paths.begin(), config_paths.end(), [&](const std::string &config_path) { std::ifstream f(config_path); if (f.is_open()) std::clog << "Reading configuration from " << config_path << "...\n"; return p.run(f, ignore_errors); } ) && p.initialize_undefined(ignore_errors); }
inline bool prefix_matches(const char* prefix, const std::string& str) { auto prefix_len = const_strlen(prefix); return str.size() > prefix_len && str.substr(0, prefix_len).compare(prefix) == 0; }