mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-21 06:14:08 -06:00
cpp merge (continued)
git-svn-id: svn://ultimatepp.org/upp/trunk@8428 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
49d3de4a8a
commit
83267af440
78 changed files with 2453 additions and 756 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -4,9 +4,6 @@ uses
|
|||
|
||||
file
|
||||
cpp.h,
|
||||
macro.cpp,
|
||||
ppfile.cpp,
|
||||
cpp.cpp,
|
||||
main.cpp,
|
||||
test.h,
|
||||
testfile,
|
||||
|
|
|
|||
|
|
@ -1,124 +0,0 @@
|
|||
#include "cpp.h"
|
||||
|
||||
inline bool IsSpc(byte c)
|
||||
{
|
||||
return c > 0 && c <= 32;
|
||||
}
|
||||
|
||||
String CppMacro::Define(const char *s)
|
||||
{
|
||||
CParser p(s);
|
||||
String id;
|
||||
try {
|
||||
if(!p.IsId())
|
||||
return Null;
|
||||
id = p.ReadId();
|
||||
param.Clear();
|
||||
if(p.Char('(')) {
|
||||
while(p.IsId()) {
|
||||
if(param.GetCount())
|
||||
param << ",";
|
||||
param << p.ReadId();
|
||||
p.Char(',');
|
||||
}
|
||||
if(p.Char3('.', '.', '.'))
|
||||
param << '.';
|
||||
p.Char(')');
|
||||
}
|
||||
body = p.GetPtr();
|
||||
}
|
||||
catch(CParser::Error) {
|
||||
return Null;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
String CppMacro::ToString() const
|
||||
{
|
||||
String r;
|
||||
if(param.GetCount()) {
|
||||
String h = param;
|
||||
h.Replace(".", "...");
|
||||
r << "(" << h << ")";
|
||||
}
|
||||
r << ' ' << body;
|
||||
return r;
|
||||
}
|
||||
|
||||
String CppMacro::Expand(const Vector<String>& p) const
|
||||
{
|
||||
String r;
|
||||
const char *s = body;
|
||||
String pp = param;
|
||||
bool variadic = false;
|
||||
if(*pp.Last() == '.') {
|
||||
variadic = true;
|
||||
pp.Trim(pp.GetCount() - 1);
|
||||
}
|
||||
Index<String> param(pick(Split(pp, ',')));
|
||||
while(*s) {
|
||||
if(IsAlpha(*s) || *s == '_') {
|
||||
const char *b = s;
|
||||
s++;
|
||||
while(IsAlNum(*s) || *s == '_')
|
||||
s++;
|
||||
String id(b, s);
|
||||
static String VA_ARGS("__VA_ARGS__"); // Speed optimization
|
||||
if(id == VA_ARGS) {
|
||||
bool next = false;
|
||||
for(int i = param.GetCount(); i < p.GetCount(); i++) {
|
||||
if(next)
|
||||
r.Cat(", ");
|
||||
r.Cat(p[i]);
|
||||
next = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int q = param.Find(id);
|
||||
if(q >= 0) {
|
||||
if(q < p.GetCount())
|
||||
r.Cat(p[q]);
|
||||
}
|
||||
else
|
||||
r.Cat(id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(s[0] == '#' && s[1] == '#') {
|
||||
int q = r.GetLength();
|
||||
while(q > 0 && IsSpc(r[q - 1]))
|
||||
q--;
|
||||
r.Trim(q);
|
||||
s += 2;
|
||||
while((byte)*s <= ' ')
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
if(*s == '#') {
|
||||
const char *ss = s + 1;
|
||||
while(IsSpc(*ss))
|
||||
ss++;
|
||||
if(IsAlpha(*ss) || *ss == '_') {
|
||||
const char *b = ss;
|
||||
ss++;
|
||||
while(IsAlNum(*ss) || *ss == '_')
|
||||
ss++;
|
||||
String id(b, ss);
|
||||
int q = param.Find(id);
|
||||
if(q >= 0) {
|
||||
if(q <= p.GetCount()) {
|
||||
if(q < p.GetCount())
|
||||
r.Cat(AsCString(p[q]));
|
||||
s = ss;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
r.Cat(String(s, ss));
|
||||
s = ss;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
r.Cat(*s++);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue