pipeline_script/core/
builtin.rs1use std::collections::HashMap;
2use std::ffi::{c_char, CStr, CString};
3use std::io;
4use std::process::{Command, Stdio};
5use std::sync::Mutex;
6use std::thread::{self, JoinHandle};
7use std::time::{Duration, SystemTime, UNIX_EPOCH};
8
9use lazy_static::lazy_static;
10
11#[repr(C)]
12#[derive(Clone, Copy)]
13pub struct Array {
14 len: i64,
15 ptr: *mut Any,
16}
17#[repr(C)]
18#[derive(Clone, Copy)]
19pub struct Any {
20 id: i32,
21 ptr: *mut i8,
22}
23#[allow(unused)]
24pub extern "C" fn len(target: Array) -> i64 {
25 target.len
26}
27pub extern "C" fn println(l: i64, ptr: *mut Any) {
28 for i in 0..l {
29 let obj = unsafe { (ptr).offset(i as isize) };
30 unsafe {
31 match (*obj).id {
32 0 => {
33 print!("Unit")
34 }
35 1 => {
36 let b = (*obj).ptr as *mut bool;
37 print!("{}", *b);
38 }
39 3 => {
40 let value = (*obj).ptr as i8;
41 print!("{}", value);
42 }
43 5 => {
44 let value = (*obj).ptr as i16;
45 print!("{}", value);
46 }
47 7 => {
48 let v = (*obj).ptr as i32;
49 print!("{}", v);
50 }
51 9 => {
52 let v = (*obj).ptr as i64;
53 print!("{}", v);
54 }
55 11 => {
56 let v = (*obj).ptr as *mut f32;
57 print!("{}", *v);
58 }
59 13 => {
60 let v = (*obj).ptr as *mut f64;
61 print!("{}", *v);
62 }
63 15 => {
64 let s = CStr::from_ptr((*obj).ptr as *const c_char);
65 print!("{}", s.to_str().unwrap());
66 }
67 t => todo!("{t}"),
68 }
69 if i < l - 1 {
70 print!("\t")
71 }
72 }
73 }
74 println!()
75}
76#[allow(unused)]
77pub extern "C" fn print(obj: Array) {
78 for i in 0..obj.len {
79 let obj = unsafe { (obj.ptr).offset(i as isize) };
80 unsafe {
81 match (*obj).id {
82 0 => {
83 print!("Unit")
84 }
85 3 => {
86 let value = (*obj).ptr as i32;
87 print!("{}", value);
88 }
89 4 => {
90 let v = (*obj).ptr as i64;
91 print!("{}", v);
92 }
93 7 => {
94 let s = CStr::from_ptr((*obj).ptr as *const c_char);
95 print!("{}", s.to_str().unwrap());
96 }
97 t => todo!("{t}"),
98 }
99 }
100 }
101}
102pub extern "C" fn append(l: i64, ptr: *mut Any) -> *mut c_char {
103 let mut s = String::new();
104 for i in 0..l {
105 let obj = unsafe { (ptr).offset(i as isize) };
106 unsafe {
107 match (*obj).id {
108 0 => {
109 s.push_str("Unit");
110 }
111 1 => {
112 let b = (*obj).ptr as i8;
113 s.push_str(&format!("{}", if b == 1 { true } else { false }));
114 }
115 7 => {
116 let value = (*obj).ptr as i32;
117 s.push_str(&format!("{}", value));
118 }
119 9 => {
120 let v = (*obj).ptr as i64;
121 s.push_str(&format!("{}", v));
122 }
123 11 => {
124 let v = (*obj).ptr as *const f32;
125 s.push_str(&format!("{}", *v));
126 }
127 13 => {
128 let v = (*obj).ptr as *mut f64;
129 s.push_str(&format!("{}", *v));
130 }
131 15 => {
132 let s0 = CStr::from_ptr((*obj).ptr as *const c_char);
133 s.push_str(s0.to_str().unwrap());
134 }
135 t => todo!("{t}"),
136 }
137 }
138 }
139 s.push('\0');
140 let s = s.leak();
141 s.as_ptr() as *mut c_char
142}
143lazy_static! {
144 static ref WORKSPACES: Mutex<HashMap<String, String>> = Mutex::new(HashMap::new());
148
149 static ref THREAD_HANDLES: Mutex<Vec<JoinHandle<()>>> = Mutex::new(Vec::new());
152}
153pub extern "C" fn cmd(key: *mut c_char, command: *mut c_char) {
165 let key_str = unsafe { CStr::from_ptr(key).to_str().unwrap() };
166 let cmd = unsafe { CStr::from_ptr(command).to_str().unwrap() };
167
168 let workspaces = WORKSPACES.lock().unwrap();
169 let binding = "./".to_string();
170 let workspace = workspaces.get(key_str).unwrap_or(&binding);
171
172 Command::new("powershell")
173 .current_dir(workspace)
174 .arg("/C")
175 .arg(cmd)
176 .stdout(Stdio::inherit())
177 .stderr(Stdio::inherit())
178 .spawn()
179 .expect("Failed to execute command"); }
181pub extern "C" fn workspace(key: *mut c_char, dir: *mut c_char) {
192 let key_str = unsafe { CStr::from_ptr(key).to_str().unwrap() };
193 let dir_str = unsafe { CStr::from_ptr(dir).to_str().unwrap() };
194
195 if !std::path::Path::new(dir_str).exists() {
197 panic!("Directory does not exist: {}", dir_str);
198 }
199
200 let mut workspaces = WORKSPACES.lock().unwrap();
202 workspaces.insert(key_str.to_string(), dir_str.to_string());
203}
204#[allow(unused)]
205pub extern "C" fn exit() {
206 std::process::exit(0);
207}
208#[allow(unused)]
209pub extern "C" fn get_env(key: *mut c_char) -> *mut c_char {
210 let key = unsafe { CStr::from_ptr(key).to_str().unwrap() };
211 let mut value = std::env::var(key).unwrap();
212 value.push('\0');
213 let value = value.leak();
214 value.as_ptr() as *mut c_char
215}
216#[allow(unused)]
217pub extern "C" fn set_env(key: *mut c_char, value: *mut c_char) {
218 let key = unsafe { CStr::from_ptr(key).to_str().unwrap() };
219 let value = unsafe { CStr::from_ptr(value).to_str().unwrap() };
220 std::env::set_var(key, value);
221}
222
223#[allow(unused)]
224pub extern "C" fn panic(ptr: *mut c_char) {
225 let s = unsafe { CStr::from_ptr(ptr).to_str().unwrap() };
226 eprintln!("\x1b[31mpanic: {}\x1b[0m", s);
227 std::process::exit(1);
228}
229
230#[no_mangle]
231pub extern "C" fn now() -> u64 {
232 SystemTime::now()
233 .duration_since(UNIX_EPOCH)
234 .unwrap_or_default() .as_millis() as u64 }
237
238pub type ExternFn = extern "C" fn();
240
241pub extern "C" fn spawn(func: ExternFn) {
250 let handle = thread::spawn(move || {
252 func();
253 });
254
255 let mut handles = THREAD_HANDLES.lock().unwrap();
257 handles.push(handle);
258}
259
260pub extern "C" fn wait() {
266 let mut handles = THREAD_HANDLES.lock().unwrap();
267
268 while let Some(handle) = handles.pop() {
270 if let Err(e) = handle.join() {
271 eprintln!("线程执行失败: {:?}", e);
272 }
273 }
274}
275
276pub extern "C" fn sleep(ms: u64) {
277 thread::sleep(Duration::from_millis(ms));
278}
279
280pub extern "C" fn string_equal(l: *const c_char, r: *const c_char) -> bool {
281 let l = unsafe { CStr::from_ptr(l).to_str().unwrap() };
282 let r = unsafe { CStr::from_ptr(r).to_str().unwrap() };
283 return l.eq(r);
284}
285
286pub extern "C" fn read_line() -> *mut c_char {
295 let mut input = String::new();
296 match io::stdin().read_line(&mut input) {
297 Ok(_) => {
298 match CString::new(input) {
300 Ok(c_string) => c_string.into_raw(),
301 Err(_) => {
302 CString::new("").unwrap().into_raw()
304 }
305 }
306 }
307 Err(_) => {
308 CString::new("").unwrap().into_raw()
310 }
311 }
312}
313
314pub extern "C" fn read_string() -> *mut c_char {
323 let mut input = String::new();
324 match io::stdin().read_line(&mut input) {
325 Ok(_) => {
326 let trimmed = input.trim_end().to_string();
328 match CString::new(trimmed) {
329 Ok(c_string) => c_string.into_raw(),
330 Err(_) => {
331 CString::new("").unwrap().into_raw()
333 }
334 }
335 }
336 Err(_) => {
337 CString::new("").unwrap().into_raw()
339 }
340 }
341}
342
343pub extern "C" fn read_int64() -> i64 {
352 let mut input = String::new();
353 match io::stdin().read_line(&mut input) {
354 Ok(_) => {
355 match input.trim().parse::<i64>() {
357 Ok(num) => num,
358 Err(_) => {
359 eprintln!("警告: 输入的不是有效的整数,返回默认值 0");
360 0
361 }
362 }
363 }
364 Err(_) => {
365 eprintln!("错误: 读取输入失败,返回默认值 0");
366 0
367 }
368 }
369}
370
371pub extern "C" fn read_double() -> f64 {
380 let mut input = String::new();
381 match io::stdin().read_line(&mut input) {
382 Ok(_) => {
383 match input.trim().parse::<f64>() {
385 Ok(num) => num,
386 Err(_) => {
387 eprintln!("警告: 输入的不是有效的浮点数,返回默认值 0.0");
388 0.0
389 }
390 }
391 }
392 Err(_) => {
393 eprintln!("错误: 读取输入失败,返回默认值 0.0");
394 0.0
395 }
396 }
397}
398pub extern "C" fn read_float() -> f32 {
407 let mut input = String::new();
408 match io::stdin().read_line(&mut input) {
409 Ok(_) => {
410 match input.trim().parse::<f32>() {
412 Ok(num) => num,
413 Err(_) => {
414 eprintln!("警告: 输入的不是有效的浮点数,返回默认值 0.0");
415 0.0
416 }
417 }
418 }
419 Err(_) => {
420 eprintln!("错误: 读取输入失败,返回默认值 0.0");
421 0.0
422 }
423 }
424}