Skip to content

Commit 8e9accc

Browse files
authored
Period (#13)
* change periodicity to period * fix memory leaks
1 parent ac13c0c commit 8e9accc

File tree

4 files changed

+88
-103
lines changed

4 files changed

+88
-103
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ The purpose of this changelog is to document new features and breaking changes t
77
- Add JSON <-> Scheme interface
88
- Separate crypto primitives into separate namespace
99
- Add unix time primitive
10+
- Use explicit period instead of periodicity
1011

1112
--- v1.0.4 (2025.09.14) ---
1213

src/config.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ pub struct Config {
3030
#[arg(
3131
short = 'c',
3232
long,
33-
default_value_t = 0,
34-
help = "Power of two determining the period of the step query"
33+
default_value_t = 1.0,
34+
help = "Number of seconds between each step inquiry"
3535
)]
36-
pub periodicity: i32,
36+
pub period: f64,
3737
}
3838

3939
impl Config {

src/evaluator.rs

Lines changed: 81 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,16 @@ impl Type {
7676

7777
pub fn obj2str(sc: *mut s7_scheme, obj: *mut s7_cell) -> String {
7878
unsafe {
79-
unsafe {
80-
let expr = s7_object_to_c_string(sc, obj);
81-
let cstr = CStr::from_ptr(expr);
82-
let result = match cstr.to_str() {
83-
Ok(expr) => expr.to_owned(),
84-
Err(_) => format!("(error 'encoding-error \"Failed to encode string\")"),
85-
};
86-
free(expr as *mut libc::c_void);
87-
result
88-
}
79+
let expr = s7_string(s7_object_to_string(sc, obj, false));
80+
let cstr = CStr::from_ptr(expr);
81+
let result = match cstr.to_str() {
82+
Ok(rust_str) => match s7_is_string(obj) {
83+
true => format!("\"{}\"", rust_str),
84+
false => format!("{}", rust_str.to_owned()),
85+
},
86+
Err(_) => format!("(error 'encoding-error \"Failed to encode string\")"),
87+
};
88+
result
8989
}
9090
}
9191

@@ -108,36 +108,32 @@ pub fn scheme2json(expression: &str) -> Result<Value, String> {
108108
// - @hash-table: {"*type/hash-table*": [["a", 6], [53, 199]]}
109109

110110
unsafe {
111-
unsafe {
112-
let sc: *mut s7_scheme = s7_init();
111+
let sc: *mut s7_scheme = s7_init();
113112

114-
// Parse the expression without evaluating it
115-
let c_expr = CString::new(expression).unwrap_or_else(|_| CString::new("()").unwrap());
116-
let input_port = s7_open_input_string(sc, c_expr.as_ptr());
117-
let s7_obj = s7_read(sc, input_port);
118-
s7_close_input_port(sc, input_port);
113+
// Parse the expression without evaluating it
114+
let c_expr = CString::new(expression).unwrap_or_else(|_| CString::new("()").unwrap());
115+
let input_port = s7_open_input_string(sc, c_expr.as_ptr());
116+
let s7_obj = s7_read(sc, input_port);
117+
s7_close_input_port(sc, input_port);
119118

120-
let result = s7_obj_to_json(sc, s7_obj);
121-
s7_free(sc);
122-
result
123-
}
119+
let result = s7_obj_to_json(sc, s7_obj);
120+
s7_free(sc);
121+
result
124122
}
125123
}
126124

127125
pub fn json2scheme(expression: Value) -> Result<String, String> {
128126
unsafe {
129-
unsafe {
130-
let sc: *mut s7_scheme = s7_init();
131-
match json_to_s7_obj(sc, &expression) {
132-
Ok(s7_obj) => {
133-
let result = obj2str(sc, s7_obj);
134-
s7_free(sc);
135-
Ok(result)
136-
}
137-
Err(err) => {
138-
s7_free(sc);
139-
Err(err)
140-
}
127+
let sc: *mut s7_scheme = s7_init();
128+
match json_to_s7_obj(sc, &expression) {
129+
Ok(s7_obj) => {
130+
let result = obj2str(sc, s7_obj);
131+
s7_free(sc);
132+
Ok(result)
133+
}
134+
Err(err) => {
135+
s7_free(sc);
136+
Err(err)
141137
}
142138
}
143139
}
@@ -163,52 +159,50 @@ impl Evaluator {
163159
primitives_.extend(primitives);
164160

165161
unsafe {
166-
unsafe {
167-
let sc: *mut s7_scheme = s7_init();
168-
169-
// remove insecure primitives
170-
for primitive in REMOVE {
171-
s7_define(
172-
sc,
173-
s7_rootlet(sc),
174-
s7_make_symbol(sc, primitive.as_ptr()),
175-
s7_make_symbol(sc, c"*removed*".as_ptr()),
176-
);
177-
}
162+
let sc: *mut s7_scheme = s7_init();
178163

179-
// add new types
180-
for (&tag_, type_) in types.iter() {
181-
let tag = s7_make_c_type(sc, type_.name.as_ptr());
182-
assert!(tag == tag_, "Type tag was not properly set");
183-
s7_c_type_set_gc_free(sc, tag, Some(type_.free));
184-
s7_c_type_set_gc_mark(sc, tag, Some(type_.mark));
185-
s7_c_type_set_is_equal(sc, tag, Some(type_.is_equal));
186-
s7_c_type_set_to_string(sc, tag, Some(type_.to_string));
187-
}
164+
// remove insecure primitives
165+
for primitive in REMOVE {
166+
s7_define(
167+
sc,
168+
s7_rootlet(sc),
169+
s7_make_symbol(sc, primitive.as_ptr()),
170+
s7_make_symbol(sc, c"*removed*".as_ptr()),
171+
);
172+
}
188173

189-
// add new primitives
190-
for primitive in primitives_.iter() {
191-
s7_define_function(
192-
sc,
193-
primitive.name.as_ptr(),
194-
Some(primitive.code),
195-
primitive
196-
.args_required
197-
.try_into()
198-
.expect("args_required conversion failed"),
199-
primitive
200-
.args_optional
201-
.try_into()
202-
.expect("args_optional conversion failed"),
203-
primitive.args_rest,
204-
primitive.description.as_ptr(),
205-
);
206-
}
174+
// add new types
175+
for (&tag_, type_) in types.iter() {
176+
let tag = s7_make_c_type(sc, type_.name.as_ptr());
177+
assert!(tag == tag_, "Type tag was not properly set");
178+
s7_c_type_set_gc_free(sc, tag, Some(type_.free));
179+
s7_c_type_set_gc_mark(sc, tag, Some(type_.mark));
180+
s7_c_type_set_is_equal(sc, tag, Some(type_.is_equal));
181+
s7_c_type_set_to_string(sc, tag, Some(type_.to_string));
182+
}
207183

208-
Self {
184+
// add new primitives
185+
for primitive in primitives_.iter() {
186+
s7_define_function(
209187
sc,
210-
primitives: primitives_,
211-
}
188+
primitive.name.as_ptr(),
189+
Some(primitive.code),
190+
primitive
191+
.args_required
192+
.try_into()
193+
.expect("args_required conversion failed"),
194+
primitive
195+
.args_optional
196+
.try_into()
197+
.expect("args_optional conversion failed"),
198+
primitive.args_rest,
199+
primitive.description.as_ptr(),
200+
);
201+
}
202+
203+
Self {
204+
sc,
205+
primitives: primitives_,
212206
}
213207
}
214208
}
@@ -233,9 +227,7 @@ impl Evaluator {
233227
impl Drop for Evaluator {
234228
fn drop(&mut self) {
235229
unsafe {
236-
unsafe {
237-
s7_free(self.sc);
238-
}
230+
s7_free(self.sc);
239231
}
240232
}
241233
}
@@ -244,19 +236,14 @@ fn primitive_expression_to_byte_vector() -> Primitive {
244236
unsafe extern "C" fn code(sc: *mut s7_scheme, args: s7_pointer) -> s7_pointer {
245237
let arg = s7_car(args);
246238

247-
let s7_c_str = s7_object_to_c_string(sc, arg);
248-
let c_string = CStr::from_ptr(s7_c_str);
239+
// let s7_c_str = s7_string(s7_object_to_string(sc, arg, false));
240+
// let c_string = CStr::from_ptr(s7_c_str);
241+
let bytes = obj2str(sc, arg).into_bytes();
249242

250-
let bv = s7_make_byte_vector(
251-
sc,
252-
c_string.to_bytes().len() as i64,
253-
1 as i64,
254-
std::ptr::null_mut(),
255-
);
256-
for (i, b) in c_string.to_bytes().iter().enumerate() {
243+
let bv = s7_make_byte_vector(sc, bytes.len() as i64, 1 as i64, std::ptr::null_mut());
244+
for (i, b) in bytes.iter().enumerate() {
257245
s7_byte_vector_set(bv, i as i64, *b);
258246
}
259-
free(s7_c_str as *mut libc::c_void);
260247
bv
261248
}
262249

@@ -328,18 +315,16 @@ fn primitive_hex_string_to_byte_vector() -> Primitive {
328315
);
329316
}
330317

331-
let s7_c_str = s7_object_to_c_string(sc, arg);
318+
let s7_c_str = s7_string(s7_object_to_string(sc, arg, false));
332319
let hex_string = CStr::from_ptr(s7_c_str)
333320
.to_str()
334321
.expect("Failed to convert C string to hex string");
335322

336-
let result: Result<Vec<u8>, ParseIntError> = (1..hex_string.len() - 1)
323+
let result: Result<Vec<u8>, ParseIntError> = (0..hex_string.len())
337324
.step_by(2)
338325
.map(|i| u8::from_str_radix(&hex_string[i..i + 2], 16))
339326
.collect();
340327

341-
free(s7_c_str as *mut libc::c_void);
342-
343328
match result {
344329
Ok(result) => {
345330
let bv =
@@ -527,14 +512,15 @@ unsafe fn s7_obj_to_json(sc: *mut s7_scheme, obj: s7_pointer) -> Result<Value, S
527512
Err("Invalid floating point number - cannot convert to JSON".to_string())
528513
}
529514
} else if s7_is_string(obj) {
530-
let c_str = s7_string(obj);
531-
let rust_str = CStr::from_ptr(c_str).to_string_lossy();
515+
// let c_str = s7_string(obj);
516+
// let rust_str = CStr::from_ptr(c_str).to_string_lossy();
517+
let rust_str = obj2str(sc, obj);
532518

533519
// Check if it's a special type marker
534520
let mut special_type = Map::new();
535521
special_type.insert(
536522
"*type/string*".to_string(),
537-
Value::String(rust_str.to_string()),
523+
Value::String(String::from(&rust_str[1..(rust_str.len() - 1)])),
538524
);
539525
Ok(Value::Object(special_type))
540526
} else if s7_is_symbol(obj) {

src/main.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,21 +117,19 @@ async fn main() {
117117
rocket_config.address = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
118118
rocket_config.limits = Limits::new().limit("string", 1_i32.mebibytes());
119119

120-
let period = 2_f64.powi(config.periodicity);
121-
122120
if config.step != "" {
123121
tokio::spawn(async move {
124122
let mut step = 0;
125123
let start = ((SystemTime::now()
126124
.duration_since(UNIX_EPOCH)
127125
.expect("Failed to get system time")
128126
.as_micros() as f64
129-
/ (period * MICRO))
127+
/ (config.period * MICRO))
130128
.ceil()
131-
* (period * MICRO)) as u128;
129+
* (config.period * MICRO)) as u128;
132130

133131
loop {
134-
let until = start + step * (period * MICRO) as u128;
132+
let until = start + step * (config.period * MICRO) as u128;
135133
let now = SystemTime::now()
136134
.duration_since(UNIX_EPOCH)
137135
.expect("Failed to get system time")

0 commit comments

Comments
 (0)