Skip to content

Commit df0c3f4

Browse files
committed
add the crangler tool
This is a command-line utility that makes changes to a preprocessed C file that are prescribed in a JSON configuration file. The initial set of transformations is as follows. * add a contract (pre/post/assigns) to a named C function * add a loop invariant to a loop identified by the name of the function its in and a loop number * remove the 'static' storage classifier from a function The resulting source file is written into the directory of the original file using the file extension ".i".
1 parent c3d7235 commit df0c3f4

19 files changed

+1602
-0
lines changed

src/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ DIRS = analyses \
44
big-int \
55
cbmc \
66
cpp \
7+
crangler \
78
goto-analyzer \
89
goto-cc \
910
goto-checker \
@@ -27,6 +28,7 @@ DIRS = analyses \
2728
# Empty last line
2829

2930
all: cbmc.dir \
31+
crangler.dir \
3032
goto-analyzer.dir \
3133
goto-cc.dir \
3234
goto-diff.dir \
@@ -59,6 +61,8 @@ $(patsubst %, %.dir, $(filter-out big-int util, $(DIRS))): util.dir
5961

6062
cpp.dir: ansi-c.dir linking.dir
6163

64+
crangler.dir: util.dir json.dir
65+
6266
languages: util.dir langapi.dir \
6367
cpp.dir ansi-c.dir xmllang.dir assembler.dir \
6468
jsil.dir json.dir json-symtab-language.dir statement-list.dir

src/crangler/Makefile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
SRC = c_defines.cpp \
2+
c_lex.yy.cpp \
3+
c_wrangler.cpp \
4+
crangler_main.cpp \
5+
crangler_parse_options.cpp \
6+
cscanner.cpp \
7+
ctokenit.cpp \
8+
mini_c_parser.cpp \
9+
# Empty last line
10+
11+
OBJ += ../big-int/big-int$(LIBEXT) \
12+
../json/json$(LIBEXT) \
13+
../util/util$(LIBEXT)
14+
15+
INCLUDES= -I ..
16+
17+
include ../config.inc
18+
include ../../$(CPROVER_DIR)/src/common
19+
20+
CLEANFILES = crangler$(LIBEXT)
21+
22+
all: crangler$(EXEEXT)
23+
24+
###############################################################################
25+
26+
c_lex.yy.cpp: scanner.l
27+
$(LEX) -Pyyc -o$@ scanner.l
28+
29+
###############################################################################
30+
31+
generated_files: c_lex.yy.cpp
32+
33+
###############################################################################
34+
35+
crangler$(EXEEXT): $(OBJ)
36+
$(LINKBIN)

src/crangler/c_defines.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
3+
/// \file
4+
/// c_defines
5+
6+
#include "c_defines.h"
7+
8+
#include "cscanner.h"
9+
10+
#include <util/prefix.h>
11+
#include <util/string_utils.h>
12+
13+
#include <sstream>
14+
15+
void c_definest::parse(const std::string &src)
16+
{
17+
const auto lines = split_string(src, '\n');
18+
for(const auto &line : lines)
19+
{
20+
// #define __x86_64__ 1
21+
// #define getc_unlocked(fp) __sgetc(fp)
22+
if(!has_prefix(line, "#define "))
23+
continue;
24+
25+
auto space_pos = line.find(' ', 8);
26+
if(space_pos == std::string::npos)
27+
continue;
28+
29+
auto id = line.substr(8, space_pos - 8);
30+
auto value = line.substr(space_pos + 1, std::string::npos);
31+
map[id].value = value;
32+
}
33+
}
34+
35+
std::string c_definest::operator()(const std::string &src) const
36+
{
37+
// tokenize
38+
std::istringstream in(src);
39+
cscannert cscanner(in);
40+
const auto tokens = cscanner.get_tokens();
41+
42+
// output
43+
std::ostringstream out;
44+
for(auto &t : tokens)
45+
{
46+
if(is_identifier(t))
47+
{
48+
auto m_it = map.find(t.text);
49+
if(m_it != map.end())
50+
{
51+
out << m_it->second.value;
52+
}
53+
else
54+
out << t.text;
55+
}
56+
else
57+
out << t.text;
58+
}
59+
60+
return out.str();
61+
}

src/crangler/c_defines.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
3+
/// \file
4+
/// c_defines
5+
6+
#ifndef CPROVER_CRANGLER_C_DEFINES_H
7+
#define CPROVER_CRANGLER_C_DEFINES_H
8+
9+
#include <util/optional.h>
10+
11+
#include <string>
12+
#include <unordered_map>
13+
#include <vector>
14+
15+
class c_definest
16+
{
17+
public:
18+
struct definet
19+
{
20+
optionalt<std::vector<std::string>> parameters;
21+
std::string value;
22+
};
23+
24+
using mapt = std::unordered_map<std::string, definet>;
25+
mapt map;
26+
27+
void parse(const std::string &);
28+
std::string operator()(const std::string &) const;
29+
};
30+
31+
#endif // CPROVER_CRANGLER_C_DEFINES_H

0 commit comments

Comments
 (0)