Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions crates/engine_bibtex/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub(crate) struct GlobalBuffer {
buffer: Buffer<ASCIICode, 2>,
sv_buffer: Buffer<ASCIICode, 0>,
ex_buf: Buffer<ASCIICode, 1>,
out_buf: Buffer<ASCIICode, 0>,
out_buf: Vec<ASCIICode>,
name_sep_char: Buffer<ASCIICode, 0>,
name_tok: Vec<BufPointer>,
}
Expand All @@ -44,7 +44,7 @@ impl GlobalBuffer {
buffer: Buffer::new(buf_len),
sv_buffer: Buffer::new(buf_len),
ex_buf: Buffer::new(buf_len),
out_buf: Buffer::new(buf_len),
out_buf: Vec::new(),
name_sep_char: Buffer::new(buf_len),
name_tok: vec![0; buf_len + 1],
}
Expand All @@ -59,7 +59,6 @@ impl GlobalBuffer {
BufTy::Base => self.buffer.ptr.as_mut_ptr(),
BufTy::Sv => self.sv_buffer.ptr.as_mut_ptr(),
BufTy::Ex => self.ex_buf.ptr.as_mut_ptr(),
BufTy::Out => self.out_buf.ptr.as_mut_ptr(),
BufTy::NameSep => self.name_sep_char.ptr.as_mut_ptr(),
}
}
Expand All @@ -69,7 +68,6 @@ impl GlobalBuffer {
BufTy::Base => &self.buffer.ptr,
BufTy::Sv => &self.sv_buffer.ptr,
BufTy::Ex => &self.ex_buf.ptr,
BufTy::Out => &self.out_buf.ptr,
BufTy::NameSep => &self.name_sep_char.ptr,
}
}
Expand All @@ -79,11 +77,14 @@ impl GlobalBuffer {
BufTy::Base => &mut self.buffer.ptr,
BufTy::Sv => &mut self.sv_buffer.ptr,
BufTy::Ex => &mut self.ex_buf.ptr,
BufTy::Out => &mut self.out_buf.ptr,
BufTy::NameSep => &mut self.name_sep_char.ptr,
}
}

pub fn out(&mut self) -> &mut Vec<u8> {
&mut self.out_buf
}

fn copy_within_same(&mut self, ty: BufTy, from: usize, to: usize, len: usize) {
let buf = self.buffer_mut(ty);
buf.copy_within(from..from + len, to);
Expand Down Expand Up @@ -130,7 +131,7 @@ impl GlobalBuffer {
match ty {
BufTy::Base => self.buffer.offset[offset - 1] = val,
BufTy::Ex => self.ex_buf.offset[offset - 1] = val,
BufTy::Sv | BufTy::Out | BufTy::NameSep => {
BufTy::Sv | BufTy::NameSep => {
unreachable!("Buffer {:?} has no offsets", ty)
}
}
Expand All @@ -148,7 +149,7 @@ impl GlobalBuffer {
match ty {
BufTy::Base => self.buffer.offset[offset - 1],
BufTy::Ex => self.ex_buf.offset[offset - 1],
BufTy::Sv | BufTy::Out | BufTy::NameSep => {
BufTy::Sv | BufTy::NameSep => {
unreachable!("Buffer {:?} has no offsets", ty)
}
}
Expand All @@ -159,7 +160,6 @@ impl GlobalBuffer {
BufTy::Base => self.buffer.init,
BufTy::Sv => self.sv_buffer.init,
BufTy::Ex => self.ex_buf.init,
BufTy::Out => self.out_buf.init,
BufTy::NameSep => self.name_sep_char.init,
}
}
Expand All @@ -169,7 +169,6 @@ impl GlobalBuffer {
BufTy::Base => self.buffer.init = val,
BufTy::Sv => self.sv_buffer.init = val,
BufTy::Ex => self.ex_buf.init = val,
BufTy::Out => self.out_buf.init = val,
BufTy::NameSep => self.name_sep_char.init = val,
}
}
Expand All @@ -179,7 +178,6 @@ impl GlobalBuffer {
self.buffer.grow(BUF_SIZE);
self.sv_buffer.grow(BUF_SIZE);
self.ex_buf.grow(BUF_SIZE);
self.out_buf.grow(BUF_SIZE);
self.name_sep_char.grow(BUF_SIZE);
self.name_tok.resize(self.name_tok.len() + BUF_SIZE, 0);
self.buf_len = new_len;
Expand All @@ -191,6 +189,5 @@ pub(crate) enum BufTy {
Base,
Sv,
Ex,
Out,
NameSep,
}
106 changes: 47 additions & 59 deletions crates/engine_bibtex/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ pub(crate) fn figure_out_the_formatted_name(
let str = pool.get_str(s1);
let mut idx = 0;

buffers.set_init(BufTy::Ex, 0);
add_buf_pool(pool, buffers, s1);
buffers.set_offset(BufTy::Ex, 1, 0);

while idx < str.len() {
Expand Down Expand Up @@ -651,31 +653,25 @@ pub(crate) fn add_out_pool(
str: StrNumber,
) {
let str = pool.get_str(str);
let out = buffers.out();

while buffers.init(BufTy::Out) + str.len() > buffers.len() {
buffers.grow_all();
}

let out_offset = buffers.init(BufTy::Out);
buffers.copy_from(BufTy::Out, out_offset, str);
buffers.set_init(BufTy::Out, out_offset + str.len());
out.extend(str);

let mut unbreakable_tail = false;
while buffers.init(BufTy::Out) > MAX_PRINT_LINE && !unbreakable_tail {
let end_ptr = buffers.init(BufTy::Out);
while out.len() > MAX_PRINT_LINE && !unbreakable_tail {
let end_ptr = out.len();
let mut out_offset = MAX_PRINT_LINE;
let mut break_pt_found = false;

while LexClass::of(buffers.at(BufTy::Out, out_offset)) != LexClass::Whitespace
&& out_offset >= MIN_PRINT_LINE
while LexClass::of(out[out_offset]) != LexClass::Whitespace && out_offset >= MIN_PRINT_LINE
{
out_offset -= 1;
}

if out_offset == MIN_PRINT_LINE - 1 {
out_offset = MAX_PRINT_LINE + 1;
while out_offset < end_ptr {
if LexClass::of(buffers.at(BufTy::Out, out_offset)) != LexClass::Whitespace {
if LexClass::of(out[out_offset]) != LexClass::Whitespace {
out_offset += 1;
} else {
break;
Expand All @@ -687,8 +683,7 @@ pub(crate) fn add_out_pool(
} else {
break_pt_found = true;
while out_offset + 1 < end_ptr {
if LexClass::of(buffers.at(BufTy::Out, out_offset + 1)) == LexClass::Whitespace
{
if LexClass::of(out[out_offset + 1]) == LexClass::Whitespace {
out_offset += 1;
} else {
break;
Expand All @@ -699,15 +694,15 @@ pub(crate) fn add_out_pool(
break_pt_found = true;
}

// Write `out` up to break, then prepend two spaces to the rest and shift it left
if break_pt_found {
buffers.set_init(BufTy::Out, out_offset);
let break_ptr = buffers.init(BufTy::Out) + 1;
output_bbl_line(ctx, buffers);
buffers.set_at(BufTy::Out, 0, b' ');
buffers.set_at(BufTy::Out, 1, b' ');
let break_ptr = out_offset + 1;
output_bbl_line(ctx, &out[..out_offset]);
out[0] = b' ';
out[1] = b' ';
let len = end_ptr - break_ptr;
buffers.copy_within(BufTy::Out, BufTy::Out, break_ptr, 2, len);
buffers.set_init(BufTy::Out, len + 2);
out.copy_within(break_ptr..end_ptr, 2);
out.truncate(len + 2);
}
}
}
Expand Down Expand Up @@ -1421,19 +1416,18 @@ fn interp_format_name(

let mut brace_level = 0;
let mut xptr = 0;
buffers.set_init(BufTy::Ex, 0);
add_buf_pool(pool, buffers, s3);
buffers.set_offset(BufTy::Ex, 1, 0);
let str = pool.get_str(s3);
let mut str_idx = 0;

let mut num_names = 0;
while num_names < i2 && buffers.offset(BufTy::Ex, 1) < buffers.init(BufTy::Ex) {
while num_names < i2 && str_idx < str.len() {
num_names += 1;
xptr = buffers.offset(BufTy::Ex, 1);
name_scan_for_and(ctx, pool, buffers, cites, s3, &mut brace_level)?;
xptr = str_idx;
name_scan_for_and(ctx, pool, cites, str, &mut str_idx, s3, &mut brace_level)?;
}

if buffers.offset(BufTy::Ex, 1) < buffers.init(BufTy::Ex) {
buffers.set_offset(BufTy::Ex, 1, buffers.offset(BufTy::Ex, 1) - 4);
if str_idx < str.len() {
str_idx -= 4;
}

if num_names < i2 {
Expand All @@ -1447,18 +1441,18 @@ fn interp_format_name(
bst_ex_warn_print(ctx, pool, cites)?;
}

while buffers.offset(BufTy::Ex, 1) > xptr {
match LexClass::of(buffers.at(BufTy::Ex, buffers.offset(BufTy::Ex, 1) - 1)) {
while str_idx > xptr {
match LexClass::of(str[str_idx - 1]) {
LexClass::Whitespace | LexClass::Sep => {
buffers.set_offset(BufTy::Ex, 1, buffers.offset(BufTy::Ex, 1) - 1);
str_idx -= 1;
}
_ => {
if buffers.at(BufTy::Ex, buffers.offset(BufTy::Ex, 1) - 1) == b',' {
if str[str_idx - 1] == b',' {
ctx.write_logs(&format!("Name {i2} in \""));
print_a_pool_str(ctx, s3, pool)?;
ctx.write_logs("\" has a comma at the end");
bst_ex_warn_print(ctx, pool, cites)?;
buffers.set_offset(BufTy::Ex, 1, buffers.offset(BufTy::Ex, 1) - 1);
str_idx -= 1;
} else {
break;
}
Expand All @@ -1477,8 +1471,8 @@ fn interp_format_name(
let mut name_ptr = 0;
let mut token_starting = true;

while xptr < buffers.offset(BufTy::Ex, 1) {
match buffers.at(BufTy::Ex, xptr) {
while xptr < str_idx {
match str[xptr] {
b',' => {
match commas {
Commas::None => {
Expand All @@ -1505,16 +1499,16 @@ fn interp_format_name(
buffers.set_name_tok(num_tokens, name_ptr);
num_tokens += 1;
}
buffers.set_at(BufTy::Sv, name_ptr, buffers.at(BufTy::Ex, xptr));
buffers.set_at(BufTy::Sv, name_ptr, str[xptr]);
name_ptr += 1;
xptr += 1;
while brace_level > 0 && xptr < buffers.offset(BufTy::Ex, 1) {
match buffers.at(BufTy::Ex, xptr) {
while brace_level > 0 && xptr < str_idx {
match str[xptr] {
b'{' => brace_level += 1,
b'}' => brace_level -= 1,
_ => (),
}
buffers.set_at(BufTy::Sv, name_ptr, buffers.at(BufTy::Ex, xptr));
buffers.set_at(BufTy::Sv, name_ptr, str[xptr]);
name_ptr += 1;
xptr += 1;
}
Expand All @@ -1533,7 +1527,7 @@ fn interp_format_name(
xptr += 1;
token_starting = false;
}
_ => match LexClass::of(buffers.at(BufTy::Ex, xptr)) {
_ => match LexClass::of(str[xptr]) {
LexClass::Whitespace => {
if !token_starting {
buffers.set_at(BufTy::NameSep, num_tokens, b' ');
Expand All @@ -1543,7 +1537,7 @@ fn interp_format_name(
}
LexClass::Sep => {
if !token_starting {
buffers.set_at(BufTy::NameSep, num_tokens, buffers.at(BufTy::Ex, xptr));
buffers.set_at(BufTy::NameSep, num_tokens, str[xptr]);
}
xptr += 1;
token_starting = true;
Expand All @@ -1553,7 +1547,7 @@ fn interp_format_name(
buffers.set_name_tok(num_tokens, name_ptr);
num_tokens += 1;
}
buffers.set_at(BufTy::Sv, name_ptr, buffers.at(BufTy::Ex, xptr));
buffers.set_at(BufTy::Sv, name_ptr, str[xptr]);
name_ptr += 1;
xptr += 1;
token_starting = false;
Expand Down Expand Up @@ -1645,8 +1639,6 @@ fn interp_format_name(
}
}

buffers.set_init(BufTy::Ex, 0);
add_buf_pool(pool, buffers, s1);
figure_out_the_formatted_name(
ctx,
buffers,
Expand Down Expand Up @@ -1751,20 +1743,18 @@ fn interp_missing(
fn interp_num_names(
ctx: &mut ExecCtx<'_, '_, '_>,
pool: &mut StringPool,
buffers: &mut GlobalBuffer,
hash: &HashData,
cites: &CiteInfo,
) -> Result<(), BibtexError> {
let pop1 = ctx.pop_stack(pool, cites)?;
match pop1 {
ExecVal::String(s1) => {
buffers.set_init(BufTy::Ex, 0);
add_buf_pool(pool, buffers, s1);
buffers.set_offset(BufTy::Ex, 1, 0);
let str = pool.get_str(s1);
let mut idx = 0;
let mut num_names = 0;
while buffers.offset(BufTy::Ex, 1) < buffers.init(BufTy::Ex) {
while idx < str.len() {
let mut brace_level = 0;
name_scan_for_and(ctx, pool, buffers, cites, s1, &mut brace_level)?;
name_scan_for_and(ctx, pool, cites, str, &mut idx, s1, &mut brace_level)?;
num_names += 1;
}
ctx.push_stack(ExecVal::Integer(num_names))
Expand Down Expand Up @@ -2388,16 +2378,14 @@ pub(crate) fn execute_fn(
}
BstBuiltin::Missing => interp_missing(ctx, globals.pool, globals.hash, globals.cites),
BstBuiltin::Newline => {
output_bbl_line(ctx, globals.buffers);
let to_print = globals.buffers.out();
output_bbl_line(ctx, to_print);
to_print.clear();
Ok(())
}
BstBuiltin::NumNames => interp_num_names(
ctx,
globals.pool,
globals.buffers,
globals.hash,
globals.cites,
),
BstBuiltin::NumNames => {
interp_num_names(ctx, globals.pool, globals.hash, globals.cites)
}
BstBuiltin::Pop => ctx.pop_stack(globals.pool, globals.cites).map(|_| ()),
BstBuiltin::Preamble => interp_preamble(ctx, globals.pool, globals.bibs),
BstBuiltin::Purify => interp_purify(ctx, globals.pool, globals.hash, globals.cites),
Expand Down
23 changes: 8 additions & 15 deletions crates/engine_bibtex/src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,29 +588,22 @@ pub(crate) fn nonexistent_cross_reference_error(
Ok(())
}

pub(crate) fn output_bbl_line(ctx: &mut Bibtex<'_, '_>, buffers: &mut GlobalBuffer) {
if buffers.init(BufTy::Out) != 0 {
let mut init = buffers.init(BufTy::Out);
while init > 0 {
if LexClass::of(buffers.at(BufTy::Out, init - 1)) == LexClass::Whitespace {
init -= 1;
} else {
break;
}
}
buffers.set_init(BufTy::Out, init);
if init == 0 {
pub(crate) fn output_bbl_line(ctx: &mut Bibtex<'_, '_>, line: &[u8]) {
if !line.is_empty() {
let pos = line
.iter()
.rposition(|b| LexClass::of(*b) != LexClass::Whitespace)
.unwrap_or(0);
if pos == 0 {
return;
}
let slice = &buffers.buffer(BufTy::Out)[..init];
ctx.engine
.get_output(ctx.bbl_file.unwrap())
.write_all(slice)
.write_all(&line[..pos + 1])
.unwrap();
}
writeln!(ctx.engine.get_output(ctx.bbl_file.unwrap())).unwrap();
ctx.bbl_line_num += 1;
buffers.set_init(BufTy::Out, 0);
}

pub(crate) fn skip_token_print(
Expand Down
Loading
Loading