diff --git a/xdr-codec/Cargo.toml b/xdr-codec/Cargo.toml index 1d62c78..59c33bf 100644 --- a/xdr-codec/Cargo.toml +++ b/xdr-codec/Cargo.toml @@ -19,7 +19,7 @@ unstable = [] [dependencies] byteorder = "1.0" -error-chain = "0.10" +error-chain = "0.12" [dev-dependencies] quickcheck = "0.4" diff --git a/xdr-codec/src/lib.rs b/xdr-codec/src/lib.rs index 968fa73..6f10055 100644 --- a/xdr-codec/src/lib.rs +++ b/xdr-codec/src/lib.rs @@ -23,11 +23,11 @@ extern crate byteorder; #[macro_use] extern crate error_chain; +use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; +use std::borrow::{Borrow, Cow}; +use std::cmp::min; pub use std::io::{Read, Write}; use std::ops::Deref; -use std::cmp::min; -use std::borrow::{Borrow, Cow}; -use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; pub mod record; @@ -193,9 +193,11 @@ where T: Unpack + Clone, { #[inline] - fn set(p: &mut T, v: T) { *p = v } + fn set(p: &mut T, v: T) { + *p = v + } #[inline] - fn drop(_: &mut T) { } + fn drop(_: &mut T) {} unpack_array_with(input, array, arraysz, set, drop, defl) } @@ -207,7 +209,7 @@ pub fn unpack_array_with( input: &mut In, array: &mut [T], arraysz: usize, - set: fn (&mut T, T), + set: fn(&mut T, T), drop: fn(&mut T), defl: Option<&T>, ) -> Result @@ -217,24 +219,24 @@ where { let mut rsz = 0; let sz = min(arraysz, array.len()); - + // If we fail part way through then return the error and the index we got up to // so we can clean up the entries we did initialize. let res = (|| { - for (idx, elem) in (&mut array[..sz]).into_iter().enumerate() { - let (v, sz) = match Unpack::unpack(input) { - Ok(v) => v, - Err(e) => return Some((idx, e)), - }; - rsz += sz; - set(elem, v); - } - None - })(); + for (idx, elem) in (&mut array[..sz]).into_iter().enumerate() { + let (v, sz) = match Unpack::unpack(input) { + Ok(v) => v, + Err(e) => return Some((idx, e)), + }; + rsz += sz; + set(elem, v); + } + None + })(); if let Some((idx, err)) = res { for elem in &mut array[..idx] { drop(elem) - }; + } return Err(err); } @@ -398,54 +400,54 @@ impl Pack for i8 { impl Pack for u32 { #[inline] fn pack(&self, out: &mut Out) -> Result { - out.write_u32::(*self).map_err(Error::from).map( - |_| 4, - ) + out.write_u32::(*self) + .map_err(Error::from) + .map(|_| 4) } } impl Pack for i32 { #[inline] fn pack(&self, out: &mut Out) -> Result { - out.write_i32::(*self).map_err(Error::from).map( - |_| 4, - ) + out.write_i32::(*self) + .map_err(Error::from) + .map(|_| 4) } } impl Pack for u64 { #[inline] fn pack(&self, out: &mut Out) -> Result { - out.write_u64::(*self).map_err(Error::from).map( - |_| 8, - ) + out.write_u64::(*self) + .map_err(Error::from) + .map(|_| 8) } } impl Pack for i64 { #[inline] fn pack(&self, out: &mut Out) -> Result { - out.write_i64::(*self).map_err(Error::from).map( - |_| 8, - ) + out.write_i64::(*self) + .map_err(Error::from) + .map(|_| 8) } } impl Pack for f32 { #[inline] fn pack(&self, out: &mut Out) -> Result { - out.write_f32::(*self).map_err(Error::from).map( - |_| 4, - ) + out.write_f32::(*self) + .map_err(Error::from) + .map(|_| 4) } } impl Pack for f64 { #[inline] fn pack(&self, out: &mut Out) -> Result { - out.write_f64::(*self).map_err(Error::from).map( - |_| 8, - ) + out.write_f64::(*self) + .map_err(Error::from) + .map(|_| 8) } } @@ -587,11 +589,10 @@ pub trait Unpack: Sized { impl Unpack for u8 { #[inline] fn unpack(input: &mut In) -> Result<(Self, usize)> { - input.read_u32::().map_err(Error::from).map( - |v| { - (v as u8, 4) - }, - ) + input + .read_u32::() + .map_err(Error::from) + .map(|v| (v as u8, 4)) } } @@ -599,63 +600,68 @@ impl Unpack for u8 { impl Unpack for i8 { #[inline] fn unpack(input: &mut In) -> Result<(Self, usize)> { - input.read_i32::().map_err(Error::from).map( - |v| { - (v as i8, 4) - }, - ) + input + .read_i32::() + .map_err(Error::from) + .map(|v| (v as i8, 4)) } } impl Unpack for u32 { #[inline] fn unpack(input: &mut In) -> Result<(Self, usize)> { - input.read_u32::().map_err(Error::from).map( - |v| (v, 4), - ) + input + .read_u32::() + .map_err(Error::from) + .map(|v| (v, 4)) } } impl Unpack for i32 { #[inline] fn unpack(input: &mut In) -> Result<(Self, usize)> { - input.read_i32::().map_err(Error::from).map( - |v| (v, 4), - ) + input + .read_i32::() + .map_err(Error::from) + .map(|v| (v, 4)) } } impl Unpack for u64 { #[inline] fn unpack(input: &mut In) -> Result<(Self, usize)> { - input.read_u64::().map_err(Error::from).map( - |v| (v, 8), - ) + input + .read_u64::() + .map_err(Error::from) + .map(|v| (v, 8)) } } impl Unpack for i64 { #[inline] fn unpack(input: &mut In) -> Result<(Self, usize)> { - input.read_i64::().map_err(Error::from).map( - |v| (v, 8), - ) + input + .read_i64::() + .map_err(Error::from) + .map(|v| (v, 8)) } } impl Unpack for f32 { fn unpack(input: &mut In) -> Result<(Self, usize)> { - input.read_f32::().map_err(Error::from).map( - |v| (v, 4), - ) + input + .read_f32::() + .map_err(Error::from) + .map(|v| (v, 4)) } } impl Unpack for f64 { fn unpack(input: &mut In) -> Result<(Self, usize)> { - input.read_f64::().map_err(Error::from).map( - |v| (v, 8), - ) + input + .read_f64::() + .map_err(Error::from) + .map(|v| (v, 8)) } } diff --git a/xdr-codec/src/record.rs b/xdr-codec/src/record.rs index 572792f..33a07b7 100644 --- a/xdr-codec/src/record.rs +++ b/xdr-codec/src/record.rs @@ -12,12 +12,12 @@ //! //! There's no magic number or other way to determine whether a stream //! is using record marking; both ends must agree. -use std::io::{self, BufRead, Read, Write}; use std::cmp::min; +use std::io::{self, BufRead, Read, Write}; use error::*; -use super::{Error, pack, unpack}; +use super::{pack, unpack, Error}; const LAST_REC: u32 = 1u32 << 31; @@ -36,9 +36,9 @@ fn mapioerr(xdrerr: Error) -> io::Error { /// determine record ends. #[derive(Debug)] pub struct XdrRecordReader { - size: usize, // record size + size: usize, // record size consumed: usize, // bytes consumed - eor: bool, // is last record + eor: bool, // is last record reader: R, // reader } @@ -62,7 +62,10 @@ impl XdrRecordReader { let rechdr: u32 = match unpack(&mut self.reader) { Ok(v) => v, Err(Error(ErrorKind::IOError(ref err), _)) - if err.kind() == io::ErrorKind::UnexpectedEof => return Ok(true), + if err.kind() == io::ErrorKind::UnexpectedEof => + { + return Ok(true) + } Err(e) => return Err(mapioerr(e)), }; @@ -151,9 +154,9 @@ impl Iterator for XdrRecordReaderIter { // Do we need next fragment? if rr.totremains() == 0 { match rr.nextrec() { - Err(e) => return Some(Err(e)), // IO error - Ok(true) => return None, // EOF - Ok(false) => (), // keep going + Err(e) => return Some(Err(e)), // IO error + Ok(true) => return None, // EOF + Ok(false) => (), // keep going } } @@ -161,9 +164,9 @@ impl Iterator for XdrRecordReaderIter { let eor = rr.eor(); match rr.by_ref().take(remains as u64).read_to_end(&mut buf) { - Ok(sz) if sz == remains => (), // OK, keep going - Ok(_) => return None, // short read - Err(e) => return Some(Err(e)), // error + Ok(sz) if sz == remains => (), // OK, keep going + Ok(_) => return None, // short read + Err(e) => return Some(Err(e)), // error }; if eor { @@ -186,8 +189,8 @@ const WRBUF: usize = 65536; pub struct XdrRecordWriter { buf: Vec, // accumulated record fragment bufsz: usize, // max fragment size - eor: bool, // last fragment was eor - writer: W, // writer we're passing on to + eor: bool, // last fragment was eor + writer: W, // writer we're passing on to } impl XdrRecordWriter { diff --git a/xdr-codec/tests/qc-record.rs b/xdr-codec/tests/qc-record.rs index 476ff23..4ae0594 100644 --- a/xdr-codec/tests/qc-record.rs +++ b/xdr-codec/tests/qc-record.rs @@ -3,10 +3,10 @@ extern crate xdr_codec; use std::io::{Cursor, Write}; -use quickcheck::{TestResult, quickcheck}; +use quickcheck::{quickcheck, TestResult}; -use xdr_codec::Pack; use xdr_codec::record::{XdrRecordReader, XdrRecordWriter}; +use xdr_codec::Pack; // Make sure XdrRecordWriter writes the right stuff fn check_writerec(bufsz: usize, eor: bool, ref bytes: Vec) -> TestResult { diff --git a/xdr-codec/tests/quickcheck.rs b/xdr-codec/tests/quickcheck.rs index c38e451..b96f552 100644 --- a/xdr-codec/tests/quickcheck.rs +++ b/xdr-codec/tests/quickcheck.rs @@ -1,13 +1,15 @@ -extern crate xdr_codec; extern crate quickcheck; +extern crate xdr_codec; -use std::io::Cursor; use std::fmt::Debug; +use std::io::Cursor; use std::iter; -use xdr_codec::{Error, ErrorKind, Pack, Unpack, pack_array, pack_opaque_array, padding, - unpack_array, unpack_opaque_array}; -use quickcheck::{Arbitrary, quickcheck}; +use quickcheck::{quickcheck, Arbitrary}; +use xdr_codec::{ + pack_array, pack_opaque_array, padding, unpack_array, unpack_opaque_array, Error, ErrorKind, + Pack, Unpack, +}; // Output of packing is a multiple of 4 fn pack(v: T) -> bool @@ -201,8 +203,8 @@ fn check_array(arraysz: usize, rxsize: usize, data: Vec, defl: Option) // unpack rxsize elements let rsz = match unpack_array(&mut cur, &mut recv[..], arraysz, defl.as_ref()) { - Ok(rsz) if recv.len() <= arraysz || defl.is_some() => rsz, // normal success - Err(Error(ErrorKind::InvalidLen(_), _)) => return defl.is_none() && recv.len() > arraysz, // expected if recv is too big and there's no default + Ok(rsz) if recv.len() <= arraysz || defl.is_some() => rsz, // normal success + Err(Error(ErrorKind::InvalidLen(_), _)) => return defl.is_none() && recv.len() > arraysz, // expected if recv is too big and there's no default Err(e) => { println!("unpack_array failed {:?}", e); return false; @@ -224,9 +226,10 @@ fn check_array(arraysz: usize, rxsize: usize, data: Vec, defl: Option) } // data and recv must match their common prefix up to arraysz - if data.iter().zip(recv.iter().take(arraysz)).any( - |(d, r)| *d != *r, - ) + if data + .iter() + .zip(recv.iter().take(arraysz)) + .any(|(d, r)| *d != *r) { println!("nonmatching\ndata {:?}\nrecv {:?}", data, recv); return false; @@ -246,9 +249,7 @@ fn check_array(arraysz: usize, rxsize: usize, data: Vec, defl: Option) #[test] fn quickcheck_array() { - quickcheck( - check_array as fn(usize, usize, Vec, Option) -> bool, - ); + quickcheck(check_array as fn(usize, usize, Vec, Option) -> bool); } fn check_opaque(arraysz: usize, rxsize: usize, data: Vec) -> bool { @@ -292,9 +293,10 @@ fn check_opaque(arraysz: usize, rxsize: usize, data: Vec) -> bool { } // data and recv must match their common prefix up to arraysz - if data.iter().zip(recv.iter().take(arraysz)).any( - |(d, r)| *d != *r, - ) + if data + .iter() + .zip(recv.iter().take(arraysz)) + .any(|(d, r)| *d != *r) { println!("nonmatching\ndata {:?}\nrecv {:?}", data, recv); return false; diff --git a/xdrgen/Cargo.toml b/xdrgen/Cargo.toml index 8db2d60..3d790eb 100644 --- a/xdrgen/Cargo.toml +++ b/xdrgen/Cargo.toml @@ -21,13 +21,13 @@ doc = false unstable = [] [dependencies] -log = "0.3" -env_logger = "0.4" +log = "0.4" +env_logger = "0.9" nom = { version="3.1", features=["verbose-errors"] } quote = "0.3" -clap = "2.24" -lazy_static = "0.2" -bitflags = "0.9" +clap = "3.2" +lazy_static = "1.4" +bitflags = "1.3" [dependencies.xdr-codec] path = "../xdr-codec" @@ -35,4 +35,4 @@ version = "0.4" [dev-dependencies] tempdir = "0.3" -error-chain = "0.10" +error-chain = "0.12" diff --git a/xdrgen/example/src/simple.rs b/xdrgen/example/src/simple.rs index 569a061..62cfbb6 100644 --- a/xdrgen/example/src/simple.rs +++ b/xdrgen/example/src/simple.rs @@ -1,19 +1,22 @@ extern crate xdr_codec; use std::io::Cursor; -use xdr_codec::{unpack,pack}; +use xdr_codec::{pack, unpack}; mod simple { use xdr_codec; - - #[allow(dead_code)] + include!(concat!(env!("OUT_DIR"), "/simple_xdr.rs")); } fn main() { let foo = simple::Foo { - a: 1, b: 2, c: 3, - bar: vec![simple::Bar { data: vec![1,2,3] }], + a: 1, + b: 2, + c: 3, + bar: vec![simple::Bar { + data: vec![1, 2, 3], + }], barish: None, name: String::from("foox"), thing: simple::Things::C, @@ -27,7 +30,7 @@ fn main() { println!("buf={:?} len={}", buf, buf.len()); let mut cur = Cursor::new(buf); - + let foo2 = unpack(&mut cur).unwrap(); println!("foo={:?}", foo); diff --git a/xdrgen/src/lib.rs b/xdrgen/src/lib.rs index 1093aa0..c1e2cc0 100644 --- a/xdrgen/src/lib.rs +++ b/xdrgen/src/lib.rs @@ -6,7 +6,7 @@ //! It is intended to be used with the "xdr-codec" crate, which provides the runtime library for //! encoding/decoding primitive types, strings, opaque data and arrays. -#![recursion_limit="128"] +#![recursion_limit = "128"] extern crate xdr_codec as xdr; @@ -25,11 +25,11 @@ extern crate nom; #[macro_use] extern crate bitflags; +use std::env; +use std::fmt::Display; use std::fs::File; -use std::path::{Path, PathBuf}; use std::io::{Read, Write}; -use std::fmt::Display; -use std::env; +use std::path::{Path, PathBuf}; use std::result; use xdr::Result; @@ -66,27 +66,34 @@ where let xdr = xdr; let res: Vec<_> = { - let consts = xdr.constants() - .filter_map(|(c, &(v, ref scope))| if scope.is_none() { - Some(spec::Const(c.clone(), v)) - } else { - None + let consts = xdr + .constants() + .filter_map(|(c, &(v, ref scope))| { + if scope.is_none() { + Some(spec::Const(c.clone(), v)) + } else { + None + } }) .map(|c| c.define(&xdr)); - let typespecs = xdr.typespecs() + let typespecs = xdr + .typespecs() .map(|(n, ty)| spec::Typespec(n.clone(), ty.clone())) .map(|c| c.define(&xdr)); - let typesyns = xdr.typesyns() + let typesyns = xdr + .typesyns() .map(|(n, ty)| spec::Typesyn(n.clone(), ty.clone())) .map(|c| c.define(&xdr)); - let packers = xdr.typespecs() + let packers = xdr + .typespecs() .map(|(n, ty)| spec::Typespec(n.clone(), ty.clone())) .filter_map(|c| result_option(c.pack(&xdr))); - let unpackers = xdr.typespecs() + let unpackers = xdr + .typespecs() .map(|(n, ty)| spec::Typespec(n.clone(), ty.clone())) .filter_map(|c| result_option(c.unpack(&xdr))); diff --git a/xdrgen/src/spec/mod.rs b/xdrgen/src/spec/mod.rs index 24b4e8e..4eb7515 100644 --- a/xdrgen/src/spec/mod.rs +++ b/xdrgen/src/spec/mod.rs @@ -1,6 +1,6 @@ use std::collections::btree_map::{BTreeMap, Iter}; use std::collections::{HashMap, HashSet}; -use std::io::{Write, stderr}; +use std::io::{stderr, Write}; use std::result; @@ -36,19 +36,19 @@ impl ToTokens for Derives { let mut der = Vec::new(); - if self.contains(COPY) { + if self.contains(Derives::COPY) { der.push(quote!(Copy)) } - if self.contains(CLONE) { + if self.contains(Derives::CLONE) { der.push(quote!(Clone)) } - if self.contains(DEBUG) { + if self.contains(Derives::DEBUG) { der.push(quote!(Debug)) } - if self.contains(EQ) { + if self.contains(Derives::EQ) { der.push(quote!(Eq)) } - if self.contains(PARTIALEQ) { + if self.contains(Derives::PARTIALEQ) { der.push(quote!(PartialEq)) } @@ -60,20 +60,15 @@ impl ToTokens for Derives { lazy_static! { static ref KEYWORDS: HashSet<&'static str> = { let kws = [ - "abstract", "alignof", "as", "become", "box", - "break", "const", "continue", "crate", "do", - "else", "enum", "extern", "false", "final", - "fn", "for", "if", "impl", "in", - "let", "loop", "macro", "match", "mod", - "move", "mut", "offsetof", "override", "priv", - "proc", "pub", "pure", "ref", "return", - "Self", "self", "sizeof", "static", "struct", - "super", "trait", "true", "type", "typeof", - "unsafe", "unsized", "use", "virtual", "where", - "while", "yield", + "abstract", "alignof", "as", "become", "box", "break", "const", "continue", "crate", + "do", "else", "enum", "extern", "false", "final", "fn", "for", "if", "impl", "in", + "let", "loop", "macro", "match", "mod", "move", "mut", "offsetof", "override", "priv", + "proc", "pub", "pure", "ref", "return", "Self", "self", "sizeof", "static", "struct", + "super", "trait", "true", "type", "typeof", "unsafe", "unsized", "use", "virtual", + "where", "while", "yield", ]; - kws.into_iter().map(|x| *x).collect() + kws.iter().map(|x| *x).collect() }; } @@ -101,13 +96,11 @@ impl Value { fn as_ident(&self) -> quote::Ident { match self { &Value::Ident(ref id) => quote_ident(id), - &Value::Const(val) => { - quote::Ident::new(format!( - "Const{}{}", - (if val < 0 { "_" } else { "" }), - val.abs() - )) - } + &Value::Const(val) => quote::Ident::new(format!( + "Const{}{}", + (if val < 0 { "_" } else { "" }), + val.abs() + )), } } @@ -207,12 +200,10 @@ impl Type { match self { &Int | &UInt | &Hyper | &UHyper | &Float | &Double | &Quadruple | &Bool => true, - &Ident(ref id, _) => { - match symtab.typespec(id) { - None => false, - Some(ref ty) => ty.is_prim(symtab), - } - } + &Ident(ref id, _) => match symtab.typespec(id) { + None => false, + Some(ref ty) => ty.is_prim(symtab), + }, _ => false, } @@ -222,7 +213,7 @@ impl Type { use self::Type::*; let mut memoset = HashMap::new(); - let mut memo = match memo { + let memo = match memo { None => &mut memoset, Some(m) => m, }; @@ -238,56 +229,63 @@ impl Type { &Array(ref ty, ref len) => { let ty = ty.as_ref(); let set = match ty { - &Opaque | &String => EQ | PARTIALEQ | COPY | CLONE | DEBUG, + &Opaque | &String => { + Derives::EQ + | Derives::PARTIALEQ + | Derives::COPY + | Derives::CLONE + | Derives::DEBUG + } ref ty => ty.derivable(symtab, Some(memo)), }; match len.as_i64(symtab) { Some(v) if v <= 32 => set, - _ => Derives::empty(), // no #[derive] for arrays > 32 + _ => Derives::empty(), // no #[derive] for arrays > 32 } } &Flex(ref ty, ..) => { let set = ty.derivable(symtab, Some(memo)); - set & !COPY // no Copy, everything else OK + set & !Derives::COPY // no Copy, everything else OK } - &Enum(_) => EQ | PARTIALEQ | COPY | CLONE | DEBUG, - &Option(ref ty) => ty.derivable(symtab, Some(memo)), - &Struct(ref fields) => { - fields.iter().fold(Derives::all(), |a, f| { - a & f.derivable(symtab, memo) - }) + &Enum(_) => { + Derives::EQ | Derives::PARTIALEQ | Derives::COPY | Derives::CLONE | Derives::DEBUG } + &Option(ref ty) => ty.derivable(symtab, Some(memo)), + &Struct(ref fields) => fields + .iter() + .fold(Derives::all(), |a, f| a & f.derivable(symtab, memo)), &Union(_, ref cases, ref defl) => { - cases.iter().map(|c| &c.1).fold(Derives::all(), |a, c| { - a & c.derivable(symtab, memo) - }) & - defl.as_ref().map_or( - Derives::all(), - |d| d.derivable(symtab, memo), - ) + cases + .iter() + .map(|c| &c.1) + .fold(Derives::all(), |a, c| a & c.derivable(symtab, memo)) + & defl + .as_ref() + .map_or(Derives::all(), |d| d.derivable(symtab, memo)) } &Ident(_, Some(derives)) => derives, &Ident(ref id, None) => { match symtab.typespec(id) { - None => Derives::empty(), // unknown, really + None => Derives::empty(), // unknown, really Some(ref ty) => ty.derivable(symtab, Some(memo)), } } - &Float | &Double => PARTIALEQ | COPY | CLONE | DEBUG, + &Float | &Double => { + Derives::PARTIALEQ | Derives::COPY | Derives::CLONE | Derives::DEBUG + } ty if ty.is_prim(symtab) => Derives::all(), - _ => Derives::all() & !COPY, + _ => Derives::all() & !Derives::COPY, }; memo.insert(self.clone(), set); set } - fn packer(&self, val: Tokens, symtab: &Symtab) -> Result { use self::Type::*; @@ -331,8 +329,8 @@ impl Type { use self::Type::*; match self { - &Opaque | &String | &Option(_) | &Ident(..) | &Int | &UInt | &Hyper | &UHyper | - &Float | &Double | &Quadruple | &Bool => true, + &Opaque | &String | &Option(_) | &Ident(..) | &Int | &UInt | &Hyper | &UHyper + | &Float | &Double | &Quadruple | &Bool => true, _ => false, } } @@ -610,12 +608,12 @@ impl Emit for Typespec { &Enum(ref edefs) => { let defs: Vec<_> = edefs .iter() - .filter_map(|&EnumDefn(ref field, _)| if let Some((val, Some(_))) = - symtab.getconst(field) - { - Some((quote_ident(field), val as isize)) - } else { - None + .filter_map(|&EnumDefn(ref field, _)| { + if let Some((val, Some(_))) = symtab.getconst(field) { + Some((quote_ident(field), val as isize)) + } else { + None + } }) .map(|(field, val)| quote!(#field = #val,)) .collect(); @@ -653,19 +651,15 @@ impl Emit for Typespec { }; match case { - &Const(val) if val < 0 => { - match seltype { - &Int | &Hyper => true, - _ => false, - } - } + &Const(val) if val < 0 => match seltype { + &Int | &Hyper => true, + _ => false, + }, - &Const(_) => { - match seltype { - &Int | &Hyper | &UInt | &UHyper => true, - _ => false, - } - } + &Const(_) => match seltype { + &Int | &Hyper | &UInt | &UHyper => true, + _ => false, + }, &Ident(ref id) => { if *seltype == Bool { @@ -688,9 +682,10 @@ impl Emit for Typespec { .iter() .map(|&UnionCase(ref val, ref decl)| { if !compatcase(val) { - return Err(Error::from( - format!("incompat selector {:?} case {:?}", selector, val), - )); + return Err(Error::from(format!( + "incompat selector {:?} case {:?}", + selector, val + ))); } let label = val.as_ident(); @@ -759,8 +754,8 @@ impl Emit for Typespec { impl Emitpack for Typespec { fn pack(&self, symtab: &Symtab) -> Result> { - use self::Type::*; use self::Decl::*; + use self::Type::*; let name = quote_ident(&self.0); let ty = &self.1; @@ -773,7 +768,8 @@ impl Emitpack for Typespec { } &Struct(ref decl) => { - let decls: Vec<_> = decl.iter() + let decls: Vec<_> = decl + .iter() .filter_map(|d| match d { &Void => None, &Named(ref name, ref ty) => Some((quote_ident(name), ty)), @@ -856,8 +852,8 @@ impl Emitpack for Typespec { } fn unpack(&self, symtab: &Symtab) -> Result> { - use self::Type::*; use self::Decl::*; + use self::Type::*; let name = quote_ident(&self.0); let ty = &self.1; @@ -866,7 +862,8 @@ impl Emitpack for Typespec { let body = match ty { &Enum(ref defs) => { directive = quote!(#[inline]); - let matchdefs: Vec<_> = defs.iter() + let matchdefs: Vec<_> = defs + .iter() .filter_map(|&EnumDefn(ref name, _)| { let tok = quote_ident(name); if let Some((ref _val, ref scope)) = symtab.getconst(name) { @@ -1031,15 +1028,13 @@ impl Symtab { for &EnumDefn(ref name, ref maybeval) in edefn { let v = match maybeval { &None => prev + 1, - &Some(ref val) => { - match self.value(val) { - Some(c) => c, - None => { - let _ = writeln!(&mut err, "Unknown value {:?}", val); - continue; - } + &Some(ref val) => match self.value(val) { + Some(c) => c, + None => { + let _ = writeln!(&mut err, "Unknown value {:?}", val); + continue; } - } + }, }; prev = v; @@ -1078,12 +1073,10 @@ impl Symtab { pub fn typespec(&self, name: &String) -> Option<&Type> { match self.typespecs.get(name) { - None => { - match self.typesyns.get(name) { - None => None, - Some(ty) => Some(ty), - } - } + None => match self.typesyns.get(name) { + None => None, + Some(ty) => Some(ty), + }, Some(ty) => Some(ty), } } @@ -1101,6 +1094,5 @@ impl Symtab { } } - #[cfg(test)] mod test; diff --git a/xdrgen/src/spec/test.rs b/xdrgen/src/spec/test.rs index 25b2441..31824e9 100644 --- a/xdrgen/src/spec/test.rs +++ b/xdrgen/src/spec/test.rs @@ -1,5 +1,5 @@ -use super::specification; use super::super::generate; +use super::specification; use std::io::Cursor; #[test] @@ -232,7 +232,6 @@ default: ); println!("spec {:?}", s); assert!(s.is_ok()) - } #[test] diff --git a/xdrgen/src/spec/xdr_nom.rs b/xdrgen/src/spec/xdr_nom.rs index 79cf95d..dd7879e 100644 --- a/xdrgen/src/spec/xdr_nom.rs +++ b/xdrgen/src/spec/xdr_nom.rs @@ -1,11 +1,10 @@ // Grammar for a .x file specifying XDR type codecs. Does not include any RPC syntax. Should match RFC4506. -use nom::{Err, ErrorKind, IResult, Needed, is_digit, is_space, not_line_ending}; use nom::IResult::*; +use nom::{is_digit, is_space, not_line_ending, Err, ErrorKind, IResult, Needed}; use std::str; -use super::{Decl, Defn, EnumDefn, Type, UnionCase, Value}; -use super::{CLONE, COPY, DEBUG, EQ, PARTIALEQ}; +use super::{Decl, Defn, Derives, EnumDefn, Type, UnionCase, Value}; #[inline] fn ignore(_: T) -> () { @@ -28,38 +27,38 @@ fn eof(input: &[u8]) -> IResult<&[u8], ()> { pub fn specification(input: &str) -> Result, String> { match spec(input.as_bytes()) { Done(_, spec) => Ok(spec), - Error(Err::Position(kind, input)) => { - Err(format!( - "{:?}: {}", - kind, - String::from(str::from_utf8(input).unwrap()) - )) - } + Error(Err::Position(kind, input)) => Err(format!( + "{:?}: {}", + kind, + String::from(str::from_utf8(input).unwrap()) + )), Error(err) => Err(format!("Error: {:?}", err)), Incomplete(need) => Err(format!("Incomplete {:?}", need)), } } -named!(spec< Vec >, - do_parse!( - opt!(directive) >> - defns: many0!(definition) >> - spaces >> eof >> - (defns)) +named!( + spec>, + do_parse!(opt!(directive) >> defns: many0!(definition) >> spaces >> eof >> (defns)) ); #[test] fn test_spec() { - assert_eq!(spec(&b"#include "[..]), - Done(&b""[..], vec!())); + assert_eq!(spec(&b"#include "[..]), Done(&b""[..], vec!())); - assert_eq!(spec(&b"// hello\n#include "[..]), - Done(&b""[..], vec!())); + assert_eq!( + spec(&b"// hello\n#include "[..]), + Done(&b""[..], vec!()) + ); - assert_eq!(spec(&b"#include \ntypedef int foo;"[..]), - Done(&b""[..], vec!(Defn::typesyn("foo", Type::Int)))); + assert_eq!( + spec(&b"#include \ntypedef int foo;"[..]), + Done(&b""[..], vec!(Defn::typesyn("foo", Type::Int))) + ); - assert_eq!(spec(&br#" + assert_eq!( + spec( + &br#" /* test file */ #define foo bar const mip = 123; @@ -71,30 +70,48 @@ struct bar { }; #include "other" enum bop { a = 2, b = 1 }; -"#[..]), - Done(&b""[..], - vec!(Defn::constant("mip", 123), - Defn::typesyn("foo", Type::Int), - Defn::typespec("bar", Type::Struct(vec!(Decl::named("a", Type::Int), - Decl::named("b", Type::Int)))), - Defn::typespec("bop", Type::Enum(vec!(EnumDefn::new("a", Some(Value::Const(2))), - EnumDefn::new("b", Some(Value::Const(1))))))))); +"#[..] + ), + Done( + &b""[..], + vec!( + Defn::constant("mip", 123), + Defn::typesyn("foo", Type::Int), + Defn::typespec( + "bar", + Type::Struct(vec!( + Decl::named("a", Type::Int), + Decl::named("b", Type::Int) + )) + ), + Defn::typespec( + "bop", + Type::Enum(vec!( + EnumDefn::new("a", Some(Value::Const(2))), + EnumDefn::new("b", Some(Value::Const(1))) + )) + ) + ) + ) + ); } -named!(definition, - alt!(type_def => { |t| t } | - const_def => { |c| c })); +named!( + definition, + alt!(type_def => { |t| t } | + const_def => { |c| c }) +); fn is_hexdigit(ch: u8) -> bool { match ch as char { - '0'...'9' | 'A'...'F' | 'a'...'f' => true, + '0'..='9' | 'A'..='F' | 'a'..='f' => true, _ => false, } } fn is_octdigit(ch: u8) -> bool { match ch as char { - '0'...'7' => true, + '0'..='7' => true, _ => false, } } @@ -112,46 +129,53 @@ fn digit bool>(input: &[u8], isdigit: F) -> IResult<&[u8], &[u8]> { Incomplete(Needed::Unknown) } -named!(lbrace, preceded!(spaces, apply!(ctag, "{"))); -named!(rbrace, preceded!(spaces, apply!(ctag, "}"))); -named!(lbrack, preceded!(spaces, apply!(ctag, "["))); -named!(rbrack, preceded!(spaces, apply!(ctag, "]"))); -named!(lparen, preceded!(spaces, apply!(ctag, "("))); -named!(rparen, preceded!(spaces, apply!(ctag, ")"))); -named!(lt, preceded!(spaces, apply!(ctag, "<"))); -named!(gt, preceded!(spaces, apply!(ctag, ">"))); -named!(colon, preceded!(spaces, apply!(ctag, ":"))); -named!(semi, preceded!(spaces, apply!(ctag, ";"))); -named!(comma, preceded!(spaces, apply!(ctag, ","))); -named!(eq, preceded!(spaces, apply!(ctag, "="))); -named!(star, preceded!(spaces, apply!(ctag, "*"))); - -named!(hexnumber, +named!(lbrace, preceded!(spaces, apply!(ctag, "{"))); +named!(rbrace, preceded!(spaces, apply!(ctag, "}"))); +named!(lbrack, preceded!(spaces, apply!(ctag, "["))); +named!(rbrack, preceded!(spaces, apply!(ctag, "]"))); +named!(lparen, preceded!(spaces, apply!(ctag, "("))); +named!(rparen, preceded!(spaces, apply!(ctag, ")"))); +named!(lt, preceded!(spaces, apply!(ctag, "<"))); +named!(gt, preceded!(spaces, apply!(ctag, ">"))); +named!(colon, preceded!(spaces, apply!(ctag, ":"))); +named!(semi, preceded!(spaces, apply!(ctag, ";"))); +named!(comma, preceded!(spaces, apply!(ctag, ","))); +named!(eq, preceded!(spaces, apply!(ctag, "="))); +named!(star, preceded!(spaces, apply!(ctag, "*"))); + +named!( + hexnumber, do_parse!( - apply!(ctag, "0x") >> - val: map_res!(apply!(digit, is_hexdigit), str::from_utf8) >> - (i64::from_str_radix(val, 16).unwrap()) + apply!(ctag, "0x") + >> val: map_res!(apply!(digit, is_hexdigit), str::from_utf8) + >> (i64::from_str_radix(val, 16).unwrap()) ) ); -named!(octnumber, +named!( + octnumber, do_parse!( - sign: opt!(apply!(ctag, "-")) >> - apply!(ctag, "0") >> - val: opt!(map_res!(apply!(digit, is_octdigit), str::from_utf8)) >> - (i64::from_str_radix(val.unwrap_or("0"), 8).unwrap() * (if sign.is_some() { -1 } else { 1 })) + sign: opt!(apply!(ctag, "-")) + >> apply!(ctag, "0") + >> val: opt!(map_res!(apply!(digit, is_octdigit), str::from_utf8)) + >> (i64::from_str_radix(val.unwrap_or("0"), 8).unwrap() + * (if sign.is_some() { -1 } else { 1 })) ) ); -named!(decnumber, +named!( + decnumber, do_parse!( - sign: opt!(apply!(ctag, "-")) >> - val: map_res!(apply!(digit, is_digit), str::from_utf8) >> - (i64::from_str_radix(val, 10).unwrap() * (if sign.is_some() { -1 } else { 1 })) + sign: opt!(apply!(ctag, "-")) + >> val: map_res!(apply!(digit, is_digit), str::from_utf8) + >> (i64::from_str_radix(val, 10).unwrap() * (if sign.is_some() { -1 } else { 1 })) ) ); -named!(number, preceded!(spaces, alt!(hexnumber | octnumber | decnumber))); +named!( + number, + preceded!(spaces, alt!(hexnumber | octnumber | decnumber)) +); #[test] fn test_nums() { @@ -188,8 +212,8 @@ fn token(input: &[u8]) -> IResult<&[u8], &[u8]> { for (idx, item) in input.iter().enumerate() { match *item as char { - 'a'...'z' | 'A'...'Z' | '_' => continue, - '0'...'9' if idx > 0 => continue, + 'a'..='z' | 'A'..='Z' | '_' => continue, + '0'..='9' if idx > 0 => continue, _ => { if idx > 0 { return Done(&input[idx..], &input[0..idx]); @@ -203,15 +227,16 @@ fn token(input: &[u8]) -> IResult<&[u8], &[u8]> { } macro_rules! kw { - ($fnname:ident, $kw:expr) => ( + ($fnname:ident, $kw:expr) => { fn $fnname(input: &[u8]) -> IResult<&[u8], ()> { match token(input) { - Done(rest, val) => + Done(rest, val) => { if val == $kw { Done(rest, ()) } else { Error(Err::Position(ErrorKind::Custom(0), input)) - }, + } + } Error(e) => Error(e), Incomplete(_) => { // If its either incomplete but longer that what we're looking for, or what we @@ -221,9 +246,10 @@ macro_rules! kw { } else { Incomplete(Needed::Size($kw.len() - input.len())) } - }, + } } - }); + } + }; } kw!(kw_bool, b"bool"); @@ -248,32 +274,52 @@ kw!(kw_union, b"union"); kw!(kw_unsigned, b"unsigned"); kw!(kw_void, b"void"); -named!(keyword<()>, - alt!(kw_bool | - kw_case | - kw_const | - kw_default | - kw_double | - kw_enum | - kw_float | - kw_hyper | - kw_int | - kw_opaque | - kw_quadruple | - kw_string | - kw_struct | - kw_switch | - kw_typedef | - kw_union | - kw_unsigned | - kw_void)); +named!( + keyword<()>, + alt!( + kw_bool + | kw_case + | kw_const + | kw_default + | kw_double + | kw_enum + | kw_float + | kw_hyper + | kw_int + | kw_opaque + | kw_quadruple + | kw_string + | kw_struct + | kw_switch + | kw_typedef + | kw_union + | kw_unsigned + | kw_void + ) +); #[test] fn test_kw() { - let kws = vec!("bool", "case", "const", "default", - "double", "enum", "float", "hyper", "int", - "opaque", "quadruple", "string", "struct", - "switch", "typedef", "union", "unsigned", "void"); + let kws = vec![ + "bool", + "case", + "const", + "default", + "double", + "enum", + "float", + "hyper", + "int", + "opaque", + "quadruple", + "string", + "struct", + "switch", + "typedef", + "union", + "unsigned", + "void", + ]; for k in &kws { println!("testing \"{}\"", k); @@ -307,24 +353,21 @@ fn test_kw() { } } - for nk in &vec!("boo", "in", "inx", "booll") { + for nk in &vec!["boo", "in", "inx", "booll"] { match keyword((*nk).as_bytes()) { e @ Done(..) => panic!("{:?} => {:?}", nk, e), e => println!("{:?} => {:?}", nk, e), } } - } fn ident(input: &[u8]) -> IResult<&[u8], &str> { // Grab an identifier and make sure it isn't a keyword match token(input) { - Done(rest, val) => { - match keyword(input) { - Done(..) => Error(Err::Position(ErrorKind::Custom(1), val)), - Error(..) | Incomplete(..) => Done(rest, str::from_utf8(val).unwrap()), - } - } + Done(rest, val) => match keyword(input) { + Done(..) => Error(Err::Position(ErrorKind::Custom(1), val)), + Error(..) | Incomplete(..) => Done(rest, str::from_utf8(val).unwrap()), + }, Error(e) => Error(e), Incomplete(need) => Incomplete(need), } @@ -334,70 +377,96 @@ fn ident(input: &[u8]) -> IResult<&[u8], &str> { fn test_ident() { assert_eq!(ident(&b"foo "[..]), Done(&b" "[..], "foo")); assert_eq!(ident(&b" foo "[..]), Done(&b" "[..], "foo")); - assert_eq!(ident(&b" bool "[..]), Error(Err::Position(ErrorKind::Custom(1), &b"bool"[..]))); + assert_eq!( + ident(&b" bool "[..]), + Error(Err::Position(ErrorKind::Custom(1), &b"bool"[..])) + ); } -named!(blockcomment<()>, - do_parse!(apply!(ctag, "/*") >> take_until_and_consume!(&b"*/"[..]) >> (()))); +named!( + blockcomment<()>, + do_parse!(apply!(ctag, "/*") >> take_until_and_consume!(&b"*/"[..]) >> (())) +); // `linecomment`, and `directive` end at eol, but do not consume it -named!(linecomment<()>, - do_parse!( - apply!(ctag, "//") >> opt!(not_line_ending) >> peek!(alt!(eol | eof)) >> (()) - ) +named!( + linecomment<()>, + do_parse!(apply!(ctag, "//") >> opt!(not_line_ending) >> peek!(alt!(eol | eof)) >> (())) ); // Directive should always follow eol unless its the first thing in the file -named!(directive<()>, +named!( + directive<()>, do_parse!( - opt!(whitespace) >> - alt!( - apply!(ctag, "#") | - apply!(ctag, "%")) >> - opt!(not_line_ending) >> - peek!(alt!(eol | eof)) >> (()) + opt!(whitespace) + >> alt!(apply!(ctag, "#") | apply!(ctag, "%")) + >> opt!(not_line_ending) + >> peek!(alt!(eol | eof)) + >> (()) ) ); #[test] fn test_comments() { assert_eq!(blockcomment(&b"/* foo */bar"[..]), Done(&b"bar"[..], ())); - assert_eq!(blockcomment(&b"/* blip /* foo */bar"[..]), Done(&b"bar"[..], ())); - assert_eq!(blockcomment(&b"x"[..]), Error(Err::Position(ErrorKind::Tag, &b"x"[..]))); + assert_eq!( + blockcomment(&b"/* blip /* foo */bar"[..]), + Done(&b"bar"[..], ()) + ); + assert_eq!( + blockcomment(&b"x"[..]), + Error(Err::Position(ErrorKind::Tag, &b"x"[..])) + ); assert_eq!(linecomment(&b"// foo\nbar"[..]), Done(&b"\nbar"[..], ())); assert_eq!(linecomment(&b"// foo bar\n "[..]), Done(&b"\n "[..], ())); - assert_eq!(linecomment(&b"x"[..]), Error(Err::Position(ErrorKind::Tag, &b"x"[..]))); + assert_eq!( + linecomment(&b"x"[..]), + Error(Err::Position(ErrorKind::Tag, &b"x"[..])) + ); assert_eq!(directive(&b"#define foo bar\n "[..]), Done(&b"\n "[..], ())); - assert_eq!(directive(&b"%#define foo bar\n "[..]), Done(&b"\n "[..], ())); - - assert_eq!(directive(&b"x"[..]), Error(Err::Position(ErrorKind::Alt, &b"x"[..]))); - - assert_eq!(preceded!(&b"\n#define x\n"[..], eol, directive), - Done(&b"\n"[..], ())); + assert_eq!( + directive(&b"%#define foo bar\n "[..]), + Done(&b"\n "[..], ()) + ); + + assert_eq!( + directive(&b"x"[..]), + Error(Err::Position(ErrorKind::Alt, &b"x"[..])) + ); + + assert_eq!( + preceded!(&b"\n#define x\n"[..], eol, directive), + Done(&b"\n"[..], ()) + ); } -named!(eol<()>, map!(alt!(apply!(ctag, "\n") | - apply!(ctag, "\r\n") | - apply!(ctag, "\u{2028}") | - apply!(ctag, "\u{2029}")), - ignore) - ); +named!( + eol<()>, + map!( + alt!( + apply!(ctag, "\n") + | apply!(ctag, "\r\n") + | apply!(ctag, "\u{2028}") + | apply!(ctag, "\u{2029}") + ), + ignore + ) +); -named!(whitespace<()>, - map!(take_while1!(is_space), ignore)); +named!(whitespace<()>, map!(take_while1!(is_space), ignore)); // `spaces` consumes spans of space and tab characters interpolated // with comments, c-preproc and passthrough lines. -named!(spaces<()>, +named!( + spaces<()>, map!( - many0!( - alt!( do_parse!(eol >> opt!(complete!(directive)) >> (())) + many0!(alt!( + do_parse!(eol >> opt!(complete!(directive)) >> (())) | whitespace | blockcomment | linecomment - ) - ), + )), ignore ) ); @@ -415,7 +484,10 @@ fn test_spaces() { assert_eq!(eol(&b"\r\nx"[..]), Done(&b"x"[..], ())); assert_eq!(eol(&b"\nx"[..]), Done(&b"x"[..], ())); - assert_eq!(whitespace(&b"x"[..]), Error(Err::Position(ErrorKind::TakeWhile1, &b"x"[..]))); + assert_eq!( + whitespace(&b"x"[..]), + Error(Err::Position(ErrorKind::TakeWhile1, &b"x"[..])) + ); assert_eq!(whitespace(&b" x"[..]), Done(&b"x"[..], ())); assert_eq!(whitespace(&b" x"[..]), Done(&b"x"[..], ())); assert_eq!(whitespace(&b"\tx"[..]), Done(&b"x"[..], ())); @@ -434,148 +506,209 @@ fn test_spaces() { assert_eq!(spaces(&b"\n%foo a b\n x"[..]), Done(&b"x"[..], ())); } -named!(enum_type_spec< Vec >, - preceded!(kw_enum, enum_body)); +named!(enum_type_spec>, preceded!(kw_enum, enum_body)); -named!(enum_body< Vec >, - do_parse!( - lbrace >> - b: separated_nonempty_list!(comma, enum_assign) >> - rbrace >> - (b) - ) +named!( + enum_body>, + do_parse!(lbrace >> b: separated_nonempty_list!(comma, enum_assign) >> rbrace >> (b)) ); -named!(enum_assign, - do_parse!( - id: ident >> - v: opt!(preceded!(eq, value)) >> - (EnumDefn::new(id, v)) - ) +named!( + enum_assign, + do_parse!(id: ident >> v: opt!(preceded!(eq, value)) >> (EnumDefn::new(id, v))) ); -named!(value, - alt!(number => { |c| Value::Const(c) } | - ident => { |id| Value::ident(id) } - ) - ); +named!( + value, + alt!(number => { |c| Value::Const(c) } | + ident => { |id| Value::ident(id) } + ) +); -named!(struct_type_spec< Vec >, - preceded!(kw_struct, struct_body)); +named!( + struct_type_spec>, + preceded!(kw_struct, struct_body) +); -named!(struct_body< Vec >, - do_parse!( - lbrace >> - decls: many1!(terminated!(declaration, semi)) >> - rbrace >> - (decls) - ) +named!( + struct_body>, + do_parse!(lbrace >> decls: many1!(terminated!(declaration, semi)) >> rbrace >> (decls)) ); -named!(union_type_spec<(Decl, Vec, Option)>, - do_parse!(kw_union >> body:union_body >> (body))); +named!( + union_type_spec<(Decl, Vec, Option)>, + do_parse!(kw_union >> body: union_body >> (body)) +); -named!(union_body<(Decl, Vec, Option)>, +named!( + union_body<(Decl, Vec, Option)>, do_parse!( - kw_switch >> lparen >> decl:declaration >> rparen >> - lbrace >> - ucss: many1!(union_case) >> - dfl: opt!(union_default) >> - rbrace >> - (decl, ucss.into_iter().flat_map(|v| v).collect(), dfl) + kw_switch + >> lparen + >> decl: declaration + >> rparen + >> lbrace + >> ucss: many1!(union_case) + >> dfl: opt!(union_default) + >> rbrace + >> (decl, ucss.into_iter().flat_map(|v| v).collect(), dfl) ) ); -named!(union_case< Vec >, +named!( + union_case>, do_parse!( - vs: many1!(do_parse!(kw_case >> v:value >> colon >> (v))) >> - decl: declaration >> semi >> - (vs.into_iter().map(|v| UnionCase(v, decl.clone())).collect()) + vs: many1!(do_parse!(kw_case >> v: value >> colon >> (v))) + >> decl: declaration + >> semi + >> (vs.into_iter().map(|v| UnionCase(v, decl.clone())).collect()) ) ); -named!(union_default, - do_parse!( - kw_default >> colon >> - decl: declaration >> semi >> - (decl) - ) +named!( + union_default, + do_parse!(kw_default >> colon >> decl: declaration >> semi >> (decl)) ); -named!(declaration, +named!( + declaration, alt!(kw_void => { |_| Decl::Void } | - nonvoid_declaration)); + nonvoid_declaration) +); -named!(nonvoid_declaration, +named!( + nonvoid_declaration, alt!( - do_parse!(ty: array_type_spec >> id: ident >> lbrack >> sz:value >> rbrack >> - (Decl::named(id, Type::array(ty, sz)))) - | do_parse!(ty: array_type_spec >> id: ident >> lt >> sz:opt!(value) >> gt >> - (Decl::named(id, Type::flex(ty, sz)))) - | do_parse!(ty: type_spec >> star >> id: ident >> - (Decl::named(id, Type::option(ty)))) - | do_parse!(ty: type_spec >> id: ident >> - (Decl::named(id, ty))) + do_parse!( + ty: array_type_spec + >> id: ident + >> lbrack + >> sz: value + >> rbrack + >> (Decl::named(id, Type::array(ty, sz))) + ) | do_parse!( + ty: array_type_spec + >> id: ident + >> lt + >> sz: opt!(value) + >> gt + >> (Decl::named(id, Type::flex(ty, sz))) + ) | do_parse!(ty: type_spec >> star >> id: ident >> (Decl::named(id, Type::option(ty)))) + | do_parse!(ty: type_spec >> id: ident >> (Decl::named(id, ty))) ) ); -named!(array_type_spec, - alt!(kw_opaque => { |_| Type::Opaque } | - kw_string => { |_| Type::String } | - type_spec - ) - ); +named!( + array_type_spec, + alt!(kw_opaque => { |_| Type::Opaque } | + kw_string => { |_| Type::String } | + type_spec + ) +); #[test] fn test_decls() { assert_eq!(declaration(&b"void "[..]), Done(&b" "[..], Decl::Void)); - assert_eq!(declaration(&b"int foo;"[..]), Done(&b";"[..], Decl::named("foo", Type::Int))); - assert_eq!(declaration(&b"int foo[123] "[..]), - Done(&b" "[..], Decl::named("foo", - Type::Array(Box::new(Type::Int), Value::Const(123))))); - - assert_eq!(declaration(&b"int foo<123> "[..]), - Done(&b" "[..], Decl::named("foo", - Type::Flex(Box::new(Type::Int), Some(Value::Const(123)))))); - assert_eq!(declaration(&b"int foo<> "[..]), - Done(&b" "[..], Decl::named("foo", - Type::Flex(Box::new(Type::Int), None)))); - assert_eq!(declaration(&b"int *foo "[..]), - Done(&b" "[..], Decl::named("foo", - Type::Option(Box::new(Type::Int))))); - - assert_eq!(declaration(&b"opaque foo[123] "[..]), - Done(&b" "[..], Decl::named("foo", - Type::Array(Box::new(Type::Opaque), Value::Const(123))))); - assert_eq!(declaration(&b"opaque foo<123> "[..]), - Done(&b" "[..], Decl::named("foo", - Type::Flex(Box::new(Type::Opaque), Some(Value::Const(123)))))); - assert_eq!(declaration(&b"opaque foo<> "[..]), - Done(&b" "[..], Decl::named("foo", - Type::Flex(Box::new(Type::Opaque), None)))); - - assert_eq!(declaration(&b"string foo<123> "[..]), - Done(&b" "[..], Decl::named("foo", - Type::Flex(Box::new(Type::String), Some(Value::Const(123)))))); - assert_eq!(declaration(&b"string foo<> "[..]), - Done(&b" "[..], Decl::named("foo", - Type::Flex(Box::new(Type::String), None)))); + assert_eq!( + declaration(&b"int foo;"[..]), + Done(&b";"[..], Decl::named("foo", Type::Int)) + ); + assert_eq!( + declaration(&b"int foo[123] "[..]), + Done( + &b" "[..], + Decl::named("foo", Type::Array(Box::new(Type::Int), Value::Const(123))) + ) + ); + + assert_eq!( + declaration(&b"int foo<123> "[..]), + Done( + &b" "[..], + Decl::named( + "foo", + Type::Flex(Box::new(Type::Int), Some(Value::Const(123))) + ) + ) + ); + assert_eq!( + declaration(&b"int foo<> "[..]), + Done( + &b" "[..], + Decl::named("foo", Type::Flex(Box::new(Type::Int), None)) + ) + ); + assert_eq!( + declaration(&b"int *foo "[..]), + Done( + &b" "[..], + Decl::named("foo", Type::Option(Box::new(Type::Int))) + ) + ); + + assert_eq!( + declaration(&b"opaque foo[123] "[..]), + Done( + &b" "[..], + Decl::named( + "foo", + Type::Array(Box::new(Type::Opaque), Value::Const(123)) + ) + ) + ); + assert_eq!( + declaration(&b"opaque foo<123> "[..]), + Done( + &b" "[..], + Decl::named( + "foo", + Type::Flex(Box::new(Type::Opaque), Some(Value::Const(123))) + ) + ) + ); + assert_eq!( + declaration(&b"opaque foo<> "[..]), + Done( + &b" "[..], + Decl::named("foo", Type::Flex(Box::new(Type::Opaque), None)) + ) + ); + + assert_eq!( + declaration(&b"string foo<123> "[..]), + Done( + &b" "[..], + Decl::named( + "foo", + Type::Flex(Box::new(Type::String), Some(Value::Const(123))) + ) + ) + ); + assert_eq!( + declaration(&b"string foo<> "[..]), + Done( + &b" "[..], + Decl::named("foo", Type::Flex(Box::new(Type::String), None)) + ) + ); } -named!(type_spec, - preceded!(spaces, +named!( + type_spec, + preceded!( + spaces, alt!( do_parse!(kw_unsigned >> kw_int >> (Type::UInt)) | do_parse!(kw_unsigned >> kw_long >> (Type::UInt)) | // backwards compat with rpcgen do_parse!(kw_unsigned >> kw_char >> // backwards compat with rpcgen - (Type::ident_with_derives("u8", COPY | CLONE | EQ | PARTIALEQ | DEBUG))) | + (Type::ident_with_derives("u8", Derives::COPY | Derives::CLONE | Derives::EQ | Derives::PARTIALEQ | Derives::DEBUG))) | do_parse!(kw_unsigned >> kw_short >> (Type::UInt)) | // backwards compat with rpcgen do_parse!(kw_unsigned >> kw_hyper >> (Type::UHyper)) | kw_unsigned => { |_| Type::UInt } | // backwards compat with rpcgen kw_long => { |_| Type::Int } | // backwards compat with rpcgen kw_char => { // backwards compat with rpcgen - |_| Type::ident_with_derives("i8", COPY | CLONE | EQ | PARTIALEQ | DEBUG) + |_| Type::ident_with_derives("i8", Derives::COPY | Derives::CLONE | Derives::EQ | Derives::PARTIALEQ | Derives::DEBUG) } | kw_short => { |_| Type::Int } | // backwards compat with rpcgen kw_int => { |_| Type::Int } | @@ -596,116 +729,242 @@ named!(type_spec, #[test] fn test_type() { assert_eq!(type_spec(&b"int "[..]), Done(&b" "[..], Type::Int)); - assert_eq!(type_spec(&b"unsigned int "[..]), Done(&b" "[..], Type::UInt)); - assert_eq!(type_spec(&b"unsigned\nint "[..]), Done(&b" "[..], Type::UInt)); - assert_eq!(type_spec(&b"unsigned/* foo */int "[..]), Done(&b" "[..], Type::UInt)); - assert_eq!(type_spec(&b"unsigned//\nint "[..]), Done(&b" "[..], Type::UInt)); - - assert_eq!(type_spec(&b"unsigned hyper "[..]), Done(&b" "[..], Type::UHyper)); - - assert_eq!(type_spec(&b"unsigned char "[..]), Done(&b" "[..], - Type::Ident("u8".into(), Some(COPY | CLONE | EQ | PARTIALEQ | DEBUG)))); - assert_eq!(type_spec(&b"unsigned short "[..]), Done(&b" "[..], Type::UInt)); + assert_eq!( + type_spec(&b"unsigned int "[..]), + Done(&b" "[..], Type::UInt) + ); + assert_eq!( + type_spec(&b"unsigned\nint "[..]), + Done(&b" "[..], Type::UInt) + ); + assert_eq!( + type_spec(&b"unsigned/* foo */int "[..]), + Done(&b" "[..], Type::UInt) + ); + assert_eq!( + type_spec(&b"unsigned//\nint "[..]), + Done(&b" "[..], Type::UInt) + ); + + assert_eq!( + type_spec(&b"unsigned hyper "[..]), + Done(&b" "[..], Type::UHyper) + ); + + assert_eq!( + type_spec(&b"unsigned char "[..]), + Done( + &b" "[..], + Type::Ident( + "u8".into(), + Some( + Derives::COPY + | Derives::CLONE + | Derives::EQ + | Derives::PARTIALEQ + | Derives::DEBUG + ) + ) + ) + ); + assert_eq!( + type_spec(&b"unsigned short "[..]), + Done(&b" "[..], Type::UInt) + ); assert_eq!(type_spec(&b" hyper "[..]), Done(&b" "[..], Type::Hyper)); assert_eq!(type_spec(&b" double "[..]), Done(&b" "[..], Type::Double)); - assert_eq!(type_spec(&b"// thing\nquadruple "[..]), Done(&b" "[..], Type::Quadruple)); - assert_eq!(type_spec(&b"// thing\n bool "[..]), Done(&b" "[..], Type::Bool)); - - assert_eq!(type_spec(&b"char "[..]), Done(&b" "[..], - Type::Ident("i8".into(), Some(COPY | CLONE | EQ | PARTIALEQ | DEBUG)))); + assert_eq!( + type_spec(&b"// thing\nquadruple "[..]), + Done(&b" "[..], Type::Quadruple) + ); + assert_eq!( + type_spec(&b"// thing\n bool "[..]), + Done(&b" "[..], Type::Bool) + ); + + assert_eq!( + type_spec(&b"char "[..]), + Done( + &b" "[..], + Type::Ident( + "i8".into(), + Some( + Derives::COPY + | Derives::CLONE + | Derives::EQ + | Derives::PARTIALEQ + | Derives::DEBUG + ) + ) + ) + ); assert_eq!(type_spec(&b"short "[..]), Done(&b" "[..], Type::Int)); - - assert_eq!(type_spec(&b"struct { int a; int b; } "[..]), - Done(&b" "[..], - Type::Struct(vec!(Decl::named("a", Type::Int), - Decl::named("b", Type::Int))))); - - assert_eq!(type_spec(&b"union switch (int a) { case 1: void; case 2: int a; default: void; } "[..]), - Done(&b" "[..], - Type::Union(Box::new(Decl::named("a", Type::Int)), - vec!(UnionCase(Value::Const(1), Decl::Void), - UnionCase(Value::Const(2), Decl::named("a", Type::Int))), - Some(Box::new(Decl::Void))))); + assert_eq!( + type_spec(&b"struct { int a; int b; } "[..]), + Done( + &b" "[..], + Type::Struct(vec!( + Decl::named("a", Type::Int), + Decl::named("b", Type::Int) + )) + ) + ); + + assert_eq!( + type_spec(&b"union switch (int a) { case 1: void; case 2: int a; default: void; } "[..]), + Done( + &b" "[..], + Type::Union( + Box::new(Decl::named("a", Type::Int)), + vec!( + UnionCase(Value::Const(1), Decl::Void), + UnionCase(Value::Const(2), Decl::named("a", Type::Int)) + ), + Some(Box::new(Decl::Void)) + ) + ) + ); } #[test] fn test_enum() { - assert_eq!(type_spec(&b"enum { a, b, c } "[..]), - Done(&b" "[..], - Type::Enum(vec!(EnumDefn::new("a", None), - EnumDefn::new("b", None), - EnumDefn::new("c", None))))); - - assert_eq!(type_spec(&b"enum { a = 1, b, c } "[..]), - Done(&b" "[..], - Type::Enum(vec!(EnumDefn::new("a", Some(Value::Const(1))), - EnumDefn::new("b", None), - EnumDefn::new("c", None))))); - - assert_eq!(type_spec(&b"enum { a = Bar, b, c } "[..]), - Done(&b" "[..], - Type::Enum(vec!(EnumDefn::new("a", Some(Value::ident("Bar"))), - EnumDefn::new("b", None), - EnumDefn::new("c", None))))); - - assert_eq!(type_spec(&b"enum { } "[..]), - Error(Err::Position(ErrorKind::Alt, &b"enum { } "[..]))); + assert_eq!( + type_spec(&b"enum { a, b, c } "[..]), + Done( + &b" "[..], + Type::Enum(vec!( + EnumDefn::new("a", None), + EnumDefn::new("b", None), + EnumDefn::new("c", None) + )) + ) + ); + + assert_eq!( + type_spec(&b"enum { a = 1, b, c } "[..]), + Done( + &b" "[..], + Type::Enum(vec!( + EnumDefn::new("a", Some(Value::Const(1))), + EnumDefn::new("b", None), + EnumDefn::new("c", None) + )) + ) + ); + + assert_eq!( + type_spec(&b"enum { a = Bar, b, c } "[..]), + Done( + &b" "[..], + Type::Enum(vec!( + EnumDefn::new("a", Some(Value::ident("Bar"))), + EnumDefn::new("b", None), + EnumDefn::new("c", None) + )) + ) + ); + + assert_eq!( + type_spec(&b"enum { } "[..]), + Error(Err::Position(ErrorKind::Alt, &b"enum { } "[..])) + ); } -named!(const_def, - do_parse!( - kw_const >> id:ident >> eq >> v:number >> semi >> - (Defn::constant(id, v))) +named!( + const_def, + do_parse!(kw_const >> id: ident >> eq >> v: number >> semi >> (Defn::constant(id, v))) ); #[test] fn test_const() { - assert_eq!(const_def(&b"const foo = 123;"[..]), Done(&b""[..], Defn::constant("foo", 123))); + assert_eq!( + const_def(&b"const foo = 123;"[..]), + Done(&b""[..], Defn::constant("foo", 123)) + ); } -named!(type_def, +named!( + type_def, alt!( - do_parse!(kw_typedef >> decl: nonvoid_declaration >> semi >> - ({ - match decl.clone() { - Decl::Named(name, ty) => { - if ty.is_syn() { - Defn::typesyn(name, ty) - } else { - Defn::typespec(name, ty) + do_parse!( + kw_typedef + >> decl: nonvoid_declaration + >> semi + >> ({ + match decl.clone() { + Decl::Named(name, ty) => { + if ty.is_syn() { + Defn::typesyn(name, ty) + } else { + Defn::typespec(name, ty) + } } - }, - Decl::Void => panic!("void non-void declaration?"), - } - }) + Decl::Void => panic!("void non-void declaration?"), + } + }) + ) | do_parse!( + kw_enum >> id: ident >> e: enum_body >> semi >> (Defn::typespec(id, Type::Enum(e))) + ) | do_parse!( + kw_struct + >> id: ident + >> s: struct_body + >> semi + >> (Defn::typespec(id, Type::Struct(s))) + ) | do_parse!( + kw_union >> id: ident >> u: union_body >> semi >> (Defn::typespec(id, Type::union(u))) ) - | do_parse!(kw_enum >> id:ident >> e:enum_body >> semi >> (Defn::typespec(id, Type::Enum(e)))) - | do_parse!(kw_struct >> id:ident >> s:struct_body >> semi >> (Defn::typespec(id, Type::Struct(s)))) - | do_parse!(kw_union >> id:ident >> u:union_body >> semi >> (Defn::typespec(id, Type::union(u)))) ) ); #[test] fn test_typedef() { - assert_eq!(type_def(&b"typedef int foo;"[..]), - Done(&b""[..], Defn::typesyn("foo", Type::Int))); - assert_eq!(type_def(&b"typedef unsigned int foo;"[..]), - Done(&b""[..], Defn::typesyn("foo", Type::UInt))); - assert_eq!(type_def(&b"typedef int foo<>;"[..]), - Done(&b""[..], Defn::typespec("foo", Type::Flex(Box::new(Type::Int), None)))); - - assert_eq!(type_def(&b"enum foo { a };"[..]), - Done(&b""[..], Defn::typespec("foo", Type::Enum(vec!(EnumDefn::new("a", None)))))); - - assert_eq!(type_def(&b"struct foo { int a; };"[..]), - Done(&b""[..], Defn::typespec("foo", Type::Struct(vec!(Decl::named("a", Type::Int)))))); - - assert_eq!(type_def(&b"union foo switch(int a) { case 1: int a; };"[..]), - Done(&b""[..], Defn::typespec("foo", - Type::Union(Box::new(Decl::named("a", Type::Int)), - vec!(UnionCase(Value::Const(1), Decl::named("a", Type::Int))), - None)))); + assert_eq!( + type_def(&b"typedef int foo;"[..]), + Done(&b""[..], Defn::typesyn("foo", Type::Int)) + ); + assert_eq!( + type_def(&b"typedef unsigned int foo;"[..]), + Done(&b""[..], Defn::typesyn("foo", Type::UInt)) + ); + assert_eq!( + type_def(&b"typedef int foo<>;"[..]), + Done( + &b""[..], + Defn::typespec("foo", Type::Flex(Box::new(Type::Int), None)) + ) + ); + + assert_eq!( + type_def(&b"enum foo { a };"[..]), + Done( + &b""[..], + Defn::typespec("foo", Type::Enum(vec!(EnumDefn::new("a", None)))) + ) + ); + + assert_eq!( + type_def(&b"struct foo { int a; };"[..]), + Done( + &b""[..], + Defn::typespec("foo", Type::Struct(vec!(Decl::named("a", Type::Int)))) + ) + ); + + assert_eq!( + type_def(&b"union foo switch(int a) { case 1: int a; };"[..]), + Done( + &b""[..], + Defn::typespec( + "foo", + Type::Union( + Box::new(Decl::named("a", Type::Int)), + vec!(UnionCase(Value::Const(1), Decl::named("a", Type::Int))), + None + ) + ) + ) + ); } diff --git a/xdrgen/src/xdrgen.rs b/xdrgen/src/xdrgen.rs index 7422664..d3a9018 100644 --- a/xdrgen/src/xdrgen.rs +++ b/xdrgen/src/xdrgen.rs @@ -1,12 +1,12 @@ #![crate_type = "bin"] -extern crate xdrgen; -extern crate env_logger; extern crate clap; +extern crate env_logger; +extern crate xdrgen; use std::fs::File; -use std::io::{BufReader, Write}; use std::io::{stderr, stdin, stdout}; +use std::io::{BufReader, Write}; use clap::App; diff --git a/xdrgen/tests/lib.rs b/xdrgen/tests/lib.rs index 4817b5e..c696a39 100644 --- a/xdrgen/tests/lib.rs +++ b/xdrgen/tests/lib.rs @@ -1,15 +1,15 @@ -extern crate xdrgen; -extern crate xdr_codec; extern crate tempdir; +extern crate xdr_codec; +extern crate xdrgen; #[macro_use] extern crate error_chain; -use std::fs::{File, create_dir_all}; +use std::fs::{create_dir_all, File}; use std::io::{Cursor, Write}; use std::process::Command; -use xdrgen::generate; use xdr_codec::Result; +use xdrgen::generate; fn build_test(name: &str, xdr_spec: &str) -> Result<()> { let tempdir = tempdir::TempDir::new("build").expect("Failed to make tempdir");