cpp merge (continued)

git-svn-id: svn://ultimatepp.org/upp/trunk@8428 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2015-05-11 17:14:39 +00:00
parent 49d3de4a8a
commit 83267af440
78 changed files with 2453 additions and 756 deletions

View file

@ -18,8 +18,11 @@ void Test(const char *path)
FileIn in(path);
errs.Clear();
Index<String> hh;
Parser p;
p.Do(in, Vector<String>(), base, path, callback(AddError));
p.Do(in, base, 0, 0, "title", callback(AddError),
Vector<String>(), Vector<String>(), hh);
if(errs.GetCount())
DUMPC(errs);
@ -32,14 +35,23 @@ void Test(const char *path)
const Array<CppItem>& ma = base[i];
for(int j = 0; j < ma.GetCount(); j++) {
const CppItem& m = ma[j];
out << '\t' << CppItemKindAsString(m.kind) << ' ' << m.qitem << ", line " << m.line << "\n";
out << '\t' << CppItemKindAsString(m.kind) << ", name: " << m.name << ", qitem: " << m.qitem
<< ", qtype: " << m.qtype
<< ", qptype: " << m.qptype
<< ", natural: " << m.natural
<< ", line " << m.line
<< ", using " << m.using_namespaces;
if(m.isptr)
out << ", pointer";
out << "\n";
}
out << "}\n";
}
p.dobody = true;
in.Seek(0);
p.Do(in, Vector<String>(), base, path, callback(AddError));
p.Do(in, base, 0, 0, "title", callback(AddError),
Vector<String>(), Vector<String>(), hh);
out << "<locals> {\n";
for(int i = 0; i < p.local.GetCount(); i++) {
@ -52,19 +64,21 @@ void Test(const char *path)
LOG("====");
LOG(out);
LOG("-------------------------------------------------------------------------------");
#ifdef flagSAVE
SaveFile(ForceExt(path, ".out"), out);
#else
String h = LoadFile(ForceExt(path, ".out"));
h.Replace("\r", "");
ASSERT(out == h);
#endif
}
CONSOLE_APP_MAIN {
StdLogSetup(LOG_COUT|LOG_FILE);
SeedRandom(0);
#ifdef flagSINGLE
FindFile ff(GetDataFile("test5.in"));
#else
FindFile ff(GetDataFile("*.in"));
#endif
while(ff) {
Test(ff.GetPath());
ff.Next();

View file

@ -15,9 +15,41 @@ file
test4.in,
test4.out,
test5.in,
test5.out;
test5.out,
test6.in,
test6.out,
test7.in,
test7.out,
test8.in,
test8.out,
test9.in,
test9.out,
test10.in,
test10.out,
test11.in,
test11.out,
test12.in,
test12.out,
test13.in,
test13.out,
test14.in,
test14.out,
test15.in,
test15.out,
test16.in,
test16.out,
test17.in,
test17.out,
test18.in,
test18.out,
test19.in,
test19.out,
test20.in,
test20.out,
test21.in,
test21.out;
mainconfig
"" = "",
"" = "SINGLE";
"" = "SAVE";

View file

@ -1,19 +1,19 @@
ERRORS: [63: Name expected]
<globals> {
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
}
<locals> {
ERRORS: [63: Name expected]
<globals> {
VARIABLE, name: , qitem: , qtype: NAMESPACE_UPP, qptype: , natural: NAMESPACE_UPP, line 3, using
VARIABLE, name: cpp_file_mutex, qitem: cpp_file_mutex, qtype: StaticMutex, qptype: , natural: static StaticMutex cpp_file_mutex, line 10, using
VARIABLE, name: cpp_file, qitem: cpp_file, qtype: Index<String>, qptype: , natural: static Index<String> cpp_file, line 11, using
FUNCTION, name: GetCppFileIndex, qitem: GetCppFileIndex(const String&), qtype: , qptype: String, natural: int GetCppFileIndex(const String& path), line 13, using
FUNCTION, name: GetCppFile, qitem: GetCppFile(int), qtype: String, qptype: , natural: const String& GetCppFile(int i), line 21, using
FUNCTION, name: SLPos, qitem: SLPos(SrcFile&), qtype: , qptype: SrcFile, natural: void SLPos(SrcFile& res), line 51, using
VARIABLE, name: , qitem: , qtype: , qptype: , natural: void, line 63, using
FUNCTION, name: Foo, qitem: Foo(int,const String&), qtype: , qptype: ;String, natural: void Foo(int x, const String& y), line 65, using
FUNCTION, name: Foo, qitem: Foo(int,const String&), qtype: , qptype: ;String, natural: void Foo(int x, const String& y), line 67, using
FUNCTION, name: PreProcess, qitem: PreProcess(Stream&), qtype: SrcFile, qptype: Stream, natural: SrcFile PreProcess(Stream& in), line 69, using
VARIABLE, name: , qitem: , qtype: END_UPP_NAMESPACE, qptype: , natural: END_UPP_NAMESPACE, line 201, using
}
SrcFile {
CONSTRUCTOR, name: SrcFile, qitem: SrcFile(), qtype: , qptype: , natural: SrcFile(), line 56, using
}
<locals> {
}

View file

@ -1,22 +1,22 @@
<globals> {
FUNCTION Test(), line 1
FUNCTION foo(), line 15
VARIABLE global, line 13
}
Foo {
CONSTRUCTOR Foo(), line 4
STRUCT class, line 3
}
Point {
INSTANCEVARIABLE bar, line 10
INSTANCEVARIABLE next, line 9
STRUCT struct, line 7
INSTANCEVARIABLE x, line 8
INSTANCEVARIABLE y, line 8
}
<locals> {
x , line: 17
a Point, line: 18
b Point, line: 18
c Point pointer, line: 18
<globals> {
FUNCTION, name: Test, qitem: Test(), qtype: , qptype: , natural: void Test(), line 1, using
VARIABLE, name: global, qitem: global, qtype: Point, qptype: , natural: Point global, line 13, using
FUNCTION, name: foo, qitem: foo(), qtype: , qptype: , natural: void foo(), line 15, using
}
Foo {
STRUCT, name: Foo, qitem: class, qtype: Foo, qptype: , natural: class Foo, line 3, using
CONSTRUCTOR, name: Foo, qitem: Foo(), qtype: , qptype: , natural: Foo(), line 4, using
}
Point {
STRUCT, name: Point, qitem: struct, qtype: Point, qptype: , natural: struct Point, line 7, using
INSTANCEVARIABLE, name: x, qitem: x, qtype: , qptype: , natural: int x, line 8, using
INSTANCEVARIABLE, name: y, qitem: y, qtype: , qptype: , natural: int y, line 8, using
INSTANCEVARIABLE, name: next, qitem: next, qtype: Point, qptype: , natural: Point *next, line 9, using , pointer
INSTANCEVARIABLE, name: bar, qitem: bar, qtype: Foo, qptype: , natural: Foo bar, line 10, using
}
<locals> {
x , line: 17
a Point, line: 18
b Point, line: 18
c Point pointer, line: 18
}

View file

@ -0,0 +1,5 @@
template <class T, class B = EmptyClass>
class Moveable : public B
{
int boo;
};

View file

@ -0,0 +1,6 @@
Moveable {
STRUCTTEMPLATE, name: Moveable, qitem: class, qtype: Moveable, qptype: 1, natural: template <class T, class B = EmptyClass> class Moveable : public B, line 1, using
INSTANCEVARIABLE, name: boo, qitem: boo, qtype: , qptype: , natural: int boo, line 4, using
}
<locals> {
}

View file

@ -0,0 +1,3 @@
struct Foo {
friend class Bar;
};

View file

@ -0,0 +1,5 @@
Foo {
STRUCT, name: Foo, qitem: struct, qtype: Foo, qptype: , natural: struct Foo, line 1, using
}
<locals> {
}

View file

@ -0,0 +1,11 @@
enum Alpha {
FOO, BAR
};
typedef enum {
FOO, BAR
} Beta;
typedef enum Gamma {
FOO, BAR
} Gamma;

View file

@ -0,0 +1,10 @@
<globals> {
ENUM, name: FOO, qitem: FOO, qtype: , qptype: , natural: enum Alpha FOO, line 2, using
ENUM, name: BAR, qitem: BAR, qtype: , qptype: , natural: enum Alpha BAR, line 2, using
ENUM, name: FOO, qitem: FOO, qtype: , qptype: , natural: enum FOO, line 6, using
ENUM, name: BAR, qitem: BAR, qtype: , qptype: , natural: enum BAR, line 6, using
ENUM, name: FOO, qitem: FOO, qtype: , qptype: , natural: enum Gamma FOO, line 10, using
ENUM, name: BAR, qitem: BAR, qtype: , qptype: , natural: enum Gamma BAR, line 10, using
}
<locals> {
}

View file

@ -0,0 +1,48 @@
typedef struct _LARGE_INTEGER {
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
} ;
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;
typedef LARGE_INTEGER *PLARGE_INTEGER;
typedef struct _ULARGE_INTEGER {
typedef union _ULARGE_INTEGER {
struct {
DWORD LowPart;
DWORD HighPart;
} ;
struct {
DWORD LowPart;
DWORD HighPart;
} u;
ULONGLONG QuadPart;
} ULARGE_INTEGER;
typedef ULARGE_INTEGER *PULARGE_INTEGER;
typedef struct _LUID {
DWORD LowPart;
LONG HighPart;
} LUID, *PLUID;
#define _DWORDLONG_
typedef ULONGLONG DWORDLONG;
typedef DWORDLONG *PDWORDLONG;
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, * PRLIST_ENTRY;

View file

@ -0,0 +1,80 @@
_LARGE_INTEGER {
STRUCT, name: _LARGE_INTEGER, qitem: struct, qtype: _LARGE_INTEGER, qptype: , natural: , line 1, using
STRUCT, name: _LARGE_INTEGER, qitem: union, qtype: _LARGE_INTEGER, qptype: , natural: union _LARGE_INTEGER, line 3, using
INSTANCEVARIABLE, name: u, qitem: u, qtype: .u, qptype: , natural: struct { DWORD LowPart; LONG HighPart; } u, line 10, using
INSTANCEVARIABLE, name: QuadPart, qitem: QuadPart, qtype: LONGLONG, qptype: , natural: LONGLONG QuadPart, line 13, using
}
_LARGE_INTEGER::@rAp/jC+qxJd1pha3wMwh2A==/title {
STRUCT, name: @rAp/jC+qxJd1pha3wMwh2A==/title, qitem: struct, qtype: @rAp/jC+qxJd1pha3wMwh2A==/title, qptype: , natural: struct @rAp/jC+qxJd1pha3wMwh2A==/title, line 4, using
INSTANCEVARIABLE, name: LowPart, qitem: LowPart, qtype: DWORD, qptype: , natural: DWORD LowPart, line 5, using
INSTANCEVARIABLE, name: HighPart, qitem: HighPart, qtype: LONG, qptype: , natural: LONG HighPart, line 6, using
}
_LARGE_INTEGER::.u {
STRUCT, name: .u, qitem: struct, qtype: .u, qptype: , natural: struct .u, line 8, using
INSTANCEVARIABLE, name: LowPart, qitem: LowPart, qtype: DWORD, qptype: , natural: DWORD LowPart, line 9, using
INSTANCEVARIABLE, name: HighPart, qitem: HighPart, qtype: LONG, qptype: , natural: LONG HighPart, line 10, using
}
LARGE_INTEGER {
TYPEDEF, name: LARGE_INTEGER, qitem: typedef, qtype: _LARGE_INTEGER, qptype: , natural: typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; } ; struct { DWORD LowPart; LONG HighPart; } u; LONGLONG QuadPart; } LARGE_INTEGER, line 13, using
}
PLARGE_INTEGER {
TYPEDEF, name: PLARGE_INTEGER, qitem: typedef, qtype: LARGE_INTEGER, qptype: , natural: typedef LARGE_INTEGER *PLARGE_INTEGER, line 16, using
}
_ULARGE_INTEGER {
STRUCT, name: _ULARGE_INTEGER, qitem: struct, qtype: _ULARGE_INTEGER, qptype: , natural: , line 19, using
STRUCT, name: _ULARGE_INTEGER, qitem: union, qtype: _ULARGE_INTEGER, qptype: , natural: union _ULARGE_INTEGER, line 21, using
INSTANCEVARIABLE, name: u, qitem: u, qtype: .u, qptype: , natural: struct { DWORD LowPart; DWORD HighPart; } u, line 28, using
INSTANCEVARIABLE, name: QuadPart, qitem: QuadPart, qtype: ULONGLONG, qptype: , natural: ULONGLONG QuadPart, line 31, using
}
_ULARGE_INTEGER::@Q7NOmvtSotvDdn2LZ33l2A==/title {
STRUCT, name: @Q7NOmvtSotvDdn2LZ33l2A==/title, qitem: struct, qtype: @Q7NOmvtSotvDdn2LZ33l2A==/title, qptype: , natural: struct @Q7NOmvtSotvDdn2LZ33l2A==/title, line 22, using
INSTANCEVARIABLE, name: LowPart, qitem: LowPart, qtype: DWORD, qptype: , natural: DWORD LowPart, line 23, using
INSTANCEVARIABLE, name: HighPart, qitem: HighPart, qtype: DWORD, qptype: , natural: DWORD HighPart, line 24, using
}
_ULARGE_INTEGER::.u {
STRUCT, name: .u, qitem: struct, qtype: .u, qptype: , natural: struct .u, line 26, using
INSTANCEVARIABLE, name: LowPart, qitem: LowPart, qtype: DWORD, qptype: , natural: DWORD LowPart, line 27, using
INSTANCEVARIABLE, name: HighPart, qitem: HighPart, qtype: DWORD, qptype: , natural: DWORD HighPart, line 28, using
}
ULARGE_INTEGER {
TYPEDEF, name: ULARGE_INTEGER, qitem: typedef, qtype: _ULARGE_INTEGER, qptype: , natural: typedef union _ULARGE_INTEGER { struct { DWORD LowPart; DWORD HighPart; } ; struct { DWORD LowPart; DWORD HighPart; } u; ULONGLONG QuadPart; } ULARGE_INTEGER, line 31, using
}
PULARGE_INTEGER {
TYPEDEF, name: PULARGE_INTEGER, qitem: typedef, qtype: ULARGE_INTEGER, qptype: , natural: typedef ULARGE_INTEGER *PULARGE_INTEGER, line 34, using
}
_LUID {
STRUCT, name: _LUID, qitem: struct, qtype: _LUID, qptype: , natural: struct _LUID, line 36, using
INSTANCEVARIABLE, name: LowPart, qitem: LowPart, qtype: DWORD, qptype: , natural: DWORD LowPart, line 37, using
INSTANCEVARIABLE, name: HighPart, qitem: HighPart, qtype: LONG, qptype: , natural: LONG HighPart, line 38, using
}
LUID {
TYPEDEF, name: LUID, qitem: typedef, qtype: _LUID, qptype: , natural: typedef struct _LUID { DWORD LowPart; LONG HighPart; } LUID, line 38, using
}
PLUID {
TYPEDEF, name: PLUID, qitem: typedef, qtype: _LUID, qptype: , natural: typedef struct _LUID { DWORD LowPart; LONG HighPart; } *PLUID, line 38, using
}
<globals> {
MACRO, name: _DWORDLONG_, qitem: _DWORDLONG_, qtype: , qptype: , natural: _DWORDLONG_, line 41, using
}
DWORDLONG {
TYPEDEF, name: DWORDLONG, qitem: typedef, qtype: ULONGLONG, qptype: , natural: typedef ULONGLONG DWORDLONG, line 42, using
}
PDWORDLONG {
TYPEDEF, name: PDWORDLONG, qitem: typedef, qtype: DWORDLONG, qptype: , natural: typedef DWORDLONG *PDWORDLONG, line 43, using
}
_LIST_ENTRY {
STRUCT, name: _LIST_ENTRY, qitem: struct, qtype: _LIST_ENTRY, qptype: , natural: struct _LIST_ENTRY, line 45, using
INSTANCEVARIABLE, name: Flink, qitem: Flink, qtype: _LIST_ENTRY, qptype: , natural: struct _LIST_ENTRY *Flink, line 46, using , pointer
INSTANCEVARIABLE, name: Blink, qitem: Blink, qtype: _LIST_ENTRY, qptype: , natural: struct _LIST_ENTRY *Blink, line 47, using , pointer
}
LIST_ENTRY {
TYPEDEF, name: LIST_ENTRY, qitem: typedef, qtype: _LIST_ENTRY, qptype: , natural: typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } LIST_ENTRY, line 47, using
}
PLIST_ENTRY {
TYPEDEF, name: PLIST_ENTRY, qitem: typedef, qtype: _LIST_ENTRY, qptype: , natural: typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } *PLIST_ENTRY, line 47, using
}
PRLIST_ENTRY {
TYPEDEF, name: PRLIST_ENTRY, qitem: typedef, qtype: _LIST_ENTRY, qptype: , natural: typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } * PRLIST_ENTRY, line 47, using
}
<locals> {
}

View file

@ -0,0 +1,28 @@
typedef struct {
int x;
struct Foo {
int a;
} y;
struct {
int bar;
};
struct {
int foo;
} quack;
} name;
namespace std {
struct string {};
};
// void Foo(string a);
using namespace std;
struct Bar {
struct string {};
std::string Foo(string a);
};
void Foo(string a);

View file

@ -0,0 +1,36 @@
.name {
STRUCT, name: .name, qitem: struct, qtype: .name, qptype: , natural: struct .name, line 1, using
INSTANCEVARIABLE, name: x, qitem: x, qtype: , qptype: , natural: int x, line 2, using
INSTANCEVARIABLE, name: y, qitem: y, qtype: .name::Foo, qptype: , natural: struct Foo { int a; } y, line 4, using
INSTANCEVARIABLE, name: quack, qitem: quack, qtype: .quack, qptype: , natural: struct { int foo; } quack, line 10, using
}
.name::Foo {
STRUCT, name: Foo, qitem: struct, qtype: .name::Foo, qptype: , natural: struct Foo, line 3, using
INSTANCEVARIABLE, name: a, qitem: a, qtype: , qptype: , natural: int a, line 4, using
}
.name::@WJqy9ozNzEU6OSliwUJIeg==/title {
STRUCT, name: @WJqy9ozNzEU6OSliwUJIeg==/title, qitem: struct, qtype: @WJqy9ozNzEU6OSliwUJIeg==/title, qptype: , natural: struct @WJqy9ozNzEU6OSliwUJIeg==/title, line 6, using
INSTANCEVARIABLE, name: bar, qitem: bar, qtype: , qptype: , natural: int bar, line 7, using
}
.name::.quack {
STRUCT, name: .quack, qitem: struct, qtype: .quack, qptype: , natural: struct .quack, line 9, using
INSTANCEVARIABLE, name: foo, qitem: foo, qtype: , qptype: , natural: int foo, line 10, using
}
name {
TYPEDEF, name: name, qitem: typedef, qtype: .name, qptype: , natural: typedef struct { int x; struct Foo { int a; } y; struct { int bar; }; struct { int foo; } quack; } name, line 10, using
}
std::string {
STRUCT, name: string, qitem: struct, qtype: std::string, qptype: , natural: struct string, line 15, using
}
Bar {
STRUCT, name: Bar, qitem: struct, qtype: Bar, qptype: , natural: struct Bar, line 22, using std
INSTANCEFUNCTION, name: Foo, qitem: Foo(Bar::string), qtype: std::string, qptype: Bar::string, natural: std::string Foo(string a), line 25, using std
}
Bar::string {
STRUCT, name: string, qitem: struct, qtype: Bar::string, qptype: , natural: struct string, line 23, using std
}
<globals> {
FUNCTION, name: Foo, qitem: Foo(std::string), qtype: , qptype: std::string, natural: void Foo(string a), line 28, using std
}
<locals> {
}

View file

@ -0,0 +1,3 @@
#define _THROW0() throw ()
void Test() _THROW0()

View file

@ -0,0 +1,7 @@
<globals> {
MACRO, name: _THROW0, qitem: _THROW0(), qtype: , qptype: , natural: _THROW0(), line 1, using
FUNCTION, name: Test, qitem: Test(), qtype: , qptype: , natural: void Test(), line 3, using
VARIABLE, name: , qitem: , qtype: _THROW0, qptype: , natural: _THROW0(), line 3, using
}
<locals> {
}

View file

@ -0,0 +1,9 @@
typedef enum _MANDATORY_LEVEL {
MandatoryLevelUntrusted = 0,
MandatoryLevelLow,
MandatoryLevelMedium,
MandatoryLevelHigh,
MandatoryLevelSystem,
MandatoryLevelSecureProcess,
MandatoryLevelCount
} MANDATORY_LEVEL, *PMANDATORY_LEVEL;

View file

@ -0,0 +1,11 @@
<globals> {
ENUM, name: MandatoryLevelUntrusted, qitem: MandatoryLevelUntrusted, qtype: , qptype: , natural: enum _MANDATORY_LEVEL MandatoryLevelUntrusted = 0, line 2, using
ENUM, name: MandatoryLevelLow, qitem: MandatoryLevelLow, qtype: , qptype: , natural: enum _MANDATORY_LEVEL MandatoryLevelLow, line 3, using
ENUM, name: MandatoryLevelMedium, qitem: MandatoryLevelMedium, qtype: , qptype: , natural: enum _MANDATORY_LEVEL MandatoryLevelMedium, line 4, using
ENUM, name: MandatoryLevelHigh, qitem: MandatoryLevelHigh, qtype: , qptype: , natural: enum _MANDATORY_LEVEL MandatoryLevelHigh, line 5, using
ENUM, name: MandatoryLevelSystem, qitem: MandatoryLevelSystem, qtype: , qptype: , natural: enum _MANDATORY_LEVEL MandatoryLevelSystem, line 6, using
ENUM, name: MandatoryLevelSecureProcess, qitem: MandatoryLevelSecureProcess, qtype: , qptype: , natural: enum _MANDATORY_LEVEL MandatoryLevelSecureProcess, line 7, using
ENUM, name: MandatoryLevelCount, qitem: MandatoryLevelCount, qtype: , qptype: , natural: enum _MANDATORY_LEVEL MandatoryLevelCount, line 8, using
}
<locals> {
}

View file

@ -0,0 +1,4 @@
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, * PRLIST_ENTRY;

View file

@ -0,0 +1,16 @@
_LIST_ENTRY {
STRUCT, name: _LIST_ENTRY, qitem: struct, qtype: _LIST_ENTRY, qptype: , natural: struct _LIST_ENTRY, line 1, using
INSTANCEVARIABLE, name: Flink, qitem: Flink, qtype: _LIST_ENTRY, qptype: , natural: struct _LIST_ENTRY *Flink, line 2, using , pointer
INSTANCEVARIABLE, name: Blink, qitem: Blink, qtype: _LIST_ENTRY, qptype: , natural: struct _LIST_ENTRY *Blink, line 3, using , pointer
}
LIST_ENTRY {
TYPEDEF, name: LIST_ENTRY, qitem: typedef, qtype: _LIST_ENTRY, qptype: , natural: typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } LIST_ENTRY, line 3, using
}
PLIST_ENTRY {
TYPEDEF, name: PLIST_ENTRY, qitem: typedef, qtype: _LIST_ENTRY, qptype: , natural: typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } *PLIST_ENTRY, line 3, using
}
PRLIST_ENTRY {
TYPEDEF, name: PRLIST_ENTRY, qitem: typedef, qtype: _LIST_ENTRY, qptype: , natural: typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } * PRLIST_ENTRY, line 3, using
}
<locals> {
}

View file

@ -0,0 +1 @@
String EncodeHtml(const String& x, const VectorMap<String, String>& escape = VectorMap<String, String>());

View file

@ -0,0 +1,5 @@
<globals> {
FUNCTION, name: EncodeHtml, qitem: EncodeHtml(const String&,const VectorMap<String,String>&), qtype: String, qptype: String;VectorMap<String,String>, natural: String EncodeHtml(const String& x, const VectorMap<String, String>& escape = VectorMap<String, String>()), line 1, using
}
<locals> {
}

View file

@ -0,0 +1 @@
[attr] [attr] int function([attr] [attr] string x[4], [attr] int y[4][5], [attr] const int& x, int (*f)[4]);

View file

@ -0,0 +1,5 @@
<globals> {
FUNCTION, name: function, qitem: function(string[4],int[4][5],const int&,int(*)[4]), qtype: , qptype: string;;;, natural: int function(string x[4], int y[4][5], const int& x, int (*f)[4]), line 1, using
}
<locals> {
}

View file

@ -1,8 +1,8 @@
_CrtEnableIf<true, _Ty> {
STRUCTTEMPLATE struct, line 1
}
_CrtEnableIf<true, _Ty> ::_Type {
TYPEDEF typedef, line 4
}
<locals> {
_CrtEnableIf<true, _Ty> {
STRUCTTEMPLATE, name: _CrtEnableIf<true, _Ty> , qitem: struct, qtype: _CrtEnableIf<true,_Ty>, qptype: , natural: template <true, typename _Ty> struct _CrtEnableIf<true, _Ty> , line 1, using
}
_CrtEnableIf<true, _Ty> ::_Type {
TYPEDEF, name: _Type, qitem: typedef, qtype: 1, qptype: , natural: typedef _Ty _Type, line 4, using
}
<locals> {
}

View file

@ -0,0 +1 @@
;

View file

@ -0,0 +1,2 @@
<locals> {
}

View file

@ -0,0 +1,5 @@
int static foo();
FOO
static Bar bar;

View file

@ -0,0 +1,7 @@
<globals> {
FUNCTION, name: foo, qitem: foo(), qtype: , qptype: , natural: int foo(), line 1, using
VARIABLE, name: , qitem: , qtype: FOO, qptype: , natural: FOO, line 3, using
VARIABLE, name: bar, qitem: bar, qtype: Bar, qptype: , natural: static Bar bar, line 5, using
}
<locals> {
}

View file

@ -1,5 +1,5 @@
<globals> {
FUNCTIONTEMPLATE memcpy(_DstType(&)[_Size],const void*,size_t)throw(), line 3
}
<locals> {
<globals> {
FUNCTIONTEMPLATE, name: memcpy, qitem: memcpy(_DstType(&)[_Size],const void*,size_t)throw(), qtype: _CrtEnableIf<(_Size>1),void*>, qptype: _DstType;;size_t, natural: template <size_t _Size, typename _DstType> typename _CrtEnableIf<(_Size > 1), void *>::_Type memcpy(_DstType (&_Dst)[_Size], const void *_Src, size_t _SrcSize) throw(), line 3, using
}
<locals> {
}

View file

@ -1,5 +1,5 @@
<globals> {
FUNCTIONTEMPLATE Fn<true,int>(), line 1
}
<locals> {
<globals> {
FUNCTIONTEMPLATE, name: Fn<true, int>, qitem: Fn<true,int>(), qtype: , qptype: , natural: template <class T> void Fn<true, int>(), line 1, using
}
<locals> {
}

View file

@ -1,9 +1,9 @@
Value {
STRUCT class, line 1
INSTANCEFUNCTION operator<(const Value&)const, line 4
INSTANCEFUNCTION operator<=(const Value&)const, line 2
INSTANCEFUNCTION operator>(const Value&)const, line 5
INSTANCEFUNCTION operator>=(const Value&)const, line 3
}
<locals> {
Value {
STRUCT, name: Value, qitem: class, qtype: Value, qptype: , natural: class Value, line 1, using
INSTANCEFUNCTION, name: operator<=, qitem: operator<=(const Value&)const, qtype: , qptype: Value, natural: bool operator<=(const Value& x) const, line 2, using
INSTANCEFUNCTION, name: operator>=, qitem: operator>=(const Value&)const, qtype: , qptype: Value, natural: bool operator>=(const Value& x) const, line 3, using
INSTANCEFUNCTION, name: operator<, qitem: operator<(const Value&)const, qtype: , qptype: Value, natural: bool operator<(const Value& x) const, line 4, using
INSTANCEFUNCTION, name: operator>, qitem: operator>(const Value&)const, qtype: , qptype: Value, natural: bool operator>(const Value& x) const, line 5, using
}
<locals> {
}

View file

@ -0,0 +1 @@
[attribute] void test([attribute] const int a);

View file

@ -0,0 +1,5 @@
<globals> {
FUNCTION, name: test, qitem: test(const int), qtype: , qptype: , natural: void test(const int a), line 1, using
}
<locals> {
}

View file

@ -0,0 +1,20 @@
__inline
char *
__insecure__strlwr_l(
[SA_Pre( Null=SA_No, NullTerminated=SA_Yes)]
[SA_Pre(Deref=1, Valid=SA_Yes)]
[SA_Post( NullTerminated=SA_Yes)]
[SA_Post(Deref=1, Valid=SA_Yes)]
char *_String,
[SA_Pre( Null=SA_Maybe)] [SA_Pre(Deref=1, Valid=SA_Yes)]
[SA_Pre(Deref=1, Access=SA_Read)]
_locale_t _Locale)
{
char * _strlwr_l([SA_Pre( Null=SA_No, NullTerminated=SA_Yes)]
[SA_Pre(Deref=1, Valid=SA_Yes)]
[SA_Post( NullTerminated=SA_Yes)]
[SA_Post(Deref=1, Valid=SA_Yes)]
char *_String,
[SA_Pre( Null=SA_Maybe)] [SA_Pre(Deref=1, Valid=SA_Yes)]
[SA_Pre(Deref=1, Access=SA_Read)] _locale_t _Locale);
return _strlwr_l(_String, _Locale); }

View file

@ -0,0 +1,5 @@
<globals> {
FUNCTION, name: __insecure__strlwr_l, qitem: __insecure__strlwr_l(char*,_locale_t), qtype: , qptype: ;_locale_t, natural: __inline char * __insecure__strlwr_l( char *_String, _locale_t _Locale), line 1, using
}
<locals> {
}

View file

@ -0,0 +1,26 @@
struct {
DWORD TimeCheck;
BYTE DemotePercent;
BYTE PromotePercent;
BYTE Spare[2];
} vPROCESSOR_IDLESTATE_INFO, *vPPROCESSOR_IDLESTATE_INFO;
typedef struct {
DWORD TimeCheck;
BYTE DemotePercent;
BYTE PromotePercent;
BYTE Spare[2];
} PROCESSOR_IDLESTATE_INFO, *PPROCESSOR_IDLESTATE_INFO;
struct Point {
int x, y;
} xxx, yyy;
typedef struct PointT {
int x, y;
} PPP;
template <class T>
struct TPoint {
T x, y;
};

View file

@ -0,0 +1,46 @@
.vPROCESSOR_IDLESTATE_INFO {
STRUCT, name: .vPROCESSOR_IDLESTATE_INFO, qitem: struct, qtype: .vPROCESSOR_IDLESTATE_INFO, qptype: , natural: struct .vPROCESSOR_IDLESTATE_INFO, line 1, using
INSTANCEVARIABLE, name: TimeCheck, qitem: TimeCheck, qtype: DWORD, qptype: , natural: DWORD TimeCheck, line 2, using
INSTANCEVARIABLE, name: DemotePercent, qitem: DemotePercent, qtype: BYTE, qptype: , natural: BYTE DemotePercent, line 3, using
INSTANCEVARIABLE, name: PromotePercent, qitem: PromotePercent, qtype: BYTE, qptype: , natural: BYTE PromotePercent, line 4, using
INSTANCEVARIABLE, name: Spare, qitem: Spare, qtype: BYTE, qptype: , natural: BYTE Spare[2], line 5, using , pointer
}
<globals> {
VARIABLE, name: vPROCESSOR_IDLESTATE_INFO, qitem: vPROCESSOR_IDLESTATE_INFO, qtype: .vPROCESSOR_IDLESTATE_INFO, qptype: , natural: struct { DWORD TimeCheck; BYTE DemotePercent; BYTE PromotePercent; BYTE Spare[2]; } vPROCESSOR_IDLESTATE_INFO, line 5, using
VARIABLE, name: vPPROCESSOR_IDLESTATE_INFO, qitem: vPPROCESSOR_IDLESTATE_INFO, qtype: .vPROCESSOR_IDLESTATE_INFO, qptype: , natural: struct { DWORD TimeCheck; BYTE DemotePercent; BYTE PromotePercent; BYTE Spare[2]; } *vPPROCESSOR_IDLESTATE_INFO, line 5, using , pointer
VARIABLE, name: xxx, qitem: xxx, qtype: Point, qptype: , natural: struct Point { int x, y; } xxx, line 16, using
VARIABLE, name: yyy, qitem: yyy, qtype: Point, qptype: , natural: struct Point { int x, y; } yyy, line 16, using
}
.PROCESSOR_IDLESTATE_INFO {
STRUCT, name: .PROCESSOR_IDLESTATE_INFO, qitem: struct, qtype: .PROCESSOR_IDLESTATE_INFO, qptype: , natural: struct .PROCESSOR_IDLESTATE_INFO, line 8, using
INSTANCEVARIABLE, name: TimeCheck, qitem: TimeCheck, qtype: DWORD, qptype: , natural: DWORD TimeCheck, line 9, using
INSTANCEVARIABLE, name: DemotePercent, qitem: DemotePercent, qtype: BYTE, qptype: , natural: BYTE DemotePercent, line 10, using
INSTANCEVARIABLE, name: PromotePercent, qitem: PromotePercent, qtype: BYTE, qptype: , natural: BYTE PromotePercent, line 11, using
INSTANCEVARIABLE, name: Spare, qitem: Spare, qtype: BYTE, qptype: , natural: BYTE Spare[2], line 12, using , pointer
}
PROCESSOR_IDLESTATE_INFO {
TYPEDEF, name: PROCESSOR_IDLESTATE_INFO, qitem: typedef, qtype: .PROCESSOR_IDLESTATE_INFO, qptype: , natural: typedef struct { DWORD TimeCheck; BYTE DemotePercent; BYTE PromotePercent; BYTE Spare[2]; } PROCESSOR_IDLESTATE_INFO, line 12, using
}
PPROCESSOR_IDLESTATE_INFO {
TYPEDEF, name: PPROCESSOR_IDLESTATE_INFO, qitem: typedef, qtype: .PROCESSOR_IDLESTATE_INFO, qptype: , natural: typedef struct { DWORD TimeCheck; BYTE DemotePercent; BYTE PromotePercent; BYTE Spare[2]; } *PPROCESSOR_IDLESTATE_INFO, line 12, using
}
Point {
STRUCT, name: Point, qitem: struct, qtype: Point, qptype: , natural: struct Point, line 15, using
INSTANCEVARIABLE, name: x, qitem: x, qtype: , qptype: , natural: int x, line 16, using
INSTANCEVARIABLE, name: y, qitem: y, qtype: , qptype: , natural: int y, line 16, using
}
PointT {
STRUCT, name: PointT, qitem: struct, qtype: PointT, qptype: , natural: struct PointT, line 19, using
INSTANCEVARIABLE, name: x, qitem: x, qtype: , qptype: , natural: int x, line 20, using
INSTANCEVARIABLE, name: y, qitem: y, qtype: , qptype: , natural: int y, line 20, using
}
PPP {
TYPEDEF, name: PPP, qitem: typedef, qtype: PointT, qptype: , natural: typedef struct PointT { int x, y; } PPP, line 20, using
}
TPoint {
STRUCTTEMPLATE, name: TPoint, qitem: struct, qtype: TPoint, qptype: , natural: template <class T> struct TPoint, line 23, using
INSTANCEVARIABLE, name: x, qitem: x, qtype: 0, qptype: , natural: T x, line 25, using
INSTANCEVARIABLE, name: y, qitem: y, qtype: 0, qptype: , natural: T y, line 25, using
}
<locals> {
}

View file

@ -0,0 +1,6 @@
SHORT
_InterlockedCompareExchange16 (
SHORT volatile *Destination,
SHORT ExChange,
SHORT Comperand
);

View file

@ -0,0 +1,5 @@
<globals> {
FUNCTION, name: _InterlockedCompareExchange16, qitem: _InterlockedCompareExchange16(SHORT volatile*,SHORT,SHORT), qtype: SHORT, qptype: SHORT;SHORT;SHORT, natural: SHORT _InterlockedCompareExchange16 ( SHORT volatile *Destination, SHORT ExChange, SHORT Comperand ), line 1, using
}
<locals> {
}

View file

@ -0,0 +1,27 @@
#include <Core/Core.h>
#include <CppBase/CppBase.h>
using namespace Upp;
CONSOLE_APP_MAIN
{
String path = GetDataFile("test.in");
PPSync(GetFileFolder(path));
Cpp cpp;
FileIn in(path);
cpp.Preprocess(path, in, path);
String s = cpp.output;
String opath = GetDataFile("test.out");
LOG("======================");
LOG(cpp.output);
#ifdef flagSAVE
SaveFile(opath, s);
#else
ASSERT(LoadFile(opath) == s);
#endif
LOG("===================== OK");
}

View file

@ -0,0 +1,14 @@
uses
Core,
CppBase;
file
PPTest.cpp,
test.in,
test.out,
help.in;
mainconfig
"" = "",
"" = "SAVE";

127
autotest/PPTest/help.in Normal file
View file

@ -0,0 +1,127 @@
#define COMBINE__(a, b) a##b
#define COMBINE(a, b) COMBINE__(a, b)
#define COMBINE3__(a, b, c) a##b##c
#define COMBINE3(a, b, c) COMBINE3__(a, b, c)
#define COMBINE4__(a, b, c, d) a##b##c##d
#define COMBINE4(a, b, c, d) COMBINE4__(a, b, c, d)
#define COMBINE5__(a, b, c, d, e) a##b##c##d##e
#define COMBINE5(a, b, c, d, e) COMBINE5__(a, b, c, d, e)
#define _cm_ ,
#define __countof(a) int(sizeof(a) / sizeof(a[0]))
#define __Expand1(x) x(1)
#define __Expand2(x) __Expand1(x) x(2)
#define __Expand3(x) __Expand2(x) x(3)
#define __Expand4(x) __Expand3(x) x(4)
#define __Expand5(x) __Expand4(x) x(5)
#define __List1(x) x(1)
#define __List2(x) __List1(x), x(2)
#define __List3(x) __List2(x), x(3)
#define __List4(x) __List3(x), x(4)
#define __List5(x) __List4(x), x(5)
#define E__p(I) p##I
#define MK__s__(x) s__s##x
#define MK__s_(x) MK__s__(x)
// #define MK__s MK__s_(__LINE__)
#define MK__s MK__s_(COMBINE3(BLITZ_INDEX__, _, __LINE__))
#define INITBLOCK \
static void COMBINE(MK__s, _fn)(); static UPP::Callinit MK__s(COMBINE(MK__s, _fn), __FILE__, __LINE__); \
static void COMBINE(MK__s, _fn)()
//---------------------------------------------------
#define E__NFValue(I) const Value& COMBINE(p, I)
#define E__NFBody(I) \
String Format(const char *fmt, __List##I(E__NFValue));
__Expand5(E__NFBody)
// =============
INITBLOCK {
Value::SvoRegister<Color>("Color");
}
// =============
#define max (a, b) (a < b ? b : a)
max(12, 23)
max (A, B)
#undef max
#define max(a, b) (a < b ? b : a)
max(12, 23)
max (A, B)
// =============
#define macro something // comment
macro
something
//$- comment
#define mm(a, b, c, d) (d) [c] {b} <a>
mm(1, 2, 3, 4)
mm(1, 2,
3, 4)
mm(1,
2,
3,
4
)
// =============
#define MACRO(x) 123+x
MACRO(
x
)
MACRO(x
)
MACRO(x)
MACRO(x)
MACRO(x
)
// =============
#undef _STCONS
#define _STCONS(ty, name, val) static const ty name = (ty)(val)
_STCONS(float_denorm_style, has_denorm, denorm_absent);
#define InterlockedIncrement16 _InterlockedIncrement16
SHORT
InterlockedIncrement16 (
SHORT volatile *Addend
);

5
autotest/PPTest/init Normal file
View file

@ -0,0 +1,5 @@
#ifndef _PPTest_icpp_init_stub
#define _PPTest_icpp_init_stub
#include "Core/init"
#include "CppBase/init"
#endif

127
autotest/PPTest/test.in Normal file
View file

@ -0,0 +1,127 @@
#define COMBINE__(a, b) a##b
#define COMBINE(a, b) COMBINE__(a, b)
#define COMBINE3__(a, b, c) a##b##c
#define COMBINE3(a, b, c) COMBINE3__(a, b, c)
#define COMBINE4__(a, b, c, d) a##b##c##d
#define COMBINE4(a, b, c, d) COMBINE4__(a, b, c, d)
#define COMBINE5__(a, b, c, d, e) a##b##c##d##e
#define COMBINE5(a, b, c, d, e) COMBINE5__(a, b, c, d, e)
#define _cm_ ,
#define __countof(a) int(sizeof(a) / sizeof(a[0]))
#define __Expand1(x) x(1)
#define __Expand2(x) __Expand1(x) x(2)
#define __Expand3(x) __Expand2(x) x(3)
#define __Expand4(x) __Expand3(x) x(4)
#define __Expand5(x) __Expand4(x) x(5)
#define __List1(x) x(1)
#define __List2(x) __List1(x), x(2)
#define __List3(x) __List2(x), x(3)
#define __List4(x) __List3(x), x(4)
#define __List5(x) __List4(x), x(5)
#define E__p(I) p##I
#define MK__s__(x) s__s##x
#define MK__s_(x) MK__s__(x)
// #define MK__s MK__s_(__LINE__)
#define MK__s MK__s_(COMBINE3(BLITZ_INDEX__, _, __LINE__))
#define INITBLOCK \
static void COMBINE(MK__s, _fn)(); static UPP::Callinit MK__s(COMBINE(MK__s, _fn), __FILE__, __LINE__); \
static void COMBINE(MK__s, _fn)()
//---------------------------------------------------
#define E__NFValue(I) const Value& COMBINE(p, I)
#define E__NFBody(I) \
String Format(const char *fmt, __List##I(E__NFValue));
__Expand5(E__NFBody)
// =============
INITBLOCK {
Value::SvoRegister<Color>("Color");
}
// =============
#define max (a, b) (a < b ? b : a)
max(12, 23)
max (A, B)
#undef max
#define max(a, b) (a < b ? b : a)
max(12, 23)
max (A, B)
// =============
#define macro something // comment
macro
something
//$- comment
#define mm(a, b, c, d) (d) [c] {b} <a>
mm(1, 2, 3, 4)
mm(1, 2,
3, 4)
mm(1,
2,
3,
4
)
// =============
#define MACRO(x) 123+x
MACRO(
x
)
MACRO(x
)
MACRO(x)
MACRO(x)
MACRO(x
)
// =============
#undef _STCONS
#define _STCONS(ty, name, val) static const ty name = (ty)(val)
_STCONS(float_denorm_style, has_denorm, denorm_absent);
#define InterlockedIncrement16 _InterlockedIncrement16
SHORT
InterlockedIncrement16 (
SHORT volatile *Addend
);

127
autotest/PPTest/test.out Normal file
View file

@ -0,0 +1,127 @@
#define COMBINE__(a, b) a##b
#define COMBINE(a, b) COMBINE__(a, b)
#define COMBINE3__(a, b, c) a##b##c
#define COMBINE3(a, b, c) COMBINE3__(a, b, c)
#define COMBINE4__(a, b, c, d) a##b##c##d
#define COMBINE4(a, b, c, d) COMBINE4__(a, b, c, d)
#define COMBINE5__(a, b, c, d, e) a##b##c##d##e
#define COMBINE5(a, b, c, d, e) COMBINE5__(a, b, c, d, e)
#define _cm_ ,
#define __countof(a) int(sizeof(a) / sizeof(a[0]))
#define __Expand1(x) x(1)
#define __Expand2(x) __Expand1(x) x(2)
#define __Expand3(x) __Expand2(x) x(3)
#define __Expand4(x) __Expand3(x) x(4)
#define __Expand5(x) __Expand4(x) x(5)
#define __List1(x) x(1)
#define __List2(x) __List1(x), x(2)
#define __List3(x) __List2(x), x(3)
#define __List4(x) __List3(x), x(4)
#define __List5(x) __List4(x), x(5)
#define E__p(I) p##I
#define MK__s__(x) s__s##x
#define MK__s_(x) MK__s__(x)
// #define MK__s MK__s_(__LINE__)
#define MK__s MK__s_(COMBINE3(BLITZ_INDEX__, _, __LINE__))
#define INITBLOCK static void COMBINE(MK__s, _fn)(); static UPP::Callinit MK__s(COMBINE(MK__s, _fn), __FILE__, __LINE__); static void COMBINE(MK__s, _fn)()
//---------------------------------------------------
#define E__NFValue(I) const Value& COMBINE(p, I)
#define E__NFBody(I) String Format(const char *fmt, __List##I(E__NFValue));
String Format(const char *fmt, const Value& p1); String Format(const char *fmt, const Value& p1, const Value& p2); String Format(const char *fmt, const Value& p1, const Value& p2, const Value& p3); String Format(const char *fmt, const Value& p1, const Value& p2, const Value& p3, const Value& p4); String Format(const char *fmt, const Value& p1, const Value& p2, const Value& p3, const Value& p4, const Value& p5);
// =============
 static void s__sBLITZ_INDEX_____LINE___fn(); static UPP::Callinit  s__sBLITZ_INDEX_____LINE__(s__sBLITZ_INDEX_____LINE___fn, __FILE__, __LINE__); static void s__sBLITZ_INDEX_____LINE___fn() {
Value::SvoRegister<Color>("Color");
}
// =============
#define max (a, b) (a < b ? b : a)
 (a, b) (a < b ? b : a)(12, 23)
 (a, b) (a < b ? b : a) (A, B)
#undef max
#define max(a, b) (a < b ? b : a)
(12 < 23 ? 23 : 12)
(A < B ? B : A)
// =============
#define macro something // comment
 something
something
//$- comment
#define mm(a, b, c, d) (d) [c] {b} <a>
(4) [3] {2} <1>
(4) [3] {2} <1>
(4) [3] {2} <1>
// =============
#define MACRO(x) 123+x
123+x
123+x
123+x
123+x
123+x
// =============
#undef _STCONS
#define _STCONS(ty, name, val) static const ty name = (ty)(val)
static const float_denorm_style has_denorm = (float_denorm_style)(denorm_absent);
#define InterlockedIncrement16 _InterlockedIncrement16
SHORT
 _InterlockedIncrement16 (
SHORT volatile *Addend
);

View file

@ -0,0 +1,8 @@
file
file.cpp,
file2.h,
file1.h;
mainconfig
"" = "";

7
uppdev/CppTest/file.cpp Normal file
View file

@ -0,0 +1,7 @@
#include "file2.h"
void Foo2() {}
MACRO(printf("Hello!"));
void Foo() {}

5
uppdev/CppTest/file1.h Normal file
View file

@ -0,0 +1,5 @@
#define MACRO3
#define MACRO_NEW test
#include "file2.h"

3
uppdev/CppTest/file2.h Normal file
View file

@ -0,0 +1,3 @@
#define MACRO(x) void main() { x; }x
#define MACRO3 xxx2333

3
uppdev/CppTest/init Normal file
View file

@ -0,0 +1,3 @@
#ifndef _CppTest_icpp_init_stub
#define _CppTest_icpp_init_stub
#endif

View file

@ -0,0 +1,79 @@
#include <CppBase/CppBase.h>
using namespace Upp;
Vector<String> errs;
void AddError(int ln, const String& s)
{
errs.Add(AsString(ln) + ": " + s);
}
void Test(const char *path)
{
CppBase base;
LOG("**** " << GetFileName(path));
FileIn in(path);
errs.Clear();
Index<String> hh;
hh.Add("test");
Parser p;
// p.Do(in, base, 0, 0, GetFileTitle(path), callback(AddError), Vector<String>(), Vector<String>(), Index<String>());
p.Do(in, base, 0, 0, GetFileTitle(path), callback(AddError),
Vector<String>(), Vector<String>(), hh);
if(errs.GetCount())
DUMPC(errs);
Qualify(base);
String out;
for(int i = 0; i < base.GetCount(); i++) {
out << Nvl(base.GetKey(i), "<globals>") << " {\n";
const Array<CppItem>& ma = base[i];
for(int j = 0; j < ma.GetCount(); j++) {
const CppItem& m = ma[j];
out << '\t' << CppItemKindAsString(m.kind) << ", name: " << m.name << ", qitem: " << m.qitem
<< ", qtype " << m.qtype << ", qptype: " << m.qptype << ", line " << m.line
<< ", using " << m.using_namespaces
<< ", item " << m.item
<< ", natural " << m.natural
<< "\n";
}
out << "}\n";
}
// base.Dump(VppLog());
p.dobody = true;
in.Seek(0);
p.Do(in, base, 0, 0, GetFileTitle(path), callback(AddError),
Vector<String>(), Vector<String>(), hh);
out << "<locals> {\n";
for(int i = 0; i < p.local.GetCount(); i++) {
out << p.local.GetKey(i) << " " << p.local[i].type;
if(p.local[i].isptr)
out << " pointer";
out << ", line: " << p.local[i].line << "\n";
}
out << "}";
LOG("====");
LOG(out);
LOG("-------------------------------------------------------------------------------");
}
CONSOLE_APP_MAIN {
StdLogSetup(LOG_COUT|LOG_FILE);
// Test("C:/xxx/cpp/math");
Test(GetDataFile("test1.in"));
/*
FindFile ff(GetDataFile("test1.in"));
while(ff) {
Test(ff.GetPath());
ff.Next();
}
*/
}

View file

@ -0,0 +1,18 @@
uses
Core,
CppBase;
file
CppParser.cpp,
todo.txt,
test1.in,
test1.out,
test2.in,
test2.out,
test3.in,
todo.in,
totest.in;
mainconfig
"" = "SSE2";

View file

@ -0,0 +1,5 @@
#ifndef _TestCppParser_icpp_init_stub
#define _TestCppParser_icpp_init_stub
#include "Core/init"
#include "CppBase/init"
#endif

View file

@ -0,0 +1 @@
inline int static foo();

View file

@ -0,0 +1,29 @@
typedef struct {
int x;
struct Foo {
int a;
} y;
struct {
int bar;
};
struct {
int foo;
} quack;
} name;
namespace std {
struct string {};
};
// void Foo(string a);
using namespace std;
struct Bar {
struct string {};
std::string Foo(string a);
};
void Foo(string a);

View file

@ -0,0 +1,31 @@
============
struct Foo {
struct Foo;
Foo *x;
};
============
String EncodeHtml(const RichText& text, Index<String>& css,
const VectorMap<String, String>& links,
const VectorMap<String, String>& labels,
const String& path, const String& base = Null, Zoom z = Zoom(8, 40),
const VectorMap<String, String>& escape = VectorMap<String, String>(),
int imtolerance = 0);
============
_onexit_t onexit( [SA_Pre( Null=SA_Maybe)] [SA_Pre(Deref=1, Valid=SA_Yes)] [SA_Pre(Deref=1, Access=SA_Read)] _onexit_t _Func);
============
typedef struct tagMONCONVSTRUCT {
UINT cb;
BOOL fConnect;
DWORD dwTime;
HANDLE hTask;
HSZ hszSvc;
HSZ hszTopic;
HCONV hConvClient; // Globally unique value != apps local hConv
HCONV hConvServer; // Globally unique value != apps local hConv
} MONCONVSTRUCT, *PMONCONVSTRUCT;
// ^^^^ have invalid line number
=============
typedef GUID *REFGUID;

View file

@ -0,0 +1,5 @@
========================
[attr] [attr] int function([attr] [attr] string x[4], [attr] int y[4], [attr] const int& x);
==============
;
==============

View file

@ -1,243 +0,0 @@
#include "cpp.h"
void Cpp::Define(const char *s)
{
CppMacro m;
String id = m.Define(s);
if(id.GetCount())
macro.GetAdd(id) = pick(m);
}
const char *Cpp::SkipString(const char *s)
{
CParser p(s);
p.ReadOneString(*s);
s = p.GetPtr();
while((byte)*(s - 1) <= ' ')
s--;
return s;
}
void Cpp::ParamAdd(Vector<String>& param, const char *s, const char *e)
{
while(s < e && (byte)*s <= ' ') s++;
while(e > s && (byte)*(e - 1) <= ' ') e--;
String h;
while(s < e) {
if((byte)*s <= ' ') {
h.Cat(' ');
s++;
while(s < e && (byte)*s <= ' ')
s++;
}
else
if(*s == '\"' || *s == '\'') {
const char *q = SkipString(s);
h.Cat(String(s, q));
s = q;
}
else
h.Cat(*s++);
}
param.Add(h);
}
String Cpp::Expand(const char *s)
{
Index<String> notmacro;
return Expand(s, notmacro);
}
String Cpp::Expand(const char *s, Index<String>& notmacro)
{
StringBuffer r;
while(*s) {
if(incomment) {
if(s[0] == '*' && s[1] == '/') {
incomment = false;
s += 2;
r.Cat("*/");
}
else
r.Cat(*s++);
}
else
if(iscib(*s)) {
const char *b = s;
s++;
while(iscid(*s))
s++;
String id(b, s);
if(notmacro.Find(id) < 0) {
const CppMacro *m = macro.FindPtr(id);
if(m && !id.StartsWith("__$allowed_on_")) {
Vector<String> param;
const char *s0 = s;
while(*s && (byte)*s <= ' ')
s++;
if(*s == '(') {
s++;
const char *b = s;
int level = 0;
for(;;)
if(*s == ',' && level == 0) {
ParamAdd(param, b, s);
s++;
b = s;
}
else
if(*s == ')') {
s++;
if(level == 0) {
ParamAdd(param, b, s - 1);
break;
}
level--;
}
else
if(*s == '(') {
s++;
level++;
}
else
if(*s == '\0')
break;
else
if(*s == '\"' || *s == '\'')
s = SkipString(s);
else
s++;
}
else
s = s0; // otherwise we eat spaces after parameterless macro
usedmacro.FindAdd(id);
int ti = notmacro.GetCount();
notmacro.Add(id);
id = '\x1a' + Expand(m->Expand(param));
notmacro.Trim(ti);
}
}
r.Cat(id);
}
else
if(s[0] == '/' && s[1] == '*') {
incomment = true;
s += 2;
r.Cat("/*");
}
else
if(s[0] == '/' && s[1] == '/') {
r.Cat(s);
break;
}
else
r.Cat(*s++);
}
return r;
}
bool Cpp::Preprocess(const String& sourcefile, Stream& in, const String& currentfile,
const Index<String> *get_macros)
{
macro.Clear();
Vector<String> ignorelist = Split("__declspec;__cdecl;"
"__out;__in;__inout;__deref_in;__deref_inout;__deref_out;"
"__AuToQuOtE;__xin;__xout;"
"$drv_group;$allowed_on_parameter",
';');
for(int i = 0; i < ignorelist.GetCount(); i++)
macro.GetAdd(ignorelist[i]).param = ".";
done = false;
incomment = false;
Index<String> visited;
if(get_macros)
DUMP(*get_macros);
Do(NormalizePath(sourcefile), in, NormalizePath(currentfile), visited, get_macros);
return done;
}
void Cpp::Do(const String& sourcefile, Stream& in, const String& currentfile,
Index<String>& visited, const Index<String> *get_macros)
{
// DUMP(currentfile);
if(visited.Find(currentfile) >= 0 || visited.GetCount() > 20000)
return;
visited.Add(currentfile);
String current_folder = GetFileFolder(currentfile);
if(sourcefile != currentfile) {
const PPFile& pp = GetPPFile(currentfile);
#ifdef _DEBUG
pp.Dump();
#endif
for(int i = 0; i < pp.item.GetCount() && !done; i++) {
const PPItem& m = pp.item[i];
if(m.type == PP_DEFINE) {
// RTIMING("macro Add");
if(!get_macros || get_macros->Find(m.id) >= 0)
macro.GetAdd(m.id) = m.macro;
}
else
if(m.type == PP_INCLUDE) {
String s = GetIncludePath(m.id, current_folder, include_path);
if(s.GetCount())
Do(sourcefile, in, s, visited, get_macros);
}
else
if(m.type == PP_NAMESPACE)
namespace_stack.Add(m.id);
else
if(m.type == PP_NAMESPACE_END && namespace_stack.GetCount())
namespace_stack.Drop();
else
if(m.type == PP_USING)
namespace_using.FindAdd(m.id);
}
return;
}
done = true;
if(get_macros)
return;
RTIMING("Expand");
incomment = false;
StringBuffer result;
result.Clear();
result.Reserve(16384);
int lineno = 0;
bool incomment = false;
while(!in.IsEof()) {
String l = in.GetLine();
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")) {
result.Cat(l + "\n");
Define(p.GetPtr());
}
else {
result.Cat('\n');
if(p.Id("include")) {
String hdr = Expand(p.GetPtr());
String header_path = GetIncludePath(hdr, current_folder, include_path);
if(header_path.GetCount())
Do(Null, NilStream(), header_path, visited, get_macros);
}
}
}
else {
result.Cat(Expand(l) + "\n");
}
while(el--)
result.Cat("\n");
}
DUMP(macro.GetCount());
output = result;
}

View file

@ -7,78 +7,4 @@
using namespace Upp;
void RemoveComments(String& l, bool& incomment);
struct CppMacro : Moveable<CppMacro>, DeepCopyOption<CppMacro> {
String param;
String body;
String Define(const char *s);
String Expand(const Vector<String>& p) const;
String ToString() const;
};
enum PPItemType {
PP_DEFINE,
PP_INCLUDE,
PP_USING,
PP_NAMESPACE,
PP_NAMESPACE_END
};
struct PPItem {
int type;
String id;
CppMacro macro;
};
struct PPFile { // contains "macro extract" of file, only info about macros defined and namespaces
FileTime filetime;
Array<PPItem> item;
Index<String> includes;
void Parse(Stream& in);
void Dump() const;
private:
void CheckEndNamespace(Vector<int>& namespace_block, int level);
};
const PPFile& GetPPFile(const char *path);
String GetIncludePath(const String& s, const String& filedir, const String& include_path);
bool IncludesFile(const String& parent_path, const String& header_path, const String& include_path);
struct Cpp {
bool incomment;
bool done;
String include_path;
VectorMap<String, CppMacro> macro;
String output;
Index<String> usedmacro;
Index<String> namespace_using;
Vector<String> namespace_stack;
void Define(const char *s);
static const char *SkipString(const char *s);
void ParamAdd(Vector<String>& param, const char *b, const char *e);
String Expand(const char *s, Index<String>& notmacro);
String Expand(const char *s);
void Do(const String& sourcefile, Stream& in, const String& currentfile,
Index<String>& visited, const Index<String> *get_macros);
bool Preprocess(const String& sourcefile, Stream& in, const String& currentfile,
const Index<String> *get_macros = NULL);
typedef Cpp CLASSNAME;
};
#endif

View file

@ -1 +1,79 @@
Gather files 0.375
Checking files 0.031
Removing files 0.000
Parsing files 5.125
TIMING PP_DEFINE : 0.00 ns - 0.00 ns (593.00 ms / 12471437 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 12471437
TIMING Parse : 636.94 ms - 554.35 us (637.00 ms / 1149 ), min: 0.00 ns, max: 16.00 ms, nesting: 1 - 1149
TIMING Expand : 424.95 ms - 376.39 us (425.00 ms / 1129 ), min: 0.00 ns, max: 38.00 ms, nesting: 1 - 1129
TIMING macros : 500.95 ms - 443.71 us (501.00 ms / 1129 ), min: 0.00 ns, max: 2.00 ms, nesting: 1 - 1129
TIMING Gather IDs : 208.95 ms - 185.07 us (209.00 ms / 1129 ), min: 0.00 ns, max: 9.00 ms, nesting: 1 - 1129
TIMING GetMasterFile : 742.94 ms - 646.60 us (743.00 ms / 1149 ), min: 0.00 ns, max: 4.00 ms, nesting: 1 - 1149
TIMING Preprocess : 3.25 s - 2.83 ms ( 3.25 s / 1149 ), min: 0.00 ns, max: 45.00 ms, nesting: 1 - 1149
TIMING GetIncludePath : 190.24 ms - 420.12 ns (212.00 ms / 452817 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 452817
TIMING sCppFile make : 999.95 us - 999.95 us ( 1.00 ms / 1 ), min: 1.00 ms, max: 1.00 ms, nesting: 1 - 1
Gather files 0.375
Checking files 0.016
Removing files 0.000
Parsing files 6.531
TIMING PP_DEFINE : 1.67 s - 134.20 ns ( 2.30 s / 12471407 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 12471407
TIMING Parse : 676.94 ms - 589.16 us (677.00 ms / 1149 ), min: 0.00 ns, max: 27.00 ms, nesting: 1 - 1149
TIMING Expand : 523.94 ms - 464.08 us (524.00 ms / 1129 ), min: 0.00 ns, max: 39.00 ms, nesting: 1 - 1129
TIMING GetMasterFile : 728.94 ms - 634.41 us (729.00 ms / 1149 ), min: 0.00 ns, max: 4.00 ms, nesting: 1 - 1149
TIMING Preprocess : 4.41 s - 3.84 ms ( 4.41 s / 1149 ), min: 0.00 ns, max: 50.00 ms, nesting: 1 - 1149
TIMING GetIncludePath : 189.15 ms - 417.72 ns (212.00 ms / 452817 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 452817
TIMING sCppFile make : 999.95 us - 999.95 us ( 1.00 ms / 1 ), min: 1.00 ms, max: 1.00 ms, nesting: 1 - 1
* c:\upp\cppide.exe 29.03.2015 22:44:02, user: cxl
Gather files 0.375
Checking files 0.016
Removing files 0.000
Parsing files 5.109
TIMING PP_DEFINE : 0.00 ns - 0.00 ns (609.00 ms / 12471437 ), min: 0.00 ns, max: 2.00 ms, nesting: 1 - 12471437
TIMING Parse : 658.94 ms - 573.49 us (659.00 ms / 1149 ), min: 0.00 ns, max: 16.00 ms, nesting: 1 - 1149
TIMING Expand : 408.94 ms - 362.22 us (409.00 ms / 1129 ), min: 0.00 ns, max: 38.00 ms, nesting: 1 - 1129
TIMING macros : 487.94 ms - 432.19 us (488.00 ms / 1129 ), min: 0.00 ns, max: 2.00 ms, nesting: 1 - 1129
TIMING add macro : 65.11 ms - 30.71 ns (169.00 ms / 2120492 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 2120492
TIMING Gather IDs : 382.94 ms - 339.19 us (383.00 ms / 1129 ), min: 0.00 ns, max: 16.00 ms, nesting: 1 - 1129
TIMING GetMasterFile : 705.94 ms - 614.40 us (706.00 ms / 1149 ), min: 0.00 ns, max: 5.00 ms, nesting: 1 - 1149
TIMING Preprocess : 3.32 s - 2.89 ms ( 3.32 s / 1149 ), min: 0.00 ns, max: 45.00 ms, nesting: 1 - 1149
TIMING GetIncludePath : 188.82 ms - 416.98 ns (211.00 ms / 452817 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 452817
TIMING PP read : 302.94 ms - 263.43 us (303.00 ms / 1150 ), min: 0.00 ns, max: 10.00 ms, nesting: 1 - 1150
TIMING sCppFile make : 999.95 us - 999.95 us ( 1.00 ms / 1 ), min: 1.00 ms, max: 1.00 ms, nesting: 1 - 1
* c:\upp\cppide.exe 30.03.2015 22:21:31, user: cxl
Gather files 0.687
Checking files 0.032
Removing files 0.000
Parsing files 3.281
TIMING PP_DEFINES : 0.00 ns - 0.00 ns ( 5.00 ms / 154902 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 154902
TIMING Parse : 631.95 ms - 551.44 us (632.00 ms / 1146 ), min: 0.00 ns, max: 26.00 ms, nesting: 1 - 1146
TIMING Expand include : 10.90 ms - 4.96 us (11.00 ms / 2199 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 2199
TIMING Expand expand : 544.38 ms - 831.97 ns (574.00 ms / 654331 ), min: 0.00 ns, max: 16.00 ms, nesting: 1 - 654331
TIMING Expand define : 13.69 ms - 268.12 ns (16.00 ms / 51057 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 51057
TIMING Expand : 737.95 ms - 655.37 us (738.00 ms / 1126 ), min: 0.00 ns, max: 39.00 ms, nesting: 1 - 1126
TIMING GetMasterFile : 695.95 ms - 607.28 us (696.00 ms / 1146 ), min: 0.00 ns, max: 4.00 ms, nesting: 1 - 1146
TIMING Preprocess : 1.59 s - 1.38 ms ( 1.59 s / 1146 ), min: 0.00 ns, max: 41.00 ms, nesting: 1 - 1146
TIMING GetIncludePath : 188.51 ms - 416.39 ns (209.00 ms / 452724 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 452724
TIMING PP read : 492.95 ms - 429.77 us (493.00 ms / 1147 ), min: 0.00 ns, max: 11.00 ms, nesting: 1 - 1147
TIMING sCppFile make : 999.95 us - 999.95 us ( 1.00 ms / 1 ), min: 1.00 ms, max: 1.00 ms, nesting: 1 - 1
Gather files 0.375
Checking files 0.016
Removing files 0.000
Parsing files 3.297
TIMING PP_DEFINES : 869.25 us - 5.61 ns ( 7.00 ms / 154902 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 154902
TIMING Parse : 656.95 ms - 573.26 us (657.00 ms / 1146 ), min: 0.00 ns, max: 25.00 ms, nesting: 1 - 1146
TIMING Expand include : 4.91 ms - 2.23 us ( 5.00 ms / 2199 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 2199
TIMING Expand expand : 517.10 ms - 790.28 ns (543.00 ms / 654331 ), min: 0.00 ns, max: 16.00 ms, nesting: 1 - 654331
TIMING Expand define : 19.98 ms - 391.31 ns (22.00 ms / 51057 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 51057
TIMING Expand : 731.96 ms - 650.05 us (732.00 ms / 1126 ), min: 0.00 ns, max: 40.00 ms, nesting: 1 - 1126
TIMING GetMasterFile : 699.95 ms - 610.78 us (700.00 ms / 1146 ), min: 0.00 ns, max: 4.00 ms, nesting: 1 - 1146
TIMING Preprocess : 1.58 s - 1.38 ms ( 1.58 s / 1146 ), min: 0.00 ns, max: 41.00 ms, nesting: 1 - 1146
TIMING GetIncludePath : 166.08 ms - 366.85 ns (184.00 ms / 452724 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 452724
TIMING PP read : 315.95 ms - 275.46 us (316.00 ms / 1147 ), min: 0.00 ns, max: 11.00 ms, nesting: 1 - 1147
TIMING sCppFile make : 999.96 us - 999.96 us ( 1.00 ms / 1 ), min: 1.00 ms, max: 1.00 ms, nesting: 1 - 1

View file

@ -4,9 +4,6 @@ uses
file
cpp.h,
macro.cpp,
ppfile.cpp,
cpp.cpp,
main.cpp,
test.h,
testfile,

View file

@ -22,11 +22,13 @@ void Test(const char *sourcefile, const char *currentfile)
{ RTIMING("Preprocess");
cpp.Preprocess(sourcefile, in, currentfile);
DUMP(cpp.namespace_stack);
// DDUMP(cpp.output);
DUMP(cpp.usedmacro);
DUMP(cpp.macro.GetCount());
}
LOG("=================================");
LOG(cpp.output);
/*
{
Cpp cpp2;
cpp2.include_path = include_path;
@ -40,6 +42,7 @@ void Test(const char *sourcefile, const char *currentfile)
cpp2.include_path = include_path;
cpp2.Preprocess(sourcefile, NilStream(), currentfile, &cpp.usedmacro);
}
*/
}
void TestC(const char *ln)
@ -68,45 +71,10 @@ CONSOLE_APP_MAIN
// f.Parse(in);
// f.Dump();
GetPPFile("C:\\u\\upp.src\\uppsrc\\Core\\Core.h").Dump();
DLOG("==============");
Test("C:\\u\\upp.src\\uppsrc\\Core\\Format.h", "C:\\u\\upp.src\\uppsrc\\Core\\Format.cpp");
// Test("c:/u/upp.src/uppsrc/CtrlLib/EditField.cpp", "c:/u/upp.src/uppsrc/CtrlLib/EditField.cpp");
#if 0
TestC("test");
TestC("*/ test /*c2*/ /* comment");
TestC(" */ test /*c2*/ a /* comment */");
TestC(" */ test /*c2*/ a /*/* comment */");
return;
#endif
{
RTIMING("Pass1");
Test("C:\\u\\upp.src\\uppsrc\\Core\\Format.h", "C:\\u\\upp.src\\uppsrc\\Core\\Format.cpp");
}
#ifndef _DEBUG
for(int i = 0; i < 100; i++) {
Test("C:\\u\\upp.src\\uppsrc\\Core\\Format.h", "C:\\u\\upp.src\\uppsrc\\Core\\Format.cpp");
}
#endif
#if 0
{
RTIMING("Pass1");
Index<String> visited;
// RecursePP("c:/u/upp.src/uppsrc/CtrlLib/EditField.cpp", include_path, visited);
}
DDUMP(IncludesFile("c:/u/upp.src/uppsrc/CtrlLib/EditField.cpp", "c:/u/upp.src/uppsrc/Core/Core.h", include_path));
DDUMP(IncludesFile("c:/u/upp.src/uppsrc/CtrlLib/EditField.cpp", "c:/u/upp.src/uppsrc/Core/Core2.h", include_path));
for(int i = 0; i < 1000; i++) {
RTIMING("IncludesFile true");
IncludesFile("c:/u/upp.src/uppsrc/CtrlLib/EditField.cpp", "c:/u/upp.src/uppsrc/Core/Core.h", include_path);
}
for(int i = 0; i < 1000; i++) {
RTIMING("IncludesFile false");
IncludesFile("c:/u/upp.src/uppsrc/CtrlLib/EditField.cpp", "c:/u/upp.src/uppsrc/Core/Core1.h", include_path);
}
#endif
// GetPPFile(GetDataFile("test.h")).Dump();
return;
}

View file

@ -1,285 +0,0 @@
#include "cpp.h"
void SetSpaces(String& l, int pos, int count)
{
StringBuffer s = l;
memset(~s + pos, ' ', count);
l = s;
}
void RemoveComments(String& l, bool& incomment)
{
int q = -1;
int w = -1;
if(incomment)
q = w = 0;
else {
q = l.Find("/*");
if(q >= 0)
w = q + 2;
}
while(q >= 0) {
int eq = l.Find("*/", w);
if(eq < 0) {
incomment = true;
SetSpaces(l, q, l.GetCount() - q);
return;
}
SetSpaces(l, q, eq + 2 - q);
incomment = false;
q = l.Find("/*");
w = q + 2;
}
}
void PPFile::CheckEndNamespace(Vector<int>& namespace_block, int level)
{
if(namespace_block.GetCount() && namespace_block.Top() == level) {
namespace_block.Drop();
item.Add().type = PP_NAMESPACE_END;
}
}
void PPFile::Parse(Stream& in)
{
item.Clear();
includes.Clear();
bool was_using = false;
bool was_namespace = false;
int level = 0;
bool incomment = false;
Vector<int> namespace_block;
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")) {
PPItem& m = item.Add();
m.type = PP_DEFINE;
m.id = m.macro.Define(p.GetPtr());
if(IsNull(m.id))
item.Drop();
}
else
if(p.Id("include")) {
PPItem& m = item.Add();
m.type = PP_INCLUDE;
m.id = TrimBoth(p.GetPtr());
if(IsNull(m.id))
item.Drop();
else
includes.FindAdd(m.id);
}
}
else {
while(!p.IsEof()) {
if(was_namespace) {
int type = was_using ? PP_USING : PP_NAMESPACE;
String id;
while(p.Char2(':', ':'))
id = "::";
id << p.ReadId();
while(p.Char2(':', ':'))
id << "::" << p.ReadId();
if(!was_using)
namespace_block.Add(level);
PPItem& m = item.Add();
m.type = type;
m.id = 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 VectorMap<String, String> namespace_macro; // TODO: Make this ugly trick dynamic
ONCELOCK {
namespace_macro.Add("_STD_BEGIN", "std");
namespace_macro.Add("_C_STD_BEGIN", "std");
namespace_macro.Add("_STDEXT_BEGIN", "stdext");
namespace_macro.Add("NAMESPACE_UPP", "Upp");
}
static Index<String> namespace_end_macro;
ONCELOCK {
namespace_end_macro.Add("_STD_END");
namespace_end_macro.Add("_STDEXT_END");
namespace_end_macro.Add("_C_STD_END");
namespace_end_macro.Add("END_UPP_NAMESPACE");
}
String id = p.ReadId();
int q = namespace_macro.Find(id);
if(q > 0) {
PPItem& m = item.Add();
m.type = PP_NAMESPACE;
m.id = namespace_macro[q];
namespace_block.Add(level);
level++;
}
else {
q = namespace_end_macro.Find(id);
if(q >= 0) {
level--;
CheckEndNamespace(namespace_block, level);
}
}
}
else
if(p.Char('}')) {
if(level > 0) {
level--;
CheckEndNamespace(namespace_block, level);
}
}
else
if(p.Char('{'))
level++;
else
p.SkipTerm();
}
}
}
}
catch(...) {}
}
}
void PPFile::Dump() const
{
for(int i = 0; i < item.GetCount(); i++) {
const PPItem& m = item[i];
String ll;
ll << decode(m.type, PP_DEFINE, "#define", PP_INCLUDE, "#include",
PP_USING, "using namespace", PP_NAMESPACE, "namespace",
PP_NAMESPACE_END, "}", "")
<< ' ' << m.id;
if(m.type == PP_DEFINE)
ll << m.macro;
if(m.type == PP_NAMESPACE)
ll << " {";
LOG(ll);
}
LOG("----- includes:");
DUMPC(includes);
}
static ArrayMap<String, FileTime> sPathFileTime;
static VectorMap<String, String> sIncludePath;
static VectorMap<String, bool> sIncludes;
void PPSyncPath()
{
sPathFileTime.Clear();
sIncludePath.Clear();
sIncludes.Clear();
}
String GetIncludePath0(const char *s, const char *filedir, const String& include_path)
{
while(IsSpace(*s))
s++;
int type = *s;
if(type == '<' || type == '\"' || type == '?') {
s++;
String name;
if(type == '<') type = '>';
while(*s != '\r' && *s != '\n') {
if(*s == type) {
if(type == '\"') {
String fn = NormalizePath(name, filedir);
if(FileExists(fn))
return fn;
}
return GetFileOnPath(name, include_path, false);
}
name.Cat(*s++);
}
}
return Null;
}
FileTime GetFileTimeCached(const String& p)
{
int q = sPathFileTime.Find(p);
if(q >= 0)
return sPathFileTime[q];
FileTime m = GetFileTime(p);
sPathFileTime.Add(p, m);
return m;
}
String GetIncludePath(const String& s, const String& filedir, const String& include_path)
{
RTIMING("GetIncludePath");
String key;
key << s << "#" << filedir << "#" << include_path;
int q = sIncludePath.Find(key);
if(q >= 0)
return sIncludePath[q];
String p = GetIncludePath0(s, filedir, include_path);
sIncludePath.Add(key, p);
return p;
}
const PPFile& GetPPFile(const char *path)
{
static ArrayMap<String, PPFile> file;
FileTime tm = GetFileTimeCached(path);
PPFile& f = file.GetAdd(path);
if(f.filetime != tm) {
f.filetime = tm;
FileIn in(path);
f.Parse(in);
}
return f;
}
bool IsSameFile(const String& f1, const String& f2)
{
return NormalizePath(f1) == NormalizePath(f2);
}
bool IncludesFile(const String& parent_path, const String& path, const String& include_path, Index<String>& visited)
{
if(visited.Find(parent_path) >= 0)
return false;
visited.Add(parent_path);
if(IsSameFile(parent_path, path))
return true;
const PPFile& f = GetPPFile(parent_path);
for(int i = 0; i < f.includes.GetCount(); i++) {
String p = GetIncludePath(f.includes[i], GetFileFolder(parent_path), include_path);
if(p.GetCount()) {
String key = p + "#" + path;
int q = sIncludes.Find(key);
if(q >= 0) {
if(sIncludes[q])
return true;
}
else {
bool b = IncludesFile(p, path, include_path, visited);
sIncludes.Add(key, b);
if(b)
return true;
}
}
}
return false;
}
bool IncludesFile(const String& parent_path, const String& path, const String& include_path)
{
Index<String> visited;
return IncludesFile(parent_path, path, include_path, visited);
}

View file

@ -0,0 +1,132 @@
#include "CppBase.h"
NAMESPACE_UPP
#define LLOG(x)
#define LTIMING(x) // RTIMING(x)
ScopeInfo::ScopeInfo(const CppBase& base, int scopei)
: scopei(scopei), base(base)
{
LTIMING("ScopeInfo(const CppBase& base, int scopei)");
Init();
}
ScopeInfo::ScopeInfo(int scopei, const CppBase& base)
: scopei(scopei), base(base)
{
LTIMING("ScopeInfo(int scopei, const CppBase& base)");
Init();
}
ScopeInfo::ScopeInfo(const CppBase& base, const String& scope)
: scopei(base.Find(scope)), base(base)
{
LTIMING("ScopeInfo(const CppBase& base, const String& scope)");
Init();
}
ScopeInfo::ScopeInfo(const ScopeInfo& f)
: base(f.base)
{
LTIMING("ScopeInfo copy contructor");
scopes <<= f.scopes;
bvalid = nvalid = false;
scopei = f.scopei;
}
void ScopeInfo::Init()
{
bvalid = nvalid = false;
}
void ScopeInfo::Bases(int i, Vector<int>& g)
{ // recursively retrieve all base classes
if(base.IsType(i)) {
const Array<CppItem>& n = base[i];
for(int i = 0; i < n.GetCount(); i++) {
const CppItem& im = n[i];
if(im.IsType()) {
const char *q = im.qptype;
const char *b = q;
for(;;) {
if(*q == ';' || *q == '\0') {
if(b < q) {
String h = String(b, q);
int q = h.Find('<');
if(q >= 0)
h.Trim(q);
h = TrimBoth(h);
int nq = base.Find(h);
if(nq >= 0)
g.Add(nq);
}
if(*q == '\0')
return;
q++;
b = q;
}
else
q++;
}
}
}
}
}
const Vector<String>& ScopeInfo::GetBases()
{
LTIMING("GetBases");
if(!bvalid) {
bvalid = true;
baselist.Clear();
if(scopei < 0)
return baselist;
Vector<int> b;
Index<int> bi;
Bases(scopei, b);
while(b.GetCount()) {
Vector<int> bb;
for(int i = 0; i < b.GetCount(); i++) {
int q = b[i];
if(bi.Find(q) < 0) {
bi.Add(q);
Bases(b[i], bb);
}
}
b = pick(bb);
}
for(int i = 0; i < bi.GetCount(); i++)
baselist.Add(base.GetKey(bi[i]) + "::");
}
return baselist;
}
const Vector<String>& ScopeInfo::GetScopes(const String& usings_)
{
LTIMING("GetScopes");
if(!nvalid || usings != usings_) {
usings = usings_;
nvalid = true;
scopes.Clear();
if(scopei < 0)
return scopes;
String nn = base.GetKey(scopei);
while(nn.GetCount()) {
if(nn[0] == ':' && nn.GetCount() == 2) {
scopes.Add(nn);
return scopes;
}
scopes.Add(nn + "::");
int q = nn.ReverseFind(':');
nn.Trim(max(0, q - 1));
}
scopes.Add("");
Vector<String> h = Split(usings, ';');
for(int i = 0; i < h.GetCount(); i++)
scopes.Add(h[i] + "::");
}
return scopes;
}
END_UPP_NAMESPACE

400
uppsrc/CppBase/cpp.cpp Normal file
View file

@ -0,0 +1,400 @@
#include "CppBase.h"
NAMESPACE_UPP
#define LTIMING(x) RTIMING(x)
#define LLOG(x) // DLOG(x)
const char *Cpp::SkipString(const char *s)
{
CParser p(s);
try {
p.ReadOneString(*s);
}
catch(CParser::Error) {}
s = p.GetPtr();
while((byte)*(s - 1) <= ' ')
s--;
return s;
}
void Cpp::ParamAdd(Vector<String>& param, const char *s, const char *e)
{
while(s < e && (byte)*s <= ' ') s++;
while(e > s && (byte)*(e - 1) <= ' ') e--;
String h;
while(s < e) {
if((byte)*s <= ' ') {
h.Cat(' ');
s++;
while(s < e && (byte)*s <= ' ')
s++;
}
else
if(*s == '\"' || *s == '\'') {
const char *q = SkipString(s);
h.Cat(String(s, q));
s = q;
}
else
h.Cat(*s++);
}
param.Add(h);
}
String Cpp::Expand(const char *s)
{
StringBuffer r;
const char *l0 = s;
while(*s) {
if(incomment) {
if(s[0] == '*' && s[1] == '/') {
incomment = false;
s += 2;
r.Cat("*/");
}
else
r.Cat(*s++);
}
else
if(iscib(*s)) {
LTIMING("Expand ID");
const char *bid = s;
s++;
while(iscid(*s))
s++;
String id(bid, s);
LTIMING("Expand ID2");
ids.FindAdd(id);
if(notmacro.Find(id) < 0) {
const PPMacro *pp = macro.FindLastPtr(id);
int segmenti = pp ? segment_id.Find(pp->segment_id) : -1;
const CppMacro *m = FindMacro(id, segment_id, segmenti);
if(!m && pp)
m = &pp->macro;
if(m && m->IsUndef())
m = NULL;
if(m) {
LTIMING("Expand macro");
Vector<String> param;
bool function_like = false;
const char *s0 = s;
if(m->param.GetCount()) {
while(*s && (byte)*s <= ' ')
s++;
if(*s == '(') {
function_like = true;
s++;
const char *b = s;
int level = 0;
for(;;)
if(*s == ',' && level == 0) {
ParamAdd(param, b, s);
s++;
b = s;
}
else
if(*s == ')') {
s++;
if(level == 0) {
ParamAdd(param, b, s - 1);
break;
}
level--;
}
else
if(*s == '(') {
s++;
level++;
}
else
if(*s == '\0') { // macro use spread into more lines
if(bid == l0) // begin of line
prefix_macro = bid;
else
prefix_macro = String(' ', 1) + bid; // do not want to emit grounding in body
return r;
}
else
if(*s == '\"' || *s == '\'')
s = SkipString(s);
else
s++;
}
}
if(!!m->param.GetCount() == function_like) {
int ti = notmacro.GetCount();
Vector<String> eparam;
eparam.SetCount(param.GetCount());
for(int i = 0; i < param.GetCount(); i++)
eparam[i] = Expand(param[i]);
notmacro.Add(id);
id = '\x1f' + Expand(m->Expand(param, eparam)); // \x1f is info for Pre that there was a macro expansion
notmacro.Trim(ti);
}
else
s = s0;
}
else
notmacro.Add(id);
}
r.Cat(id);
}
else
if(*s == '\"') {
const char *e = SkipString(s);
r.Cat(s, e);
s = e;
}
else
if(s[0] == '/' && s[1] == '*') {
incomment = true;
s += 2;
r.Cat("/*");
}
else
if(s[0] == '/' && s[1] == '/') {
r.Cat(s);
break;
}
else
r.Cat(*s++);
}
return r;
}
Index<String> Cpp::kw;
bool Cpp::Preprocess(const String& sourcefile, Stream& in, const String& currentfile,
bool get_macros)
{
LLOG("===== Preprocess " << sourcefile << " <- " << currentfile);
LTIMING("Cpp::Preprocess");
macro.Clear();
macro.Reserve(1000);
segment_id.Clear();
segment_id.Reserve(100);
const Vector<String>& 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<String> visited;
Do(NormalizePath(sourcefile), in, NormalizePath(currentfile), visited, get_macros);
return done;
}
void Cpp::DoFlatInclude(const String& header_path)
{
LLOG("Flat include " << 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++) {
const PPItem& m = pp.item[i];
if(m.type == PP_DEFINES) {
segment_id.FindAdd(m.segment_id);
// DDUMP(m.segment_id);
}
else
if(m.type == PP_USING) {
namespace_using.FindAdd(m.text);
usings << ";" << m.text;
}
else
if(m.type == PP_INCLUDE) // In flat PP, only marker
usings << ";[" << m.text << "]";
}
}
}
void Cpp::Do(const String& sourcefile, Stream& in, const String& currentfile,
Index<String>& visited, bool get_macros)
{
if(visited.Find(currentfile) >= 0 || visited.GetCount() > 20000)
return;
visited.Add(currentfile);
String current_folder = GetFileFolder(currentfile);
bool notthefile = sourcefile != currentfile;
if(notthefile || get_macros) {
const PPFile& pp = GetPPFile(currentfile);
for(int i = 0; i < pp.item.GetCount() && !done; i++) {
const PPItem& m = pp.item[i];
if(m.type == PP_DEFINES) {
LTIMING("PP_DEFINES");
if(notthefile) // if getting macros, we are interested in included macros only
segment_id.FindAdd(m.segment_id);
}
else
if(m.type == PP_INCLUDE) {
String s = GetIncludePath(m.text, current_folder);
if(s.GetCount()) {
if(notthefile && IncludesFile(s, sourcefile)) {
LLOG("Include IN " << s);
Do(sourcefile, in, s, visited, get_macros);
RHITCOUNT("Include IN");
}
else {
LLOG("Include FLAT " << s);
RHITCOUNT("Include FLAT");
DoFlatInclude(s);
}
}
}
else
if(m.type == PP_NAMESPACE) {
namespace_stack.Add(m.text);
LLOG("pp namespace " << m.text << " " << namespace_stack);
}
else
if(m.type == PP_NAMESPACE_END && namespace_stack.GetCount()) {
namespace_stack.Drop();
LLOG("pp end namespace " << namespace_stack);
}
else
if(m.type == PP_USING)
namespace_using.FindAdd(m.text);
}
if(sourcefile != currentfile)
return;
}
namespaces = Join(namespace_stack, ";");
if(!get_macros) {
LTIMING("Expand");
incomment = false;
prefix_macro.Clear();
StringBuffer result;
result.Clear();
result.Reserve(16384);
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")) {
result.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")) {
result.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 {
result.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);
DoFlatInclude(s);
segment_id.Add(--segment_serial);
includes << ';' << s;
}
}
}
else {
LTIMING("Expand expand");
#ifdef IGNORE_ELSE
if(ignore_else)
result.Cat('\n');
else
#endif
result.Cat(Expand(l) + "\n");
}
while(el--)
result.Cat("\n");
}
output = result;
}
done = true;
}
VectorMap<String, String> Cpp::GetDefinedMacros()
{
LTIMING("GetDefinedMacros");
VectorMap<String, String> r;
for(int i = std_macros; i < macro.GetCount(); i++)
r.GetAdd(macro.GetKey(i)) << macro[i].macro << "\n";
LLOG("GetDefinedMacros " << r);
for(int i = 0; i < r.GetCount(); i++)
r[i] = MD5String(r[i]);
return r;
}
String Cpp::GetIncludedMacroValues(const Vector<String>& m)
{
String r;
LTIMING("GetUsedMacroValues");
r << "##namespace\n" << namespaces << "\n"
<< "##usings\n" << usings << "\n";
for(int i = 0; i < m.GetCount(); i++) {
String mm = GetAllMacros(m[i], segment_id);
if(mm.GetCount())
r << '#' << m[i] << '\n' << mm << '\n';
}
return MD5String(r);
}
END_UPP_NAMESPACE

View file

@ -1,4 +1,6 @@
#include "cpp.h"
#include "CppBase.h"
NAMESPACE_UPP
inline bool IsSpc(byte c)
{
@ -12,9 +14,12 @@ String CppMacro::Define(const char *s)
try {
if(!p.IsId())
return Null;
p.NoSkipSpaces().NoSkipComments(); // '#define TEST(x)' is difference form '#define TEST (x)' - later is parameterless
id = p.ReadId();
param.Clear();
if(p.Char('(')) {
p.SkipSpaces();
p.Spaces();
while(p.IsId()) {
if(param.GetCount())
param << ",";
@ -24,8 +29,13 @@ String CppMacro::Define(const char *s)
if(p.Char3('.', '.', '.'))
param << '.';
p.Char(')');
if(param.GetCount() == 0) // #define foo() bar - need to 'eat' parenthesis, cheap way
param = ".";
}
body = p.GetPtr();
const char *b = p.GetPtr();
while(!p.IsEof() && !p.IsChar2('/', '/'))
p.SkipTerm();
body = String(b, p.GetPtr());
}
catch(CParser::Error) {
return Null;
@ -41,11 +51,14 @@ String CppMacro::ToString() const
h.Replace(".", "...");
r << "(" << h << ")";
}
r << ' ' << body;
if(IsUndef())
r << " #undef";
else
r << ' ' << body;
return r;
}
String CppMacro::Expand(const Vector<String>& p) const
String CppMacro::Expand(const Vector<String>& p, const Vector<String>& ep) const
{
String r;
const char *s = body;
@ -56,6 +69,7 @@ String CppMacro::Expand(const Vector<String>& p) const
pp.Trim(pp.GetCount() - 1);
}
Index<String> param(pick(Split(pp, ',')));
static String VA_ARGS("__VA_ARGS__"); // static - Speed optimization
while(*s) {
if(IsAlpha(*s) || *s == '_') {
const char *b = s;
@ -63,21 +77,31 @@ String CppMacro::Expand(const Vector<String>& p) const
while(IsAlNum(*s) || *s == '_')
s++;
String id(b, s);
static String VA_ARGS("__VA_ARGS__"); // Speed optimization
const char *ss = b;
bool cat = false;
while(ss > ~body && ss[-1] == ' ')
ss--;
if(ss >= ~body + 2 && ss[-1] == '#' && ss[-2] == '#')
cat = true;
ss = s;
while(*ss && *ss == ' ')
ss++;
if(ss[0] == '#' && ss[1] == '#')
cat = true;
if(id == VA_ARGS) {
bool next = false;
for(int i = param.GetCount(); i < p.GetCount(); i++) {
for(int i = param.GetCount(); i < ep.GetCount(); i++) {
if(next)
r.Cat(", ");
r.Cat(p[i]);
r.Cat((cat ? p : ep)[i]);
next = true;
}
}
else {
int q = param.Find(id);
if(q >= 0) {
if(q < p.GetCount())
r.Cat(p[q]);
if(q < ep.GetCount())
r.Cat((cat ? p : ep)[q]);
}
else
r.Cat(id);
@ -122,3 +146,5 @@ String CppMacro::Expand(const Vector<String>& p) const
}
return r;
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,84 @@
#include "CppBase.h"
namespace Upp {
Value StringArray(const char *s)
{
Vector<String> h = Split(s, ';');
ValueArray va;
for(int i = 0; i < h.GetCount(); i++)
va.Add(h[i]);
return va;
}
String GetStdConfig()
{
static const char ns[] = "_STD_BEGIN:std;_C_STD_BEGIN:std;_STDEXT_BEGIN:stdext;NAMESPACE_UPP:Upp";
static const char endns[] = "_STD_END;_STDEXT_END;_C_STD_END;END_UPP_NAMESPACE";
static const char ignore[] = "__declspec(...);__cdecl;__attribute__(...);__stdcall;__forceinline;"
"__out;__in;__inout;__deref_in;__deref_inout;__deref_out;"
"__pragma(...);__pascal;_far;_pascal;_cdecl;"
"__AuToQuOtE;__xin;__xout;__export;"
"__clrcall;__alignof(...)";
ValueMap json;
ValueArray va;
Vector<String> h = Split(ns, ';');
for(int i = 0; i < h.GetCount(); i++) {
String id, n;
SplitTo(h[i], ':', id, n);
ValueMap m;
m.Add(id, n);
va.Add(m);
}
json.Add("namespace", va);
json.Add("end_namespace", StringArray(endns));
json.Add("ignore", StringArray(ignore));
return AsJSON(json);
}
static VectorMap<String, String> s_namespace_macro;
static Index<String> s_namespace_end_macro;
static Vector<String> s_ignorelist;
void LoadPPConfig(const String& json)
{
Value m = ParseJSON(json);
try {
s_namespace_macro.Clear();
ValueArray va = m["namespace"];
for(int i = 0; i < va.GetCount(); i++) {
ValueMap m = va[i];
if(m.GetCount())
s_namespace_macro.Add(m.GetKey(0), m.GetValue(0));
}
s_namespace_end_macro.Clear();
va = m["end_namespace"];
for(int i = 0; i < va.GetCount(); i++)
s_namespace_end_macro.Add(va[i]);
s_ignorelist.Clear();
va = m["ignore"];
for(int i = 0; i < va.GetCount(); i++)
s_ignorelist.Add(va[i]);
}
catch(ValueTypeError) {}
}
const VectorMap<String, String>& GetNamespaceMacros()
{
return s_namespace_macro;
}
const Index<String>& GetNamespaceEndMacros()
{
return s_namespace_end_macro;
}
const Vector<String>& GetIgnoreList()
{
return s_ignorelist;
}
};

489
uppsrc/CppBase/ppfile.cpp Normal file
View file

@ -0,0 +1,489 @@
#include "CppBase.h"
NAMESPACE_UPP
#define LTIMING(x) RTIMING(x)
#define LLOG(x) // LOG(x)
bool IsCPPFile(const String& path)
{
return findarg(ToLower(GetFileExt(path)) , ".c", ".cpp", ".cc" , ".cxx", ".icpp") >= 0;
}
bool IsHFile(const String& path)
{
return findarg(ToLower(GetFileExt(path)) , ".h", ".hpp", ".hxx" , ".hh") >= 0;
}
void SetSpaces(String& l, int pos, int count)
{
StringBuffer s = l;
memset(~s + pos, ' ', count);
l = s;
}
void RemoveComments(String& l, bool& incomment)
{
int q = -1;
int w = -1;
if(incomment)
q = w = 0;
else {
q = l.Find("/*");
if(q >= 0)
w = q + 2;
}
while(q >= 0) {
int eq = l.Find("*/", w);
if(eq < 0) {
incomment = true;
SetSpaces(l, q, l.GetCount() - q);
return;
}
SetSpaces(l, q, eq + 2 - q);
incomment = false;
q = l.Find("/*");
w = q + 2;
}
}
static VectorMap<String, PPMacro> sAllMacros;
static ArrayMap<String, PPFile> sPPfile;
static int sPPserial;
void SerializePPFiles(Stream& s)
{
s % sAllMacros % sPPfile % sPPserial;
}
void CleanPP()
{
sAllMacros.Clear();
sPPfile.Clear();
sPPserial = 0;
}
void SweepPPFiles(const Index<String>& keep)
{
for(int i = 0; i < sPPfile.GetCount(); i++)
if(keep.Find(sPPfile.GetKey(i)) < 0 && !sPPfile.IsUnlinked(i))
sPPfile.Unlink(i);
}
String GetSegmentFile(int segment_id)
{
for(int i = 0; i < sPPfile.GetCount(); i++) {
const Array<PPItem>& m = sPPfile[i].item;
for(int j = 0; j < m.GetCount(); j++)
if(m[j].type == PP_DEFINES && m[j].segment_id == segment_id)
return sPPfile.GetKey(i);
}
return "<not found>";
}
PPMacro *FindPPMacro(const String& id, Index<int>& segment_id, int& segmenti)
{
Index<int> undef;
PPMacro *r;
for(int pass = 0; pass < 2; pass++) {
r = NULL;
int best = segmenti;
int line = -1;
int q = sAllMacros.Find(id);
while(q >= 0) {
PPMacro& m = sAllMacros[q];
if(m.macro.IsUndef()) {
if(pass == 0 && segment_id.Find(m.segment_id) >= 0) {
undef.FindAdd(m.segment_id);
}
}
else
if(pass == 0 || undef.Find(m.undef_segment_id) < 0) {
int si = segment_id.Find(m.segment_id);
if(si > best || si >= 0 && si == best && m.line > line) {
best = si;
line = m.line;
r = &m;
}
}
q = sAllMacros.FindNext(q);
}
if(undef.GetCount() == 0)
break;
}
return r;
}
const CppMacro *FindMacro(const String& id, Index<int>& segment_id, int& segmenti)
{
PPMacro *m = FindPPMacro(id, segment_id, segmenti);
return m ? &m->macro : NULL;
}
String GetAllMacros(const String& id, Index<int>& 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<int>& namespace_block, int level)
{
if(namespace_block.GetCount() && namespace_block.Top() == level) {
namespace_block.Drop();
item.Add().type = PP_NAMESPACE_END;
}
}
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;
int linei = 0;
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));
}
}
else
if(p.Id("undef")) {
if(p.IsId()) {
String id = p.ReadId();
int segmenti = -1;
PPMacro *um = FindPPMacro(id, local_segments, segmenti);
if(um) { // 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);
}
}
else {
while(!p.IsEof()) {
if(was_namespace) {
int type = was_using ? PP_USING : PP_NAMESPACE;
String id;
while(p.Char2(':', ':'))
id = "::";
id << p.ReadId();
while(p.Char2(':', ':'))
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;
}
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++;
}
else {
q = namespace_end_macro.Find(id);
if(q >= 0) {
level--;
CheckEndNamespace(namespace_block, level);
}
}
}
else
if(p.Char('}')) {
if(level > 0) {
level--;
CheckEndNamespace(namespace_block, level);
}
}
else
if(p.Char('{'))
level++;
else
p.SkipTerm();
}
}
}
}
catch(...) {}
linei++;
}
}
void PPFile::Dump() const
{
for(int i = 0; i < item.GetCount(); i++) {
const PPItem& m = item[i];
String ll;
ll << decode(m.type, PP_DEFINES, "#defines ", PP_INCLUDE, "#include ",
PP_USING, "using namespace ", PP_NAMESPACE, "namespace ",
PP_NAMESPACE_END, "}", "");
if(m.type == PP_DEFINES)
ll << m.segment_id;
else
ll << m.text;
if(m.type == PP_NAMESPACE)
ll << " {";
LOG(ll);
}
LOG("----- includes:");
DUMPC(includes);
}
static VectorMap<String, Time> sPathFileTime;
static VectorMap<String, String> sIncludePath;
static VectorMap<String, bool> sIncludes;
static ArrayMap<String, PPFile> sFlatPP;
static String sInclude_Path;
void PPSync(const String& include_path)
{
sPathFileTime.Clear();
sIncludePath.Clear();
sIncludes.Clear();
sFlatPP.Clear();
sInclude_Path = include_path;
}
String GetIncludePath()
{
return sInclude_Path;
}
String GetIncludePath0(const char *s, const char *filedir)
{
LTIMING("GetIncludePath0");
while(IsSpace(*s))
s++;
int type = *s;
if(type == '<' || type == '\"' || type == '?') {
s++;
String name;
if(type == '<') type = '>';
while(*s != '\r' && *s != '\n') {
if(*s == type) {
if(type == '\"') {
String fn = NormalizePath(name, filedir);
if(FileExists(fn))
return fn;
}
return GetFileOnPath(name, GetIncludePath(), false);
}
name.Cat(*s++);
}
}
return Null;
}
Time GetFileTimeCached(const String& p)
{
LTIMING("GetFileTimeCached");
int q = sPathFileTime.Find(p);
if(q >= 0)
return sPathFileTime[q];
Time m = FileGetTime(p);
sPathFileTime.Add(p, m);
return m;
}
String GetIncludePath(const String& s, const String& filedir)
{
LTIMING("GetIncludePath");
String key;
key << s << "#" << filedir << "#" << GetIncludePath();
int q = sIncludePath.Find(key);
if(q >= 0)
return sIncludePath[q];
String p = GetIncludePath0(s, filedir);
sIncludePath.Add(key, p);
return p;
}
const PPFile& GetPPFile(const char *path)
{
Time tm = GetFileTimeCached(path);
PPFile& f = sPPfile.GetPut(path);
if(f.filetime != tm) {
f.filetime = tm;
LTIMING("PP read");
FileIn in(path);
f.Parse(in);
}
return f;
}
bool IsSameFile(const String& f1, const String& f2)
{
return NormalizePath(f1) == NormalizePath(f2);
}
bool IncludesFile(const String& parent_path, const String& path, Index<String>& visited)
{
HITCOUNT("IncludesFile0");
if(visited.Find(parent_path) >= 0)
return false;
visited.Add(parent_path);
if(IsSameFile(parent_path, path))
return true;
const PPFile& f = GetPPFile(parent_path);
for(int i = 0; i < f.includes.GetCount(); i++) {
String key = path + "#" + f.includes[i];
int q = sIncludes.Find(key);
if(q >= 0) {
HITCOUNT("IncludesFile cached");
if(sIncludes[q])
return true;
}
else {
HITCOUNT("IncludesFile getpath");
String p = GetIncludePath(f.includes[i], GetFileFolder(parent_path));
bool b = p.GetCount() && IncludesFile(p, path, visited);
sIncludes.Add(key, b);
if(b)
return true;
}
}
return false;
}
bool IncludesFile(const String& parent_path, const String& path)
{
LTIMING("IncludesFile");
Index<String> visited;
return IncludesFile(parent_path, path, visited);
}
void CreateFlatPP(PPFile& fp, const char *path, Index<String>& visited)
{
if(visited.Find(path) >= 0)
return;
visited.Add(path);
LLOG("CreateFlatPP " << path << LOG_BEGIN);
const PPFile& pp = GetPPFile(path);
for(int i = 0; i < pp.item.GetCount(); i++) {
const PPItem& m = pp.item[i];
if(m.type == PP_INCLUDE) {
String s = GetIncludePath(m.text, GetFileFolder(path));
if(s.GetCount())
CreateFlatPP(fp, s, visited);
}
else
fp.item.Add(m);
}
LLOG(LOG_END);
}
const PPFile& GetFlatPPFile(const char *path, Index<String>& visited)
{
LLOG("GetFlatPPFile " << path);
int q = sFlatPP.Find(path);
if(q >= 0)
return sFlatPP[q];
PPFile& fp = sFlatPP.Add(path);
const PPFile& pp = GetPPFile(path);
for(int i = 0; i < pp.item.GetCount(); i++) {
const PPItem& m = pp.item[i];
fp.item.Add(m);
if(m.type == PP_INCLUDE) {
String s = GetIncludePath(m.text, GetFileFolder(path));
if(s.GetCount() && visited.Find(s) < 0) {
visited.Add(s);
const PPFile& pp = GetFlatPPFile(s, visited);
for(int i = 0; i < pp.item.GetCount(); i++)
fp.item.Add(pp.item[i]);
}
}
}
return fp;
}
const PPFile& GetFlatPPFile(const char *path)
{
Index<String> visited;
visited.Add(path);
return GetFlatPPFile(path, visited);
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,31 @@
topic "";
[ $$0,0#00000000000000000000000000000000:Default]
[H6;0 $$1,0#05600065144404261032431302351956:begin]
[i448;a25;kKO9;2 $$2,0#37138531426314131252341829483370:codeitem]
[l288;2 $$3,0#27521748481378242620020725143825:desc]
[0 $$4,0#96390100711032703541132217272105:end]
[{_}%EN-US
[s1;%- &]
[s2;:Builder`:`:BuildPackage`(const String`&`,Vector`<String`>`&`,Vector`<String`>`&`,String`&`,const Vector`<String`>`&`,const Vector`<String`>`&`,int`):%- [@(0.0.255) v
irtual] [@(0.0.255) bool]_[* BuildPackage]([@(0.0.255) const]_[_^String^ String][@(0.0.255) `&
]_[*@3 package], [_^Vector^ Vector]<[_^String^ String]>`&_[*@3 linkfile],
[_^Vector^ Vector]<[_^String^ String]>`&_[*@3 immfile], [_^String^ String][@(0.0.255) `&]_[*@3 l
inkoptions], [@(0.0.255) const]_[_^Vector^ Vector]<[_^String^ String]>`&_[*@3 all`_uses],
[@(0.0.255) const]_[_^Vector^ Vector]<[_^String^ String]>`&_[*@3 all`_libraries],
[@(0.0.255) int]_[*@3 optimize])&]
[s3; Called for each package during building.&]
[s3; [%-*@3 package] name of package.&]
[s3; [%-*@3 linkfile] builder puts here files to link, for Link method&]
[s3; [%-*@3 immfile] builder puts here all intermediate files (.a,
.o, .lib ...) so that theide knows them and can touch them (set
current time) as needed&]
[s3; [%-*@3 linkoptions] again, like linkfile, a place to gather link
options so that Link method recieves them&]
[s3; [%-*@3 all`_uses] all packages that package uses (including indirect).
important for .so builds only&]
[s3; [%-*@3 all`_libraries] all libraries that package uses (including
indirect). important for .so builds only&]
[s3; [%-*@3 optimize] global optimization setting `- R`_SPEED, R`_SIZE,
R`_OPTIMAL&]
[s4; &]
[s0; ]]

View file

@ -19,7 +19,7 @@ void Test(const char *path)
errs.Clear();
Parser p;
p.Do(in, Vector<String>(), base, path, callback(AddError));
p.Do(in, base, 0, 0, callback(AddError));
if(errs.GetCount())
DUMPC(errs);
@ -30,7 +30,10 @@ void Test(const char *path)
const Array<CppItem>& ma = base[i];
for(int j = 0; j < ma.GetCount(); j++) {
const CppItem& m = ma[j];
out << '\t' << CppItemKindAsString(m.kind) << ", name: " << m.name << ", qitem: " << m.qitem << ", line " << m.line << "\n";
out << '\t' << CppItemKindAsString(m.kind) << ", name: " << m.name << ", qitem: " << m.qitem << ", qtype: " << m.qtype << ", line " << m.line;
if(m.isptr)
out << ", pointer";
out << "\n";
}
out << "}\n";
}
@ -39,7 +42,7 @@ void Test(const char *path)
p.dobody = true;
in.Seek(0);
p.Do(in, Vector<String>(), base, path, callback(AddError));
p.Do(in, base, 0, 0, callback(AddError));
out << "<locals> {\n";
for(int i = 0; i < p.local.GetCount(); i++) {
@ -54,14 +57,8 @@ void Test(const char *path)
LOG("-------------------------------------------------------------------------------");
}
CONSOLE_APP_MAIN {
CONSOLE_APP_MAIN
{
StdLogSetup(LOG_COUT|LOG_FILE);
Test(GetDataFile("test1.in"));
/*
FindFile ff(GetDataFile("test1.in"));
while(ff) {
Test(ff.GetPath());
ff.Next();
}
*/
Test(GetDataFile("test.in"));
}

View file

@ -4,11 +4,8 @@ uses
file
CppParser.cpp,
test1.in,
test1.out,
test2.in,
test2.out,
test3.in;
todo.txt,
test.in;
mainconfig
"" = "SSE2";

1
upptst/CppParser/test.in Normal file
View file

@ -0,0 +1 @@
typedef HMODULE DLLHANDLE;

View file

@ -1,9 +0,0 @@
extern "C++"
{
template <size_t _Size, typename _DstType>
inline
typename _CrtEnableIf<(_Size > 1), void *>::_Type memcpy(_DstType (&_Dst)[_Size], const void *_Src, size_t _SrcSize) throw()
{
return memcpy_s(_Dst, _Size * sizeof(_DstType), _Src, _SrcSize) == 0 ? _Dst : 0;
}
}

View file

@ -1,5 +0,0 @@
template<true, typename _Ty>
struct _CrtEnableIf<true, _Ty>
{
typedef _Ty _Type;
};

23
upptst/CppParser/todo.txt Normal file
View file

@ -0,0 +1,23 @@
enum
{
INVALID_SOCKET = -1,
TCP_NODELAY = 1,
SD_RECEIVE = 0,
SD_SEND = 1,
SD_BOTH = 2,
};
--------------------------
typedef HMODULE DLLHANDLE;
--------------------------
void RichEdit::Pick(RichText t)
{
Clear();
text = pick(t);
if(text.GetPartCount() == 0)
text.Cat(RichPara());
ReadStyles();
EndSizeTracking();
SetupLanguage(text.GetAllLanguages());
Move(0);
Update();
}