Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Ужас. Это вместо того, чтоб уже закопать стюардессу препроцессор...
Ну если я правильно понял вам и нужен ужас. Примерно такой:
[test.cpp]
#include <string>
#include <iostream>
// где-то по коду
static const int z[]={1,2};
static const double x=10;
static const int y[]={1,2,3,4,5,6,7,8,9,10};
// собираем всех кого нужно в древовидную структуру в отдельной единице трансляции маркер имя namespace-а
namespace Consts {
auto &z=::z;
namespace Nested {
auto &x=::x;
auto &y=::y;
}
}
// decl
typedef decltype(typeid(0)) ti;
#define DECL(name) decl(ctx,(void*)&name,sizeof(name),#name,typeid(name));
void enum_vars( void (*decl)(void *ctx,void *ptr,size_t size,const char* name,ti t),void *ctx) {
#include "consts.inc" // что-бы вручную не писать используем готовый код. готовим отдельно
}
#undef DECL
// utils
#include <cxxabi.h>
#include <stdlib.h>
std::string getTypeName(ti t) {
std::string res; int err=0;
char* name=abi::__cxa_demangle(t.name(),0,0,&err);
if (name) { res=name; free(name); }
return res;
}
void print_var(void *ctx,void *ptr,size_t size,const char* name,ti t) {
std::cout<<size<<"\t"<<name<<"\t"<<getTypeName(t)<<"\n";
}
int main() {
enum_vars(print_var,0); // пробегаем по линейному списку (можем делать всё что хотим, например выводим на печать)
return 0;
}
| build.sh |
| #!/bin/sh
echo > consts.inc
g++ -c test.cpp && \
objdump -x test.o | c++filt | lua filter.lua > consts.inc && \
rm test.o && \
g++ -o test test.cpp && \
./test
|
| |
| filter.lua |
| for line in io.lines() do
local size,name=line:match"%.data%.rel%.ro%.local%s+(%x+)%s+(Consts::[%w%d:_]+)"
if name then print("DECL("..name..")") end
end
|
| |
[output]
8 Consts::z int [2]
8 Consts::Nested::x double
40 Consts::Nested::y int [10]