Skip to content

Commit

Permalink
Support seeking past the end of writable file streams as Bocfel needs…
Browse files Browse the repository at this point in the history
… it (see iftechfoundation/ifarchive-if-specs#17)

Support non-existent files in `glkunix_stream_open_pathname_gen`
Wrap glkstart.h in `extern "C"`
  • Loading branch information
curiousdannii committed Oct 1, 2024
1 parent 3b4e2b9 commit ca09641
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 5 deletions.
4 changes: 4 additions & 0 deletions remglk/src/glkapi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1632,9 +1632,13 @@ where S: Default + GlkSystem {

#[derive(Default)]
pub struct Directories {
/** The storyfile directory, used by `garglk_add_resource_from_file` */
pub storyfile: PathBuf,
/** The system current working directory, used by `glkunix_stream_open_pathname` */
pub system_cwd: PathBuf,
/** Temp folder */
pub temp: PathBuf,
/** The Glk "current directory", used by `glk_fileref_create_by_name`/`glk_fileref_create_by_prompt` */
pub working: PathBuf,
}

Expand Down
10 changes: 10 additions & 0 deletions remglk/src/glkapi/streams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,16 @@ where T: Clone + Default, Box<[T]>: GlkArray {
}

fn set_position(&mut self, mode: SeekMode, pos: i32) {
// Despite the Glk spec saying that it's illegal to specify a position after the end of a file (5.4) this is needed by Bocfel, and seemingly supported by all libc based Glk interpreters, so we might need to expand first
// See https://github.com/iftechfoundation/ifarchive-if-specs/issues/17
let new_pos = match mode {
SeekMode::Current => self.str.pos as i32 + pos,
SeekMode::End => self.str.len as i32 + pos,
SeekMode::Start => pos,
} as usize;
if new_pos > self.str.len {
self.expand(new_pos - self.str.len);
}
self.str.set_position(mode, pos);
}

Expand Down
8 changes: 8 additions & 0 deletions remglk_capi/src/glk/glkstart.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
#ifndef GT_START_H
#define GT_START_H

#ifdef __cplusplus
extern "C" {
#endif

/* We define our own TRUE and FALSE and NULL, because ANSI
is a strange world. */
#ifndef TRUE
Expand Down Expand Up @@ -115,5 +119,9 @@ extern void glkunix_fileref_set_dispatch_rock(frefid_t fref, glk_objrock_u rock)

#endif /* GLKUNIX_AUTOSAVE_FEATURES */

#ifdef __cplusplus
}
#endif

#endif /* GT_START_H */

9 changes: 4 additions & 5 deletions remglk_capi/src/glkstart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,10 @@ unsafe fn glkunix_arguments() -> Vec<GlkUnixArgument> {

#[no_mangle]
pub extern "C" fn glkunix_fileref_create_by_name_uncleaned(usage: u32, filename_ptr: *const i8, rock: u32) -> FileRefPtr {
let mut glkapi = glkapi().lock().unwrap();
let filename_cstr = unsafe {CStr::from_ptr(filename_ptr)};
let filename = filename_cstr.to_string_lossy().to_string();
let fileref = glkapi.glkunix_fileref_create_by_name_uncleaned(usage, filename, rock);
to_owned(fileref)
let result = glkapi().lock().unwrap().glkunix_fileref_create_by_name_uncleaned(usage, filename, rock);
to_owned(result)
}

#[no_mangle]
Expand Down Expand Up @@ -242,7 +241,7 @@ pub extern "C" fn glkunix_stream_open_pathname_gen(filename_ptr: *const i8, writ
let fileref = glkunix_fileref_create_by_name_uncleaned(fileusage_Data | if textmode > 0 {fileusage_TextMode} else {fileusage_BinaryMode}, filename_ptr, 0);
let fileref = reclaim(fileref);
let mut glkapi = glkapi().lock().unwrap();
let str = glkapi.glk_stream_open_file(&fileref, if writemode > 0 {FileMode::Write} else {FileMode::Read}, rock).unwrap().unwrap();
let result = glkapi.glk_stream_open_file(&fileref, if writemode > 0 {FileMode::Write} else {FileMode::Read}, rock);
glkapi.glk_fileref_destroy(fileref);
to_owned(str)
to_owned_opt(result.unwrap())
}

0 comments on commit ca09641

Please sign in to comment.