Merge continued

git-svn-id: svn://ultimatepp.org/upp/trunk@10263 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2016-10-04 08:34:39 +00:00
parent adf46bd64e
commit 2e4b276e07
3860 changed files with 1161787 additions and 438 deletions

354
uppdev/cpp/cpp.cpp Normal file
View file

@ -0,0 +1,354 @@
#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;
}
String Cpp::Define(const char *s)
{
CParser p(s);
String id;
try {
if(!p.IsId())
return Null;
id = p.ReadId();
CppMacro& m = macro.GetAdd(id);
m.param.Clear();
if(p.Char('(')) {
while(p.IsId()) {
m.param.Add(p.ReadId());
p.Char(',');
}
if(p.Char3('.', '.', '.'))
m.variadic = true;
p.Char(')');
}
m.body = p.GetPtr();
}
catch(CParser::Error) {}
return "#define " + id;
}
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)
{
StringBuffer r;
while(*s) {
if(incomment) {
if(s[0] == '*' && s[1] == '/') {
incomment = false;
s += 2;
r.Cat("*/");
}
else
r.Cat(*s++);
}
else
if(iscib2(*s)) {
const char *b = s;
s++;
while(iscid2(*s))
s++;
String id(b, s);
if(notmacro.Find(id) < 0) {
const CppMacro *m = NULL;
const Cpp *p = this;
while(!m && p) {
m = p->macro.FindPtr(id);
p = p->parent;
}
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);
}
else
notmacro.Add(id);
}
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;
}
void Cpp::DoCpp(Stream& in, Index<String>& header)
{
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]).variadic = true;
Do(in, header);
}
void Cpp::Parse()
{
DDUMP(result.GetCount());
String r = result;
_DBG_ SaveFile("c:/xxx/cpp/" + GetFileTitle(path) + ".hpp", r);
DDUMP(result.GetCount());
StringStream ss(r);
DDUMP(result.GetCount());
Parse(ss, Vector<String>(), base, path, THISBACK(AddError));
}
void Cpp::Do(Stream& in, Index<String>& header)
{
incomment = false;
StringBuffer result;
result.Clear();
result.Reserve(16384);
int lineno = 0;
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());
}
const char *s = l;
while(*s == ' ')
s++;
if(*s == '#') {
if(strncmp(s + 1, "define", 6) == 0)
result << Define(s + 7) << "\n";
else {
result.Cat("\n");
if(strncmp(s + 1, "include", 7) == 0) {
String hdr = Expand(s + 8);
String header_path = GetIncludePath(hdr);
if(path.GetCount() == 0) DLOG("Include file " << String(s + 8) << " not found");
String include = String().Cat() << path << ':' << lineno << ':' << header_path;
if(path.GetCount() && header.Find(include) < 0) {
DLOG(">>> " << l << " -> " << header_path << LOG_BEGIN);
Parse(result);
header.Add(include);
Cpp cpp;
cpp.WhenError = Proxy(WhenError);
cpp.path = header_path;
cpp.filedir = GetFileFolder(header_path);
cpp.include_path = include_path;
cpp.parent = this;
DDUMP(cpp.macro.GetCount());
FileIn in(header_path);
cpp.Do(in, header);
DLOG(path << ": " << cpp.macro);
DLOG("USED: " << cpp.usedmacro);
// TODO: caching, this is the place to retrieve used macro values
{ RTIMING("Mixing macros");
for(int i = 0; i < cpp.macro.GetCount(); i++)
macro.GetAdd(cpp.macro.GetKey(i)) = pick(cpp.macro[i]);
}
DDUMP(macro.GetCount());
RTIMING("Mixing bases");
for(int i = 0; i < cpp.base.GetCount(); i++)
base.GetAdd(cpp.base.GetKey(i)).AppendPick(cpp.base[i]);
DLOG("---" << LOG_END);
}
notmacro.Clear();
}
}
}
else {
result.Cat(Expand(l) + "\n");
}
while(el--)
result.Cat("\n");
}
Parse(result);
}
String Cpp::GetIncludePath(const char *s)
{
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;
}

67
uppdev/cpp/cpp.h Normal file
View file

@ -0,0 +1,67 @@
#ifndef _cpp_cpp_h_
#define _cpp_cpp_h_
#include <Core/Core.h>
#include <CppBase/CppBase.h>
using namespace Upp;
struct CppMacro : Moveable<CppMacro>, DeepCopyOption<CppMacro> {
String body;
Index<String> param;
bool variadic;
String Expand(const Vector<String>& p) 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; }
};
struct Cpp {
bool incomment;
String path;
String filedir;
String include_path;
Index<String> header;
VectorMap<String, CppMacro> macro;
Index<String> usedmacro;
Index<String> notmacro;
CppBase base;
Cpp *parent;
void SyncSet();
String 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);
void Include(const char *s);
String GetIncludePath(const char *s);
void Parse();
void Do(Stream& in, Index<String>& header);
void DoCpp(Stream& in, Index<String>& header);
Callback3<const String&, int, const String&> WhenError;
void AddError(int ln, const String& s) { WhenError(path, ln, s); }
Cpp() { parent = NULL; }
typedef Cpp CLASSNAME;
};
String Preprocess(const String& filename, const String& include_path);
#endif

16
uppdev/cpp/cpp.txt Normal file
View file

@ -0,0 +1,16 @@
%'\1'%"\2"%
%1 +1%3%
%"1" "2" ","%','%
"a"
"a x y"
"\"A\""
a3
3a
a#
a"X"
"Y""X"
x
haha
haha ble
alfa xy.r #hahaha

15
uppdev/cpp/cpp.upp Normal file
View file

@ -0,0 +1,15 @@
uses
Core,
CppBase;
file
cpp.h,
cpp.cpp,
main.cpp,
test.h,
testfile,
cpp.txt;
mainconfig
"" = "";

5
uppdev/cpp/init Normal file
View file

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

55
uppdev/cpp/main.cpp Normal file
View file

@ -0,0 +1,55 @@
#include "cpp.h"
Vector<String> errs;
void AddError(const String& path, int ln, const String& s)
{
errs.Add(path + " " + AsString(ln) + ": " + s);
}
void Test(const char *path)
{
DDUMP(sizeof(CppItem));
Cpp cpp;
cpp.WhenError = callback(AddError);
cpp.path = path;
cpp.filedir = GetFileFolder(path);
// cpp.include_path = cpp.filedir;//"C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Vc\\Include;C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Include;C:\\OpenSSL-Win32\\include;C:\\u\\pgsql\\include;C:\\u\\OpenSSL-Win32\\include";
// cpp.include_path = "C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Vc\\Include;C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Include;C:\\OpenSSL-Win32\\include;C:\\u\\pgsql\\include;C:\\u\\OpenSSL-Win32\\include";
cpp.include_path = "C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\Vc\\Include;C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0\\Include;C:\\u\\OpenSSL-Win32\\include;C:\\u\\pgsql\\include;C:\\Program Files (x86)\\MySQL\\MySQL Connector C 6.1\\include";
cpp.include_path << ";c:/u/upp.src/uppsrc";
FileIn in(path);
Index<String> inc;
cpp.DoCpp(in, inc);
// StringStream ss(pp);
// Parse(ss, Vector<String>() << "__cdecl", base, path, callback(AddError));
DLOG("=======================");
DUMPC(inc);
DLOG("=======================");
DUMPC(errs);
DLOG("=======================");
Qualify(cpp.base);
String out;
for(int i = 0; i < cpp.base.GetCount(); i++) {
out << Nvl(cpp.base.GetKey(i), "<globals>") << " {\n";
const Array<CppItem>& ma = cpp.base[i];
for(int j = 0; j < ma.GetCount(); j++) {
const CppItem& m = ma[j];
out << '\t' << CppItemKindAsString(m.kind) << ' ' << m.qitem << ' ' << m.line << "\n";
// DDUMP(StoreAsString(const_cast<CppItem&>(m)).GetCount());
}
out << "}\n";
}
LOG(out);
}
CONSOLE_APP_MAIN
{
StdLogSetup(LOG_FILE, NULL, 150000000);
// Test(GetDataFile("testfile"));
Test("c:/u/upp.src/uppsrc/CtrlLib/EditField.cpp");
getchar();
return;
}
// TEST:a,b:|a|b|\n

165
uppdev/cpp/test.h Normal file
View file

@ -0,0 +1,165 @@
#include <string.h>
#include <winbase.h>
#include <wingdi.h>
#include <winuser.h>
#define eprintf(x, ...) if(x) printf(__VA_ARGS__)
eprintf(TEST, "%d is %d", a, b, c)
#define TEST test_expanded
TEST /* TEST in comment */ TEST
/* TEST in comment 2
TEST second line
*/ TEST
TEST // TEST
#undef TEST
This should not be expanded, it was undefined: TEST
#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 __Expand6(x) __Expand5(x) x(6)
#define __Expand7(x) __Expand6(x) x(7)
#define __Expand8(x) __Expand7(x) x(8)
#define __Expand9(x) __Expand8(x) x(9)
#define __Expand10(x) __Expand9(x) x(10)
#define __Expand11(x) __Expand10(x) x(11)
#define __Expand12(x) __Expand11(x) x(12)
#define __Expand13(x) __Expand12(x) x(13)
#define __Expand14(x) __Expand13(x) x(14)
#define __Expand15(x) __Expand14(x) x(15)
#define __Expand16(x) __Expand15(x) x(16)
#define __Expand17(x) __Expand16(x) x(17)
#define __Expand18(x) __Expand17(x) x(18)
#define __Expand19(x) __Expand18(x) x(19)
#define __Expand20(x) __Expand19(x) x(20)
#define __Expand21(x) __Expand20(x) x(21)
#define __Expand22(x) __Expand21(x) x(22)
#define __Expand23(x) __Expand22(x) x(23)
#define __Expand24(x) __Expand23(x) x(24)
#define __Expand25(x) __Expand24(x) x(25)
#define __Expand26(x) __Expand25(x) x(26)
#define __Expand27(x) __Expand26(x) x(27)
#define __Expand28(x) __Expand27(x) x(28)
#define __Expand29(x) __Expand28(x) x(29)
#define __Expand30(x) __Expand29(x) x(30)
#define __Expand31(x) __Expand30(x) x(31)
#define __Expand32(x) __Expand31(x) x(32)
#define __Expand33(x) __Expand32(x) x(33)
#define __Expand34(x) __Expand33(x) x(34)
#define __Expand35(x) __Expand34(x) x(35)
#define __Expand36(x) __Expand35(x) x(36)
#define __Expand37(x) __Expand36(x) x(37)
#define __Expand38(x) __Expand37(x) x(38)
#define __Expand39(x) __Expand38(x) x(39)
#define __Expand40(x) __Expand39(x) x(40)
#define __Expand(x) __Expand40(x)
#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 __List6(x) __List5(x), x(6)
#define __List7(x) __List6(x), x(7)
#define __List8(x) __List7(x), x(8)
#define __List9(x) __List8(x), x(9)
#define __List10(x) __List9(x), x(10)
#define __List11(x) __List10(x), x(11)
#define __List12(x) __List11(x), x(12)
#define __List13(x) __List12(x), x(13)
#define __List14(x) __List13(x), x(14)
#define __List15(x) __List14(x), x(15)
#define __List16(x) __List15(x), x(16)
#define __List17(x) __List16(x), x(17)
#define __List18(x) __List17(x), x(18)
#define __List19(x) __List18(x), x(19)
#define __List20(x) __List19(x), x(20)
#define __List21(x) __List20(x), x(21)
#define __List22(x) __List21(x), x(22)
#define __List23(x) __List22(x), x(23)
#define __List24(x) __List23(x), x(24)
#define __List25(x) __List24(x), x(25)
#define __List26(x) __List25(x), x(26)
#define __List27(x) __List26(x), x(27)
#define __List28(x) __List27(x), x(28)
#define __List29(x) __List28(x), x(29)
#define __List30(x) __List29(x), x(30)
#define __List31(x) __List30(x), x(31)
#define __List32(x) __List31(x), x(32)
#define __List33(x) __List32(x), x(33)
#define __List34(x) __List33(x), x(34)
#define __List35(x) __List34(x), x(35)
#define __List36(x) __List35(x), x(36)
#define __List37(x) __List36(x), x(37)
#define __List38(x) __List37(x), x(38)
#define __List39(x) __List38(x), x(39)
#define __List40(x) __List39(x), x(40)
#define E__p(I) p##I
#define ASSTRING_(x) #x
#define ASSTRING(x) ASSTRING_(x)
#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 E__NFValue(I) const Value& COMBINE(p, I)
#define E__NFBody(I) String Format(const char *fmt, __List##I(E__NFValue));
EXPAND: __Expand20(E__NFBody)
ASSTRING(Just a test)
COMBINE(aaaa, bbbb)
#define TEST(x, y) %x%y%
#define TESTS(x) #x
#define TEST2(x, y) x ## y
#define TEST4 alfa x ## y.r #hahaha
#define TESTX x
#define TESTY haha
#define TESTZ haha
TEST('\1', "\2")
TEST( 1 +1 , 3 )
TEST( "1" "2" ",", ',')
TESTS(a)
TESTS(a x y)
TESTS("A")
TEST2(a, 3)
TEST2(3, a)
TEST2(a, #)
TEST2(a, "X")
TEST2("Y", "X")
TESTX
TESTY
TESTZ
TEST4
#define pow2(x) (x) * (x)
#define dist(a, b) pow2(a.x - b.x) + pow2(a.y - b.y)
dist(x, y);
#define __countof(a) int(sizeof(a) / sizeof(a[0]))
__countof(bla)

1
uppdev/cpp/testfile Normal file
View file

@ -0,0 +1 @@
#include <windows.h>