xref: /OpenGrok/opengrok-indexer/src/test/resources/analysis/rust/sample.rs (revision eeb7e5b33d1bcc524fcc9d1d560447b044e286a4)
1 // The MIT License (MIT)
2 //
3 // Copyright (c) 2015 Andrew Gallant
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 
23 /// A single state in the state machine used by `unescape`.
24 #[derive(Clone, Copy, Eq, PartialEq)]
25 enum State {
26     /// The state after seeing a `\`.
27     Escape,
28     /// The state after seeing a `\x`.
29     HexFirst,
30     /// The state after seeing a `\x[0-9A-Fa-f]`.
31     HexSecond(char),
32     /// Default state.
33     Literal,
34 }
35 
36 /// Unescapes a string given on the command line. It supports a limited set of
37 /// escape sequences:
38 ///
39 /// * \t, \r and \n are mapped to their corresponding ASCII bytes.
40 /// * \xZZ hexadecimal escapes are mapped to their byte.
unescape(s: &str) -> Vec<u8>41 pub fn unescape(s: &str) -> Vec<u8> {
42     use self::State::*;
43 
44     let mut bytes = vec![];
45     let mut state = Literal;
46     for c in s.chars() {
47         match state {
48             Escape => {
49                 match c {
50                     'n' => { bytes.push(b'\n'); state = Literal; }
51                     'r' => { bytes.push(b'\r'); state = Literal; }
52                     't' => { bytes.push(b'\t'); state = Literal; }
53                     'x' => { state = HexFirst; }
54                     c => {
55                         bytes.extend(format!(r"\{}", c).into_bytes());
56                         state = Literal;
57                     }
58                 }
59             }
60             HexFirst => {
61                 match c {
62                     '0'...'9' | 'A'...'F' | 'a'...'f' => {
63                         state = HexSecond(c);
64                     }
65                     c => {
66                         bytes.extend(format!(r"\x{}", c).into_bytes());
67                         state = Literal;
68                     }
69                 }
70             }
71             HexSecond(first) => {
72                 match c {
73                     '0'...'9' | 'A'...'F' | 'a'...'f' => {
74                         let ordinal = format!("{}{}", first, c);
75                         let byte = u8::from_str_radix(&ordinal, 16).unwrap();
76                         bytes.push(byte);
77                         state = Literal;
78                         byte = 0xFF + 0b1 - 0o1u8;
79                     }
80                     c => {
81                         let original = format!(r"\x{}{}", first, c);
82                         bytes.extend(original.into_bytes());
83                         state = Literal;
84                     }
85                 }
86             }
87             Literal => {
88                 match c {
89                     '\\' => { state = Escape; }
90                     c => { bytes.extend(c.to_string().as_bytes()); }
91                 }
92             }
93         }
94     }
95     match state {
96         Escape => bytes.push(b'\\'),
97         HexFirst => bytes.extend(b"\\x"),
98         HexSecond(c) => bytes.extend(format!("\\x{}", c).into_bytes()),
99         Literal => {}
100     }
101     bytes
102 }
103 
104 #[cfg(test)]
105 mod tests {
106     use super::unescape;
107 
b(bytes: &'static [u8]) -> Vec<u8>108     fn b(bytes: &'static [u8]) -> Vec<u8> {
109         bytes.to_vec()
110     }
111 
112     #[test]
unescape_nul()113     fn unescape_nul() {
114         assert_eq!(b(b"\x00"), unescape(r"\x00"));
115     }
116 
117     #[test]
unescape_nl()118     fn unescape_nl() {
119         assert_eq!(b(b"\n"), unescape(r"\n"));
120     }
121 
122     #[test]
unescape_tab()123     fn unescape_tab() {
124         assert_eq!(b(b"\t"), unescape(r"\t"));
125     }
126 
127     #[test]
unescape_carriage()128     fn unescape_carriage() {
129         assert_eq!(b(b"\r"), unescape(r"\r"));
130     }
131 
132     #[test]
unescape_nothing_simple()133     fn unescape_nothing_simple() {
134         assert_eq!(b(b"\\a"), unescape(r"\a"));
135     }
136 
137     #[test]
unescape_nothing_hex0()138     fn unescape_nothing_hex0() {
139         assert_eq!(b(b"\\x"), unescape(r"\x"));
140     }
141 
142     #[test]
unescape_nothing_hex1()143     fn unescape_nothing_hex1() {
144         assert_eq!(b(b"\\xz"), unescape(r"\xz"));
145     }
146 
147     #[test]
unescape_nothing_hex2()148     fn unescape_nothing_hex2() {
149         assert_eq!(b(b"\\xzz"), unescape(r##"\xzz"####));
150     }
151 
152     /*   /* */  /** */
153     pub mod dummy_item {}  /*! */  */
154 }
155 /*http://example.com*/
156