Skip to content

Commit 896ff44

Browse files
committed
Crangler: support removing static from objects
Just like functions, objects can be file-local. To support accessing them, permit removing "static" from objects as well.
1 parent 25f1922 commit 896ff44

File tree

4 files changed

+156
-0
lines changed

4 files changed

+156
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
int foo()
2+
{
3+
return 0;
4+
}
5+
6+
int bar();
7+
8+
static void foobar1()
9+
{
10+
}
11+
12+
void static foobar2()
13+
{
14+
}
15+
16+
static short x;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
remove_static1.json
3+
4+
^\s+void foobar1\(\)$
5+
^\s+short x;$
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"sources": [
3+
"remove_static1.c"
4+
],
5+
"functions": [
6+
{
7+
"foobar1": [
8+
"remove static"
9+
]
10+
}
11+
],
12+
"objects": [
13+
{
14+
"x": [
15+
"remove static"
16+
]
17+
}
18+
],
19+
"output": "stdout"
20+
}

src/crangler/c_wrangler.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,20 @@ struct c_wranglert
9090
using functionst = std::list<std::pair<std::regex, functiont>>;
9191
functionst functions;
9292

93+
struct objectt
94+
{
95+
bool remove_static = false;
96+
};
97+
98+
using objectst = std::list<std::pair<std::regex, objectt>>;
99+
objectst objects;
100+
93101
// output
94102
std::string output;
95103

96104
void configure_sources(const jsont &);
97105
void configure_functions(const jsont &);
106+
void configure_objects(const jsont &);
98107
void configure_output(const jsont &);
99108
};
100109

@@ -239,6 +248,62 @@ void c_wranglert::configure_functions(const jsont &config)
239248
}
240249
}
241250

251+
void c_wranglert::configure_objects(const jsont &config)
252+
{
253+
auto objects = config["objects"];
254+
255+
if(objects.is_null())
256+
return;
257+
258+
if(!objects.is_array())
259+
throw deserialization_exceptiont("objects entry must be sequence");
260+
261+
for(const auto &object : to_json_array(objects))
262+
{
263+
if(!object.is_object())
264+
throw deserialization_exceptiont("object entry must be object");
265+
266+
for(const auto &object_entry : to_json_object(object))
267+
{
268+
const auto &object_name = object_entry.first;
269+
const auto &items = object_entry.second;
270+
271+
if(!items.is_array())
272+
throw deserialization_exceptiont("object entry must be sequence");
273+
274+
this->objects.emplace_back(object_name, objectt{});
275+
objectt &object_config = this->objects.back().second;
276+
277+
for(const auto &object_item : to_json_array(items))
278+
{
279+
// Needs to start with "remove"
280+
if(!object_item.is_string())
281+
throw deserialization_exceptiont("object entry must be string");
282+
283+
auto item_string = object_item.value;
284+
auto split = split_string(item_string, ' ');
285+
if(split.empty())
286+
continue;
287+
288+
if(split[0] == "remove")
289+
{
290+
if(split.size() == 1)
291+
throw deserialization_exceptiont("unexpected remove entry");
292+
293+
if(split[1] == "static")
294+
object_config.remove_static = true;
295+
else
296+
throw deserialization_exceptiont(
297+
"unexpected remove entry " + split[1]);
298+
}
299+
else
300+
throw deserialization_exceptiont(
301+
"unexpected object entry " + split[0]);
302+
}
303+
}
304+
}
305+
}
306+
242307
void c_wranglert::configure_output(const jsont &config)
243308
{
244309
auto output = config["output"];
@@ -393,6 +458,39 @@ static void mangle_function(
393458
}
394459
}
395460

461+
static void mangle_object(
462+
const c_declarationt &declaration,
463+
const c_definest &defines,
464+
const c_wranglert::objectt &object_config,
465+
std::ostream &out)
466+
{
467+
if(object_config.remove_static)
468+
{
469+
for(auto &t : declaration.pre_declarator)
470+
{
471+
if(t.text == "static")
472+
{
473+
// we replace by white space
474+
out << std::string(6, ' ');
475+
}
476+
else
477+
out << t.text;
478+
}
479+
}
480+
else
481+
{
482+
for(auto &t : declaration.pre_declarator)
483+
out << t.text;
484+
}
485+
486+
for(auto &t : declaration.declarator)
487+
out << t.text;
488+
for(auto &t : declaration.post_declarator)
489+
out << t.text;
490+
for(auto &t : declaration.initializer)
491+
out << t.text;
492+
}
493+
396494
static void mangle(
397495
const c_declarationt &declaration,
398496
const c_definest &defines,
@@ -414,6 +512,19 @@ static void mangle(
414512
}
415513
}
416514
}
515+
else if(!declaration.is_function() && name_opt.has_value())
516+
{
517+
for(const auto &entry : config.objects)
518+
{
519+
if(std::regex_match(name_opt->text, entry.first))
520+
{
521+
// we are to modify this function
522+
mangle_object(declaration, defines, entry.second, out);
523+
524+
return;
525+
}
526+
}
527+
}
417528

418529
// output
419530
out << declaration;
@@ -441,6 +552,7 @@ void c_wrangler(const jsont &config)
441552

442553
c_wrangler.configure_sources(config);
443554
c_wrangler.configure_functions(config);
555+
c_wrangler.configure_objects(config);
444556
c_wrangler.configure_output(config);
445557

446558
for(auto &source_file : c_wrangler.source_files)

0 commit comments

Comments
 (0)