nom_kconfig/util.rs
1use nom::{
2 branch::alt,
3 bytes::complete::tag,
4 character::complete::{line_ending, multispace1, not_line_ending, space1},
5 combinator::{eof, value},
6 error::ParseError,
7 multi::many0,
8 sequence::{preceded, terminated},
9 AsChar, Compare, IResult, Input, Parser,
10};
11
12use crate::KconfigInput;
13
14/// ignores comments
15///
16/// # Example
17/// ```
18/// use nom::combinator::eof;
19/// use nom::bytes::complete::tag;
20/// use nom_kconfig::util::ws_comment;
21/// let input = r#"# a comment# \
22///
23/// hello"#;
24/// assert_eq!(ws_comment::<&str, ()>(input), Ok(("hello", ())))
25/// ```
26pub fn ws_comment<I, E: ParseError<I>>(input: I) -> IResult<I, (), E>
27where
28 I: Clone + Input,
29 I: Compare<&'static str>,
30 <I as Input>::Item: AsChar,
31{
32 value(
33 (),
34 many0(alt((
35 // TODO 3.0.19/drivers/staging/iio/light/Kconfig, backslash??
36 preceded(
37 alt((tag("#"), tag("\\#"))),
38 terminated(not_line_ending, alt((line_ending, eof))),
39 ),
40 multispace1,
41 // TODO linux v3.2, in file /drivers/dma/Kconfig
42 tag(" "),
43 ))),
44 )
45 .parse(input)
46}
47/// Gets rid of comments, spaces, tabs and newlines.
48///
49/// # Example
50/// ```
51/// use nom::bytes::complete::tag;
52/// use nom::Parser;
53/// use nom_kconfig::util::ws;
54/// let input = r#"# a comment# \
55///
56/// hello"#;
57/// assert_eq!(ws(tag::<&str, &str, ()>("hello")).parse(input), Ok(("", "hello")))
58/// ```
59pub fn ws<I, F, O, E: ParseError<I>>(inner: F) -> impl Parser<I, Output = O, Error = E>
60where
61 I: Clone + Input,
62 I: Compare<&'static str>,
63 <I as Input>::Item: AsChar,
64 F: Parser<I, Output = O, Error = E>,
65{
66 preceded(ws_comment, inner)
67}
68
69/// Parses the content until EOF or new line.
70///
71/// # Example
72/// ```rust
73/// use nom::combinator::map;
74/// use nom_kconfig::util::parse_until_eol;
75/// use nom_kconfig::KconfigInput;
76///
77/// let input = KconfigInput::new_extra("parse me if you\ncan!", Default::default());
78/// let (remaining, line) = parse_until_eol(input).unwrap();
79/// assert_eq!(line.to_string(), "parse me if you");
80/// assert_eq!(remaining.to_string(), "can!");
81/// ```
82///
83pub fn parse_until_eol(input: KconfigInput) -> IResult<KconfigInput, KconfigInput> {
84 terminated(not_line_ending, alt((line_ending, eof))).parse(input)
85}
86
87/// Gets rid of spaces, tabs and backslash + newline.
88/// # Example
89/// ```
90/// use nom::bytes::complete::tag;
91/// use nom::Parser;
92/// use nom_kconfig::util::wsi;
93/// let input = r#" \
94/// hello"#;
95/// assert_eq!(wsi(tag::<&str, &str, ()>("hello")).parse(input), Ok(("", "hello")))
96/// ```
97pub fn wsi<I, F, O, E: ParseError<I>>(inner: F) -> impl Parser<I, Output = O, Error = E>
98where
99 I: Clone + Input,
100 I: Compare<&'static str>,
101 <I as Input>::Item: AsChar,
102 F: Parser<I, Output = O, Error = E>,
103{
104 preceded(
105 value((), many0(alt((preceded(tag("\\"), line_ending), space1)))),
106 inner,
107 )
108}