Skip to content

Commit c4b4049

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 c9ae54d commit c4b4049

File tree

4 files changed

+155
-0
lines changed

4 files changed

+155
-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: 111 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

@@ -243,6 +252,61 @@ void c_wranglert::configure_functions(const jsont &config)
243252
}
244253
}
245254

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

464+
static void mangle_object(
465+
const c_declarationt &declaration,
466+
const c_definest &defines,
467+
const c_wranglert::objectt &object_config,
468+
std::ostream &out)
469+
{
470+
if(object_config.remove_static)
471+
{
472+
for(auto &t : declaration.pre_declarator)
473+
{
474+
if(t.text == "static")
475+
{
476+
// we replace by white space
477+
out << std::string(6, ' ');
478+
}
479+
else
480+
out << t.text;
481+
}
482+
}
483+
else
484+
{
485+
for(auto &t : declaration.pre_declarator)
486+
out << t.text;
487+
}
488+
489+
for(auto &t : declaration.declarator)
490+
out << t.text;
491+
for(auto &t : declaration.post_declarator)
492+
out << t.text;
493+
for(auto &t : declaration.initializer)
494+
out << t.text;
495+
}
496+
400497
static void mangle(
401498
const c_declarationt &declaration,
402499
const c_definest &defines,
@@ -418,6 +515,19 @@ static void mangle(
418515
}
419516
}
420517
}
518+
else if(!declaration.is_function() && name_opt.has_value())
519+
{
520+
for(const auto &entry : config.objects)
521+
{
522+
if(std::regex_match(name_opt->text, entry.first))
523+
{
524+
// we are to modify this function
525+
mangle_object(declaration, defines, entry.second, out);
526+
527+
return;
528+
}
529+
}
530+
}
421531

422532
// output
423533
out << declaration;
@@ -445,6 +555,7 @@ void c_wrangler(const jsont &config)
445555

446556
c_wrangler.configure_sources(config);
447557
c_wrangler.configure_functions(config);
558+
c_wrangler.configure_objects(config);
448559
c_wrangler.configure_output(config);
449560

450561
for(auto &source_file : c_wrangler.source_files)

0 commit comments

Comments
 (0)