void TextSettings::Load(const char *filename) { FileIn in(filename); int themei = 0; settings.Add(""); while(!in.IsEof()) { String ln = in.GetLine(); const char *s = ln; if(*s == '[') { s++; String theme; while(*s && *s != ']') theme.Cat(*s++); themei = settings.FindAdd(theme); } else { if(themei >= 0) { String key; while(*s && *s != '=') { key.Cat(*s++); } if(*s == '=') s++; String value; while(*s) { value.Cat(*s++); } if(!IsEmpty(key)) settings[themei].GetAdd(TrimBoth(key)) = TrimBoth(value); } } } }
void GenerateCmd() { String cmdBuild("-"); if (rebuild) cmdBuild << 'a'; if (blitz) cmdBuild << 'b'; if (!umk && msgonfail) cmdBuild << 'e'; if (silent) cmdBuild << 'l'; if (map) cmdBuild << 'm'; cmdBuild << cmdBuildMode; if (shared) cmdBuild << 's'; else if (sharedbuild) cmdBuild << 'S'; if (verbose) cmdBuild << 'v'; if (savetargetdir) cmdBuild << 'k'; switch (exportproject) { case 1: cmdBuild << 'x'; break; case 2: cmdBuild << 'X'; break; } if (makefile) cmdBuild << 'M'; int numThreads = ~threads; if (umk && !IsNull(numThreads) && numThreads > 0) cmdBuild << 'H' << numThreads; String output; if (outoption) { output = TrimBoth(~out); if (output.Find(" ") >= 0) output = String().Cat() << "\"" << output << "\""; } cmd <<= TrimRight(Format("%s %s %s %s%s %s", cmdAssembly, cmdPackage, cmdMethod, cmdBuild, cmdMainConfig, output)); }
Vector<String> SvnInfo(const String& package) { Vector<String> info; String d = GetFileFolder(PackagePath(package)); if(IsSvnDir2(d)) { String v = Sys("svnversion " + d); if(IsDigit(*v)) info.Add("#define bmSVN_REVISION " + AsCString(TrimBoth(v))); v = Sys("svn info " + d); StringStream in(v); while(!in.IsEof()) { String l = in.GetLine(); if(l.StartsWith("URL: ")) { info.Add("#define bmSVN_URL " + AsCString(TrimBoth(l.Mid(5)))); break; } } } return info; }
double IniDouble::Load() { Mutex::Lock __(sMtx); if(IniChanged__(version)) { value = ScanDouble(TrimBoth(ToLower(GetIniKey(id)))); if(IsNull(value)) value = (*def)(); IniSet__(version); } return value; }
bool IniBool::Load() { Mutex::Lock __(sMtx); if(IniChanged__(version)) { String h = TrimBoth(ToLower(GetIniKey(id))); if(h.GetCount()) value = h == "1" || h == "yes" || h == "true" || h == "y"; else value = (*def)(); IniSet__(version); } return value; }
IniString::operator String() { String x; { Mutex::Lock __(strMtx); String& s = (*ref_fn)(); if(IniChanged__(version)) { s = TrimBoth(GetIniKey(id)); if(IsNull(s)) s = (*def)(); } x = s; IniSet__(version); } return x; }
MIValue Gdb_MI2::ReadGdb(bool wait) { String output, s; MIValue res; // blocking path // waits for 2 minutes max, then return empty value // some commands (in particular if they return python exceptions) // have a delay between returned exception text and command result // so we shall wait up to the final (gdb) bool stop = false; int retries = 120 * 50; while(dbg && --retries && !stop) { dbg->Read(s); StringStream ss(s); while(!ss.IsEof()) { String s2 = ss.GetLine(); output << s2 << "\n"; // wait till (gdb) end marker appears s2 = TrimBoth(s2); if(s2 == "(gdb)" || s2 == "&\"quit\\n\"") { stop = true; #ifdef flagMT // exit if in service threa and thread is stoppint if(!IsMainThread() && IsStopThread()) throw BreakExc(); #endif } } // non-blocking quick exit if(!wait) break; Sleep(20); continue; } if(output.IsEmpty()) return res; return ParseGdb(output); }
Time ScanIso8601(const String& p) { String s = TrimBoth(p); // 19980717T14:08:55 // 01234567890123456 if(s.GetCount() != 17 || s[8] != 'T' || s[11] != ':' || s[14] != ':') return Null; Time tm; tm.year = atoi(s.Mid(0, 4)); tm.month = atoi(s.Mid(4, 2)); tm.day = atoi(s.Mid(6, 2)); tm.hour = atoi(s.Mid(9, 2)); tm.minute = atoi(s.Mid(12, 2)); tm.second = atoi(s.Mid(15, 2)); if(!tm.IsValid()) return Null; return tm; }
void LoadPPConfig() { for(int i = 0; i < sAllMacros.GetCount(); i++) if(sAllMacros[i].segment_id == 0 && !sAllMacros.IsUnlinked(i)) sAllMacros.Unlink(i); s_namespace_macro.Clear(); s_namespace_end_macro.Clear(); StringStream ss(sDefs); int linei = 0; while(!ss.IsEof()) { String l = ss.GetLine(); try { CParser p(l); if(p.Char('#')) { if(p.Id("define")) { CppMacro def; String id = def.Define(p.GetPtr()); if(id.GetCount()) { PPMacro m; m.segment_id = 0; m.line = linei; m.macro = def; sAllMacros.Put(id, m); if(findarg(TrimBoth(def.body), "}", "};") >= 0) s_namespace_end_macro.Add(id); try { CParser p(def.body); if(p.Id("namespace") && p.IsId()) { String n = p.ReadId(); if(p.Char('{') && p.IsEof()) s_namespace_macro.Add(id, n); } } catch(CParser::Error) {} } } } } catch(CParser::Error) {} linei++; } }
// fetch list of available app versions ProductVersions Updater::FetchVersions(void) { String verStr; if(isWebServer) { http.Timeout(1000); http.Url(GetPlatformRoot() + "versions"); http.WhenDo.Clear(); // fetch version file from server verStr = http.Execute(); int err = http.GetStatusCode(); if(err != 200) return ProductVersions(); } else verStr = LoadFile(GetPlatformRoot() + "versions"); verStr = TrimBoth(verStr); if(verStr.IsEmpty()) return ProductVersions(); return ProductVersions(verStr); }
void PPFile::Parse(Stream& in) { LTIMING("PPFile::Parse"); for(int i = 0; i < ppmacro.GetCount(); i++) sAllMacros.Unlink(ppmacro[i]); ppmacro.Clear(); item.Clear(); includes.Clear(); bool was_using = false; bool was_namespace = false; int level = 0; bool incomment = false; Vector<int> namespace_block; bool next_segment = true; Index<int> local_segments; keywords.Clear(); int linei = 0; Md5Stream md5; while(!in.IsEof()) { String l = in.GetLine(); while(*l.Last() == '\\' && !in.IsEof()) { l.Trim(l.GetLength() - 1); l.Cat(in.GetLine()); } RemoveComments(l, incomment); try { CParser p(l); if(p.Char('#')) { if(p.Id("define")) { if(next_segment) { PPItem& m = item.Add(); m.type = PP_DEFINES; m.segment_id = ++sPPserial; next_segment = false; local_segments.Add(sPPserial); } CppMacro def; String id = def.Define(p.GetPtr()); if(id.GetCount()) { PPMacro m; m.segment_id = sPPserial; m.line = linei; m.macro = def; ppmacro.Add(sAllMacros.Put(id, m)); md5.Put("#", 1); md5.Put(id); md5.Put(0); md5.Put(m.macro.md5, 16); } } else if(p.Id("undef")) { if(p.IsId()) { String id = p.ReadId(); md5.Put("#", 1); md5.Put(id); md5.Put(1); int segmenti = -1; PPMacro *um = FindPPMacro(id, local_segments, segmenti); if(um && segmenti) { // heuristic: only local undefs are allowed PPItem& m = item.Add(); m.type = PP_DEFINES; m.segment_id = ++sPPserial; um->undef_segment_id = m.segment_id; next_segment = true; local_segments.Add(sPPserial); if(id.GetCount()) { PPMacro m; m.segment_id = sPPserial; m.line = linei; m.macro.SetUndef(); ppmacro.Add(sAllMacros.Put(id, m)); } } } } else if(p.Id("include")) { PPItem& m = item.Add(); next_segment = true; m.type = PP_INCLUDE; m.text = TrimBoth(p.GetPtr()); if(IsNull(m.text)) item.Drop(); else includes.FindAdd(m.text); md5.Put('@'); md5.Put(m.text); } } else { while(!p.IsEof()) { if(was_namespace) { int type = was_using ? PP_USING : PP_NAMESPACE; String id; while(p.Char2(':', ':')) id = "::"; if(p.IsId()) { id << p.ReadId(); while(p.Char2(':', ':') && p.IsId()) id << "::" << p.ReadId(); if(!was_using) namespace_block.Add(level); if(!was_using || level == 0) { PPItem& m = item.Add(); next_segment = true; m.type = type; m.text = id; } md5.Put('$'); md5.Put(type); md5.Put(id); } was_namespace = was_using = false; } else if(p.Id("using")) was_using = true; else if(p.Id("namespace")) was_namespace = true; else { was_using = was_namespace = false; if(p.IsId()) { static const VectorMap<String, String>& namespace_macro = GetNamespaceMacros(); static const Index<String>& namespace_end_macro = GetNamespaceEndMacros(); String id = p.ReadId(); int q = namespace_macro.Find(id); if(q > 0) { PPItem& m = item.Add(); next_segment = true; m.type = PP_NAMESPACE; m.text = namespace_macro[q]; namespace_block.Add(level); level++; md5.Put('%'); md5.Put(id); } else { q = namespace_end_macro.Find(id); if(q >= 0) { level--; CheckEndNamespace(namespace_block, level, md5); } } keywords.Add(id); } else if(p.Char('}')) { if(level > 0) { level--; CheckEndNamespace(namespace_block, level, md5); } } else if(p.Char('{')) level++; else p.SkipTerm(); } } } } catch(...) {} linei++; } md5sum = md5.FinishString(); Sort(keywords); Vector<int> remove; int i = 0; while(i < keywords.GetCount()) { // Remove identical items int ii = i; i++; while(i < keywords.GetCount() && keywords[ii] == keywords[i]) remove.Add(i++); } keywords.Remove(remove); }
void Navigator::Search() { sortitems.Check(sorting); int sc = scope.GetScroll(); String key = scope.GetKey(); String s = TrimBoth(~search); String search_name, search_nest; bool wholeclass = false; bool both = false; navigator_global = false; if(s.Find('.') >= 0) { Vector<String> h = Split((String)~search, '.'); if(*s.Last() == '.') search_nest = Join(h, "::"); else { search_name = h.Pop(); if(h.GetCount()) search_nest = Join(h, "::"); } wholeclass = *s == '.' && search_nest.GetCount(); } else { search_name = search_nest = ~search; both = true; } s = Join(Split(s, '.'), "::") + (s.EndsWith(".") ? "::" : ""); int lineno = StrInt(s); gitem.Clear(); nitem.Clear(); if(IsNull(theide->editfile)) return; int fileii = GetSourceFileIndex(theide->editfile); if(!IsNull(lineno)) { NavItem& m = nitem.Add(); m.type = "Go to line " + AsString(lineno); m.kind = KIND_LINE; m.line = lineno; gitem.Add(Null).Add(&m); } else if(IsNull(s) && !sorting) { const CppBase& b = CodeBase(); for(int i = 0; i < b.GetCount(); i++) { String nest = b.GetKey(i); const Array<CppItem>& ci = b[i]; for(int j = 0; j < ci.GetCount(); j++) { const CppItem& m = ci[j]; if(m.file == fileii) { NavItem& n = nitem.Add(); n.Set(m); n.nest = nest; n.decl_line = m.line; n.decl_file = m.file; n.decl = !m.impl; NavLine& l = n.linefo.Add(); l.impl = m.impl; l.file = m.file; l.line = m.line; } } } Sort(nitem, FieldRelation(&NavItem::line, StdLess<int>())); NavGroup(true); } else { navigator_global = true; const CppBase& b = CodeBase(); String usearch_nest = ToUpper(search_nest); String usearch_name = ToUpper(search_name); ArrayMap<String, NavItem> imap; bool local = sorting && IsNull(s); VectorMap<String, int> nest_pass; for(int pass = -1; pass < 2; pass++) { for(int i = 0; i < b.GetCount(); i++) { String nest = b.GetKey(i); bool foundnest = (wholeclass ? pass < 0 ? false : pass ? ToUpper(nest) == usearch_nest : nest == search_nest : pass < 0 ? nest == search_nest : (pass ? ToUpper(nest).Find(usearch_nest) >= 0 : nest.StartsWith(search_nest))) && nest.Find('@') < 0; if(local || foundnest || both) { const Array<CppItem>& ci = b[i]; for(int j = 0; j < ci.GetCount(); j++) { const CppItem& m = ci[j]; if(local ? m.file == fileii : m.uname.Find('@') < 0 && (pass < 0 ? m.name == search_name : pass ? m.uname.Find(usearch_name) >= 0 : m.name.StartsWith(search_name)) || both && foundnest) { String key = nest + '\1' + m.qitem; int q = nest_pass.Find(nest); int p = pass; if(q < 0) // We do not want classes to be split based on pass nest_pass.Add(nest, pass); else p = nest_pass[q]; q = imap.Find(key); if(q < 0) { NavItem& ni = imap.Add(key); ni.Set(m); ni.nest = nest; ni.decl_line = ni.line; ni.decl_file = ni.file; ni.decl = !ni.impl; ni.pass = p; NavLine& l = ni.linefo.Add(); l.impl = m.impl; l.file = m.file; l.line = m.line; } else { NavItem& mm = imap[q]; if(!m.impl && (!mm.decl || CombineCompare(mm.decl_file, m.file)(mm.decl_line, m.line) < 0)) { mm.decl = true; mm.decl_line = m.line; mm.decl_file = m.file; mm.natural = m.natural; } NavLine& l = mm.linefo.Add(); l.impl = m.impl; l.file = m.file; l.line = m.line; } } } } } } nitem = imap.PickValues(); NavGroup(false); SortByKey(gitem); Vector<String> keys = gitem.PickKeys(); Vector<Vector<NavItem *> > values = gitem.PickValues(); IndexSort(keys, values); for(int i = 0; i < keys.GetCount(); i++) keys[i].Remove(0); VectorMap<String, Vector<NavItem *> > h(pick(keys), pick(values)); gitem = pick(h); for(int i = 0; i < gitem.GetCount(); i++) Sort(gitem[i], sorting ? SortByNames : SortByLines); } scope.Clear(); scope.Add(Null); Index<String> done; for(int i = 0; i < gitem.GetCount(); i++) { String s = gitem.GetKey(i); if(done.Find(s) < 0) { done.Add(s); scope.Add(s); } } scope.ScrollTo(sc); if(!navigator_global || !scope.FindSetCursor(key)) scope.GoBegin(); }
// read debugger output analyzing command responses and async output // things are quite tricky because debugger output seems to be // slow and we have almost no terminator to stop on -- (gdb) is not // so reliable as it can happen (strangely) in middle of nothing MIValue Gdb_MI2::ParseGdb(String const &output, bool wait) { MIValue res; // parse result data StringStream ss(output); while(!ss.IsEof()) { String s; String str = ss.GetLine(); s = str; while(str.GetCount() == 1024 && !ss.IsEof()) { str = ss.GetLine(); s << str; } s = TrimBoth(s); // check 'running' and 'stopped' async output if(s.StartsWith("*running")) { started = true; stopReason.Clear(); continue; } else if(s.StartsWith("*stopped")) { stopped = true; s = '{' + s.Mid(9) + '}'; stopReason = MIValue(s); continue; } // catch process start/stop and store/remove pids else if(s.StartsWith("=thread-group-started,id=")) { String id, pid; int i = s.Find("id="); if(i < 0) continue; i += 4; while(s[i] && s[i] != '"') id.Cat(s[i++]); i = s.Find("pid="); if(i < 0) continue; i += 5; while(s[i] && s[i] != '"') pid.Cat(s[i++]); processes.Add(id, atoi(pid)); continue; } else if(s.StartsWith("=thread-group-exited,id=")) { String id; int i = s.Find("id="); if(i < 0) continue; i += 4; while(s[i] && s[i] != '"') id.Cat(s[i++]); i = processes.Find(id); if(i >= 0) processes.Remove(i); continue; } // skip asynchronous responses // in future, we could be gather/use them if(s[0] == '*'|| s[0] == '=') continue; // here handling of command responses // we're not interested either, as we use MI interface if(s[0] == '~') continue; // here handling of target output // well, for now discard this one too, but it should go on console output if(s[0] == '~') continue; // here handling of gdb log/debug message // not interesting here if(s[0] == '&') continue; // now we SHALL have something starting with any of // // "^done", "^running", "^connected", "^error" or "^exit" records if(s.StartsWith("^done") || s.StartsWith("^running")) { // here we've got succesful command output in list form, if any // shall skip the comma; following can be a serie of pairs, // or directly an array of maps in form of : // [{key="value",key="value",...},{key="value"...}...] int i = 5; // just skip shortest, ^done while(s[i] && s[i] != ',') i++; if(!s[i]) continue; i++; if(!s[i]) continue; res = MIValue(s.Mid(i)); continue; } else if(s.StartsWith("^error")) { // first array element is reserved for command result status s = s.Right(12); // '^error,msg=\"' s = s.Left(s.GetCount() - 1); res.SetError(s); } else continue; } return res; }
static void LoadIniStream(Stream& in, VectorMap<String, String>& key, const char *sfile) { bool env = false; while(!in.IsEof()) { String line = in.GetLine(); CParser p(line); if(p.IsId()) { String k = p.ReadId(); if(p.Char('=')) { String h = TrimBoth((String)p.GetSpacePtr()); if(env) { String hh; const char *s = ~h; while(*s) { if(*s == '$') { s++; if(*s == '$') { hh.Cat('$'); s++; } else { String id; if (*s == '{') { while(*++s != '}') id.Cat(*s); s++; } else { while(iscid(*s)) id.Cat(*s++); } hh.Cat(GetEnv(id)); } } else hh.Cat(*s++); } key.Add(k, hh); } else key.Add(k, h); } } else if(p.Char('@')) { if(p.Id("include")) { String fn = p.GetPtr(); if(!IsFullPath(fn) && sfile) fn = AppendFileName(GetFileFolder(GetFullPath(sfile)), fn); LoadIniFile(fn, key); } else if(p.Id("end")) return; else if(p.Id("replace-env")) env = true; else if(p.Id("ignore-env")) env = false; } } }
NAMESPACE_UPP Value ParseXmlRpcValue(XmlParser& p) { Value r; p.PassTag("value"); if(p.Tag("int") || p.Tag("i4")) { String s = p.ReadText(); CParser p(s); if(!p.IsInt()) throw XmlError("integer expected"); r = p.ReadInt(); } else if(p.Tag("boolean")) { int n = StrInt(p.ReadText()); if(n != 0 && n != 1) throw XmlError("boolean expected"); r = (bool)n; } else if(p.Tag("double")) { String s = p.ReadText(); CParser p(s); if(!p.IsDouble()) throw XmlError("double expected"); r = p.ReadDouble(); } else if(p.Tag("string") || p.Tag("base64")) r = p.ReadText(); else if(p.TagE("nil")) { p.PassEnd(); return r; } else if(p.Tag("dateTime.iso8601")) { String s = TrimBoth(p.ReadText()); // 19980717T14:08:55 // 01234567890123456 if(s.GetCount() != 17 || s[8] != 'T' || s[11] != ':' || s[14] != ':') throw XmlError("invalid dateTime format"); Time tm; tm.year = atoi(s.Mid(0, 4)); tm.month = atoi(s.Mid(4, 2)); tm.day = atoi(s.Mid(6, 2)); tm.hour = atoi(s.Mid(9, 2)); tm.minute = atoi(s.Mid(12, 2)); tm.second = atoi(s.Mid(15, 2)); r = tm; } else if(p.Tag("array")) { ValueArray va; p.PassTag("data"); while(!p.End()) va.Add(ParseXmlRpcValue(p)); r = va; } else if(p.Tag("struct")) { ValueMap vm; while(p.Tag("member")) { p.PassTag("name"); String name = p.ReadText(); p.PassEnd(); vm.Add((Value)name, ParseXmlRpcValue(p)); p.PassEnd(); } r = vm; } else throw XmlError("unknown value type"); p.PassEnd(); p.PassEnd(); return r; }