From 4d1c45aa50b464ab7c98fbd2ff02860ce0047af5 Mon Sep 17 00:00:00 2001 From: cxl Date: Fri, 15 May 2015 10:19:56 +0000 Subject: [PATCH] .cpp git-svn-id: svn://ultimatepp.org/upp/trunk@8451 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CppBase/CppBase.h | 2 - uppsrc/CppBase/Parser.cpp | 2 +- uppsrc/CppBase/cpp.cpp | 266 ++++++++++++++++++++++++++++++++------ uppsrc/CppBase/ppfile.cpp | 26 ++-- 4 files changed, 237 insertions(+), 59 deletions(-) diff --git a/uppsrc/CppBase/CppBase.h b/uppsrc/CppBase/CppBase.h index b14572b61..23c8f048c 100644 --- a/uppsrc/CppBase/CppBase.h +++ b/uppsrc/CppBase/CppBase.h @@ -82,8 +82,6 @@ private: PPMacro *FindPPMacro(const String& id, Index& segment_id, int& segmenti); const CppMacro *FindMacro(const String& id, Index& segment_id, int& segmenti); -String GetAllMacros(const String& id, Index& segment_id); - void PPSync(const String& include_path); String GetIncludePath(); diff --git a/uppsrc/CppBase/Parser.cpp b/uppsrc/CppBase/Parser.cpp index 647e0478d..febd9690e 100644 --- a/uppsrc/CppBase/Parser.cpp +++ b/uppsrc/CppBase/Parser.cpp @@ -377,7 +377,7 @@ void Parser::ThrowError(const String& e) int i = 0; while(i < 40 && lex[i] != t_eof) i++; - DLOG("ERROR: (" << GetLine(lex.Pos()) << ") " << e << ", scope: " << current_scope << + LLOG("ERROR: (" << GetLine(lex.Pos()) << ") " << e << ", scope: " << current_scope << ", code: " << AsCString(String(lex.Pos(), lex.Pos(i)))); #endif throw Error(); diff --git a/uppsrc/CppBase/cpp.cpp b/uppsrc/CppBase/cpp.cpp index 66fd0896e..ddbefe6ae 100644 --- a/uppsrc/CppBase/cpp.cpp +++ b/uppsrc/CppBase/cpp.cpp @@ -150,46 +150,6 @@ String Cpp::Expand(const char *s) return r; } -Index Cpp::kw; - -bool Cpp::Preprocess(const String& sourcefile, Stream& in, const String& currentfile, - bool get_macros) -{ - LLOG("===== Preprocess " << sourcefile << " <- " << currentfile); - RTIMING("Cpp::Preprocess"); - macro.Clear(); - macro.Reserve(1000); - segment_id.Clear(); - segment_id.Reserve(100); - - const Vector& ignorelist = GetIgnoreList(); - - for(int i = 0; i < ignorelist.GetCount(); i++) { - PPMacro h; - PPMacro& pp = macro.GetAdd(h.macro.Define(ignorelist[i])); - pp = h; - pp.segment_id = -999999999; - } - segment_id.Add(-999999999); - - std_macros = macro.GetCount(); - - ONCELOCK { - const char **h = CppKeyword(); - while(*h) { - kw.Add(*h); - h++; - } - } - notmacro = clone(kw); - - done = false; - incomment = false; - Index visited; - Do(NormalizePath(sourcefile), in, NormalizePath(currentfile), visited, get_macros); - return done; -} - void Cpp::DoFlatInclude(const String& header_path) { RTIMING("DoFlatInclude"); @@ -197,7 +157,7 @@ void Cpp::DoFlatInclude(const String& header_path) if(header_path.GetCount()) { const PPFile& pp = GetFlatPPFile(header_path); LLOG("DoFlatInclude " << header_path << ", " << pp.item.GetCount() << " items"); - for(int i = 0; i < pp.item.GetCount() && !done; i++) { + for(int i = 0; i < pp.item.GetCount(); i++) { const PPItem& m = pp.item[i]; if(m.type == PP_DEFINES) { segment_id.FindAdd(m.segment_id); @@ -212,6 +172,7 @@ void Cpp::DoFlatInclude(const String& header_path) } } +#if 0 void Cpp::Do(const String& sourcefile, Stream& in, const String& currentfile, Index& visited, bool get_macros) { @@ -356,6 +317,220 @@ void Cpp::Do(const String& sourcefile, Stream& in, const String& currentfile, } done = true; } +#endif + +static String sReadCppName(CParser& p) +{ + String id; + for(;;) + if(p.IsId()) + id.Cat(p.ReadId()); + else + if(p.Char2(':', ':')) + id.Cat("::"); + else + break; + return id; +} + +void Cpp::Do(const String& sourcefile, Stream& in, const String& currentfile, + Index& visited, bool get_macros) +{ + if(visited.Find(currentfile) >= 0 || visited.GetCount() > 100) // TODO: Remove? + return; + visited.Add(currentfile); + String current_folder = GetFileFolder(currentfile); + bool finalfile = sourcefile == currentfile; + + if(finalfile) { // Need to recognize usings and namespaces + done = true; + CParser p(output); + DDUMP(output); + try { // TODO: Add grounding (to namespace level) + Vector namespace_block; + while(!p.IsEof()) { + int plvl = 0; + if(p.Id("using") && p.Id("namespace")) { + do { + String id = sReadCppName(p); + if(id.GetCount()) + namespace_using.FindAdd(id); + } + while(p.Char(',')); + } + else + if(p.Id("namespace")) { + String id = sReadCppName(p); + if(id.GetCount()) { + namespace_stack.Add(id); + namespace_block.Add(plvl); + } + } + else + if(p.Char('{')) + plvl++; + else + if(p.Char('}')) { + if(namespace_block.GetCount() && namespace_block.Top() == plvl) { + namespace_stack.Drop(); + namespace_block.Drop(); + } + plvl--; + } + else + p.SkipTerm(); + } + } + catch(CParser::Error) {} + namespaces = Join(namespace_stack, ";"); + DDUMP(namespace_stack); + DDUMP(namespace_using); + output.Clear(); + } + + RTIMING("Expand"); + incomment = false; + prefix_macro.Clear(); + output.Reserve(8192); + int lineno = 0; + bool incomment = false; + int segment_serial = 0; + segment_id.Add(--segment_serial); + +#ifdef IGNORE_ELSE + int ignore_else = 0; +#endif + + while(!in.IsEof()) { + String l = prefix_macro + in.GetLine(); + prefix_macro.Clear(); + lineno++; + int el = 0; + while(*l.Last() == '\\' && !in.IsEof()) { + el++; + l.Trim(l.GetLength() - 1); + l.Cat(in.GetLine()); + } + RemoveComments(l, incomment); + CParser p(l); + if(p.Char('#')) { + if(p.Id("define")) { + output.Cat(l + "\n"); + CppMacro m; + String id = m.Define(p.GetPtr()); + if(id.GetCount()) { + PPMacro& pp = macro.Add(id); + pp.macro = m; + pp.segment_id = segment_serial; + notmacro.Trim(kw.GetCount()); + } + } + else + if(p.Id("undef")) { + output.Cat(l + "\n"); + if(p.IsId()) { + segment_id.Add(--segment_serial); + PPMacro& m = macro.Add(p.ReadId()); + m.segment_id = segment_serial; + m.macro.SetUndef(); + notmacro.Trim(kw.GetCount()); + segment_id.Add(--segment_serial); + } + } + else { + output.Cat('\n'); + #ifdef IGNORE_ELSE + if(ignore_else) { + if(p.Id("if") || p.Id("ifdef") || p.Id("ifndef")) + ignore_else++; + else + if(p.Id("endif")) + ignore_else--; + } + else { + if(p.Id("else") || p.Id("elif")) + ignore_else = 1; + } + #endif + if(p.Id("include")) { + LTIMING("Expand include"); + String s = GetIncludePath(p.GetPtr(), current_folder); + DLOG("#include " << s); + if(s.GetCount()) { + DDUMP(IncludesFile(s, sourcefile)); + if(!finalfile && IncludesFile(s, sourcefile)) { + DLOG("Include IN " << s); + RHITCOUNT("Include IN"); + Do(sourcefile, in, s, visited, get_macros); + return; + } + else { + DLOG("Include FLAT " << s); + RHITCOUNT("Include FLAT"); + DoFlatInclude(s); + segment_id.Add(--segment_serial); + includes << ';' << s; + } + } + } + } + } + else { + LTIMING("Expand expand"); + #ifdef IGNORE_ELSE + if(ignore_else) + output.Cat('\n'); + else + #endif + output.Cat(Expand(l) + "\n"); + } + while(el--) + output.Cat("\n"); + } +} + +Index Cpp::kw; + +bool Cpp::Preprocess(const String& sourcefile, Stream& in, const String& currentfile, + bool get_macros) +{ + DLOG("===== Preprocess " << sourcefile << " <- " << currentfile); + RTIMING("Cpp::Preprocess"); + macro.Clear(); + macro.Reserve(1000); + segment_id.Clear(); + segment_id.Reserve(100); + + const Vector& ignorelist = GetIgnoreList(); + + for(int i = 0; i < ignorelist.GetCount(); i++) { + PPMacro h; + PPMacro& pp = macro.GetAdd(h.macro.Define(ignorelist[i])); + pp = h; + pp.segment_id = -999999999; + } + segment_id.Add(-999999999); + + std_macros = macro.GetCount(); + + ONCELOCK { + const char **h = CppKeyword(); + while(*h) { + kw.Add(*h); + h++; + } + } + notmacro = clone(kw); + + done = false; + incomment = false; + output.Clear(); + Index visited; + Do(NormalizePath(sourcefile), in, NormalizePath(currentfile), visited, get_macros); + if(!done) + output.Clear(); + return done; +} VectorMap Cpp::GetDefinedMacros() { @@ -369,10 +544,12 @@ VectorMap Cpp::GetDefinedMacros() return r; } +String GetAllMacros(const String& id, Index& segment_id); + String Cpp::GetIncludedMacroValues(const Vector& m) { String r; - LTIMING("GetUsedMacroValues"); + RTIMING("GetUsedMacroValues"); r << "##namespace\n" << namespaces << "\n" << "##usings\n" << usings << "\n"; for(int i = 0; i < m.GetCount(); i++) { @@ -380,8 +557,11 @@ String Cpp::GetIncludedMacroValues(const Vector& m) if(mm.GetCount()) r << '#' << m[i] << '\n' << mm << '\n'; } +#ifdef DEBUG return r; -// return MD5String(r); +#else + return MD5String(r); +#endif } END_UPP_NAMESPACE diff --git a/uppsrc/CppBase/ppfile.cpp b/uppsrc/CppBase/ppfile.cpp index 560e14f71..09f2b9fac 100644 --- a/uppsrc/CppBase/ppfile.cpp +++ b/uppsrc/CppBase/ppfile.cpp @@ -145,19 +145,6 @@ const CppMacro *FindMacro(const String& id, Index& segment_id, int& segment return m ? &m->macro : NULL; } -String GetAllMacros(const String& id, Index& segment_id) -{ - String r; - int q = sAllMacros.Find(id); - while(q >= 0) { - const PPMacro& m = sAllMacros[q]; - if(segment_id.Find(m.segment_id) >= 0) - r << '\n' << m.macro; - q = sAllMacros.FindNext(q); - } - return r; -} - void PPFile::CheckEndNamespace(Vector& namespace_block, int level) { if(namespace_block.GetCount() && namespace_block.Top() == level) { @@ -527,4 +514,17 @@ const PPFile& GetFlatPPFile(const char *path) return GetFlatPPFile(path, visited); } +String GetAllMacros(const String& id, Index& segment_id) +{ + String r; + int q = sAllMacros.Find(id); + while(q >= 0) { + const PPMacro& m = sAllMacros[q]; + if(segment_id.Find(m.segment_id) >= 0) + r << '\n' << m.macro; + q = sAllMacros.FindNext(q); + } + return r; +} + END_UPP_NAMESPACE