git-svn-id: svn://ultimatepp.org/upp/trunk@8292 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2015-03-24 14:50:32 +00:00
parent cd6850090e
commit adef44db1c
6 changed files with 169 additions and 145 deletions

View file

@ -1,88 +1,5 @@
#include "cpp.h" #include "cpp.h"
#include <string.h>
inline bool IsSpc(byte c)
{
return c > 0 && c <= 32;
}
String CppMacro::ToString() const
{
return String().Cat() << "(" << AsString(param) << ") " << body;
}
String CppMacro::Expand(const Vector<String>& p) const
{
String r;
const char *s = body;
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;
}
void Cpp::Define(const char *s) void Cpp::Define(const char *s)
{ {
CppMacro m; CppMacro m;
@ -145,10 +62,10 @@ String Cpp::Expand(const char *s, Index<String>& notmacro)
r.Cat(*s++); r.Cat(*s++);
} }
else else
if(iscib2(*s)) { if(iscib(*s)) {
const char *b = s; const char *b = s;
s++; s++;
while(iscid2(*s)) while(iscid(*s))
s++; s++;
String id(b, s); String id(b, s);
if(notmacro.Find(id) < 0) { if(notmacro.Find(id) < 0) {
@ -219,7 +136,8 @@ String Cpp::Expand(const char *s, Index<String>& notmacro)
return r; return r;
} }
bool Cpp::Preprocess(const String& sourcefile, Stream& in, const String& currentfile) bool Cpp::Preprocess(const String& sourcefile, Stream& in, const String& currentfile,
const Index<String> *get_macros)
{ {
macro.Clear(); macro.Clear();
Vector<String> ignorelist = Split("__declspec;__cdecl;" Vector<String> ignorelist = Split("__declspec;__cdecl;"
@ -228,35 +146,39 @@ bool Cpp::Preprocess(const String& sourcefile, Stream& in, const String& current
"$drv_group;$allowed_on_parameter", "$drv_group;$allowed_on_parameter",
';'); ';');
for(int i = 0; i < ignorelist.GetCount(); i++) for(int i = 0; i < ignorelist.GetCount(); i++)
macro.GetAdd(ignorelist[i]).variadic = true; macro.GetAdd(ignorelist[i]).param = ".";
done = false; done = false;
incomment = false; incomment = false;
Index<String> visited; Index<String> visited;
Do(NormalizePath(sourcefile), in, NormalizePath(currentfile), visited); Do(NormalizePath(sourcefile), in, NormalizePath(currentfile), visited, get_macros);
return done; return done;
} }
void Cpp::Do(const String& sourcefile, Stream& in, const String& currentfile, Index<String>& visited) void Cpp::Do(const String& sourcefile, Stream& in, const String& currentfile,
Index<String>& visited, const Index<String> *get_macros)
{ {
DDUMP(currentfile); // DUMP(currentfile);
if(visited.Find(currentfile) >= 0 || visited.GetCount() > 20000) if(visited.Find(currentfile) >= 0 || visited.GetCount() > 20000)
return; return;
visited.Add(currentfile); visited.Add(currentfile);
String current_folder = GetFileFolder(currentfile); String current_folder = GetFileFolder(currentfile);
if(sourcefile != currentfile) { if(sourcefile != currentfile) {
const PPFile& pp = GetPPFile(currentfile); const PPFile& pp = GetPPFile(currentfile);
#ifdef _DEBUG
pp.Dump(); pp.Dump();
#endif
for(int i = 0; i < pp.item.GetCount() && !done; i++) { for(int i = 0; i < pp.item.GetCount() && !done; i++) {
const PPItem& m = pp.item[i]; const PPItem& m = pp.item[i];
if(m.type == PP_DEFINE) { if(m.type == PP_DEFINE) {
if(m.macro.body.GetCount()) // RTIMING("macro Add");
macro.GetAdd(m.id) = clone(m.macro); if(!get_macros || get_macros->Find(m.id) >= 0)
macro.GetAdd(m.id) = m.macro;
} }
else else
if(m.type == PP_INCLUDE) { if(m.type == PP_INCLUDE) {
String s = GetIncludePath(m.id, current_folder, include_path); String s = GetIncludePath(m.id, current_folder, include_path);
if(s.GetCount()) if(s.GetCount())
Do(sourcefile, in, s, visited); Do(sourcefile, in, s, visited, get_macros);
} }
else else
if(m.type == PP_NAMESPACE) if(m.type == PP_NAMESPACE)
@ -271,6 +193,11 @@ void Cpp::Do(const String& sourcefile, Stream& in, const String& currentfile, In
return; return;
} }
done = true;
if(get_macros)
return;
RTIMING("Expand");
incomment = false; incomment = false;
StringBuffer result; StringBuffer result;
result.Clear(); result.Clear();
@ -299,7 +226,7 @@ void Cpp::Do(const String& sourcefile, Stream& in, const String& currentfile, In
String hdr = Expand(p.GetPtr()); String hdr = Expand(p.GetPtr());
String header_path = GetIncludePath(hdr, current_folder, include_path); String header_path = GetIncludePath(hdr, current_folder, include_path);
if(header_path.GetCount()) if(header_path.GetCount())
Do(Null, NilStream(), header_path, visited); Do(Null, NilStream(), header_path, visited, get_macros);
} }
} }
} }
@ -309,6 +236,6 @@ void Cpp::Do(const String& sourcefile, Stream& in, const String& currentfile, In
while(el--) while(el--)
result.Cat("\n"); result.Cat("\n");
} }
done = true; DUMP(macro.GetCount());
output = result; output = result;
} }

View file

@ -10,19 +10,14 @@ using namespace Upp;
void RemoveComments(String& l, bool& incomment); void RemoveComments(String& l, bool& incomment);
struct CppMacro : Moveable<CppMacro>, DeepCopyOption<CppMacro> { struct CppMacro : Moveable<CppMacro>, DeepCopyOption<CppMacro> {
String param;
String body; String body;
Index<String> param;
bool variadic;
String Define(const char *s); String Define(const char *s);
String Expand(const Vector<String>& p) const; String Expand(const Vector<String>& p) const;
String ToString() const; String ToString() const;
CppMacro() { variadic = false; }
rval_default(CppMacro);
CppMacro(const CppMacro& s, int) { body = s.body, param = clone(s.param); variadic = s.variadic; }
}; };
enum PPItemType { enum PPItemType {
@ -77,9 +72,11 @@ struct Cpp {
void ParamAdd(Vector<String>& param, const char *b, const char *e); void ParamAdd(Vector<String>& param, const char *b, const char *e);
String Expand(const char *s, Index<String>& notmacro); String Expand(const char *s, Index<String>& notmacro);
String Expand(const char *s); String Expand(const char *s);
void Do(const String& sourcefile, Stream& in, const String& currentfile, Index<String>& visited); 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); bool Preprocess(const String& sourcefile, Stream& in, const String& currentfile,
const Index<String> *get_macros = NULL);
typedef Cpp CLASSNAME; typedef Cpp CLASSNAME;
}; };

View file

@ -4,6 +4,7 @@ uses
file file
cpp.h, cpp.h,
macro.cpp,
ppfile.cpp, ppfile.cpp,
cpp.cpp, cpp.cpp,
main.cpp, main.cpp,

124
uppdev/cpp2/macro.cpp Normal file
View file

@ -0,0 +1,124 @@
#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;
}

View file

@ -19,11 +19,18 @@ void Test(const char *sourcefile, const char *currentfile)
Cpp cpp; Cpp cpp;
cpp.include_path = include_path; cpp.include_path = include_path;
FileIn in(sourcefile); FileIn in(sourcefile);
DDUMP(cpp.Preprocess(sourcefile, in, currentfile)); RDUMP(cpp.Preprocess(sourcefile, in, currentfile));
DDUMP(cpp.namespace_stack); DDUMP(cpp.namespace_stack);
DDUMP(cpp.output); // DDUMP(cpp.output);
DDUMP(cpp.usedmacro); DDUMP(cpp.usedmacro);
DLOG("================================="); DLOG("=================================");
{
Cpp cpp;
cpp.include_path = include_path;
cpp.Preprocess(sourcefile, NilStream(), currentfile, &cpp.usedmacro);
DDUMP(cpp.macro);
}
} }
void RecursePP(const char *path, const char *include_path, Index<String>& visited) void RecursePP(const char *path, const char *include_path, Index<String>& visited)
@ -47,7 +54,7 @@ void TestC(const char *ln)
for(int q = 0; q < 2; q++) { for(int q = 0; q < 2; q++) {
bool incomment = q; bool incomment = q;
String l = ln; String l = ln;
DDUMP(incomment); DUMP(incomment);
LOG(l); LOG(l);
RemoveComments(l, incomment); RemoveComments(l, incomment);
LOG(l); LOG(l);
@ -79,13 +86,14 @@ CONSOLE_APP_MAIN
#endif #endif
{ {
RTIMING("Pass1"); RTIMING("Pass1");
Test("C:\\u\\upp.src\\uppsrc\\Core\\Profile.h", "C:\\u\\upp.src\\uppsrc\\Core\\Format.cpp"); Test("C:\\u\\upp.src\\uppsrc\\Core\\Format.h", "C:\\u\\upp.src\\uppsrc\\Core\\Format.cpp");
} }
if(0) { #ifndef _DEBUG
for(int i = 0; i < 100; i++) {
RTIMING("Pass2"); RTIMING("Pass2");
Test("C:\\u\\upp.src\\uppsrc\\Core\\Format.h", "C:\\u\\upp.src\\uppsrc\\Core\\Format.cpp"); Test("C:\\u\\upp.src\\uppsrc\\Core\\Format.h", "C:\\u\\upp.src\\uppsrc\\Core\\Format.cpp");
} }
#endif
#if 0 #if 0
{ {
RTIMING("Pass1"); RTIMING("Pass1");

View file

@ -32,33 +32,6 @@ void RemoveComments(String& l, bool& incomment)
} }
} }
String CppMacro::Define(const char *s)
{
CParser p(s);
String id;
try {
if(!p.IsId())
return Null;
id = p.ReadId();
param.Clear();
variadic = false;
if(p.Char('(')) {
while(p.IsId()) {
param.Add(p.ReadId());
p.Char(',');
}
if(p.Char3('.', '.', '.'))
variadic = true;
p.Char(')');
}
body = p.GetPtr();
}
catch(CParser::Error) {
return Null;
}
return id;
}
void PPFile::CheckEndNamespace(Vector<int>& namespace_block, int level) void PPFile::CheckEndNamespace(Vector<int>& namespace_block, int level)
{ {
if(namespace_block.GetCount() && namespace_block.Top() == level) { if(namespace_block.GetCount() && namespace_block.Top() == level) {
@ -191,15 +164,8 @@ void PPFile::Dump() const
PP_USING, "using namespace", PP_NAMESPACE, "namespace", PP_USING, "using namespace", PP_NAMESPACE, "namespace",
PP_NAMESPACE_END, "}", "") PP_NAMESPACE_END, "}", "")
<< ' ' << m.id; << ' ' << m.id;
if(m.type == PP_DEFINE) { if(m.type == PP_DEFINE)
if(m.macro.param.GetCount() || m.macro.variadic) { ll << m.macro;
ll << '(' << Join(m.macro.param.GetKeys(), ", ");
if(m.macro.variadic)
ll << "...";
ll << ')';
}
ll << ' ' << m.macro.body;
}
if(m.type == PP_NAMESPACE) if(m.type == PP_NAMESPACE)
ll << " {"; ll << " {";
LOG(ll); LOG(ll);
@ -255,6 +221,7 @@ FileTime GetFileTimeCached(const String& p)
String GetIncludePath(const String& s, const String& filedir, const String& include_path) String GetIncludePath(const String& s, const String& filedir, const String& include_path)
{ {
RTIMING("GetIncludePath");
String key; String key;
key << s << "#" << filedir << "#" << include_path; key << s << "#" << filedir << "#" << include_path;
int q = sIncludePath.Find(key); int q = sIncludePath.Find(key);