Skip to content

Commit 923b1b2

Browse files
committed
Improve aux code - remove XBuf, make bad states less representable, better ownership handling
1 parent e9915f3 commit 923b1b2

4 files changed

Lines changed: 67 additions & 82 deletions

File tree

crates/engine_bibtex/src/auxi.rs

Lines changed: 43 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -22,60 +22,41 @@ use tectonic_bridge_core::FileFormat;
2222

2323
const AUX_STACK_SIZE: usize = 20;
2424

25+
pub(crate) struct AuxFile {
26+
pub(crate) name: StrNumber,
27+
pub(crate) file: Box<PeekableInput>,
28+
pub(crate) line: i32,
29+
}
30+
2531
pub(crate) struct AuxData {
26-
aux_list: [StrNumber; AUX_STACK_SIZE + 1],
27-
aux_file: [Option<Box<PeekableInput>>; AUX_STACK_SIZE + 1],
28-
aux_ln_stack: [i32; AUX_STACK_SIZE + 1],
29-
aux_ptr: AuxNumber,
32+
aux: Vec<AuxFile>,
3033
}
3134

3235
impl AuxData {
3336
fn new() -> AuxData {
34-
AuxData {
35-
aux_list: [0; AUX_STACK_SIZE + 1],
36-
aux_file: [(); AUX_STACK_SIZE + 1].map(|_| None),
37-
aux_ln_stack: [0; AUX_STACK_SIZE + 1],
38-
aux_ptr: 0,
39-
}
40-
}
41-
42-
pub fn ptr(&self) -> AuxNumber {
43-
self.aux_ptr
44-
}
45-
46-
pub fn set_ptr(&mut self, ptr: AuxNumber) {
47-
self.aux_ptr = ptr;
48-
}
49-
50-
pub fn at_ptr(&self) -> StrNumber {
51-
self.aux_list[self.aux_ptr]
52-
}
53-
54-
pub fn set_at_ptr(&mut self, num: StrNumber) {
55-
self.aux_list[self.aux_ptr] = num;
37+
AuxData { aux: Vec::new() }
5638
}
5739

58-
pub fn file_at_ptr(&mut self) -> &mut PeekableInput {
59-
self.aux_file[self.aux_ptr].as_mut().unwrap()
40+
pub fn push_file(&mut self, file: AuxFile) {
41+
self.aux.push(file);
6042
}
6143

62-
pub fn set_file_at_ptr(&mut self, file: Box<PeekableInput>) {
63-
self.aux_file[self.aux_ptr] = Some(file);
44+
pub fn pop_file(&mut self) -> (AuxFile, bool) {
45+
let out = self.aux.pop().unwrap();
46+
let last = self.aux.len() == 0;
47+
(out, last)
6448
}
6549

66-
pub fn pop_file(&mut self) -> (Box<PeekableInput>, bool) {
67-
let out = self.aux_file[self.aux_ptr].take().unwrap();
68-
let last = self.aux_ptr == 0;
69-
self.aux_ptr = self.aux_ptr.saturating_sub(1);
70-
(out, last)
50+
pub fn top_file(&self) -> &AuxFile {
51+
self.aux.last().unwrap()
7152
}
7253

73-
pub fn ln_at_ptr(&self) -> i32 {
74-
self.aux_ln_stack[self.aux_ptr]
54+
pub fn top_file_mut(&mut self) -> &mut AuxFile {
55+
self.aux.last_mut().unwrap()
7556
}
7657

77-
pub fn set_ln_at_ptr(&mut self, ln: i32) {
78-
self.aux_ln_stack[self.aux_ptr] = ln;
58+
pub fn ptr(&self) -> AuxNumber {
59+
self.aux.len()
7960
}
8061
}
8162

@@ -367,7 +348,6 @@ fn aux_input_command(
367348
return Ok(());
368349
}
369350

370-
aux.set_ptr(aux.ptr() + 1);
371351
if aux.ptr() == AUX_STACK_SIZE {
372352
print_a_token(buffers);
373353
write_logs(": ");
@@ -386,42 +366,41 @@ fn aux_input_command(
386366
if !aux_extension_ok {
387367
print_a_token(buffers);
388368
write_logs(" has a wrong extension");
389-
aux.set_ptr(aux.ptr() - 1);
390369
aux_err_print(buffers, aux, pool)?;
391370
return Ok(());
392371
}
393372

394373
let file = &buffers.buffer(BufTy::Base)
395374
[buffers.offset(BufTy::Base, 1)..buffers.offset(BufTy::Base, 2)];
396375
let res = pool.lookup_str_insert(hash, file, StrIlk::AuxFile)?;
397-
aux.set_at_ptr(hash.text(res.loc));
398376
if res.exists {
399377
write_logs("Already encountered file ");
400-
print_aux_name(aux, pool)?;
401-
aux.set_ptr(aux.ptr() - 1);
378+
print_aux_name(pool, res.loc)?;
402379
aux_err_print(buffers, aux, pool)?;
403380
return Ok(());
404381
}
405382

406-
let name = pool.get_str(aux.at_ptr());
383+
let name = pool.get_str(hash.text(res.loc));
407384
let fname = CString::new(name).unwrap();
408385
let file = PeekableInput::open(ctx, &fname, FileFormat::Tex);
409386
match file {
410387
Err(_) => {
411388
write_logs("I couldn't open auxiliary file ");
412-
print_aux_name(aux, pool)?;
413-
aux.set_ptr(aux.ptr() - 1);
389+
print_aux_name(pool, res.loc)?;
414390
aux_err_print(buffers, aux, pool)?;
415391
return Ok(());
416392
}
417393
Ok(file) => {
418-
aux.set_file_at_ptr(file);
394+
aux.push_file(AuxFile {
395+
name: hash.text(res.loc),
396+
file,
397+
line: 0,
398+
});
419399
}
420400
}
421401

422-
write_logs(&format!("A level-{} auxiliary file: ", aux.ptr()));
402+
write_logs(&format!("A level-{} auxiliary file: ", aux.ptr() - 1));
423403
log_pr_aux_name(aux, pool)?;
424-
aux.set_ln_at_ptr(0);
425404

426405
Ok(())
427406
}
@@ -484,49 +463,53 @@ pub(crate) fn get_aux_command_and_process(
484463
Ok(())
485464
}
486465

487-
pub(crate) fn pop_the_aux_stack(ctx: &mut Bibtex<'_, '_>, aux: &mut AuxData) -> bool {
466+
pub(crate) fn pop_the_aux_stack(ctx: &mut Bibtex<'_, '_>, aux: &mut AuxData) -> Option<StrNumber> {
488467
let (file, last) = aux.pop_file();
489-
file.close(ctx).unwrap();
490-
last
468+
file.file.close(ctx).unwrap();
469+
if last {
470+
Some(file.name)
471+
} else {
472+
None
473+
}
491474
}
492475

493476
pub(crate) fn last_check_for_aux_errors(
494477
ctx: &mut Bibtex<'_, '_>,
495-
aux: &AuxData,
496478
pool: &StringPool,
497479
cites: &mut CiteInfo,
498480
bibs: &BibData,
481+
last_aux: StrNumber,
499482
) -> Result<(), BibtexError> {
500483
cites.set_num_cites(cites.ptr());
501484
ctx.num_bib_files = bibs.ptr();
502485
if !ctx.citation_seen {
503486
aux_end1_err_print();
504487
write_logs("\\citation commands");
505-
aux_end2_err_print(aux, pool)?;
488+
aux_end2_err_print(pool, last_aux)?;
506489
} else if cites.num_cites() == 0 && !ctx.all_entries {
507490
aux_end1_err_print();
508491
write_logs("cite keys");
509-
aux_end2_err_print(aux, pool)?;
492+
aux_end2_err_print(pool, last_aux)?;
510493
}
511494

512495
if !ctx.bib_seen {
513496
aux_end1_err_print();
514497
write_logs("\\bibdata command");
515-
aux_end2_err_print(aux, pool)?;
498+
aux_end2_err_print(pool, last_aux)?;
516499
} else if ctx.num_bib_files == 0 {
517500
aux_end1_err_print();
518501
write_logs("database files");
519-
aux_end2_err_print(aux, pool)?;
502+
aux_end2_err_print(pool, last_aux)?;
520503
}
521504

522505
if !ctx.bst_seen {
523506
aux_end1_err_print();
524507
write_logs("\\bibstyle command");
525-
aux_end2_err_print(aux, pool)?;
508+
aux_end2_err_print(pool, last_aux)?;
526509
} else if ctx.bst_str == 0 {
527510
aux_end1_err_print();
528511
write_logs("style file");
529-
aux_end2_err_print(aux, pool)?;
512+
aux_end2_err_print(pool, last_aux)?;
530513
}
531514

532515
Ok(())

crates/engine_bibtex/src/lib.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use tectonic_io_base::{InputHandle, OutputHandle};
4141
use xbuf::SafelyZero;
4242

4343
use crate::{
44-
auxi::{get_aux_command_and_process, last_check_for_aux_errors, pop_the_aux_stack},
44+
auxi::{get_aux_command_and_process, last_check_for_aux_errors, pop_the_aux_stack, AuxFile},
4545
bst::get_bst_command_and_process,
4646
buffer::BufTy,
4747
exec::ExecCtx,
@@ -430,25 +430,25 @@ pub(crate) fn inner_bibtex_main(
430430

431431
if ctx.config.verbose {
432432
write_logs("The top-level auxiliary file: ");
433-
print_aux_name(globals.aux, globals.pool)?;
433+
print_aux_name(globals.pool, globals.aux.top_file().name)?;
434434
} else {
435435
write_log_file("The top-level auxiliary file: ");
436436
log_pr_aux_name(globals.aux, globals.pool)?;
437437
}
438438

439-
loop {
440-
globals.aux.set_ln_at_ptr(globals.aux.ln_at_ptr() + 1);
439+
let last_aux = loop {
440+
globals.aux.top_file_mut().line += 1;
441441

442-
if !input_ln(Some(globals.aux.file_at_ptr()), globals.buffers) {
443-
if pop_the_aux_stack(ctx, globals.aux) {
444-
break;
442+
if !input_ln(Some(&mut globals.aux.top_file_mut().file), globals.buffers) {
443+
if let Some(last) = pop_the_aux_stack(ctx, globals.aux) {
444+
break last;
445445
}
446446
} else {
447447
get_aux_command_and_process(ctx, globals)?;
448448
}
449-
}
449+
};
450450

451-
last_check_for_aux_errors(ctx, globals.aux, globals.pool, globals.cites, globals.bibs)?;
451+
last_check_for_aux_errors(ctx, globals.pool, globals.cites, globals.bibs, last_aux)?;
452452

453453
if ctx.bst_str == 0 {
454454
return Err(BibtexError::NoBst);
@@ -491,16 +491,13 @@ pub(crate) fn get_the_top_level_aux_file_name(
491491
path[range].copy_from_slice(extension);
492492
};
493493

494-
aux.set_ptr(0);
495-
496494
let aux_file = match PeekableInput::open(ctx, aux_file_name, FileFormat::Tex) {
497495
Ok(file) => file,
498496
Err(_) => {
499497
sam_wrong_file_name_print(aux_file_name);
500498
return Ok(1);
501499
}
502500
};
503-
aux.set_file_at_ptr(aux_file);
504501

505502
set_extension(&mut path, b".blg");
506503
let log_file = CStr::from_bytes_with_nul(&path).unwrap();
@@ -523,7 +520,12 @@ pub(crate) fn get_the_top_level_aux_file_name(
523520
Ok(res) => res,
524521
Err(_) => return Err(BibtexError::Fatal),
525522
};
526-
aux.set_at_ptr(hash.text(lookup.loc));
523+
524+
aux.push_file(AuxFile {
525+
name: hash.text(lookup.loc),
526+
file: aux_file,
527+
line: 0,
528+
});
527529

528530
if lookup.exists {
529531
write_logs("Already encountered auxiliary file");

crates/engine_bibtex/src/log.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -225,15 +225,15 @@ pub fn sam_wrong_file_name_print(file: &CStr) {
225225
})
226226
}
227227

228-
pub(crate) fn print_aux_name(aux: &AuxData, pool: &StringPool) -> Result<(), BibtexError> {
229-
print_a_pool_str(aux.at_ptr(), pool)?;
228+
pub(crate) fn print_aux_name(pool: &StringPool, name: StrNumber) -> Result<(), BibtexError> {
229+
print_a_pool_str(name, pool)?;
230230
write_logs("\n");
231231
Ok(())
232232
}
233233

234234
pub(crate) fn log_pr_aux_name(aux: &AuxData, pool: &StringPool) -> Result<(), BibtexError> {
235235
with_log(|log| {
236-
out_pool_str(pool, log, aux.at_ptr())?;
236+
out_pool_str(pool, log, aux.top_file().name)?;
237237
writeln!(log).unwrap();
238238
Ok(())
239239
})
@@ -244,8 +244,8 @@ pub(crate) fn aux_err_print(
244244
aux: &AuxData,
245245
pool: &StringPool,
246246
) -> Result<(), BibtexError> {
247-
write_logs(&format!("---line {} of file ", aux.ln_at_ptr()));
248-
print_aux_name(aux, pool)?;
247+
write_logs(&format!("---line {} of file ", aux.top_file().line));
248+
print_aux_name(pool, aux.top_file().name)?;
249249
print_bad_input_line(buffers);
250250
print_skipping_whatever_remains();
251251
write_logs("command\n");
@@ -257,7 +257,7 @@ pub(crate) enum AuxTy {
257257
Style,
258258
}
259259

260-
pub fn aux_err_illegal_another_print(cmd: AuxTy) -> Result<(), BibtexError> {
260+
pub(crate) fn aux_err_illegal_another_print(cmd: AuxTy) -> Result<(), BibtexError> {
261261
write_logs("Illegal, another \\bib");
262262
match cmd {
263263
AuxTy::Data => write_logs("data"),
@@ -283,9 +283,9 @@ pub fn aux_end1_err_print() {
283283
write_logs("I found no ");
284284
}
285285

286-
pub(crate) fn aux_end2_err_print(aux: &AuxData, pool: &StringPool) -> Result<(), BibtexError> {
286+
pub(crate) fn aux_end2_err_print(pool: &StringPool, name: StrNumber) -> Result<(), BibtexError> {
287287
write_logs("---while reading file ");
288-
print_aux_name(aux, pool)?;
288+
print_aux_name(pool, name)?;
289289
mark_error();
290290
Ok(())
291291
}

crates/engine_bibtex/src/peekable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ pub(crate) unsafe fn peekable_close(
126126
}
127127
}
128128

129-
pub fn tectonic_eof(peekable: Option<&mut PeekableInput>) -> bool {
129+
pub(crate) fn tectonic_eof(peekable: Option<&mut PeekableInput>) -> bool {
130130
// Check for EOF following Pascal semantics.
131131
match peekable {
132132
Some(peek) => peek.eof(),

0 commit comments

Comments
 (0)