src/main.rs

Thu, 19 Oct 2023 11:49:38 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Thu, 19 Oct 2023 11:49:38 -0500
changeset 0
548bf3cc032e
child 2
254e1e4bd795
permissions
-rw-r--r--

Initial rough version

0
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
1 use std::io;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
2 use std::io::BufWriter;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
3 use std::io::Write;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
4
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
5 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
6 enum Element {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7 Added,
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
8 Deleted,
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
9 Replaced,
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
10 Other,
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
11 Comment,
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
13
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
14 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
15 enum Status {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
16 Output(Element),
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
17 Ignore(Element),
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
18 Scan(Element, bool),
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
19 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
20
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
21 fn main() {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
22 let input = io::stdin();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
23 let mut output = BufWriter::new(io::stdout());
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 let mut status_stack = Vec::new();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
26 use Status::*;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
27 use Element::*;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
28
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29 let current = |s : &Vec<Status>| s.last().map_or(Output(Other), |s| *s);
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
30 let mut out = |c : char| { write!(output, "{}", c).unwrap(); };
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
31 let mut lineno = 0;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
32
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 for l in input.lines().map(|l| l.unwrap()) {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34 lineno += 1;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
35 let mut chars = l.chars();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
36 let started_ignore = if let Ignore(_) = current(&status_stack) { true } else { false };
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
37 let mut maybe_next_char = None;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
38 'process_line: loop {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
39 let next_char = match maybe_next_char {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
40 None => chars.next(),
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
41 Some(c) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
42 maybe_next_char = None;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
43 Some(c)
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
44 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
45 };
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 match(current(&status_stack), next_char) {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
47 (_, None) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
48 break 'process_line;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
49 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
50 (st @ (Output(e) | Ignore(e)), Some('\\')) if e != Comment => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
51 let mut command = String::new();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 let mut first = true;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
53 maybe_next_char = 'scan_command: loop {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54 match chars.next() {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 Some(c) if first && (c=='{' || c=='}' || c=='\\') => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
56 command.push(c);
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 break 'scan_command None;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
58 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
59 Some(c) if c.is_alphanumeric() => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
60 command.push(c);
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
62 maybe_c => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
63 break 'scan_command maybe_c;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
64 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
65 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
66 first = false;
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
67 };
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
68 let output_guard = if let Ignore(_) = st { false } else { true };
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
69 match command.as_str() {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70 "added" => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 status_stack.push(Scan(Added, true && output_guard));
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
72 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 "replaced" => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74 status_stack.push(Scan(Replaced, true && output_guard));
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
76 "deleted" => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
77 status_stack.push(Scan(Deleted, false));
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
78 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
79 _ => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
80 if output_guard {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
81 out('\\');
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
82 command.chars().for_each(|c| out(c.clone()));
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
83 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
84 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
85 };
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
86 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
87 (Scan(next, o), Some(c)) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
88 match c {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
89 '{' => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
90 status_stack.pop();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
91 status_stack.push(if o { Output(next) } else { Ignore(next) });
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
92 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
93 ' ' => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
94 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
95 _ => panic!("Non-whitespace character ({c}) separating arguments on\
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
96 line {lineno}"),
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
97 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
98 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
99 (Output(e), Some('{')) if e != Comment => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
100 out('{');
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
101 status_stack.push(Output(Other));
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
102 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
103 (Ignore(e), Some('{')) if e != Comment => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
104 status_stack.push(Ignore(Other));
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
105 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
106 (Output(Added) | Ignore(Added) | Output(Deleted) | Ignore(Deleted), Some('}')) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
107 status_stack.pop();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
108 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
109 (Output(Replaced) | Ignore(Replaced), Some('}')) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
110 status_stack.pop();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
111 status_stack.push(Scan(Deleted, false));
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
112 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
113 (Output(Other), Some('}')) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
114 out('}');
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
115 status_stack.pop();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
116 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
117 (Ignore(_), Some('}')) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
118 status_stack.pop();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
119 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
120 (Output(e), Some('%')) if e != Comment=> {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
121 out('%');
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
122 status_stack.push(Output(Comment));
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
123 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
124 (Ignore(e), Some('%')) if e != Comment => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
125 status_stack.push(Ignore(Comment));
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
126 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
127 (Output(_), Some(c)) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
128 out(c);
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
129 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
130 (Ignore(_), Some(_)) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
131 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
132 };
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
133 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
134 match current(&status_stack) {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
135 Ignore(e) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
136 if !started_ignore {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
137 out('\n');
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
138 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
139 if e == Comment {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
140 status_stack.pop();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
141 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
142 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
143 Output(e) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
144 out('\n');
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
145 if e == Comment {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
146 status_stack.pop();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
147 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
148 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
149 Scan(_, _) => {
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
150 },
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
151 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
152 }
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
153
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
154 output.flush().unwrap();
548bf3cc032e Initial rough version
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
155 }

mercurial