build: simplify string handling
This commit is contained in:
parent
09145480e1
commit
21916017c1
3 changed files with 53 additions and 63 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
anyhow::{bail, Context, Result},
|
anyhow::{bail, Context, Result},
|
||||||
bstr::{BStr, BString, ByteSlice},
|
bstr::{BString, ByteSlice},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
|
|
@ -54,14 +54,14 @@ pub struct Token<'a> {
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub enum TokenKind<'a> {
|
pub enum TokenKind<'a> {
|
||||||
Ident(&'a BStr),
|
Ident(&'a str),
|
||||||
Num(u32),
|
Num(u32),
|
||||||
Tree {
|
Tree {
|
||||||
delim: TreeDelim,
|
delim: TreeDelim,
|
||||||
body: Vec<Token<'a>>,
|
body: Vec<Token<'a>>,
|
||||||
},
|
},
|
||||||
Symbol(Symbol),
|
Symbol(Symbol),
|
||||||
String(BString),
|
String(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TokenKind<'_> {
|
impl TokenKind<'_> {
|
||||||
|
|
@ -148,7 +148,7 @@ impl<'a> Tokenizer<'a> {
|
||||||
{
|
{
|
||||||
c.pos += 1;
|
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' => {
|
b'0'..=b'9' => {
|
||||||
c.pos -= 1;
|
c.pos -= 1;
|
||||||
|
|
@ -201,7 +201,7 @@ impl<'a> Tokenizer<'a> {
|
||||||
bail!("Unterminated string in line {}", self.line);
|
bail!("Unterminated string in line {}", self.line);
|
||||||
}
|
}
|
||||||
c.pos += 1;
|
c.pos += 1;
|
||||||
TokenKind::String(res.into())
|
TokenKind::String(BString::from(res).to_string())
|
||||||
}
|
}
|
||||||
_ => bail!("Unexpected byte {:?} in line {}", b as char, self.line),
|
_ => bail!("Unexpected byte {:?} in line {}", b as char, self.line),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -35,26 +35,26 @@ enum Type {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Field {
|
struct Field {
|
||||||
name: BString,
|
name: String,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Function {
|
struct Function {
|
||||||
name: BString,
|
name: String,
|
||||||
in_fields: Vec<Field>,
|
in_fields: Vec<Field>,
|
||||||
out_fields: Vec<Field>,
|
out_fields: Vec<Field>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Property {
|
struct Property {
|
||||||
name: BString,
|
name: String,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Signal {
|
struct Signal {
|
||||||
name: BString,
|
name: String,
|
||||||
fields: Vec<Field>,
|
fields: Vec<Field>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,7 +181,7 @@ impl<'a> Parser<'a> {
|
||||||
res.with_context(|| format!("While parsing field starting at line {}", line))
|
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()?;
|
self.not_eof()?;
|
||||||
let token = &self.tokens[self.pos];
|
let token = &self.tokens[self.pos];
|
||||||
self.pos += 1;
|
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>(
|
fn write_message<W: Write>(
|
||||||
f: &mut W,
|
f: &mut W,
|
||||||
el: &Element,
|
el: &Element,
|
||||||
msg_name: &BStr,
|
msg_name: &str,
|
||||||
name: &str,
|
name: &str,
|
||||||
indent: &str,
|
indent: &str,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
|
|
@ -614,7 +614,7 @@ fn write_signal<W: Write>(f: &mut W, element: &Element, sig: &Signal, indent: &s
|
||||||
write_message(
|
write_message(
|
||||||
f,
|
f,
|
||||||
element,
|
element,
|
||||||
sig.name.as_bstr(),
|
&sig.name,
|
||||||
&name,
|
&name,
|
||||||
indent,
|
indent,
|
||||||
&sig.fields,
|
&sig.fields,
|
||||||
|
|
@ -640,7 +640,7 @@ fn write_function<W: Write>(
|
||||||
write_message(
|
write_message(
|
||||||
f,
|
f,
|
||||||
element,
|
element,
|
||||||
fun.name.as_bstr(),
|
&fun.name,
|
||||||
&in_name,
|
&in_name,
|
||||||
indent,
|
indent,
|
||||||
&fun.in_fields,
|
&fun.in_fields,
|
||||||
|
|
@ -650,7 +650,7 @@ fn write_function<W: Write>(
|
||||||
write_message(
|
write_message(
|
||||||
f,
|
f,
|
||||||
element,
|
element,
|
||||||
fun.name.as_bstr(),
|
&fun.name,
|
||||||
&out_name,
|
&out_name,
|
||||||
indent,
|
indent,
|
||||||
&fun.out_fields,
|
&fun.out_fields,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use {
|
||||||
tokens::{tokenize, Symbol, Token, TokenKind, TreeDelim},
|
tokens::{tokenize, Symbol, Token, TokenKind, TreeDelim},
|
||||||
},
|
},
|
||||||
anyhow::{bail, Context, Result},
|
anyhow::{bail, Context, Result},
|
||||||
bstr::{BStr, BString, ByteSlice},
|
bstr::ByteSlice,
|
||||||
std::{cell::Cell, collections::HashMap, io::Write, mem, os::unix::ffi::OsStrExt, rc::Rc},
|
std::{cell::Cell, collections::HashMap, io::Write, mem, os::unix::ffi::OsStrExt, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ impl<'a> Parser<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_extension(&mut self, line: u32) -> Result<BString> {
|
fn parse_extension(&mut self, line: u32) -> Result<String> {
|
||||||
let res: Result<_> = (|| {
|
let res: Result<_> = (|| {
|
||||||
let (_, name) = self.expect_string()?;
|
let (_, name) = self.expect_string()?;
|
||||||
Ok(name.to_owned())
|
Ok(name.to_owned())
|
||||||
|
|
@ -208,7 +208,7 @@ impl<'a> Parser<'a> {
|
||||||
res.with_context(|| format!("While parsing bitmask starting at line {}", line))
|
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![];
|
let mut fields = vec![];
|
||||||
while !self.eof() {
|
while !self.eof() {
|
||||||
fields.push(self.parse_field()?);
|
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()?;
|
self.not_eof()?;
|
||||||
let token = &self.tokens[self.pos];
|
let token = &self.tokens[self.pos];
|
||||||
self.pos += 1;
|
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()?;
|
self.not_eof()?;
|
||||||
let token = &self.tokens[self.pos];
|
let token = &self.tokens[self.pos];
|
||||||
self.pos += 1;
|
self.pos += 1;
|
||||||
|
|
@ -459,7 +459,7 @@ impl<'a> Parser<'a> {
|
||||||
Ok(name)
|
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 (_, tree) = self.expect_tree(TreeDelim::Paren)?;
|
||||||
let mut parser = Parser::new(tree);
|
let mut parser = Parser::new(tree);
|
||||||
let (_, name) = parser.expect_ident()?;
|
let (_, name) = parser.expect_ident()?;
|
||||||
|
|
@ -560,7 +560,7 @@ fn needs_lifetime(ty: &Type, protocols: &Protocols) -> Result<bool> {
|
||||||
Type::U64 => false,
|
Type::U64 => false,
|
||||||
Type::Fd => false,
|
Type::Fd => false,
|
||||||
Type::List(_, _) => true,
|
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::String(_) => true,
|
||||||
Type::Bitmask(_, _) => false,
|
Type::Bitmask(_, _) => false,
|
||||||
Type::Enum(n, _) => needs_lifetime(n, protocols)?,
|
Type::Enum(n, _) => needs_lifetime(n, protocols)?,
|
||||||
|
|
@ -568,7 +568,7 @@ fn needs_lifetime(ty: &Type, protocols: &Protocols) -> Result<bool> {
|
||||||
Ok(res)
|
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) {
|
let s = match protocols.types_by_name.get(name) {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
_ => bail!("Struct {} referenced but not defined", name),
|
_ => 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::String(_) => false,
|
||||||
Type::Fd => true,
|
Type::Fd => true,
|
||||||
Type::List(ty, _) => return type_has_fds(ty, protocols),
|
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::Bitmask(_, _) => false,
|
||||||
Type::Enum(n, _) => return type_has_fds(n, protocols),
|
Type::Enum(n, _) => return type_has_fds(n, protocols),
|
||||||
};
|
};
|
||||||
Ok(res)
|
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) {
|
let s = match protocols.types_by_name.get(s) {
|
||||||
Some(s) => s,
|
Some(s) => s,
|
||||||
_ => bail!("Struct {} referenced but not defined", s),
|
_ => bail!("Struct {} referenced but not defined", s),
|
||||||
|
|
@ -698,19 +698,19 @@ enum Type {
|
||||||
Fd,
|
Fd,
|
||||||
String(Expr),
|
String(Expr),
|
||||||
List(Box<Type>, Option<Expr>),
|
List(Box<Type>, Option<Expr>),
|
||||||
Bitmask(BString, Expr),
|
Bitmask(String, Expr),
|
||||||
Enum(Box<Type>, Expr),
|
Enum(Box<Type>, Expr),
|
||||||
Named(BString),
|
Named(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum Expr {
|
enum Expr {
|
||||||
It,
|
It,
|
||||||
Field(BString),
|
Field(String),
|
||||||
Len(BString),
|
Len(String),
|
||||||
Literal(u32),
|
Literal(u32),
|
||||||
Bitmask(BString),
|
Bitmask(String),
|
||||||
Variant(BString),
|
Variant(String),
|
||||||
Sum(Box<Expr>),
|
Sum(Box<Expr>),
|
||||||
Mul(Box<Expr>, Box<Expr>),
|
Mul(Box<Expr>, Box<Expr>),
|
||||||
Map(Box<Expr>, Box<Expr>),
|
Map(Box<Expr>, Box<Expr>),
|
||||||
|
|
@ -722,7 +722,7 @@ enum Expr {
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct RealField {
|
struct RealField {
|
||||||
name: BString,
|
name: String,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
value: Option<Expr>,
|
value: Option<Expr>,
|
||||||
}
|
}
|
||||||
|
|
@ -738,7 +738,7 @@ enum Field {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Struct {
|
struct Struct {
|
||||||
name: BString,
|
name: String,
|
||||||
fields: Vec<Field>,
|
fields: Vec<Field>,
|
||||||
needs_lt: Cell<Option<bool>>,
|
needs_lt: Cell<Option<bool>>,
|
||||||
has_fds: Cell<Option<bool>>,
|
has_fds: Cell<Option<bool>>,
|
||||||
|
|
@ -746,27 +746,27 @@ struct Struct {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct BitmaskVariant {
|
struct BitmaskVariant {
|
||||||
name: BString,
|
name: String,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
bit: u32,
|
bit: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Bitmask {
|
struct Bitmask {
|
||||||
name: BString,
|
name: String,
|
||||||
variants: Vec<BitmaskVariant>,
|
variants: Vec<BitmaskVariant>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct EnumVariant {
|
struct EnumVariant {
|
||||||
name: BString,
|
name: String,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
value: u32,
|
value: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Enum {
|
struct Enum {
|
||||||
name: BString,
|
name: String,
|
||||||
variants: Vec<EnumVariant>,
|
variants: Vec<EnumVariant>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -780,9 +780,9 @@ struct Event {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct EventCopy {
|
struct EventCopy {
|
||||||
name: BString,
|
name: String,
|
||||||
opcode: u32,
|
opcode: u32,
|
||||||
original: BString,
|
original: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -795,7 +795,7 @@ struct Request {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Protocol {
|
struct Protocol {
|
||||||
extension: Option<BString>,
|
extension: Option<String>,
|
||||||
structs: Vec<Struct>,
|
structs: Vec<Struct>,
|
||||||
requests: Vec<Request>,
|
requests: Vec<Request>,
|
||||||
bitmasks: Vec<Bitmask>,
|
bitmasks: Vec<Bitmask>,
|
||||||
|
|
@ -806,8 +806,8 @@ struct Protocol {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Extension {
|
struct Extension {
|
||||||
name: BString,
|
name: String,
|
||||||
ident: BString,
|
ident: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -824,8 +824,8 @@ struct Protocols {
|
||||||
bitmasks: Vec<Rc<Bitmask>>,
|
bitmasks: Vec<Rc<Bitmask>>,
|
||||||
enums: Vec<Rc<Enum>>,
|
enums: Vec<Rc<Enum>>,
|
||||||
requests: Vec<Request>,
|
requests: Vec<Request>,
|
||||||
types_by_name: HashMap<BString, NamedType>,
|
types_by_name: HashMap<String, NamedType>,
|
||||||
events_by_name: HashMap<BString, Rc<Event>>,
|
events_by_name: HashMap<String, Rc<Event>>,
|
||||||
events: Vec<Rc<Event>>,
|
events: Vec<Rc<Event>>,
|
||||||
eventcopies: Vec<EventCopy>,
|
eventcopies: Vec<EventCopy>,
|
||||||
}
|
}
|
||||||
|
|
@ -869,7 +869,7 @@ fn write_type<F: Write>(f: &mut F, ty: &Type, protocols: &Protocols) -> Result<(
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Type::Named(n) => {
|
Type::Named(n) => {
|
||||||
let lt = if named_needs_lt(n.as_bstr(), protocols)? {
|
let lt = if named_needs_lt(n, protocols)? {
|
||||||
"<'a>"
|
"<'a>"
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
|
|
@ -944,7 +944,7 @@ enum StructUsecase<'a> {
|
||||||
|
|
||||||
fn format_xevent<F: Write>(
|
fn format_xevent<F: Write>(
|
||||||
f: &mut F,
|
f: &mut F,
|
||||||
name: &BStr,
|
name: &str,
|
||||||
s: &Struct,
|
s: &Struct,
|
||||||
opcode: u32,
|
opcode: u32,
|
||||||
protocols: &Protocols,
|
protocols: &Protocols,
|
||||||
|
|
@ -965,18 +965,11 @@ fn format_xevent<F: Write>(
|
||||||
|
|
||||||
fn format_event<F: Write>(f: &mut F, s: &Event, protocols: &Protocols) -> Result<()> {
|
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_struct(f, &s.data, protocols, &StructUsecase::Event { xge: s.xge })?;
|
||||||
format_xevent(
|
format_xevent(f, &s.data.name, &s.data, s.opcode, protocols, s.ext_idx)
|
||||||
f,
|
|
||||||
s.data.name.as_bstr(),
|
|
||||||
&s.data,
|
|
||||||
s.opcode,
|
|
||||||
protocols,
|
|
||||||
s.ext_idx,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_eventcopy<F: Write>(f: &mut F, s: &EventCopy, protocols: &Protocols) -> Result<()> {
|
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,
|
Some(o) => o,
|
||||||
_ => bail!("Event {} referenced but not defined", s.original),
|
_ => 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(
|
format_xevent(
|
||||||
f,
|
f,
|
||||||
s.name.as_bstr(),
|
&s.name,
|
||||||
&original.data,
|
&original.data,
|
||||||
s.opcode,
|
s.opcode,
|
||||||
protocols,
|
protocols,
|
||||||
|
|
@ -1591,16 +1584,13 @@ pub fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
protocols.eventcopies.extend(protocol.eventcopies);
|
protocols.eventcopies.extend(protocol.eventcopies);
|
||||||
if let Some(ext) = protocol.extension {
|
if let Some(ext) = protocol.extension {
|
||||||
let mut ident = vec![];
|
let mut ident = String::new();
|
||||||
for c in ext.as_bytes() {
|
for c in ext.chars() {
|
||||||
if matches!(*c, b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9') {
|
if matches!(c, 'a'..='z' | 'A'..='Z' | '0'..='9') {
|
||||||
ident.push(*c);
|
ident.push(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protocols.extensions.push(Extension {
|
protocols.extensions.push(Extension { name: ext, ident });
|
||||||
name: ext,
|
|
||||||
ident: ident.into(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue