nom_kconfig/
util.rs

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