1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! A entry can have a number of attributes: [https://www.kernel.org/doc/html/next/kbuild/kconfig-language.html#menu-attributes](https://www.kernel.org/doc/html/next/kbuild/kconfig-language.html#menu-attributes)

pub mod default;
pub mod depends_on;
pub mod enable;
pub mod expression;
pub mod function;
pub mod help;
pub mod imply;
pub mod modules;
pub mod option;
pub mod optional;
pub mod prompt;
pub mod range;
pub mod requires;
pub mod select;
pub mod r#type;
pub mod visible;

use nom::{branch::alt, combinator::map, multi::many0, IResult};
#[cfg(feature = "deserialize")]
use serde::Deserialize;
#[cfg(feature = "serialize")]
use serde::Serialize;

use crate::{util::ws, KconfigInput};

use self::r#type::ConfigType;
pub use self::{
    default::{parse_default, DefaultAttribute},
    depends_on::parse_depends_on,
    enable::{parse_enable, Enable},
    expression::Expression,
    help::parse_help,
    imply::{parse_imply, Imply},
    modules::parse_modules,
    option::{parse_option, OptionValues},
    prompt::{parse_prompt, parse_prompt_option, Prompt},
    range::{parse_range, Range},
    requires::{parse_requires, Requires},
    select::{parse_select, Select},
    visible::{parse_visible, Visible},
};

pub use self::expression::{
    parse_expression, parse_if_attribute, AndExpression, Atom, CompareExpression, CompareOperator,
    OrExpression, Term,
};
pub use self::function::{parse_function_call, ExpressionToken, FunctionCall, Parameter};
pub use self::optional::parse_optional;

/// Official documentation regarding the different attributes: [https://www.kernel.org/doc/html/next/kbuild/kconfig-language.html#menu-attributes](https://www.kernel.org/doc/html/next/kbuild/kconfig-language.html#menu-attributes)
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "hash", derive(Hash))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
pub enum Attribute {
    Help(String),
    Prompt(Prompt),
    Modules,
    Select(Select),
    DependsOn(Expression),
    Optional,
    Range(Range),
    Visible(Visible),
    Default(DefaultAttribute),
    Enable(Enable),
    Imply(Imply),
    Requires(Requires),
    Type(ConfigType),
    Option(OptionValues),
}

pub fn parse_attributes(input: KconfigInput) -> IResult<KconfigInput, Vec<Attribute>> {
    ws(many0(parse_attribute))(input)
}

pub fn parse_attribute(input: KconfigInput) -> IResult<KconfigInput, Attribute> {
    alt((
        map(ws(parse_prompt), Attribute::Prompt),
        map(ws(parse_help), Attribute::Help),
        ws(parse_depends_on),
        map(ws(parse_select), Attribute::Select),
        map(ws(parse_default), Attribute::Default),
        map(ws(parse_requires), Attribute::Requires),
        map(ws(parse_modules), |_| Attribute::Modules),
        map(ws(parse_range), Attribute::Range),
        map(ws(parse_imply), Attribute::Imply),
        map(ws(parse_visible), Attribute::Visible),
        map(ws(parse_option), Attribute::Option),
        map(ws(parse_enable), Attribute::Enable),
    ))(input)
}

#[cfg(test)]
mod default_test;
#[cfg(test)]
mod depends_on_test;
#[cfg(test)]
mod enable_test;
#[cfg(test)]
mod expression_test;
#[cfg(test)]
mod function_test;
#[cfg(test)]
mod help_test;
#[cfg(test)]
mod imply_test;
#[cfg(test)]
mod mod_test;
#[cfg(test)]
mod modules_test;
#[cfg(test)]
mod option_test;
#[cfg(test)]
mod optional_test;
#[cfg(test)]
mod prompt_test;
#[cfg(test)]
mod range_test;
#[cfg(test)]
mod requires_test;
#[cfg(test)]
mod select_test;
#[cfg(test)]
mod type_test;
#[cfg(test)]
mod visible_test;