Skip to content

Commit

Permalink
Add C++ API.
Browse files Browse the repository at this point in the history
Fixes google#71
  • Loading branch information
davidzchen committed Oct 20, 2015
1 parent 32490bf commit 1b0d0aa
Show file tree
Hide file tree
Showing 7 changed files with 451 additions and 14 deletions.
44 changes: 30 additions & 14 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,25 @@ genrule(
# TODO(dzc): Remove the includes = ["."] lines from all cc_* targets once
# bazelbuild/bazel#445 is fixed.
cc_library(
name = "jsonnet-common",
name = "libjsonnet",
srcs = [
"core/desugaring.cpp",
"core/libjsonnet.cpp",
"core/lexer.cpp",
"core/parser.cpp",
"core/static_analysis.cpp",
"core/vm.cpp",
"stdlib/std.jsonnet.h",
],
hdrs = [
"core/desugaring.h",
"core/lexer.h",
"core/parser.h",
"core/static_analysis.h",
"core/static_error.h",
"core/vm.h",
],
hdrs = ["core/libjsonnet.h"],
includes = ["."],
linkopts = ["-lm"],
)

cc_library(
name = "libjsonnet",
srcs = ["core/libjsonnet.cpp"],
hdrs = ["core/libjsonnet.h"],
deps = [":jsonnet-common"],
name = "jsonnet-cpp",
srcs = ["cpp/jsonnet.cc"],
hdrs = ["cpp/jsonnet.h"],
deps = [":libjsonnet"],
includes = ["."],
)

Expand Down Expand Up @@ -81,3 +75,25 @@ sh_test(
":object_jsonnet",
],
)

cc_binary(
name = "libjsonnet_cpp_test_snippet",
srcs = ["cpp/libjsonnet_cpp_test_snippet.cc"],
deps = [":jsonnet-cpp"],
)

cc_binary(
name = "libjsonnet_cpp_test_file",
srcs = ["cpp/libjsonnet_cpp_test_file.cc"],
deps = [":jsonnet-cpp"],
)

sh_test(
name = "libjsonnet_cpp_test",
srcs = ["cpp/libjsonnet_cpp_test.sh"],
data = [
":libjsonnet_cpp_test_snippet",
":libjsonnet_cpp_test_file",
":object_jsonnet",
],
)
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,25 @@ LIB_SRC = \
core/parser.cpp \
core/static_analysis.cpp \
core/vm.cpp

LIB_OBJ = $(LIB_SRC:.cpp=.o)

LIB_CPP_SRC = \
$(LIB_SRC) \
cpp/jsonnet.cc

LIB_CPP_OBJ = $(LIB_CPP_SRC:.cpp=.o)

ALL = \
jsonnet \
libjsonnet.so \
libjsonnet-cpp.so \
libjsonnet_test_snippet \
libjsonnet_test_file \
libjsonnet.js \
doc/libjsonnet.js \
$(LIB_OBJ)

ALL_HEADERS = \
core/ast.h \
core/desugaring.h \
Expand All @@ -68,6 +77,7 @@ ALL_HEADERS = \
core/static_analysis.h \
core/static_error.h \
core/vm.h \
cpp/jsonnet.h \
stdlib/std.jsonnet.h

default: jsonnet
Expand Down Expand Up @@ -105,6 +115,9 @@ jsonnet: cmd/jsonnet.cpp $(LIB_OBJ)
libjsonnet.so: $(LIB_OBJ)
$(CXX) $(LDFLAGS) $(LIB_OBJ) $(SHARED_LDFLAGS) -o $@

libjsonnet-cpp.so: $(LIB_CPP_OBJ)
$(CXX) $(LDFLAGS) $(LIB_CPP_OBJ) $(SHARED_LDFLAGS) -o $@

# Javascript build of C binding
JS_EXPORTED_FUNCTIONS = 'EXPORTED_FUNCTIONS=["_jsonnet_make", "_jsonnet_evaluate_snippet", "_jsonnet_realloc", "_jsonnet_destroy"]'

Expand Down
132 changes: 132 additions & 0 deletions cpp/jsonnet.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cpp/jsonnet.h"

namespace jsonnet {

Jsonnet::Jsonnet() {}
Jsonnet::~Jsonnet() {
if (vm_ != nullptr) {
::jsonnet_destroy(vm_);
}
}

bool Jsonnet::Init() {
vm_ = static_cast<struct JsonnetVm*>(::jsonnet_make());
return vm_ != nullptr;
}

void Jsonnet::SetMaxStack(uint32_t depth) {
::jsonnet_max_stack(vm_, static_cast<unsigned>(depth));
}

void Jsonnet::SetGcMinObjects(uint32_t objects) {
::jsonnet_gc_min_objects(vm_, static_cast<unsigned>(objects));
}

void Jsonnet::SetGcGrowthTrigger(double growth) {
::jsonnet_gc_growth_trigger(vm_, growth);
}

void Jsonnet::SetStringOutput(bool string_output) {
::jsonnet_string_output(vm_, string_output);
}

void Jsonnet::SetDebugAst(bool debug_ast) {
::jsonnet_debug_ast(vm_, static_cast<int>(debug_ast));
}

void Jsonnet::SetMaxTrace(uint32_t lines) {
::jsonnet_max_trace(vm_, static_cast<unsigned>(lines));
}

void Jsonnet::BindExtVar(const std::string& key, const std::string& value) {
::jsonnet_ext_var(vm_, key.c_str(), value.c_str());
}

void Jsonnet::BindExtCodeVar(const std::string& key,
const std::string& value) {
::jsonnet_ext_code(vm_, key.c_str(), value.c_str());
}

bool Jsonnet::EvaluateFile(const std::string& filename, std::string* output) {
if (output == nullptr) {
return false;
}
int error = 0;
const char* jsonnet_output =
::jsonnet_evaluate_file(vm_, filename.c_str(), &error);
output->assign(jsonnet_output);
return error == 0;
}

bool Jsonnet::EvaluateSnippet(const std::string& filename,
const std::string& snippet,
std::string* output) {
if (output == nullptr) {
return false;
}
int error = 0;
const char* jsonnet_output = ::jsonnet_evaluate_snippet(
vm_, filename.c_str(), snippet.c_str(), &error);
output->assign(jsonnet_output);
return error == 0;
}

namespace {
void ParseMultiOutput(const char* jsonnet_output,
std::map<std::string, std::string>* outputs) {
for (const char* c = jsonnet_output; *c != '\0'; ) {
const char *filename = c;
const char *c2 = c;
while (*c2 != '\0') ++c2;
++c2;
const char *json = c2;
while (*c2 != '\0') ++c2;
++c2;
c = c2;
outputs->insert(std::make_pair(filename, json));
}
}
} // namespace

bool Jsonnet::EvaluateFileMulti(
const std::string& filename,
std::map<std::string, std::string>* outputs) {
if (outputs == nullptr) {
return false;
}
int error = 0;
const char* jsonnet_output =
::jsonnet_evaluate_file_multi(vm_, filename.c_str(), &error);
ParseMultiOutput(jsonnet_output, outputs);
return error == 0;
}

bool Jsonnet::EvaluateSnippetMulti(
const std::string& filename,
const std::string& snippet,
std::map<std::string, std::string>* outputs) {
if (outputs == nullptr) {
return false;
}
int error = 0;
const char* jsonnet_output = ::jsonnet_evaluate_snippet_multi(
vm_, filename.c_str(), snippet.c_str(), &error);
ParseMultiOutput(jsonnet_output, outputs);
return error == 0;
}

} // namespace jsonnet
Loading

0 comments on commit 1b0d0aa

Please sign in to comment.