diff --git a/autotest/CppParser/CppParser.cpp b/autotest/CppParser/CppParser.cpp index 771079c0f..0c1b0910e 100644 --- a/autotest/CppParser/CppParser.cpp +++ b/autotest/CppParser/CppParser.cpp @@ -25,6 +25,8 @@ void Test(const char *path) DUMPC(errs); Qualify(base); String out; + if(errs.GetCount()) + out << "ERRORS: " << errs << '\n'; for(int i = 0; i < base.GetCount(); i++) { out << Nvl(base.GetKey(i), "") << " {\n"; const Array& ma = base[i]; diff --git a/autotest/CppParser/CppParser.upp b/autotest/CppParser/CppParser.upp index 9203a562c..c4685fe51 100644 --- a/autotest/CppParser/CppParser.upp +++ b/autotest/CppParser/CppParser.upp @@ -4,6 +4,8 @@ uses file CppParser.cpp, + test0.in, + test0.out, test1.in, test1.out, test2.in, diff --git a/autotest/CppParser/test0.in b/autotest/CppParser/test0.in new file mode 100644 index 000000000..8059043a1 --- /dev/null +++ b/autotest/CppParser/test0.in @@ -0,0 +1,201 @@ +#include "CppBase.h" + +NAMESPACE_UPP + +#ifdef _MSC_VER +#pragma inline_depth(255) +#pragma optimize("t", on) +#endif + +static StaticMutex cpp_file_mutex; +static Index cpp_file; + +int GetCppFileIndex(const String& path) +{ + INTERLOCKED_(cpp_file_mutex) { + return cpp_file.FindAdd(path); + } + return -1; +} + +const String& GetCppFile(int i) +{ + INTERLOCKED_(cpp_file_mutex) { + return cpp_file[i]; + } + static String x; + return x; +} +/* +void CppPos::Serialize(Stream& s) +{ + s % impl % line; + String fn = GetCppFile(file); + s % fn; + file = GetCppFileIndex(fn); +} + +String SSpaces(const char *txt) +{ + StringBuffer r; + while(*txt) + if(*txt == ' ') { + while((byte)*txt <= ' ' && *txt) txt++; + r.Cat(' '); + } + else + r.Cat(*txt++); + return r; +} +*/ +void SLPos(SrcFile& res) +{ + res.linepos.Add(res.text.GetLength()); +} + +SrcFile::SrcFile() : + preprocessorLinesRemoved(0), + blankLinesRemoved(0), + commentLinesRemoved(0) +{ +} + +void 3BUG(); + +void Foo(int x, const String& y); + +void Foo(int x, const String& y) {} + +SrcFile PreProcess(Stream& in) +{ + SrcFile res; + bool include = true; + while(!in.IsEof()) { + String ln = in.GetLine(); + SLPos(res); + while(*ln.Last() == '\\') { + ln.Trim(ln.GetLength() - 1); + ln.Cat(in.GetLine()); + SLPos(res); + } + const char *rm = ln; + if(IsAlNum(*rm)) { + const char *s = ln.Last(); + while(s > rm && *s == ' ') s--; + if(*s != ':') + res.text << '\2'; + } + while(*rm == ' ' || *rm == '\t') rm++; + if(*rm == '\0') + res.blankLinesRemoved++; + else + if(*rm == '#') + { + if(rm[1] == 'd' && rm[2] == 'e' && rm[3] == 'f' && + rm[4] == 'i' && rm[5] == 'n' && rm[6] == 'e' && !iscid(rm[7])) { + const char *s = rm + 8; + while(*s == ' ') s++; + String macro; + while(iscid(*s)) + macro.Cat(*s++); + if(*s == '(') { + while(*s != ')' && *s) + macro.Cat(*s++); + macro << ')'; + } +// res.text << '#' << AsCString(SSpaces(macro)); + if(include) + res.text << '#' << AsCString(macro); + } + res.preprocessorLinesRemoved++; + } + else { + bool lineContainsComment = false; + bool lineContainsNonComment = false; + String cmd; + while(*rm) { + if(*rm == '\"') { + lineContainsNonComment = true; + res.text << '\"'; + rm++; + while((byte)*rm && *rm != '\r' && *rm != '\n') { + if(*rm == '\"') { + res.text << '\"'; + rm++; + break; + } + if(*rm == '\\' && rm[1]) { + if(include) + res.text.Cat(*rm); + rm++; + } + if(include) + res.text.Cat(*rm); + rm++; + } + } + else + if(*rm == '\\' && rm[1]) { + lineContainsNonComment = true; + if(include) { + res.text.Cat(*rm++); + res.text.Cat(*rm++); + } + else + rm += 2; + } + else + if(rm[0] == '/' && rm[1] == '/') { + cmd = rm + 2; + if(!lineContainsNonComment) + res.commentLinesRemoved++; + break; + } + else + if(rm[0] == '/' && rm[1] == '*') { + lineContainsComment = true; + rm += 2; + for(;;) { + if(*rm == '\0') { + if(!lineContainsNonComment) + res.commentLinesRemoved++; + if(in.IsEof()) break; + SLPos(res); + ln = in.GetLine(); + rm = ~ln; + lineContainsNonComment = false; + } + if(rm[0] == '*' && rm[1] == '/') { + rm += 2; + break; + } + rm++; + } + if(include) + res.text.Cat(' '); + } + else { + lineContainsNonComment = true; + if(include) + res.text.Cat(*rm); + rm++; + } + } + if(include) + res.text << ' '; + if(cmd[0] == '$') { + if(cmd[1] == '-') include = false; + if(cmd[1] == '+') include = true; + if(cmd[1]) { + res.text.Cat(~cmd + 2); + res.text.Cat(' '); + } + } + if(lineContainsComment && !lineContainsNonComment) + res.commentLinesRemoved++; + } + } + return pick(res); +} + +END_UPP_NAMESPACE diff --git a/autotest/CppParser/test0.out b/autotest/CppParser/test0.out new file mode 100644 index 000000000..50df159d0 --- /dev/null +++ b/autotest/CppParser/test0.out @@ -0,0 +1,19 @@ +ERRORS: [63: Name expected] + { + VARIABLE , line 3 + VARIABLE , line 63 + VARIABLE , line 201 + FUNCTION Foo(int,const String&), line 65 + FUNCTION Foo(int,const String&), line 67 + FUNCTION GetCppFile(int), line 21 + FUNCTION GetCppFileIndex(const String&), line 13 + FUNCTION PreProcess(Stream&), line 69 + FUNCTION SLPos(SrcFile&), line 51 + VARIABLE cpp_file, line 11 + VARIABLE cpp_file_mutex, line 10 +} +SrcFile { + CONSTRUCTOR SrcFile(), line 56 +} + { +} \ No newline at end of file