ldscript_parser/
whitespace.rs1use nom::{
2 branch::alt,
3 bytes::complete::{tag, take_until},
4 character::complete::multispace1,
5 combinator::recognize,
6 multi::{fold_many0, fold_many1},
7 sequence::delimited,
8 IResult,
9};
10
11pub fn comment(input: &str) -> IResult<&str, &str> {
12 delimited(tag("/*"), take_until("*/"), tag("*/"))(input)
13}
14
15pub fn space_or_comment(input: &str) -> IResult<&str, &str> {
16 alt((multispace1, comment))(input)
17}
18
19pub fn space(input: &str) -> IResult<&str, &str> {
20 recognize(fold_many1(space_or_comment, || (), |_, _| ()))(input)
21}
22
23pub fn opt_space(input: &str) -> IResult<&str, &str> {
24 recognize(fold_many0(space_or_comment, || (), |_, _| ()))(input)
25}
26
27macro_rules! wsc(
30 ($arg:expr) => ({
31 use $crate::whitespace::opt_space;
32 use nom::sequence::delimited;
33 delimited(opt_space, $arg, opt_space)
34 });
35
36 ($arg0:expr, $($args:expr),+) => ({
37 use $crate::whitespace::opt_space;
38 use nom::sequence::delimited;
39 use nom::sequence::tuple;
40 delimited(opt_space, tuple(($arg0, $($args),*)), opt_space)
41 })
42);
43
44#[cfg(test)]
45mod tests {
46 use nom::{
47 bytes::complete::{tag, take_while1},
48 multi::many0,
49 sequence::tuple,
50 };
51 use whitespace::opt_space;
52
53 fn is_good(c: char) -> bool {
54 c.is_alphanumeric() || c == '/' || c == '*'
55 }
56
57 #[test]
58 fn test_wsc() {
59 let mut test_parser = many0(wsc!(take_while1(is_good)));
60 let input = "a /* b */ c / * d /**/ e ";
61 assert_done!(test_parser(input), vec!["a", "c", "/", "*", "d", "e"]);
62 }
63
64 #[test]
65 fn test_opt_space() {
66 let mut test_parser = tuple((
67 tag("("),
68 opt_space,
69 take_while1(is_good),
70 opt_space,
71 tag(")"),
72 ));
73
74 let input1 = "( a )";
75 assert_done!(test_parser(input1));
76
77 let input2 = "(a)";
78 assert_done!(test_parser(input2));
79 }
80}