ldscript_parser/
commands.rs1use expressions::expression;
2use expressions::Expression;
3use idents::{pattern, symbol};
4use nom::branch::alt;
5use nom::bytes::complete::tag;
6use nom::combinator::map;
7use nom::combinator::opt;
8use nom::multi::separated_list1;
9use nom::sequence::pair;
10use nom::IResult;
11use whitespace::{opt_space, space};
12
13#[derive(Debug, PartialEq)]
14pub enum InsertOrder {
15 Before,
16 After,
17}
18
19#[derive(Debug, PartialEq)]
20pub enum Command {
21 Call {
23 name: String,
24 arguments: Vec<Expression>,
25 },
26 Include {
27 file: String,
28 },
29 Insert {
30 order: InsertOrder,
31 section: String,
32 },
33}
34
35fn inset_order(input: &str) -> IResult<&str, InsertOrder> {
36 alt((
37 map(tag("BEFORE"), |_| InsertOrder::Before),
38 map(tag("AFTER"), |_| InsertOrder::After),
39 ))(input)
40}
41
42fn call(input: &str) -> IResult<&str, Command> {
43 let (input, name) = symbol(input)?;
44 let (input, _) = wsc!(tag("("))(input)?;
45 let (input, args) = separated_list1(alt((space, wsc!(tag(",")))), expression)(input)?;
46 let (input, _) = pair(wsc!(tag(")")), opt(tag(";")))(input)?;
47 Ok((
48 input,
49 Command::Call {
50 name: name.into(),
51 arguments: args,
52 },
53 ))
54}
55
56fn include(input: &str) -> IResult<&str, Command> {
57 let (input, _) = pair(tag("INCLUDE"), space)(input)?;
58 let (input, file) = pattern(input)?;
59 let (input, _) = pair(opt_space, opt(tag(";")))(input)?;
60 Ok((input, Command::Include { file: file.into() }))
61}
62
63fn insert(input: &str) -> IResult<&str, Command> {
64 let (input, _) = tag("INSERT")(input)?;
65 let (input, order) = wsc!(inset_order)(input)?;
66 let (input, section) = symbol(input)?;
67 let (input, _) = pair(opt_space, opt(tag(";")))(input)?;
68 Ok((
69 input,
70 Command::Insert {
71 order,
72 section: section.into(),
73 },
74 ))
75}
76
77pub fn command(input: &str) -> IResult<&str, Command> {
78 alt((include, call, insert))(input)
79}
80
81#[cfg(test)]
82mod tests {
83 use commands::*;
84
85 #[test]
86 fn test_command() {
87 assert_done!(command("OUTPUT_ARCH ( 0 ) ;"));
88 assert_done!(command("OUTPUT_ARCH ( 0 )"));
89 assert_done!(command("OUTPUT_ARCH ( 0 1 2 )"));
90 assert_done!(command("OUTPUT_ARCH ( 0, 1 2 )"));
91 assert_done!(command("OUTPUT_ARCH ( 0, 1, 2 )"));
92
93 assert_fail!(command("OUTPUT_ARCH ( 0, 1, 2, )"));
94 assert_fail!(command("OUTPUT_ARCH ( )"));
95
96 assert_done!(command("INCLUDE abc.h ;"));
97 assert_done!(command("INCLUDE\tabc.h"));
98
99 assert_done!(command("INSERT BEFORE .text ;"));
100 assert_done!(command("INSERT AFTER .text"));
101 }
102}