1#[macro_export]
12macro_rules! write {
13 ($text: expr) => ({
14 let mut result: bool = false;
15
16 for len in 0i32..std::i32::MAX {
17 if unsafe {
18 *$text.offset(len as isize)
19 } == 0u8 {
20 result = write!($text, len);
21 break ;
22 }
23 }
24 result
25 });
26 ($text: expr, $len: expr) => ({
27 write!($text, $len, 1)
28 });
29 ($text: expr, $len: expr, $out: expr) => ({
30 extern crate io_synesthesist as io;
31 match unsafe {
32 io::ffi::write (
33 $out as i32,
34 $text as *const i8,
35 $len as i32,
36 )
37 } {
38 -1 => false,
39 _ => true,
40 }
41 });
42}
43
44#[macro_export]
48macro_rules! writeln {
49 ($text: expr) => ({
50 write!($text) && write!("\n".as_ptr(), 1)
51 });
52 ($text: expr, $len: expr) => ({
53 write!($text, $len) && write!("\n".as_ptr(), 1)
54 });
55 ($text: expr, $len: expr, $out: expr) => ({
56 write!($text, $len, $out) && write!("\n".as_ptr(), 1)
57 });
58}
59
60#[macro_export]
64#[cfg(not(feature = "synesthesia"))]
65macro_rules! write_number {
66 ($number: expr) => ({
67 write_number!($number, 1)
68 });
69 ($number: expr, $out: expr) => ({
70 let mut decimal = $number;
71 let mut buf: [u8; 64] = [0; 64];
72 let mut result: bool = false;
73
74 for target in (0..64).rev() {
75 buf[target] = {decimal % 10 + 48} as u8;
76 decimal /= 10;
77 if decimal == 0 {
78 result = write! (
79 buf.as_ptr().offset (
80 target as isize
81 ),
82 64 - target,
83 $out
84 );
85 break ;
86 }
87 }
88 result
89 });
90}
91
92#[macro_export]
93#[cfg(feature = "synesthesia")]
94macro_rules! write_number {
95 ($number: expr) => ({
96 write_number!($number, 1)
97 });
98 ($number: expr, $out: expr) => ({
99 let mut decimal = $number;
100 let mut buf: [u8; 384] = [0; 384]; let mut result: bool = false;
102
103 for target in {0i32..{384}}.rev().filter(|&x| x % 6 == 0) {
104 let digit: u8 = {decimal % 10 + 48} as u8;
105
106 buf[{target-5} as usize] = b'\x1B';
107 buf[{target-4} as usize] = b'[';
108 buf[{target-3} as usize] = b'3';
109 buf[{target-2} as usize] = digit;
110 buf[{target-1} as usize] = b'm';
111 buf[{target-0} as usize] = digit;
112 decimal /= 10;
113 if decimal == 0 {
114 result = write! (
115 buf.as_ptr().offset (
116 {target-5} as isize
117 ),
118 384 - target,
119 $out
120 );
121 break ;
122 }
123 }
124 result && writeln!("\x1B[0m".as_ptr(), 4)
125 });
126}
127
128#[macro_export]
132macro_rules! writeln_number {
133 ($number: expr) => ({
134 writeln_number!($number, 1)
135 });
136 ($number: expr, $out: expr) => ({
137 write_number!($number, $out) && write!("\n".as_ptr(), 1)
138 });
139}
140
141#[macro_export]
145macro_rules! write_character {
146 ($character: expr) => ({
147 write_character!($character, 1)
148 });
149 ($character: expr, $out: expr) => ({
150 write!([$character].as_ptr(), 1, $out)
151 });
152}
153
154#[macro_export]
158macro_rules! writeln_character {
159 ($character: expr) => ({
160 writeln_character!($character, 1)
161 });
162 ($character: expr, $out: expr) => ({
163 write!([$character].as_ptr(), 1, $out) && write!("\n".as_ptr(), $out)
164 });
165}
166
167#[macro_export]
171#[cfg(not(feature = "synesthesia"))]
172macro_rules! write_err {
173 ($text: expr) => ({
174 let mut result: bool = false;
175
176 for len in 0i32..std::i32::MAX {
177 if unsafe {
178 *$text.offset(len as isize)
179 } == 0u8 {
180 result = write_err!($text, len);
181 break ;
182 }
183 }
184 result
185 });
186 ($text: expr, $len: expr) => ({
187 write!($text, $len, 2)
188 });
189}
190
191#[macro_export]
192#[cfg(feature = "synesthesia")]
193macro_rules! write_err {
194 ($text: expr) => ({
195 let mut result: bool = false;
196
197 for len in 0i32..std::i32::MAX {
198 if unsafe {
199 *$text.offset(len as isize)
200 } == 0u8 {
201 result = writeln!("\x1B[31m".as_ptr(), 5)
202 && write_err!($text, len);
203 break ;
204 }
205 }
206 result && writeln!("\x1B[0m".as_ptr(), 4)
207 });
208 ($text: expr, $len: expr) => ({
209 writeln!("\x1B[31m".as_ptr(), 5) &&
210 write!($text, $len, 2) &&
211 writeln!("\x1B[0m".as_ptr(), 4)
212 });
213}
214
215#[macro_export]
219macro_rules! writeln_err {
220 ($text: expr) => ({
221 write_err!($text) && write!("\n".as_ptr(), 1, 2)
222 });
223}
224
225#[macro_export]
229macro_rules! read {
230 () => ({
231 read!(io::ffi::BUFF)
232 });
233 ($len: expr) => ({
234 read!($len, 0)
235 });
236 ($len: expr, $ins: expr) => ({
237 extern crate io_synesthesist as io;
238 let line: [i8; io::ffi::BUFF] = [0; io::ffi::BUFF];
239
240 match unsafe {
241 io::ffi::read (
242 $ins as i32,
243 line.as_ptr() as *mut i8,
244 $len as i32,
245 )
246 } {
247 -1 => None,
248 ret => Some((ret, line)),
249 }
250 });
251}
252
253
254#[macro_export]
258macro_rules! read_character {
259 () => ({
260 match read!(1) {
261 Some((_, c)) => Some(c[0]),
262 None => None,
263 }
264 });
265}
266
267#[macro_export]
271macro_rules! read_number {
272 () => ({
273 match {
274 read_character!()
275 } {
276 Some(45) => Some(-read_number!(0i8)),
277 Some(d @ 48...57) => Some(read_number!(d - 48i8)),
278 _ => None ,
279 }
280 });
281 ($start: expr) => ({
282 extern crate io_synesthesist as io;
283 read_number!($start, io::ffi::BUFF_READ_NUMBER)
284 });
285 ($start: expr, $limit: expr) => ({
286 fn result (
287 acc: i64,
288 lim: usize
289 ) -> i64 {
290 match {
291 (read_character!(), lim)
292 } {
293 (Some(d @ 48...57), lim) if lim != 0 => result (
294 {acc * 10i64} + {d - 48i8} as i64,
295 lim - 1
296 ),
297 _ => acc,
298 }
299 }
300 result($start as i64, $limit)
301 });
302}
303
304#[macro_export]
308macro_rules! read_command {
309 () => ({
310 match {
311 read_character!()
312 } {
313 Some(47) => read_command!(0u64),
314 _ => None ,
315 }
316 });
317 ($start: expr) => ({
318 extern crate io_synesthesist as io;
319 read_command!($start, io::ffi::BUFF_READ_COMMAND)
320 });
321 ($start: expr, $limit: expr) => ({
322 fn result (
323 acc: u64,
324 lim: usize
325 ) -> Option<u64> {
326 match {
327 (read_character!(), lim)
328 } {
329 (Some(d @ 65...90), lim) if lim != 0 => {
330 result(10 + acc * 100 + {d - 65i8} as u64, lim -1)
331 },
332 (Some(d @ 97...122), lim) if lim != 0 => {
333 result(10 + acc * 100 + {d - 97i8} as u64, lim -1)
334 },
335 _ => Some(acc),
336 }
337 }
338 result($start as u64, $limit)
339 });
340}
341
342#[macro_export]
346macro_rules! ioctl {
347 () => ({
348 extern crate io_synesthesist as io;
349 let mut term = Box::new(io::ffi::Termios {
350 c_iflag: 0,
351 c_oflag: 0,
352 c_cflag: 0,
353 c_lflag: 0,
354 c_line: 0,
355 c_cc: [0; io::ffi::NCCS],
356 c_ispeed: 0,
357 c_ospeed: 0,
358 });
359
360 ioctl!(io::ffi::TermiosControl::GETA, &mut *term);
361 term
362
363 });
364 ($control: expr) => ({
365 let mut term = ioctl!();
366
367 term.c_lflag = $control;
368 term
369 });
370 ($req: expr, $term: expr) => ({
371 extern crate io_synesthesist as io;
372 unsafe {
373 io::ffi::ioctl (
374 io::ffi::STDIN_FILENO,
375 $req as u64,
376 $term,
377 )
378 }
379 });
380}