Skip to content

Commit 41f9cd4

Browse files
committed
more implementation
1 parent c0a950b commit 41f9cd4

File tree

12 files changed

+253
-7
lines changed

12 files changed

+253
-7
lines changed

custom.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,9 @@ pub unsafe fn Tcl_IncrRefCount(objPtr: *mut Tcl_Obj) {
2525
let mut obj = unsafe { *objPtr };
2626
obj.refCount += 1;
2727
}
28+
29+
// TODO: fix
30+
// #[inline(always)]
31+
// pub unsafe fn Tcl_AppInit(interp: *mut Tcl_Interp) -> i32 {
32+
// tcl_sys::Tcl_AppInit(interp)
33+
// }

shared-build/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ pub fn build(
5353
.header(wrapper_file)
5454
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
5555
.blocklist_function("Tcl_DecrRefCount")
56-
.blocklist_function("Tcl_IncrRefCount");
56+
.blocklist_function("Tcl_IncrRefCount")
57+
.blocklist_function("Tcl_AppInit");
5758

5859
if tk {
5960
builder = builder.blocklist_item("(Tcl|TCL).*");

tcl/src/condition.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use std::ptr::NonNull;
2+
3+
pub struct Condition(pub(crate) NonNull<tcl_sys::Tcl_Condition>);
4+
5+
impl Condition {
6+
pub unsafe fn from_raw(condition: *mut tcl_sys::Tcl_Condition) -> Self {
7+
Condition(NonNull::new(condition).expect("Failed to create Tcl_Condition from raw pointer"))
8+
}
9+
10+
pub unsafe fn as_ptr(&self) -> *mut tcl_sys::Tcl_Condition {
11+
self.0.as_ptr()
12+
}
13+
14+
pub unsafe fn notify(&self) {
15+
unsafe {
16+
tcl_sys::Tcl_ConditionNotify(self.0.as_ptr());
17+
}
18+
}
19+
20+
pub unsafe fn wait(&self, mutex: crate::Mutex, time: &crate::Time) {
21+
unsafe {
22+
tcl_sys::Tcl_ConditionWait(self.0.as_ptr(), mutex.as_ptr(), time.as_ptr());
23+
}
24+
}
25+
26+
pub unsafe fn finalize(self) {
27+
unsafe {
28+
tcl_sys::Tcl_ConditionFinalize(self.as_ptr());
29+
}
30+
}
31+
}

tcl/src/interp.rs

Lines changed: 110 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ impl Interp {
2525
}
2626
}
2727

28+
// pub fn app_init(&mut self) -> i32 {
29+
// unsafe {
30+
// tcl_sys::Tcl_AppInit(self.0.as_ptr()) as i32
31+
// }
32+
// }
33+
2834
pub fn create_slave(&mut self, name: &str, is_safe: i32) -> Self {
2935
let name = std::ffi::CString::new(name).unwrap();
3036
let interp = unsafe {
@@ -52,11 +58,19 @@ impl Interp {
5258
}
5359

5460
pub unsafe fn get_string_result(&self) -> String {
55-
let result = self.get_obj_result();
56-
let result_ptr = tcl_sys::Tcl_GetString(result.0.as_ptr());
57-
let _ = tcl_sys::Tcl_GetStringResult(self.0.as_ptr());
58-
let result_str = std::ffi::CStr::from_ptr(result_ptr);
59-
result_str.to_string_lossy().into_owned()
61+
unsafe {
62+
let result = self.get_obj_result();
63+
let result_ptr = tcl_sys::Tcl_GetString(result.0.as_ptr());
64+
let _ = tcl_sys::Tcl_GetStringResult(self.0.as_ptr());
65+
let result_str = std::ffi::CStr::from_ptr(result_ptr);
66+
result_str.to_string_lossy().into_owned()
67+
}
68+
}
69+
70+
pub unsafe fn reset_result(&self) {
71+
unsafe {
72+
tcl_sys::Tcl_ResetResult(self.0.as_ptr());
73+
}
6074
}
6175

6276
pub unsafe fn eval(&self, script: &str) -> i32 {
@@ -85,6 +99,97 @@ impl Interp {
8599
tcl_sys::Tcl_EvalFile(self.0.as_ptr(), filename.as_ptr()) as i32
86100
}
87101
}
102+
103+
pub unsafe fn expr_string(&self, expr: &str) -> i32 {
104+
let expr = std::ffi::CString::new(expr).unwrap();
105+
unsafe {
106+
tcl_sys::Tcl_ExprString(self.0.as_ptr(), expr.as_ptr()) as i32
107+
}
108+
}
109+
110+
pub unsafe fn expr_obj(&self, obj: Obj) -> i32 {
111+
todo!()
112+
}
113+
114+
pub fn expr_long(&self, expr: &str) -> Option<i64> {
115+
todo!()
116+
}
117+
118+
pub fn expr_double(&self, expr: &str) -> Option<f64> {
119+
let expr = std::ffi::CString::new(expr).unwrap();
120+
let mut value: f64 = 0.0;
121+
let result = unsafe {
122+
tcl_sys::Tcl_ExprDouble(self.0.as_ptr(), expr.as_ptr(), &mut value)
123+
};
124+
if result == 0 {
125+
Some(value)
126+
} else {
127+
None
128+
}
129+
}
130+
131+
pub fn get_var(&self, name: &str, flags: i32) -> Option<String> {
132+
let name = std::ffi::CString::new(name).unwrap();
133+
let text = unsafe {
134+
tcl_sys::Tcl_GetVar(self.0.as_ptr(), name.as_ptr(), flags)
135+
};
136+
if text.is_null() {
137+
None
138+
} else {
139+
Some(unsafe { std::ffi::CStr::from_ptr(text) }.to_string_lossy().into_owned())
140+
}
141+
}
142+
143+
pub fn get_var2(&self, name1: &str, name2: &str, flags: i32) -> Option<String> {
144+
let name1 = std::ffi::CString::new(name1).unwrap();
145+
let name2 = std::ffi::CString::new(name2).unwrap();
146+
let text = unsafe {
147+
tcl_sys::Tcl_GetVar2(self.0.as_ptr(), name1.as_ptr(), name2.as_ptr(), flags)
148+
};
149+
if text.is_null() {
150+
None
151+
} else {
152+
Some(unsafe { std::ffi::CStr::from_ptr(text) }.to_string_lossy().into_owned())
153+
}
154+
}
155+
156+
pub fn get_var2_obj(&self, name1: &str, name2: &str, flags: i32) -> Option<Obj> {
157+
let name1 = std::ffi::CString::new(name1).unwrap();
158+
let name2 = std::ffi::CString::new(name2).unwrap();
159+
let obj = unsafe {
160+
tcl_sys::Tcl_GetVar2Ex(self.0.as_ptr(), name1.as_ptr(), name2.as_ptr(), flags)
161+
};
162+
if obj.is_null() {
163+
None
164+
} else {
165+
Some(unsafe { Obj::from_raw(obj) })
166+
}
167+
}
168+
169+
pub fn set_var(&mut self, name: &str, value: &str, flags: i32) -> i32 {
170+
let name = std::ffi::CString::new(name).unwrap();
171+
let value = std::ffi::CString::new(value).unwrap();
172+
unsafe {
173+
tcl_sys::Tcl_SetVar(self.0.as_ptr(), name.as_ptr(), value.as_ptr(), flags) as i32
174+
}
175+
}
176+
177+
pub fn set_var2(&mut self, name1: &str, name2: &str, value: &str, flags: i32) -> i32 {
178+
let name1 = std::ffi::CString::new(name1).unwrap();
179+
let name2 = std::ffi::CString::new(name2).unwrap();
180+
let value = std::ffi::CString::new(value).unwrap();
181+
unsafe {
182+
tcl_sys::Tcl_SetVar2(self.0.as_ptr(), name1.as_ptr(), name2.as_ptr(), value.as_ptr(), flags) as i32
183+
}
184+
}
185+
186+
pub fn set_var2_obj(&mut self, name1: &str, name2: &str, obj: Obj, flags: i32) -> i32 {
187+
let name1 = std::ffi::CString::new(name1).unwrap();
188+
let name2 = std::ffi::CString::new(name2).unwrap();
189+
unsafe {
190+
tcl_sys::Tcl_SetVar2Ex(self.0.as_ptr(), name1.as_ptr(), name2.as_ptr(), obj.0.as_ptr(), flags) as i32
191+
}
192+
}
88193
}
89194

90195
impl Drop for Interp {

tcl/src/lib.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
1+
mod condition;
12
mod interp;
3+
mod mutex;
24
mod obj;
5+
mod obj_type;
36
mod time;
47

8+
pub use condition::Condition;
59
pub use interp::Interp;
10+
pub use mutex::Mutex;
611
pub use obj::Obj;
12+
pub use obj_type::ObjType;
713
pub use time::Time;
814

915
pub use tcl_sys as raw;
1016
pub use tcl_sys::TCL_ERROR;
17+
pub use tcl_sys::TCL_OK;
18+
pub use tcl_sys::Tcl_ThreadId_;
1119

1220
pub fn get_errno() -> i32 {
1321
unsafe {
@@ -20,3 +28,15 @@ pub fn set_errno(errno: i32) {
2028
tcl_sys::Tcl_SetErrno(errno as _);
2129
}
2230
}
31+
32+
pub fn get_current_thread() -> Tcl_ThreadId_ {
33+
unsafe {
34+
*tcl_sys::Tcl_GetCurrentThread()
35+
}
36+
}
37+
38+
pub unsafe fn exit(code: i32) -> ! {
39+
unsafe {
40+
tcl_sys::Tcl_Exit(code as _);
41+
}
42+
}

tcl/src/mutex.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use std::ptr::NonNull;
2+
3+
pub struct Mutex(pub(crate) NonNull<tcl_sys::Tcl_Mutex>);
4+
5+
impl Mutex {
6+
pub unsafe fn from_raw(mutex: *mut tcl_sys::Tcl_Mutex) -> Self {
7+
Mutex(NonNull::new(mutex).expect("Failed to create Tcl_Mutex from raw pointer"))
8+
}
9+
10+
pub unsafe fn as_ptr(&self) -> *mut tcl_sys::Tcl_Mutex {
11+
self.0.as_ptr()
12+
}
13+
14+
pub unsafe fn lock(&self) {
15+
unsafe {
16+
tcl_sys::Tcl_MutexLock(self.0.as_ptr());
17+
}
18+
}
19+
20+
pub unsafe fn unlock(&self) {
21+
unsafe {
22+
tcl_sys::Tcl_MutexUnlock(self.0.as_ptr());
23+
}
24+
}
25+
26+
pub unsafe fn finalize(self) {
27+
unsafe {
28+
tcl_sys::Tcl_MutexFinalize(self.as_ptr());
29+
}
30+
}
31+
}

tcl/src/obj.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ impl Obj {
1919
self.0.as_ptr()
2020
}
2121

22+
pub fn get_ref_count(&self) -> i32 {
23+
unsafe {
24+
self.0.as_ref().refCount as i32
25+
}
26+
}
27+
28+
pub fn set_ref_count(&mut self, count: i32) {
29+
unsafe {
30+
self.0.as_mut().refCount = count as _;
31+
}
32+
}
33+
2234
pub fn from_string(string: &str) -> Self {
2335
let c_str = std::ffi::CString::new(string).expect("Failed to create CString");
2436
let obj = unsafe { tcl_sys::Tcl_NewStringObj(c_str.as_ptr(), c_str.as_bytes().len() as i32) };

tcl/src/obj_type.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
pub struct ObjType(pub(crate) tcl_sys::Tcl_ObjType);
2+
3+
impl ObjType {
4+
pub fn from_raw(obj_type: *const tcl_sys::Tcl_ObjType) -> Self {
5+
ObjType(unsafe { *obj_type })
6+
}
7+
8+
pub fn as_ptr(&self) -> *const tcl_sys::Tcl_ObjType {
9+
&self.0
10+
}
11+
12+
pub fn get(name: &str) -> Option<Self> {
13+
let name = std::ffi::CString::new(name).unwrap();
14+
unsafe {
15+
let obj_type = tcl_sys::Tcl_GetObjType(name.as_ptr());
16+
if obj_type.is_null() {
17+
return None;
18+
}
19+
Some(ObjType(*obj_type))
20+
}
21+
}
22+
}

tcl/src/time.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,16 @@ impl Time {
88
};
99
Time(time)
1010
}
11+
12+
pub fn into_raw(self) -> tcl_sys::Tcl_Time {
13+
self.0
14+
}
15+
16+
pub fn as_ptr(&self) -> *const tcl_sys::Tcl_Time {
17+
&self.0
18+
}
19+
20+
pub fn as_mut_ptr(&mut self) -> *mut tcl_sys::Tcl_Time {
21+
&mut self.0
22+
}
1123
}

0 commit comments

Comments
 (0)