Skip to content

Commit df2cc93

Browse files
committed
Add C++ API.
Fixes #71
1 parent 73005cd commit df2cc93

7 files changed

+485
-2
lines changed

BUILD

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ cc_library(
1818
name = "jsonnet-common",
1919
srcs = [
2020
"core/desugaring.cpp",
21+
"core/libjsonnet.cpp",
2122
"core/lexer.cpp",
2223
"core/parser.cpp",
2324
"core/static_analysis.cpp",
@@ -44,6 +45,14 @@ cc_library(
4445
includes = ["include"],
4546
)
4647

48+
cc_library(
49+
name = "libjsonnet++",
50+
srcs = ["cpp/libjsonnet++.cc"],
51+
hdrs = ["include/libjsonnet++.h"],
52+
deps = [":libjsonnet"],
53+
includes = ["include"],
54+
)
55+
4756
cc_binary(
4857
name = "jsonnet",
4958
srcs = ["cmd/jsonnet.cpp"],
@@ -80,3 +89,27 @@ sh_test(
8089
":object_jsonnet",
8190
],
8291
)
92+
93+
cc_binary(
94+
name = "libjsonnet_cpp_test_snippet",
95+
srcs = ["cpp/libjsonnet_cpp_test_snippet.cc"],
96+
deps = [":libjsonnet++"],
97+
includes = ["include"],
98+
)
99+
100+
cc_binary(
101+
name = "libjsonnet_cpp_test_file",
102+
srcs = ["cpp/libjsonnet_cpp_test_file.cc"],
103+
deps = [":libjsonnet++"],
104+
includes = ["include"],
105+
)
106+
107+
sh_test(
108+
name = "libjsonnet_cpp_test",
109+
srcs = ["cpp/libjsonnet_cpp_test.sh"],
110+
data = [
111+
":libjsonnet_cpp_test_snippet",
112+
":libjsonnet_cpp_test_file",
113+
":object_jsonnet",
114+
],
115+
)

Makefile

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,24 @@ LIB_SRC = \
4848
core/parser.cpp \
4949
core/static_analysis.cpp \
5050
core/vm.cpp
51+
5152
LIB_OBJ = $(LIB_SRC:.cpp=.o)
5253

54+
LIB_CPP_SRC = \
55+
cpp/libjsonnet++.cc
56+
57+
LIB_CPP_OBJ = $(LIB_OBJ) $(LIB_CPP_SRC:.cc=.o)
58+
5359
ALL = \
5460
jsonnet \
5561
libjsonnet.so \
62+
libjsonnet++.so \
5663
libjsonnet_test_snippet \
5764
libjsonnet_test_file \
5865
libjsonnet.js \
5966
doc/libjsonnet.js \
6067
$(LIB_OBJ)
68+
6169
ALL_HEADERS = \
6270
core/ast.h \
6371
core/desugaring.h \
@@ -68,7 +76,8 @@ ALL_HEADERS = \
6876
core/static_error.h \
6977
core/vm.h \
7078
core/std.jsonnet.h \
71-
include/libjsonnet.h
79+
include/libjsonnet.h \
80+
include/libjsonnet++.h
7281

7382
default: jsonnet
7483

@@ -86,7 +95,9 @@ test: jsonnet libjsonnet.so libjsonnet_test_snippet libjsonnet_test_file
8695
MAKEDEPEND_SRCS = \
8796
cmd/jsonnet.cpp \
8897
core/libjsonnet_test_snippet.c \
89-
core/libjsonnet_test_file.c
98+
core/libjsonnet_test_file.c \
99+
cpp/libjsonnet_cpp_test_snippet.c \
100+
cpp/libjsonnet_cpp_test_file.c
90101

91102
depend:
92103
makedepend -f- $(LIB_SRC) $(MAKEDEPEND_SRCS) > Makefile.depend
@@ -97,6 +108,9 @@ core/parser.cpp: core/std.jsonnet.h
97108
%.o: %.cpp
98109
$(CXX) -c $(CXXFLAGS) $< -o $@
99110

111+
%.o: %.cc
112+
$(CXX) -c $(CXXFLAGS) $< -o $@
113+
100114
# Commandline executable.
101115
jsonnet: cmd/jsonnet.cpp $(LIB_OBJ)
102116
$(CXX) $(CXXFLAGS) $(LDFLAGS) $< $(LIB_SRC:.cpp=.o) -o $@
@@ -105,6 +119,9 @@ jsonnet: cmd/jsonnet.cpp $(LIB_OBJ)
105119
libjsonnet.so: $(LIB_OBJ)
106120
$(CXX) $(LDFLAGS) $(LIB_OBJ) $(SHARED_LDFLAGS) -o $@
107121

122+
libjsonnet++.so: $(LIB_CPP_OBJ)
123+
$(CXX) $(LDFLAGS) $(LIB_CPP_OBJ) $(SHARED_LDFLAGS) -o $@
124+
108125
# Javascript build of C binding
109126
JS_EXPORTED_FUNCTIONS = 'EXPORTED_FUNCTIONS=["_jsonnet_make", "_jsonnet_evaluate_snippet", "_jsonnet_realloc", "_jsonnet_destroy"]'
110127

cpp/libjsonnet++.cc

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// Copyright 2015 Google Inc. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "libjsonnet++.h"
16+
17+
namespace jsonnet {
18+
19+
Jsonnet::Jsonnet() {}
20+
Jsonnet::~Jsonnet() {
21+
if (vm_ != nullptr) {
22+
::jsonnet_destroy(vm_);
23+
}
24+
}
25+
26+
bool Jsonnet::Init() {
27+
vm_ = static_cast<struct JsonnetVm*>(::jsonnet_make());
28+
return vm_ != nullptr;
29+
}
30+
31+
void Jsonnet::SetMaxStack(uint32_t depth) {
32+
::jsonnet_max_stack(vm_, static_cast<unsigned>(depth));
33+
}
34+
35+
void Jsonnet::SetGcMinObjects(uint32_t objects) {
36+
::jsonnet_gc_min_objects(vm_, static_cast<unsigned>(objects));
37+
}
38+
39+
void Jsonnet::SetGcGrowthTrigger(double growth) {
40+
::jsonnet_gc_growth_trigger(vm_, growth);
41+
}
42+
43+
void Jsonnet::SetStringOutput(bool string_output) {
44+
::jsonnet_string_output(vm_, string_output);
45+
}
46+
47+
void Jsonnet::SetDebugAst(bool debug_ast) {
48+
::jsonnet_debug_ast(vm_, static_cast<int>(debug_ast));
49+
}
50+
51+
void Jsonnet::SetMaxTrace(uint32_t lines) {
52+
::jsonnet_max_trace(vm_, static_cast<unsigned>(lines));
53+
}
54+
55+
void Jsonnet::BindExtVar(const std::string& key, const std::string& value) {
56+
::jsonnet_ext_var(vm_, key.c_str(), value.c_str());
57+
}
58+
59+
void Jsonnet::BindExtCodeVar(const std::string& key,
60+
const std::string& value) {
61+
::jsonnet_ext_code(vm_, key.c_str(), value.c_str());
62+
}
63+
64+
bool Jsonnet::EvaluateFile(const std::string& filename, std::string* output) {
65+
if (output == nullptr) {
66+
return false;
67+
}
68+
int error = 0;
69+
const char* jsonnet_output =
70+
::jsonnet_evaluate_file(vm_, filename.c_str(), &error);
71+
if (error != 0) {
72+
last_error_.assign(jsonnet_output);
73+
return false;
74+
}
75+
output->assign(jsonnet_output);
76+
return true;
77+
}
78+
79+
bool Jsonnet::EvaluateSnippet(const std::string& filename,
80+
const std::string& snippet,
81+
std::string* output) {
82+
if (output == nullptr) {
83+
return false;
84+
}
85+
int error = 0;
86+
const char* jsonnet_output = ::jsonnet_evaluate_snippet(
87+
vm_, filename.c_str(), snippet.c_str(), &error);
88+
if (error != 0) {
89+
last_error_.assign(jsonnet_output);
90+
return false;
91+
}
92+
output->assign(jsonnet_output);
93+
return true;
94+
}
95+
96+
namespace {
97+
void ParseMultiOutput(const char* jsonnet_output,
98+
std::map<std::string, std::string>* outputs) {
99+
for (const char* c = jsonnet_output; *c != '\0'; ) {
100+
const char *filename = c;
101+
const char *c2 = c;
102+
while (*c2 != '\0') ++c2;
103+
++c2;
104+
const char *json = c2;
105+
while (*c2 != '\0') ++c2;
106+
++c2;
107+
c = c2;
108+
outputs->insert(std::make_pair(filename, json));
109+
}
110+
}
111+
} // namespace
112+
113+
bool Jsonnet::EvaluateFileMulti(
114+
const std::string& filename,
115+
std::map<std::string, std::string>* outputs) {
116+
if (outputs == nullptr) {
117+
return false;
118+
}
119+
int error = 0;
120+
const char* jsonnet_output =
121+
::jsonnet_evaluate_file_multi(vm_, filename.c_str(), &error);
122+
if (error != 0) {
123+
last_error_.assign(jsonnet_output);
124+
return false;
125+
}
126+
ParseMultiOutput(jsonnet_output, outputs);
127+
return true;
128+
}
129+
130+
bool Jsonnet::EvaluateSnippetMulti(
131+
const std::string& filename,
132+
const std::string& snippet,
133+
std::map<std::string, std::string>* outputs) {
134+
if (outputs == nullptr) {
135+
return false;
136+
}
137+
int error = 0;
138+
const char* jsonnet_output = ::jsonnet_evaluate_snippet_multi(
139+
vm_, filename.c_str(), snippet.c_str(), &error);
140+
if (error != 0) {
141+
last_error_.assign(jsonnet_output);
142+
return false;
143+
}
144+
ParseMultiOutput(jsonnet_output, outputs);
145+
return true;
146+
}
147+
148+
std::string Jsonnet::LastError() const {
149+
return last_error_;
150+
}
151+
152+
} // namespace jsonnet

cpp/libjsonnet_cpp_test.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2015 Google Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
readonly TEST_SNIPPET="std.assertEqual(({ x: 1, y: self.x } { x: 2 }).y, 2)"
16+
readonly LIBJSONNET_CPP_TEST_SNIPPET="libjsonnet_cpp_test_snippet"
17+
readonly LIBJSONNET_CPP_TEST_FILE="libjsonnet_cpp_test_file"
18+
readonly OBJECT_JSONNET="test_suite/object.jsonnet"
19+
20+
function test_libjsonnet_cpp_snippet {
21+
$LIBJSONNET_CPP_TEST_SNIPPET $TEST_SNIPPET
22+
}
23+
24+
function test_libjsonnet_cpp_file {
25+
$LIBJSONNET_CPP_TEST_FILE $OBJECT_JSONNET
26+
}
27+
28+
function main {
29+
test_libjsonnet_cpp_snippet
30+
test_libjsonnet_cpp_file
31+
}
32+
33+
main

cpp/libjsonnet_cpp_test_file.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
Copyright 2015 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include <cstdlib>
18+
#include <cstdio>
19+
#include <string>
20+
#include <iostream>
21+
22+
#include "libjsonnet++.h"
23+
24+
int main(int argc, const char** argv) {
25+
if (argc != 2) {
26+
std::cerr << "libjsonnet_cpp_test_file <file>" << std::endl;
27+
return EXIT_FAILURE;
28+
}
29+
jsonnet::Jsonnet vm;
30+
if (!vm.Init()) {
31+
std::cerr << "Unable to initialize Jsonnet" << std::endl;
32+
return EXIT_FAILURE;
33+
}
34+
std::string output;
35+
if (!vm.EvaluateFile(argv[1], &output)) {
36+
std::cerr << vm.LastError() << std::endl;
37+
return EXIT_FAILURE;
38+
}
39+
std::cout << output << std::endl;
40+
return EXIT_SUCCESS;
41+
}

cpp/libjsonnet_cpp_test_snippet.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
Copyright 2015 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include <cstdlib>
18+
#include <cstdio>
19+
#include <string>
20+
#include <iostream>
21+
22+
#include "libjsonnet++.h"
23+
24+
int main(int argc, const char** argv) {
25+
if (argc != 2) {
26+
std::cerr << "libjsonnet_cpp_test_snippet <string>" << std::endl;
27+
return EXIT_FAILURE;
28+
}
29+
jsonnet::Jsonnet vm;
30+
if (!vm.Init()) {
31+
std::cerr << "Unable to initialize Jsonnet" << std::endl;
32+
return EXIT_FAILURE;
33+
}
34+
std::string output;
35+
if (!vm.EvaluateSnippet("snippet", argv[1], &output)) {
36+
std::cerr << vm.LastError() << std::endl;
37+
return EXIT_FAILURE;
38+
}
39+
std::cout << output << std::endl;
40+
return EXIT_SUCCESS;
41+
}

0 commit comments

Comments
 (0)