aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs33
1 files changed, 33 insertions, 0 deletions
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<Path>) -> 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 {