Skip to content

Commit a60fbeb

Browse files
committed
Use json format for config file
1 parent 49be660 commit a60fbeb

File tree

6 files changed

+90
-16
lines changed

6 files changed

+90
-16
lines changed

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ RUN set -x \
1313
g++ openjdk-8-jdk-headless sbt cmake make curl git \
1414
zlib1g-dev \
1515
libgc-dev libunwind8-dev libre2-dev \
16+
nlohmann-json-dev \
1617
&& rm -rf /var/lib/apt/lists/*
1718

1819
ARG LLVM_VERSION=6.0

bindgen/ir/LocationManager.cpp

Lines changed: 67 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,36 +10,90 @@ LocationManager::LocationManager(std::string mainHeaderPath)
1010
void LocationManager::loadConfig(const std::string &path) {
1111
std::string realPath = getRealPath(path.c_str());
1212

13+
std::stringstream s;
1314
std::ifstream input(realPath);
1415
for (std::string line; getline(input, line);) {
15-
size_t f = line.find('=');
16-
if (f != std::string::npos) {
17-
std::string header = line.substr(0, f);
18-
std::string import = line.substr(f + 1, std::string::npos);
19-
existingBindings[header] = import;
20-
}
16+
s << line;
2117
}
18+
config = json::parse(s.str());
19+
assert(config.is_object());
2220
}
2321

2422
bool LocationManager::inMainFile(const Location &location) const {
2523
return location.getPath() == mainHeaderPath;
2624
}
2725

2826
bool LocationManager::isImported(const Location &location) const {
29-
for (const auto &existingBinding : existingBindings) {
30-
if (endsWith(location.getPath(), existingBinding.first)) {
31-
return true;
27+
for (auto it = config.begin(); it != config.end(); ++it) {
28+
json libObject = it.value();
29+
for (const auto &header : libObject["headers"]) {
30+
if (equal(header, location)) {
31+
return true;
32+
}
3233
}
3334
}
3435
return false;
3536
}
3637

38+
bool LocationManager::equal(json header, const Location &location) const {
39+
std::string headerName = getHeaderName(header);
40+
return endsWith(location.getPath(), headerName);
41+
}
42+
3743
std::string
3844
LocationManager::getContainingObject(const Location &location) const {
39-
for (const auto &existingBinding : existingBindings) {
40-
if (endsWith(location.getPath(), existingBinding.first)) {
41-
return existingBinding.second;
45+
for (auto it = config.begin(); it != config.end(); ++it) {
46+
json libObject = it.value();
47+
for (const json &header : libObject["headers"]) {
48+
if (equal(header, location)) {
49+
return getContainingObject(libObject, header);
50+
}
4251
}
4352
}
44-
assert(false && "Location is not in the list of imported bindings");
53+
throw std::logic_error("Location: " + location.getPath() +
54+
" does not belong to any known library");
55+
}
56+
57+
std::string LocationManager::getHeaderName(const json &header) const {
58+
if (header.is_string()) {
59+
return header.get<std::string>();
60+
} else {
61+
return header["header"].get<std::string>();
62+
}
63+
}
64+
65+
std::string LocationManager::getContainingObject(const json &libObject,
66+
const json &header) const {
67+
std::string package;
68+
std::string name;
69+
if (libObject.find("package") != libObject.end()) {
70+
package = libObject["package"].get<std::string>();
71+
}
72+
if (libObject.find("name") != libObject.end()) {
73+
package = libObject["name"].get<std::string>();
74+
}
75+
if (header.is_object()) {
76+
/* override default values */
77+
if (header.find("package") != header.end()) {
78+
package = header["package"].get<std::string>();
79+
}
80+
if (header.find("name") != header.end()) {
81+
name = header["name"].get<std::string>();
82+
}
83+
}
84+
if (name.empty()) {
85+
/* extract object name from header name */
86+
name = getHeaderName(header);
87+
auto slashPos = name.find_last_of('/');
88+
if (slashPos != std::string::npos) {
89+
name = name.substr(slashPos + 1, name.length());
90+
}
91+
if (endsWith(name, ".h")) {
92+
name = name.substr(0, name.length() - 2);
93+
}
94+
}
95+
if (!package.empty()) {
96+
return package + "." + name;
97+
}
98+
return name;
4599
}

bindgen/ir/LocationManager.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
#define SCALA_NATIVE_BINDGEN_LOCATIONMANAGER_H
33

44
#include "Location.h"
5+
#include <nlohmann/json.hpp>
56
#include <string>
67
#include <unordered_map>
78

9+
using json = nlohmann::json;
10+
811
class LocationManager {
912
public:
1013
explicit LocationManager(std::string mainHeaderPath);
@@ -22,7 +25,14 @@ class LocationManager {
2225

2326
private:
2427
std::string mainHeaderPath;
25-
std::unordered_map<std::string, std::string> existingBindings;
28+
json config;
29+
30+
bool equal(json header, const Location &location) const;
31+
32+
std::string getHeaderName(const json &header) const;
33+
34+
std::string getContainingObject(const json &libObject,
35+
const json &header) const;
2636
};
2737

2838
#endif // SCALA_NATIVE_BINDGEN_LOCATIONMANAGER_H

tests/samples/ReuseBindings.config

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/samples/ReuseBindings.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"samples": {
3+
"package": "org.scalanative.bindgen.samples",
4+
"headers": [
5+
{
6+
"header": "Struct.h"
7+
}
8+
]
9+
}
10+
}

tests/src/test/scala/org/scalanative/bindgen/BindgenSpec.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class BindgenSpec extends FunSpec {
4646
val testName = input.getName.replace(".h", "")
4747
val expected = new File(inputDirectory, testName + ".scala")
4848
val output = new File(outputDir, testName + ".scala")
49-
val config = new File(inputDirectory, testName + ".config")
49+
val config = new File(inputDirectory, testName + ".json")
5050

5151
bindgen(input,
5252
testName,

0 commit comments

Comments
 (0)