From: Ben Pfaff Date: Wed, 1 Jan 2025 19:57:55 +0000 (-0800) Subject: pivot templates X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9a239c2581e12b2c07ab16b545c9a580f923d1ed;p=pspp pivot templates --- diff --git a/rust/pspp/src/output/pivot/mod.rs b/rust/pspp/src/output/pivot/mod.rs index 772a96d480..c3af6c1822 100644 --- a/rust/pspp/src/output/pivot/mod.rs +++ b/rust/pspp/src/output/pivot/mod.rs @@ -1125,21 +1125,73 @@ impl<'a, 'b> DisplayValue<'a, 'b> { } b'^' => { let (index, rest) = consume_int(iter.as_slice()); - if (1..=args.len()).contains(&index) && !args[index - 1].is_empty() { - write!(f, "{}", args[index - 1][0].display(&self.table))?; - } iter = rest.iter(); + let Some(arg) = args.get(index.wrapping_sub(1)) else { + continue; + }; + if let Some(arg) = arg.get(0) { + write!(f, "{}", arg.display(&self.table))?; + } } b'[' => { let (a, rest) = extract_inner_template(iter.as_slice()); let (b, rest) = extract_inner_template(rest); let rest = rest.strip_prefix(b"]").unwrap_or(rest); + let (index, rest) = consume_int(rest); + iter = rest.iter(); + + let Some(mut args) = args.get(index.wrapping_sub(1)).map(|vec| vec.as_slice()) + else { + continue; + }; + let (mut template, mut escape) = + if !a.is_empty() { (a, b'%') } else { (b, b'^') }; + while !args.is_empty() { + let n_consumed = self.inner_template(f, template, escape, args)?; + if n_consumed == 0 { + break; + } + args = &args[n_consumed..]; + + template = b; + escape = b'^'; + } + } + c => write!(f, "{c}")?, + } + } + Ok(()) + } + + fn inner_template<'c>( + &self, + f: &mut std::fmt::Formatter<'_>, + template: &[u8], + escape: u8, + args: &[Value], + ) -> Result { + let mut iter = template.iter(); + let mut args_consumed = 0; + while let Some(c) = iter.next() { + match c { + b'\\' => { + let c = *iter.next().unwrap_or(&b'\\') as char; + let c = if c == 'n' { '\n' } else { c }; + write!(f, "{c}")?; + } + c if *c == escape => { + let (index, rest) = consume_int(iter.as_slice()); iter = rest.iter(); + let Some(arg) = args.get(index.wrapping_sub(1)) else { + continue; + }; + args_consumed = args_consumed.max(index); + write!(f, "{}", arg.display(&self.table))?; } c => write!(f, "{c}")?, } } - todo!() + Ok(args_consumed) } } @@ -1155,7 +1207,12 @@ fn consume_int(input: &[u8]) -> (usize, &[u8]) { } fn extract_inner_template(input: &[u8]) -> (&[u8], &[u8]) { - todo!() + for (index, c) in input.iter().copied().enumerate() { + if c == b':' && (index == 0 || input[index-1] != b'\\') { + return input.split_at(index); + } + } + (input, &[]) } fn interpret_show(