Информация об изменениях

Сообщение Re[3]: Определение регулярных последовательностей статически от 14.12.2024 23:29

Изменено 14.12.2024 23:39 kov_serg

Re[3]: Определение регулярных последовательностей статически
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Ужас. Это вместо того, чтоб уже закопать стюардессу препроцессор...


Ну если я правильно понял вам и нужен ужас. Примерно такой:

[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 {
    static auto &z=::z;
    namespace Nested {
        static auto &x=::x;
        static 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

touch 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::%S+)"
    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]
Re[3]: Определение регулярных последовательностей статически
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Ужас. Это вместо того, чтоб уже закопать стюардессу препроцессор...


Ну если я правильно понял вам и нужен ужас. Примерно такой:

[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

touch 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::%S+)"
    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]