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 ffi::{CStr, CString},14 os::raw::{c_char, c_double, c_int, c_uint},15 path::PathBuf,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(PathBuf::from(filename.to_str().unwrap()))116 .and_then(|v| vm.with_tla(v))117 .and_then(|v| vm.manifest(v))118 {119 Ok(v) => {120 *error = 0;121 CString::new(&*v as &str).unwrap().into_raw()122 }123 Err(e) => {124 *error = 1;125 let out = vm.stringify_err(&e);126 CString::new(&out as &str).unwrap().into_raw()127 }128 }129}130131132133134#[no_mangle]135pub unsafe extern "C" fn jsonnet_evaluate_snippet(136 vm: &State,137 filename: *const c_char,138 snippet: *const c_char,139 error: &mut c_int,140) -> *const c_char {141 let filename = CStr::from_ptr(filename);142 let snippet = CStr::from_ptr(snippet);143 match vm144 .evaluate_snippet(145 filename.to_str().unwrap().into(),146 snippet.to_str().unwrap().into(),147 )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(PathBuf::from(filename.to_str().unwrap()))190 .and_then(|v| vm.with_tla(v))191 .and_then(|v| vm.manifest_multi(v))192 {193 Ok(v) => {194 *error = 0;195 multi_to_raw(v)196 }197 Err(e) => {198 *error = 1;199 let out = vm.stringify_err(&e);200 CString::new(&out as &str).unwrap().into_raw()201 }202 }203}204205206#[no_mangle]207pub unsafe extern "C" fn jsonnet_evaluate_snippet_multi(208 vm: &State,209 filename: *const c_char,210 snippet: *const c_char,211 error: &mut c_int,212) -> *const c_char {213 let filename = CStr::from_ptr(filename);214 let snippet = CStr::from_ptr(snippet);215 match vm216 .evaluate_snippet(217 filename.to_str().unwrap().into(),218 snippet.to_str().unwrap().into(),219 )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(PathBuf::from(filename.to_str().unwrap()))260 .and_then(|v| vm.with_tla(v))261 .and_then(|v| vm.manifest_stream(v))262 {263 Ok(v) => {264 *error = 0;265 stream_to_raw(v)266 }267 Err(e) => {268 *error = 1;269 let out = vm.stringify_err(&e);270 CString::new(&out as &str).unwrap().into_raw()271 }272 }273}274275276#[no_mangle]277pub unsafe extern "C" fn jsonnet_evaluate_snippet_stream(278 vm: &State,279 filename: *const c_char,280 snippet: *const c_char,281 error: &mut c_int,282) -> *const c_char {283 let filename = CStr::from_ptr(filename);284 let snippet = CStr::from_ptr(snippet);285 match vm286 .evaluate_snippet(287 filename.to_str().unwrap().into(),288 snippet.to_str().unwrap().into(),289 )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}