control_code/
util.rs

1//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2//                    Version 2, December 2004
3//
4// Copyleft (ↄ) meh. <meh@schizofreni.co> | http://meh.schizofreni.co
5//
6// Everyone is permitted to copy and distribute verbatim or modified
7// copies of this license document, and changing it is allowed as long
8// as the name is changed.
9//
10//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11//   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12//
13//  0. You just DO WHAT THE FUCK YOU WANT TO.
14
15#[macro_export]
16macro_rules! arg {
17	($args:ident[$index:tt] => $($default:tt)*) => ({
18		let default = $($default)* as u32;
19
20		$args.get($index)
21			.and_then(|v| v.map(|v| if v == 0 { default } else { v }))
22			.unwrap_or(default)
23	});
24
25	($args:ident[$index:tt]) => (
26		$args.get($index).and_then(|v| *v)
27	);
28}
29
30macro_rules! with_args {
31	($name:ident<$n:tt, $params:ident> -> $ty:ty, ? $body:expr) => (
32		fn $name<'a>($params: &[Option<u32>]) -> Option<$ty> {
33			if $params.len() <= $n {
34				$body.ok()
35			}
36			else {
37				None
38			}
39		}
40	);
41
42	($name:ident<$n:tt, $params:ident> -> $ty:ty, $body:expr) => (
43		fn $name<'a>($params: &[Option<u32>]) -> Option<$ty> {
44			if $params.len() <= $n {
45				Some($body)
46			}
47			else {
48				None
49			}
50		}
51	);
52
53	($name:ident<$params:ident> -> $ty:ty, ? $body:expr) => (
54		fn $name<'a>($params: &[Option<u32>]) -> Option<$ty> {
55			$body.ok()
56		}
57	);
58
59	($name:ident<$params:ident> -> $ty:ty, $body:expr) => (
60		fn $name<'a>($params: &[Option<u32>]) -> Option<$ty> {
61			Some($body)
62		}
63	);
64
65	($name:ident -> $ty:ty, $body:expr) => (
66		fn $name<'a>(args: &[Option<u32>]) -> Option<$ty> {
67			if args.is_empty() {
68				Some($body)
69			}
70			else {
71				None
72			}
73		}
74	);
75}
76
77macro_rules! small_vec {
78	() => (
79		$crate::smallvec::SmallVec::new()
80	);
81
82	($($value:expr),+) => ({
83		let mut result = small_vec![];
84		$(result.push($value));*;
85
86		result
87	});
88}
89
90macro_rules! many0 {
91	($i:expr, $submac:ident!( $($args:tt)* )) => ({
92			use $crate::nom::InputLength;
93
94			let ret;
95			let mut res   = Vec::new();
96			let mut input = $i;
97
98			loop {
99				if input.input_len() == 0 {
100					ret = $crate::nom::IResult::Done(input, res); break;
101				}
102
103				match $submac!(input, $($args)*) {
104					$crate::nom::IResult::Error(_) => {
105						ret = $crate::nom::IResult::Done(input, res); break;
106					},
107
108					$crate::nom::IResult::Incomplete($crate::nom::Needed::Unknown) => {
109						ret = $crate::nom::IResult::Incomplete($crate::nom::Needed::Unknown);
110						break;
111					},
112
113					$crate::nom::IResult::Incomplete($crate::nom::Needed::Size(i)) => {
114						let size = i + ($i).input_len() - input.input_len();
115						ret = $crate::nom::IResult::Incomplete($crate::nom::Needed::Size(size));
116						break;
117					},
118
119					$crate::nom::IResult::Done(i, o) => {
120						// loop trip must always consume (otherwise infinite loops)
121						if i == input {
122							ret = $crate::nom::IResult::Error($crate::nom::ErrorKind::Many0);
123							break;
124						}
125
126						res.push(o);
127						input = i;
128					}
129				}
130			}
131
132			ret
133		}
134	);
135
136	($i:expr, $f:expr) => (
137		many0!($i, call!($f));
138	);
139
140	($i:expr, $n:tt, $submac:ident!( $($args:tt)* )) => ({
141			use $crate::nom::InputLength;
142
143			let ret;
144			let mut res   = $crate::smallvec::SmallVec::<[_; $n]>::new();
145			let mut input = $i;
146
147			loop {
148				if input.input_len() == 0 {
149					ret = $crate::nom::IResult::Done(input, res); break;
150				}
151
152				match $submac!(input, $($args)*) {
153					$crate::nom::IResult::Error(_) => {
154						ret = $crate::nom::IResult::Done(input, res);
155						break;
156					},
157					$crate::nom::IResult::Incomplete($crate::nom::Needed::Unknown) => {
158						ret = $crate::nom::IResult::Incomplete($crate::nom::Needed::Unknown);
159						break;
160					},
161					$crate::nom::IResult::Incomplete($crate::nom::Needed::Size(i)) => {
162						let size = i + ($i).input_len() - input.input_len();
163						ret = $crate::nom::IResult::Incomplete($crate::nom::Needed::Size(size));
164						break;
165					},
166					$crate::nom::IResult::Done(i, o) => {
167						// loop trip must always consume (otherwise infinite loops)
168						if i == input {
169							ret = $crate::nom::IResult::Error($crate::nom::ErrorKind::Many0);
170							break;
171						}
172
173						res.push(o);
174						input = i;
175					}
176				}
177			}
178
179			ret
180		}
181	);
182
183	($i:expr, $n:tt, $f:expr) => (
184		many0!($i, $n, call!($f));
185	);
186}
187
188#[inline]
189pub fn number(i: &[u8]) -> u32 {
190	let mut n: u32 = 0;
191
192	for &ch in i {
193		let d = (ch as u32).wrapping_sub(b'0' as u32);
194
195		if d <= 9 {
196			n = n.saturating_mul(10).saturating_add(d);
197		}
198	}
199
200	n
201}