aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2021-05-14 21:36:50 -0600
committerMelody Horn <melody@boringcactus.com>2021-05-14 21:36:50 -0600
commit167d83ca4521e7e604747142d2a2b79ecb3f7677 (patch)
tree72527056f88a0676953442ab5357423e9eda7167 /src
parentc6a84931c7489d72112ac13b7e597c3a456ef770 (diff)
downloadtcl-sys-167d83ca4521e7e604747142d2a2b79ecb3f7677.tar.gz
tcl-sys-167d83ca4521e7e604747142d2a2b79ecb3f7677.zip
provide stdlib
Diffstat (limited to 'src')
-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 {