1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use syntax::ast::Visibility;
13 pub trait FindUncommented {
14 fn find_uncommented(&self, pat: &str) -> Option<usize>;
17 impl FindUncommented for str {
18 fn find_uncommented(&self, pat: &str) -> Option<usize> {
19 let mut needle_iter = pat.chars();
20 let mut possible_comment = false;
22 for (i, b) in self.char_indices() {
23 match needle_iter.next() {
26 needle_iter = pat.chars();
29 None => return Some(i - pat.len())
34 return self[(i+1)..].find('\n')
36 self[(end + i + 2)..].find_uncommented(pat)
37 .map(|idx| idx + end + i + 2)
40 return self[(i+1)..].find("*/")
42 self[(end + i + 3)..].find_uncommented(pat)
43 .map(|idx| idx + end + i + 3)
46 possible_comment = false;
49 possible_comment = b == '/';
53 // Handle case where the pattern is a suffix of the search string
54 match needle_iter.next() {
56 None => Some(self.len() - pat.len())
62 fn test_find_uncommented() {
63 fn check(haystack: &str, needle: &str, expected: Option<usize>) {
64 assert_eq!(expected, haystack.find_uncommented(needle));
67 check("/*//*/test", "test", Some(6));
68 check("//test\ntest", "test", Some(7));
69 check("/* comment only */", "whatever", None);
70 check("/* comment */ some text /* more commentary */ result", "result", Some(46));
71 check("sup // sup", "p", Some(2));
72 check("sup", "x", None);
73 check("π? /**/ π is nice!", "π is nice", Some(9));
74 check("/*sup yo? \n sup*/ sup", "p", Some(20));
75 check("hel/*lohello*/lo", "hello", None);
76 check("acb", "ab", None);
80 pub fn prev_char(s: &str, mut i: usize) -> usize {
81 if i == 0 { return 0; }
84 while !s.is_char_boundary(i) {
91 pub fn next_char(s: &str, mut i: usize) -> usize {
92 if i >= s.len() { return s.len(); }
94 while !s.is_char_boundary(i) {
101 pub fn make_indent(width: usize) -> String {
102 let mut indent = String::with_capacity(width);
110 pub fn format_visibility(vis: Visibility) -> &'static str {
112 Visibility::Public => "pub ",
113 Visibility::Inherited => ""
118 #[cfg(target_pointer_width="64")]
119 // Based on the trick layed out at
120 // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
121 pub fn round_up_to_power_of_two(mut x: usize) -> usize {
122 x = x.wrapping_sub(1);
133 #[cfg(target_pointer_width="32")]
134 pub fn round_up_to_power_of_two(mut x: usize) -> usize {
135 x = x.wrapping_sub(1);
144 // Macro for deriving implementations of Decodable for enums
146 macro_rules! impl_enum_decodable {
147 ( $e:ident, $( $x:ident ),* ) => {
148 impl ::rustc_serialize::Decodable for $e {
149 fn decode<D: ::rustc_serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
150 let s = try!(d.read_str());
153 stringify!($x) => Ok($e::$x),
155 _ => Err(d.error("Bad variant")),
163 fn power_rounding() {
164 assert_eq!(0, round_up_to_power_of_two(0));
165 assert_eq!(1, round_up_to_power_of_two(1));
166 assert_eq!(64, round_up_to_power_of_two(33));
167 assert_eq!(256, round_up_to_power_of_two(256));