1#[cfg(feature = "interop")]2pub mod interop;34pub mod import;5pub mod native;6pub mod val_extract;7pub mod val_make;8pub mod val_modify;9pub mod vars_tlas;1011use std::{12 alloc::Layout,13 env,14 ffi::{CStr, CString},15 os::raw::{c_char, c_double, c_int, c_uint},16};1718use import::NativeImportResolver;19use jrsonnet_evaluator::{IStr, ManifestFormat, State, Val};202122#[cfg(target_arch = "wasm32")]23#[no_mangle]24pub extern "C" fn _start() {}2526#[no_mangle]27pub extern "C" fn jsonnet_version() -> &'static [u8; 8] {28 b"v0.16.0\0"29}3031#[no_mangle]32pub extern "C" fn jsonnet_make() -> *mut State {33 let state = State::default();34 state.settings_mut().import_resolver = Box::new(NativeImportResolver::default());35 state.settings_mut().context_initializer =36 Box::new(jrsonnet_stdlib::ContextInitializer::new(state.clone()));37 Box::into_raw(Box::new(state))38}394041#[no_mangle]42#[allow(clippy::boxed_local)]43pub unsafe extern "C" fn jsonnet_destroy(vm: *mut State) {44 drop(Box::from_raw(vm));45}4647#[no_mangle]48pub extern "C" fn jsonnet_max_stack(vm: &State, v: c_uint) {49 vm.settings_mut().max_stack = v as usize;50}515253#[no_mangle]54pub extern "C" fn jsonnet_gc_min_objects(_vm: &State, _v: c_uint) {}55#[no_mangle]56pub extern "C" fn jsonnet_gc_growth_trigger(_vm: &State, _v: c_double) {}5758#[no_mangle]59pub extern "C" fn jsonnet_string_output(vm: &State, v: c_int) {60 match v {61 1 => vm.set_manifest_format(ManifestFormat::String),62 0 => vm.set_manifest_format(ManifestFormat::Json {63 padding: 4,64 #[cfg(feature = "exp-preserve-order")]65 preserve_order: false,66 }),67 _ => panic!("incorrect output format"),68 }69}7071727374#[no_mangle]75pub unsafe extern "C" fn jsonnet_realloc(_vm: &State, buf: *mut u8, sz: usize) -> *mut u8 {76 if buf.is_null() {77 assert!(sz != 0);78 return std::alloc::alloc(Layout::from_size_align(sz, std::mem::align_of::<u8>()).unwrap());79 }80 81 82 83 84 let old_layout = Layout::from_size_align(16, std::mem::align_of::<u8>()).unwrap();85 if sz == 0 {86 std::alloc::dealloc(buf, old_layout);87 return std::ptr::null_mut();88 }89 std::alloc::realloc(buf, old_layout, sz)90}919293#[no_mangle]94#[allow(clippy::boxed_local)]95pub unsafe extern "C" fn jsonnet_json_destroy(_vm: &State, v: *mut Val) {96 drop(Box::from_raw(v));97}9899#[no_mangle]100pub extern "C" fn jsonnet_max_trace(vm: &State, v: c_uint) {101 vm.set_max_trace(v as usize)102}103104105106107#[no_mangle]108pub unsafe extern "C" fn jsonnet_evaluate_file(109 vm: &State,110 filename: *const c_char,111 error: &mut c_int,112) -> *const c_char {113 let filename = CStr::from_ptr(filename);114 match vm115 .import(116 &env::current_dir().expect("cwd"),117 filename.to_str().unwrap(),118 )119 .and_then(|v| vm.with_tla(v))120 .and_then(|v| vm.manifest(v))121 {122 Ok(v) => {123 *error = 0;124 CString::new(&*v as &str).unwrap().into_raw()125 }126 Err(e) => {127 *error = 1;128 let out = vm.stringify_err(&e);129 CString::new(&out as &str).unwrap().into_raw()130 }131 }132}133134135136137#[no_mangle]138pub unsafe extern "C" fn jsonnet_evaluate_snippet(139 vm: &State,140 filename: *const c_char,141 snippet: *const c_char,142 error: &mut c_int,143) -> *const c_char {144 let filename = CStr::from_ptr(filename);145 let snippet = CStr::from_ptr(snippet);146 match vm147 .evaluate_snippet(filename.to_str().unwrap().into(), snippet.to_str().unwrap())148 .and_then(|v| vm.with_tla(v))149 .and_then(|v| vm.manifest(v))150 {151 Ok(v) => {152 *error = 0;153 CString::new(&*v as &str).unwrap().into_raw()154 }155 Err(e) => {156 *error = 1;157 let out = vm.stringify_err(&e);158 CString::new(&out as &str).unwrap().into_raw()159 }160 }161}162163fn multi_to_raw(multi: Vec<(IStr, IStr)>) -> *const c_char {164 let mut out = Vec::new();165 for (i, (k, v)) in multi.iter().enumerate() {166 if i != 0 {167 out.push(0);168 }169 out.extend_from_slice(k.as_bytes());170 out.push(0);171 out.extend_from_slice(v.as_bytes());172 }173 out.push(0);174 out.push(0);175 let v = out.as_ptr();176 std::mem::forget(out);177 v as *const c_char178}179180181#[no_mangle]182pub unsafe extern "C" fn jsonnet_evaluate_file_multi(183 vm: &State,184 filename: *const c_char,185 error: &mut c_int,186) -> *const c_char {187 let filename = CStr::from_ptr(filename);188 match vm189 .import(190 &env::current_dir().expect("cwd"),191 filename.to_str().unwrap(),192 )193 .and_then(|v| vm.with_tla(v))194 .and_then(|v| vm.manifest_multi(v))195 {196 Ok(v) => {197 *error = 0;198 multi_to_raw(v)199 }200 Err(e) => {201 *error = 1;202 let out = vm.stringify_err(&e);203 CString::new(&out as &str).unwrap().into_raw()204 }205 }206}207208209#[no_mangle]210pub unsafe extern "C" fn jsonnet_evaluate_snippet_multi(211 vm: &State,212 filename: *const c_char,213 snippet: *const c_char,214 error: &mut c_int,215) -> *const c_char {216 let filename = CStr::from_ptr(filename);217 let snippet = CStr::from_ptr(snippet);218 match vm219 .evaluate_snippet(filename.to_str().unwrap().into(), snippet.to_str().unwrap())220 .and_then(|v| vm.with_tla(v))221 .and_then(|v| vm.manifest_multi(v))222 {223 Ok(v) => {224 *error = 0;225 multi_to_raw(v)226 }227 Err(e) => {228 *error = 1;229 let out = vm.stringify_err(&e);230 CString::new(&out as &str).unwrap().into_raw()231 }232 }233}234235fn stream_to_raw(multi: Vec<IStr>) -> *const c_char {236 let mut out = Vec::new();237 for (i, v) in multi.iter().enumerate() {238 if i != 0 {239 out.push(0);240 }241 out.extend_from_slice(v.as_bytes());242 }243 out.push(0);244 out.push(0);245 let v = out.as_ptr();246 std::mem::forget(out);247 v as *const c_char248}249250251#[no_mangle]252pub unsafe extern "C" fn jsonnet_evaluate_file_stream(253 vm: &State,254 filename: *const c_char,255 error: &mut c_int,256) -> *const c_char {257 let filename = CStr::from_ptr(filename);258 match vm259 .import(260 &env::current_dir().expect("cwd"),261 filename.to_str().unwrap(),262 )263 .and_then(|v| vm.with_tla(v))264 .and_then(|v| vm.manifest_stream(v))265 {266 Ok(v) => {267 *error = 0;268 stream_to_raw(v)269 }270 Err(e) => {271 *error = 1;272 let out = vm.stringify_err(&e);273 CString::new(&out as &str).unwrap().into_raw()274 }275 }276}277278279#[no_mangle]280pub unsafe extern "C" fn jsonnet_evaluate_snippet_stream(281 vm: &State,282 filename: *const c_char,283 snippet: *const c_char,284 error: &mut c_int,285) -> *const c_char {286 let filename = CStr::from_ptr(filename);287 let snippet = CStr::from_ptr(snippet);288 match vm289 .evaluate_snippet(filename.to_str().unwrap().into(), snippet.to_str().unwrap())290 .and_then(|v| vm.with_tla(v))291 .and_then(|v| vm.manifest_stream(v))292 {293 Ok(v) => {294 *error = 0;295 stream_to_raw(v)296 }297 Err(e) => {298 *error = 1;299 let out = vm.stringify_err(&e);300 CString::new(&out as &str).unwrap().into_raw()301 }302 }303}