From 167d83ca4521e7e604747142d2a2b79ecb3f7677 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Fri, 14 May 2021 21:36:50 -0600 Subject: provide stdlib --- src/lib.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index d403fbc..a1dfc93 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,38 @@ include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +mod stdlib { + use std::env::current_exe; + use std::io; + use std::path::{Path, PathBuf}; + + const STDLIB_DATA: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/stdlib.tar.gz")); + + /// Guess where tcl will look for the standard library (from the directory containing the current executable, ../lib/tcl8.6/). + pub fn guess_expected_stdlib_target() -> PathBuf { + let exe = current_exe().unwrap(); + let exe_parent = exe.parent().unwrap(); + let exe_parent_parent = exe_parent.parent().unwrap(); + let exe_parent_parent_lib = exe_parent_parent.join("lib"); + let expected_stdlib_path = exe_parent_parent_lib.join("tcl8.6"); + expected_stdlib_path + } + + /// Extract the built-in standard library to the given path, ignoring if already exists. + pub fn extract_stdlib_to(target: impl AsRef) -> io::Result<()> { + let reader = flate2::read::GzDecoder::new(STDLIB_DATA); + let mut ar = tar::Archive::new(reader); + ar.set_overwrite(false); + let result = ar.unpack(target); + match result { + Err(e) if e.kind() == io::ErrorKind::AlreadyExists => Ok(()), + x => x, + } + } +} + +pub use stdlib::*; + #[cfg(test)] mod tests { use super::*; @@ -12,6 +44,7 @@ mod tests { #[test] fn two_plus_two() { unsafe { + extract_stdlib_to(guess_expected_stdlib_target()).unwrap(); let interp = Tcl_CreateInterp(); let init_status = Tcl_Init(interp); if init_status == TCL_ERROR as i32 { -- cgit v1.2.3