1use crate::seqstring::global_string;
9use crate::stack::{Stack, pop, push};
10use crate::value::Value;
11
12#[unsafe(no_mangle)]
21pub unsafe extern "C" fn patch_seq_getenv(stack: Stack) -> Stack {
22 unsafe {
23 let (stack, name_val) = pop(stack);
24 let name = match name_val {
25 Value::String(s) => s,
26 _ => panic!(
27 "getenv: expected String (name) on stack, got {:?}",
28 name_val
29 ),
30 };
31
32 match std::env::var(name.as_str()) {
33 Ok(value) => {
34 let stack = push(stack, Value::String(global_string(value)));
35 push(stack, Value::Int(1)) }
37 Err(_) => {
38 let stack = push(stack, Value::String(global_string(String::new())));
39 push(stack, Value::Int(0)) }
41 }
42 }
43}
44
45#[unsafe(no_mangle)]
54pub unsafe extern "C" fn patch_seq_home_dir(stack: Stack) -> Stack {
55 unsafe {
56 if let Ok(home) = std::env::var("HOME") {
58 let stack = push(stack, Value::String(global_string(home)));
59 return push(stack, Value::Int(1));
60 }
61
62 #[cfg(windows)]
64 if let Ok(home) = std::env::var("USERPROFILE") {
65 let stack = push(stack, Value::String(global_string(home)));
66 return push(stack, Value::Int(1));
67 }
68
69 let stack = push(stack, Value::String(global_string(String::new())));
71 push(stack, Value::Int(0))
72 }
73}
74
75#[unsafe(no_mangle)]
84pub unsafe extern "C" fn patch_seq_current_dir(stack: Stack) -> Stack {
85 unsafe {
86 match std::env::current_dir() {
87 Ok(path) => {
88 let path_str = path.to_string_lossy().into_owned();
89 let stack = push(stack, Value::String(global_string(path_str)));
90 push(stack, Value::Int(1)) }
92 Err(_) => {
93 let stack = push(stack, Value::String(global_string(String::new())));
94 push(stack, Value::Int(0)) }
96 }
97 }
98}
99
100#[unsafe(no_mangle)]
109pub unsafe extern "C" fn patch_seq_path_exists(stack: Stack) -> Stack {
110 unsafe {
111 let (stack, path_val) = pop(stack);
112 let path = match path_val {
113 Value::String(s) => s,
114 _ => panic!(
115 "path-exists: expected String (path) on stack, got {:?}",
116 path_val
117 ),
118 };
119
120 let exists = std::path::Path::new(path.as_str()).exists();
121 push(stack, Value::Int(if exists { 1 } else { 0 }))
122 }
123}
124
125#[unsafe(no_mangle)]
134pub unsafe extern "C" fn patch_seq_path_is_file(stack: Stack) -> Stack {
135 unsafe {
136 let (stack, path_val) = pop(stack);
137 let path = match path_val {
138 Value::String(s) => s,
139 _ => panic!(
140 "path-is-file: expected String (path) on stack, got {:?}",
141 path_val
142 ),
143 };
144
145 let is_file = std::path::Path::new(path.as_str()).is_file();
146 push(stack, Value::Int(if is_file { 1 } else { 0 }))
147 }
148}
149
150#[unsafe(no_mangle)]
159pub unsafe extern "C" fn patch_seq_path_is_dir(stack: Stack) -> Stack {
160 unsafe {
161 let (stack, path_val) = pop(stack);
162 let path = match path_val {
163 Value::String(s) => s,
164 _ => panic!(
165 "path-is-dir: expected String (path) on stack, got {:?}",
166 path_val
167 ),
168 };
169
170 let is_dir = std::path::Path::new(path.as_str()).is_dir();
171 push(stack, Value::Int(if is_dir { 1 } else { 0 }))
172 }
173}
174
175#[unsafe(no_mangle)]
184pub unsafe extern "C" fn patch_seq_path_join(stack: Stack) -> Stack {
185 unsafe {
186 let (stack, component_val) = pop(stack);
187 let (stack, base_val) = pop(stack);
188
189 let base = match base_val {
190 Value::String(s) => s,
191 _ => panic!(
192 "path-join: expected String (base) on stack, got {:?}",
193 base_val
194 ),
195 };
196
197 let component = match component_val {
198 Value::String(s) => s,
199 _ => panic!(
200 "path-join: expected String (component) on stack, got {:?}",
201 component_val
202 ),
203 };
204
205 let joined = std::path::Path::new(base.as_str())
206 .join(component.as_str())
207 .to_string_lossy()
208 .into_owned();
209
210 push(stack, Value::String(global_string(joined)))
211 }
212}
213
214#[unsafe(no_mangle)]
223pub unsafe extern "C" fn patch_seq_path_parent(stack: Stack) -> Stack {
224 unsafe {
225 let (stack, path_val) = pop(stack);
226 let path = match path_val {
227 Value::String(s) => s,
228 _ => panic!(
229 "path-parent: expected String (path) on stack, got {:?}",
230 path_val
231 ),
232 };
233
234 match std::path::Path::new(path.as_str()).parent() {
235 Some(parent) => {
236 let parent_str = parent.to_string_lossy().into_owned();
237 let stack = push(stack, Value::String(global_string(parent_str)));
238 push(stack, Value::Int(1)) }
240 None => {
241 let stack = push(stack, Value::String(global_string(String::new())));
242 push(stack, Value::Int(0)) }
244 }
245 }
246}
247
248#[unsafe(no_mangle)]
257pub unsafe extern "C" fn patch_seq_path_filename(stack: Stack) -> Stack {
258 unsafe {
259 let (stack, path_val) = pop(stack);
260 let path = match path_val {
261 Value::String(s) => s,
262 _ => panic!(
263 "path-filename: expected String (path) on stack, got {:?}",
264 path_val
265 ),
266 };
267
268 match std::path::Path::new(path.as_str()).file_name() {
269 Some(filename) => {
270 let filename_str = filename.to_string_lossy().into_owned();
271 let stack = push(stack, Value::String(global_string(filename_str)));
272 push(stack, Value::Int(1)) }
274 None => {
275 let stack = push(stack, Value::String(global_string(String::new())));
276 push(stack, Value::Int(0)) }
278 }
279 }
280}