Skip to content

Commit c2ae25f

Browse files
authored
Bibtex cleanups / type improvements (#1163)
2 parents a6fe6d7 + ac98ff8 commit c2ae25f

File tree

17 files changed

+2277
-1841
lines changed

17 files changed

+2277
-1841
lines changed

Diff for: Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: crates/bridge_core/src/lib.rs

+93-50
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ use tectonic_io_base::{
5454
};
5555
use tectonic_status_base::{tt_error, tt_warning, MessageKind, StatusBackend};
5656

57+
/// The ID of an InputHandle, used for Rust core state
58+
#[derive(Copy, Clone, PartialEq)]
59+
pub struct InputId(*mut InputHandle);
60+
61+
/// The ID of an OutputHandle, used for Rust core state
62+
#[derive(Copy, Clone, PartialEq)]
63+
pub struct OutputId(*mut OutputHandle);
64+
5765
/// Possible failures for "system request" calls to the driver.
5866
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5967
pub enum SystemRequestError {
@@ -473,16 +481,29 @@ impl<'a> CoreBridgeState<'a> {
473481
error_occurred
474482
}
475483

476-
fn output_open(&mut self, name: &str, is_gz: bool) -> *mut OutputHandle {
484+
fn output_to_id(&self, output: *mut OutputHandle) -> OutputId {
485+
OutputId(output)
486+
}
487+
488+
/// Get a mutable reference to an [`OutputHandle`] associated with an [`OutputId`]
489+
pub fn get_output(&mut self, id: OutputId) -> &mut OutputHandle {
490+
self.output_handles
491+
.iter_mut()
492+
.find(|o| ptr::addr_eq(&***o, id.0))
493+
.unwrap()
494+
}
495+
496+
/// Open a new output, provided the output name and whether it is gzipped.
497+
pub fn output_open(&mut self, name: &str, is_gz: bool) -> Option<OutputId> {
477498
let io = self.hooks.io();
478499
let name = normalize_tex_path(name);
479500

480501
let mut oh = match io.output_open_name(&name) {
481502
OpenResult::Ok(oh) => oh,
482-
OpenResult::NotAvailable => return ptr::null_mut(),
503+
OpenResult::NotAvailable => return None,
483504
OpenResult::Err(e) => {
484505
tt_warning!(self.status, "open of output {} failed", name; e);
485-
return ptr::null_mut();
506+
return None;
486507
}
487508
};
488509

@@ -495,23 +516,24 @@ impl<'a> CoreBridgeState<'a> {
495516
}
496517

497518
self.output_handles.push(Box::new(oh));
498-
&mut **self.output_handles.last_mut().unwrap()
519+
Some(OutputId(&mut **self.output_handles.last_mut().unwrap()))
499520
}
500521

501-
fn output_open_stdout(&mut self) -> *mut OutputHandle {
522+
/// Open a new stdout output.
523+
pub fn output_open_stdout(&mut self) -> Option<OutputId> {
502524
let io = self.hooks.io();
503525

504526
let oh = match io.output_open_stdout() {
505527
OpenResult::Ok(oh) => oh,
506-
OpenResult::NotAvailable => return ptr::null_mut(),
528+
OpenResult::NotAvailable => return None,
507529
OpenResult::Err(e) => {
508530
tt_warning!(self.status, "open of stdout failed"; e);
509-
return ptr::null_mut();
531+
return None;
510532
}
511533
};
512534

513535
self.output_handles.push(Box::new(oh));
514-
&mut **self.output_handles.last_mut().unwrap()
536+
Some(OutputId(&mut **self.output_handles.last_mut().unwrap()))
515537
}
516538

517539
fn output_write(&mut self, handle: *mut OutputHandle, buf: &[u8]) -> bool {
@@ -540,45 +562,57 @@ impl<'a> CoreBridgeState<'a> {
540562
}
541563
}
542564

543-
fn output_close(&mut self, handle: *mut OutputHandle) -> bool {
544-
let len = self.output_handles.len();
565+
/// Close the provided output, flushing it and performing any necessary handling.
566+
pub fn output_close(&mut self, id: OutputId) -> bool {
545567
let mut rv = false;
546568

547-
for i in 0..len {
548-
let p: *const OutputHandle = &*self.output_handles[i];
549-
550-
if p == handle {
551-
let mut oh = self.output_handles.swap_remove(i);
552-
if let Err(e) = oh.flush() {
553-
tt_warning!(self.status, "error when closing output {}", oh.name(); e.into());
554-
rv = true;
555-
}
556-
let (name, digest) = oh.into_name_digest();
557-
self.hooks.event_output_closed(name, digest);
558-
break;
569+
let pos = self
570+
.output_handles
571+
.iter()
572+
.position(|o| ptr::addr_eq(&**o, id.0));
573+
if let Some(pos) = pos {
574+
let mut oh = self.output_handles.swap_remove(pos);
575+
if let Err(e) = oh.flush() {
576+
tt_warning!(self.status, "error when closing output {}", oh.name(); e.into());
577+
rv = true;
559578
}
579+
let (name, digest) = oh.into_name_digest();
580+
self.hooks.event_output_closed(name, digest);
560581
}
561582

562583
rv
563584
}
564585

565-
fn input_open(&mut self, name: &str, format: FileFormat, is_gz: bool) -> *mut InputHandle {
586+
fn input_to_id(&self, input: *mut InputHandle) -> InputId {
587+
InputId(input)
588+
}
589+
590+
/// Get a mutable reference to an [`InputHandle`] associated with an [`InputId`]
591+
pub fn get_input(&mut self, input: InputId) -> &mut InputHandle {
592+
self.input_handles
593+
.iter_mut()
594+
.find(|i| ptr::addr_eq(&***i, input.0))
595+
.unwrap()
596+
}
597+
598+
/// Open a new input, provided the input name, the file format, and whether it is gzipped.
599+
pub fn input_open(&mut self, name: &str, format: FileFormat, is_gz: bool) -> Option<InputId> {
566600
let name = normalize_tex_path(name);
567601

568602
let (ih, path) = match self.input_open_name_format_gz(&name, format, is_gz) {
569603
OpenResult::Ok(tup) => tup,
570604
OpenResult::NotAvailable => {
571-
return ptr::null_mut();
605+
return None;
572606
}
573607
OpenResult::Err(e) => {
574608
tt_warning!(self.status, "open of input {} failed", name; e);
575-
return ptr::null_mut();
609+
return None;
576610
}
577611
};
578612

579613
self.input_handles.push(Box::new(ih));
580614
self.latest_input_path = path;
581-
&mut **self.input_handles.last_mut().unwrap()
615+
Some(InputId(&mut **self.input_handles.last_mut().unwrap()))
582616
}
583617

584618
fn input_open_primary(&mut self) -> *mut InputHandle {
@@ -650,32 +684,31 @@ impl<'a> CoreBridgeState<'a> {
650684
rhandle.ungetc(byte)
651685
}
652686

653-
fn input_close(&mut self, handle: *mut InputHandle) -> bool {
654-
let len = self.input_handles.len();
655-
656-
for i in 0..len {
657-
let p: *const InputHandle = &*self.input_handles[i];
658-
659-
if p == handle {
660-
let mut ih = self.input_handles.swap_remove(i);
661-
let mut rv = false;
662-
663-
if let Err(e) = ih.scan_remainder() {
664-
tt_warning!(self.status, "error closing out input {}", ih.name(); e);
665-
rv = true;
666-
}
667-
668-
let (name, digest_opt) = ih.into_name_digest();
669-
self.hooks.event_input_closed(name, digest_opt, self.status);
670-
return rv;
687+
/// Close the provided output, performing any necessary handling.
688+
pub fn input_close(&mut self, id: InputId) -> bool {
689+
let pos = self
690+
.input_handles
691+
.iter()
692+
.position(|i| ptr::addr_eq(&**i, id.0));
693+
if let Some(pos) = pos {
694+
let mut ih = self.input_handles.swap_remove(pos);
695+
let mut rv = false;
696+
697+
if let Err(e) = ih.scan_remainder() {
698+
tt_warning!(self.status, "error closing out input {}", ih.name(); e);
699+
rv = true;
671700
}
701+
702+
let (name, digest_opt) = ih.into_name_digest();
703+
self.hooks.event_input_closed(name, digest_opt, self.status);
704+
return rv;
672705
}
673706

674707
// TODO: Handle the error better. This indicates a bug in the engine.
675708
tt_error!(
676709
self.status,
677710
"serious internal bug: unexpected handle in input close: {:?}",
678-
handle
711+
id.0
679712
);
680713

681714
true
@@ -900,13 +933,19 @@ pub unsafe extern "C" fn ttbc_output_open(
900933
let rname = CStr::from_ptr(name).to_string_lossy();
901934
let ris_gz = is_gz != 0;
902935

903-
es.output_open(&rname, ris_gz)
936+
match es.output_open(&rname, ris_gz) {
937+
Some(id) => es.get_output(id),
938+
None => ptr::null_mut(),
939+
}
904940
}
905941

906942
/// Open the general user output stream as a Tectonic output file.
907943
#[no_mangle]
908944
pub extern "C" fn ttbc_output_open_stdout(es: &mut CoreBridgeState) -> *mut OutputHandle {
909-
es.output_open_stdout()
945+
match es.output_open_stdout() {
946+
Some(id) => es.get_output(id),
947+
None => ptr::null_mut(),
948+
}
910949
}
911950

912951
/// Write a single character to a Tectonic output file.
@@ -967,7 +1006,7 @@ pub extern "C" fn ttbc_output_close(
9671006
return 0; // This is/was the behavior of close_file() in C.
9681007
}
9691008

970-
libc::c_int::from(es.output_close(handle))
1009+
libc::c_int::from(es.output_close(es.output_to_id(handle)))
9711010
}
9721011

9731012
/// Open a Tectonic file for input.
@@ -984,7 +1023,11 @@ pub unsafe extern "C" fn ttbc_input_open(
9841023
) -> *mut InputHandle {
9851024
let rname = CStr::from_ptr(name).to_string_lossy();
9861025
let ris_gz = is_gz != 0;
987-
es.input_open(&rname, format, ris_gz)
1026+
let id = es.input_open(&rname, format, ris_gz);
1027+
match id {
1028+
Some(id) => es.get_input(id),
1029+
None => ptr::null_mut(),
1030+
}
9881031
}
9891032

9901033
/// Open the "primary input" file.
@@ -1169,7 +1212,7 @@ pub extern "C" fn ttbc_input_close(
11691212
return 0; // This is/was the behavior of close_file() in C.
11701213
}
11711214

1172-
libc::c_int::from(es.input_close(handle))
1215+
libc::c_int::from(es.input_close(es.input_to_id(handle)))
11731216
}
11741217

11751218
/// A buffer for diagnostic messages. Rust code does not need to use this type.

Diff for: crates/engine_bibtex/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ tectonic_io_base = { path = "../io_base", version = '0.0.0-dev.0' }
2323
tectonic_bridge_core = { path = "../bridge_core", version = "0.0.0-dev.0" }
2424
tectonic_errors = { path = "../errors", version = "0.0.0-dev.0" }
2525

26+
[dev-dependencies]
27+
tectonic_status_base = { path = "../status_base", version = "0.0.0-dev.0" }
28+
2629
[package.metadata.internal_dep_versions]
2730
tectonic_bridge_core = "thiscommit:2021-01-17:fohCh1sh"
2831
tectonic_errors = "5c9ba661edf5ef669f24f9904f99cca369d999e7"
2932
tectonic_io_base = "0d9169ef44b2652d6d70308a83022bfd60358e71"
33+
tectonic_status_base = "0d9169ef44b2652d6d70308a83022bfd60358e71"

0 commit comments

Comments
 (0)