mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
.uppdev
git-svn-id: svn://ultimatepp.org/upp/trunk@8288 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
d857271e4f
commit
93b425c056
10 changed files with 1175 additions and 0 deletions
368
uppdev/cpp2/cpp.cpp
Normal file
368
uppdev/cpp2/cpp.cpp
Normal file
|
|
@ -0,0 +1,368 @@
|
||||||
|
#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;
|
||||||
|
String r;
|
||||||
|
try {
|
||||||
|
if(!p.IsId())
|
||||||
|
return Null;
|
||||||
|
id = p.ReadId();
|
||||||
|
r << "#define " << id;
|
||||||
|
CppMacro& m = macro.GetAdd(id);
|
||||||
|
m.param.Clear();
|
||||||
|
if(p.Char('(')) {
|
||||||
|
r << '(';
|
||||||
|
bool next = false;
|
||||||
|
while(p.IsId()) {
|
||||||
|
String pid = p.ReadId();
|
||||||
|
if(next)
|
||||||
|
r << ", ";
|
||||||
|
r << pid;
|
||||||
|
m.param.Add(p.ReadId());
|
||||||
|
p.Char(',');
|
||||||
|
next = true;
|
||||||
|
}
|
||||||
|
if(p.Char3('.', '.', '.')) {
|
||||||
|
m.variadic = true;
|
||||||
|
if(next)
|
||||||
|
r << ", ";
|
||||||
|
r << "...";
|
||||||
|
}
|
||||||
|
p.Char(')');
|
||||||
|
r << ')';
|
||||||
|
}
|
||||||
|
m.body = p.GetPtr();
|
||||||
|
}
|
||||||
|
catch(CParser::Error) {}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(StringBuffer& result)
|
||||||
|
{
|
||||||
|
DDUMP(result.GetCount());
|
||||||
|
String r = result;
|
||||||
|
_DBG_ SaveFile("c:/xxx/cpp/" + GetFileTitle(path) + ".hpp", r);
|
||||||
|
DDUMP(result.GetCount());
|
||||||
|
StringStream ss(r);
|
||||||
|
DDUMP(result.GetCount());
|
||||||
|
Upp::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;
|
||||||
|
}
|
||||||
105
uppdev/cpp2/cpp.h
Normal file
105
uppdev/cpp2/cpp.h
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
#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 Define(const char *s);
|
||||||
|
|
||||||
|
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; }
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PPItemType {
|
||||||
|
PP_DEFINE,
|
||||||
|
PP_INCLUDE,
|
||||||
|
PP_USING,
|
||||||
|
PP_NAMESPACE,
|
||||||
|
PP_NAMESPACE_END
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PPItem {
|
||||||
|
int type;
|
||||||
|
String id;
|
||||||
|
CppMacro macro;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PPFile {
|
||||||
|
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& include, const String& path, const String& include_path);
|
||||||
|
|
||||||
|
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(StringBuffer& result);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
String Preprocess(const String& sourcefile, Stream& in, const String& surrogatefile,
|
||||||
|
const String& include_path);
|
||||||
|
|
||||||
|
#endif
|
||||||
16
uppdev/cpp2/cpp.txt
Normal file
16
uppdev/cpp2/cpp.txt
Normal 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
|
||||||
|
|
||||||
17
uppdev/cpp2/cpp2.upp
Normal file
17
uppdev/cpp2/cpp2.upp
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
uses
|
||||||
|
Core,
|
||||||
|
CppBase;
|
||||||
|
|
||||||
|
file
|
||||||
|
cpp.h,
|
||||||
|
expand.cpp,
|
||||||
|
ppfile.cpp,
|
||||||
|
cpp.cpp,
|
||||||
|
main.cpp,
|
||||||
|
test.h,
|
||||||
|
testfile,
|
||||||
|
cpp.txt;
|
||||||
|
|
||||||
|
mainconfig
|
||||||
|
"" = "";
|
||||||
|
|
||||||
94
uppdev/cpp2/expand.cpp
Normal file
94
uppdev/cpp2/expand.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
#include "cpp.h"
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
String MacroExpand(const char *s, ArrayMap<String, CppMacro>& macro, Index<String>& notmacro,
|
||||||
|
bool& incomment)
|
||||||
|
{
|
||||||
|
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 = 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);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
5
uppdev/cpp2/init
Normal file
5
uppdev/cpp2/init
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#ifndef _cpp2_icpp_init_stub
|
||||||
|
#define _cpp2_icpp_init_stub
|
||||||
|
#include "Core/init"
|
||||||
|
#include "CppBase/init"
|
||||||
|
#endif
|
||||||
103
uppdev/cpp2/main.cpp
Normal file
103
uppdev/cpp2/main.cpp
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
#include "cpp.h"
|
||||||
|
|
||||||
|
Vector<String> errs;
|
||||||
|
|
||||||
|
void AddError(const String& path, int ln, const String& s)
|
||||||
|
{
|
||||||
|
errs.Add(path + " " + AsString(ln) + ": " + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
String 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;"
|
||||||
|
"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;"
|
||||||
|
";c:/u/upp.src/uppsrc";
|
||||||
|
|
||||||
|
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(cpp.macro.GetKeys());
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecursePP(const char *path, const char *include_path, Index<String>& visited)
|
||||||
|
{
|
||||||
|
const PPFile& p = GetPPFile(path);
|
||||||
|
String filedir = GetFileFolder(path);
|
||||||
|
for(int i = 0; i < p.includes.GetCount(); i++) {
|
||||||
|
String ip = GetIncludePath(p.includes[i], filedir, include_path);
|
||||||
|
if(visited.Find(ip) < 0) {
|
||||||
|
visited.Add(ip);
|
||||||
|
RecursePP(ip, include_path, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG("-------------------------");
|
||||||
|
LOG(path);
|
||||||
|
p.Dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
CONSOLE_APP_MAIN
|
||||||
|
{
|
||||||
|
StdLogSetup(LOG_FILE, NULL, 150000000);
|
||||||
|
// Test(GetDataFile("testfile"));
|
||||||
|
// Test("c:/u/upp.src/uppsrc/CtrlLib/EditField.cpp");
|
||||||
|
// getchar();
|
||||||
|
|
||||||
|
// PPFile f;
|
||||||
|
// FileIn in(GetDataFile("test.h"));
|
||||||
|
// f.Parse(in);
|
||||||
|
// f.Dump();
|
||||||
|
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPPFile(GetDataFile("test.h")).Dump();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEST:a,b:|a|b|\n
|
||||||
284
uppdev/cpp2/ppfile.cpp
Normal file
284
uppdev/cpp2/ppfile.cpp
Normal file
|
|
@ -0,0 +1,284 @@
|
||||||
|
#include "cpp.h"
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
Vector<int> namespace_block;
|
||||||
|
while(!in.IsEof()) { // TODO: Do comments...
|
||||||
|
String l = in.GetLine();
|
||||||
|
while(*l.Last() == '\\' && !in.IsEof()) {
|
||||||
|
l.Trim(l.GetLength() - 1);
|
||||||
|
l.Cat(in.GetLine());
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
if(m.macro.param.GetCount() || m.macro.variadic) {
|
||||||
|
ll << '(' << Join(m.macro.param.GetKeys(), ", ");
|
||||||
|
if(m.macro.variadic)
|
||||||
|
ll << "...";
|
||||||
|
ll << ')';
|
||||||
|
}
|
||||||
|
ll << ' ' << m.macro.body;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
182
uppdev/cpp2/test.h
Normal file
182
uppdev/cpp2/test.h
Normal file
|
|
@ -0,0 +1,182 @@
|
||||||
|
#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)
|
||||||
|
|
||||||
|
namespace Test {
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "LaterInclude.h"
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
using
|
||||||
|
namespace
|
||||||
|
Something::otherline;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
::something::otherthing {
|
||||||
|
cool!
|
||||||
|
};
|
||||||
|
|
||||||
|
#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/cpp2/testfile
Normal file
1
uppdev/cpp2/testfile
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
#include <windows.h>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue