1
0
Fork 0
forked from wry/wry

build: simplify string handling

This commit is contained in:
Julian Orth 2024-07-24 01:37:24 +02:00
parent 09145480e1
commit 21916017c1
3 changed files with 53 additions and 63 deletions

View file

@ -1,6 +1,6 @@
use {
anyhow::{bail, Context, Result},
bstr::{BStr, BString, ByteSlice},
bstr::{BString, ByteSlice},
};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
@ -54,14 +54,14 @@ pub struct Token<'a> {
#[derive(Debug, Eq, PartialEq)]
pub enum TokenKind<'a> {
Ident(&'a BStr),
Ident(&'a str),
Num(u32),
Tree {
delim: TreeDelim,
body: Vec<Token<'a>>,
},
Symbol(Symbol),
String(BString),
String(String),
}
impl TokenKind<'_> {
@ -148,7 +148,7 @@ impl<'a> Tokenizer<'a> {
{
c.pos += 1;
}
TokenKind::Ident(c.s[b_pos..c.pos].as_bstr())
TokenKind::Ident(c.s[b_pos..c.pos].as_bstr().to_str()?)
}
b'0'..=b'9' => {
c.pos -= 1;
@ -201,7 +201,7 @@ impl<'a> Tokenizer<'a> {
bail!("Unterminated string in line {}", self.line);
}
c.pos += 1;
TokenKind::String(res.into())
TokenKind::String(BString::from(res).to_string())
}
_ => bail!("Unexpected byte {:?} in line {}", b as char, self.line),
};

View file

@ -35,26 +35,26 @@ enum Type {
#[derive(Debug)]
struct Field {
name: BString,
name: String,
ty: Type,
}
#[derive(Debug)]
struct Function {
name: BString,
name: String,
in_fields: Vec<Field>,
out_fields: Vec<Field>,
}
#[derive(Debug)]
struct Property {
name: BString,
name: String,
ty: Type,
}
#[derive(Debug)]
struct Signal {
name: BString,
name: String,
fields: Vec<Field>,
}
@ -181,7 +181,7 @@ impl<'a> Parser<'a> {
res.with_context(|| format!("While parsing field starting at line {}", line))
}
fn expect_ident(&mut self) -> Result<(u32, &'a BStr)> {
fn expect_ident(&mut self) -> Result<(u32, &'a str)> {
self.not_eof()?;
let token = &self.tokens[self.pos];
self.pos += 1;
@ -468,7 +468,7 @@ fn write_type2<W: Write>(f: &mut W, lt: &str, ty: &Type) -> Result<()> {
fn write_message<W: Write>(
f: &mut W,
el: &Element,
msg_name: &BStr,
msg_name: &str,
name: &str,
indent: &str,
fields: &[Field],
@ -614,7 +614,7 @@ fn write_signal<W: Write>(f: &mut W, element: &Element, sig: &Signal, indent: &s
write_message(
f,
element,
sig.name.as_bstr(),
&sig.name,
&name,
indent,
&sig.fields,
@ -640,7 +640,7 @@ fn write_function<W: Write>(
write_message(
f,
element,
fun.name.as_bstr(),
&fun.name,
&in_name,
indent,
&fun.in_fields,
@ -650,7 +650,7 @@ fn write_function<W: Write>(
write_message(
f,
element,
fun.name.as_bstr(),
&fun.name,
&out_name,
indent,
&fun.out_fields,

View file

@ -4,7 +4,7 @@ use {
tokens::{tokenize, Symbol, Token, TokenKind, TreeDelim},
},
anyhow::{bail, Context, Result},
bstr::{BStr, BString, ByteSlice},
bstr::ByteSlice,
std::{cell::Cell, collections::HashMap, io::Write, mem, os::unix::ffi::OsStrExt, rc::Rc},
};
@ -70,7 +70,7 @@ impl<'a> Parser<'a> {
Ok(())
}
fn parse_extension(&mut self, line: u32) -> Result<BString> {
fn parse_extension(&mut self, line: u32) -> Result<String> {
let res: Result<_> = (|| {
let (_, name) = self.expect_string()?;
Ok(name.to_owned())
@ -208,7 +208,7 @@ impl<'a> Parser<'a> {
res.with_context(|| format!("While parsing bitmask starting at line {}", line))
}
fn parse_struct_body(&mut self, name: &BStr) -> Result<Struct> {
fn parse_struct_body(&mut self, name: &str) -> Result<Struct> {
let mut fields = vec![];
while !self.eof() {
fields.push(self.parse_field()?);
@ -272,7 +272,7 @@ impl<'a> Parser<'a> {
}
}
fn expect_ident(&mut self) -> Result<(u32, &'a BStr)> {
fn expect_ident(&mut self) -> Result<(u32, &'a str)> {
self.not_eof()?;
let token = &self.tokens[self.pos];
self.pos += 1;
@ -286,7 +286,7 @@ impl<'a> Parser<'a> {
}
}
fn expect_string(&mut self) -> Result<(u32, &'a BString)> {
fn expect_string(&mut self) -> Result<(u32, &'a String)> {
self.not_eof()?;
let token = &self.tokens[self.pos];
self.pos += 1;
@ -459,7 +459,7 @@ impl<'a> Parser<'a> {
Ok(name)
}
fn parse_field_name_expr(&mut self) -> Result<BString> {
fn parse_field_name_expr(&mut self) -> Result<String> {
let (_, tree) = self.expect_tree(TreeDelim::Paren)?;
let mut parser = Parser::new(tree);
let (_, name) = parser.expect_ident()?;
@ -560,7 +560,7 @@ fn needs_lifetime(ty: &Type, protocols: &Protocols) -> Result<bool> {
Type::U64 => false,
Type::Fd => false,
Type::List(_, _) => true,
Type::Named(n) => named_needs_lt(n.as_bstr(), protocols)?,
Type::Named(n) => named_needs_lt(n, protocols)?,
Type::String(_) => true,
Type::Bitmask(_, _) => false,
Type::Enum(n, _) => needs_lifetime(n, protocols)?,
@ -568,7 +568,7 @@ fn needs_lifetime(ty: &Type, protocols: &Protocols) -> Result<bool> {
Ok(res)
}
fn named_needs_lt(name: &BStr, protocols: &Protocols) -> Result<bool> {
fn named_needs_lt(name: &str, protocols: &Protocols) -> Result<bool> {
let s = match protocols.types_by_name.get(name) {
Some(s) => s,
_ => bail!("Struct {} referenced but not defined", name),
@ -640,14 +640,14 @@ fn type_has_fds(ty: &Type, protocols: &Protocols) -> Result<bool> {
Type::String(_) => false,
Type::Fd => true,
Type::List(ty, _) => return type_has_fds(ty, protocols),
Type::Named(n) => return named_has_fds(n.as_bstr(), protocols),
Type::Named(n) => return named_has_fds(n, protocols),
Type::Bitmask(_, _) => false,
Type::Enum(n, _) => return type_has_fds(n, protocols),
};
Ok(res)
}
fn named_has_fds(s: &BStr, protocols: &Protocols) -> Result<bool> {
fn named_has_fds(s: &str, protocols: &Protocols) -> Result<bool> {
let s = match protocols.types_by_name.get(s) {
Some(s) => s,
_ => bail!("Struct {} referenced but not defined", s),
@ -698,19 +698,19 @@ enum Type {
Fd,
String(Expr),
List(Box<Type>, Option<Expr>),
Bitmask(BString, Expr),
Bitmask(String, Expr),
Enum(Box<Type>, Expr),
Named(BString),
Named(String),
}
#[derive(Debug, Clone)]
enum Expr {
It,
Field(BString),
Len(BString),
Field(String),
Len(String),
Literal(u32),
Bitmask(BString),
Variant(BString),
Bitmask(String),
Variant(String),
Sum(Box<Expr>),
Mul(Box<Expr>, Box<Expr>),
Map(Box<Expr>, Box<Expr>),
@ -722,7 +722,7 @@ enum Expr {
#[derive(Debug, Clone)]
struct RealField {
name: BString,
name: String,
ty: Type,
value: Option<Expr>,
}
@ -738,7 +738,7 @@ enum Field {
#[derive(Debug)]
struct Struct {
name: BString,
name: String,
fields: Vec<Field>,
needs_lt: Cell<Option<bool>>,
has_fds: Cell<Option<bool>>,
@ -746,27 +746,27 @@ struct Struct {
#[derive(Debug)]
struct BitmaskVariant {
name: BString,
name: String,
ty: Type,
bit: u32,
}
#[derive(Debug)]
struct Bitmask {
name: BString,
name: String,
variants: Vec<BitmaskVariant>,
}
#[derive(Debug)]
struct EnumVariant {
name: BString,
name: String,
ty: Type,
value: u32,
}
#[derive(Debug)]
struct Enum {
name: BString,
name: String,
variants: Vec<EnumVariant>,
}
@ -780,9 +780,9 @@ struct Event {
#[derive(Debug)]
struct EventCopy {
name: BString,
name: String,
opcode: u32,
original: BString,
original: String,
}
#[derive(Debug)]
@ -795,7 +795,7 @@ struct Request {
#[derive(Debug)]
struct Protocol {
extension: Option<BString>,
extension: Option<String>,
structs: Vec<Struct>,
requests: Vec<Request>,
bitmasks: Vec<Bitmask>,
@ -806,8 +806,8 @@ struct Protocol {
#[derive(Debug)]
struct Extension {
name: BString,
ident: BString,
name: String,
ident: String,
}
#[derive(Debug)]
@ -824,8 +824,8 @@ struct Protocols {
bitmasks: Vec<Rc<Bitmask>>,
enums: Vec<Rc<Enum>>,
requests: Vec<Request>,
types_by_name: HashMap<BString, NamedType>,
events_by_name: HashMap<BString, Rc<Event>>,
types_by_name: HashMap<String, NamedType>,
events_by_name: HashMap<String, Rc<Event>>,
events: Vec<Rc<Event>>,
eventcopies: Vec<EventCopy>,
}
@ -869,7 +869,7 @@ fn write_type<F: Write>(f: &mut F, ty: &Type, protocols: &Protocols) -> Result<(
return Ok(());
}
Type::Named(n) => {
let lt = if named_needs_lt(n.as_bstr(), protocols)? {
let lt = if named_needs_lt(n, protocols)? {
"<'a>"
} else {
""
@ -944,7 +944,7 @@ enum StructUsecase<'a> {
fn format_xevent<F: Write>(
f: &mut F,
name: &BStr,
name: &str,
s: &Struct,
opcode: u32,
protocols: &Protocols,
@ -965,18 +965,11 @@ fn format_xevent<F: Write>(
fn format_event<F: Write>(f: &mut F, s: &Event, protocols: &Protocols) -> Result<()> {
format_struct(f, &s.data, protocols, &StructUsecase::Event { xge: s.xge })?;
format_xevent(
f,
s.data.name.as_bstr(),
&s.data,
s.opcode,
protocols,
s.ext_idx,
)
format_xevent(f, &s.data.name, &s.data, s.opcode, protocols, s.ext_idx)
}
fn format_eventcopy<F: Write>(f: &mut F, s: &EventCopy, protocols: &Protocols) -> Result<()> {
let original = match protocols.events_by_name.get(s.original.as_bstr()) {
let original = match protocols.events_by_name.get(&s.original) {
Some(o) => o,
_ => bail!("Event {} referenced but not defined", s.original),
};
@ -992,7 +985,7 @@ fn format_eventcopy<F: Write>(f: &mut F, s: &EventCopy, protocols: &Protocols) -
)?;
format_xevent(
f,
s.name.as_bstr(),
&s.name,
&original.data,
s.opcode,
protocols,
@ -1591,16 +1584,13 @@ pub fn main() -> Result<()> {
}
protocols.eventcopies.extend(protocol.eventcopies);
if let Some(ext) = protocol.extension {
let mut ident = vec![];
for c in ext.as_bytes() {
if matches!(*c, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9') {
ident.push(*c);
let mut ident = String::new();
for c in ext.chars() {
if matches!(c, 'a'..='z' | 'A'..='Z' | '0'..='9') {
ident.push(c);
}
}
protocols.extensions.push(Extension {
name: ext,
ident: ident.into(),
});
protocols.extensions.push(Extension { name: ext, ident });
}
}