1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
/// This is an implementation of a very simple (read very-bad) C pre-processor /// it doesn't do true tokenization and it doesn't support many features. /// /// It does support the following: /// * Logical line concatenation /// * Comments (Line and block) /// * `define` for constant strings /// * `undef` /// * `ifdef` and `ifndef` /// /// It does not support the following: /// * Macro functions /// * Symbol concatenation /// * Generalized `if` pub mod lexer; use lexer::OwningTokenizer; use regex::Regex; use std::path::PathBuf; // Reference: // * https://www.lysator.liu.se/c/ANSI-C-grammar-l.html // * https://github.com/bagder/fcpp // * https://github.com/danmar/simplecpp pub fn splice_lines<S: AsRef<str>>(input: S) -> String { let line_regex = Regex::new("\r\n|\n\r|\r").unwrap(); line_regex.replace_all(input.as_ref(), "\n").into() } #[cfg(test)] mod splice_tests { use crate::splice_lines; #[test] fn nothing_to_do() { assert_eq!(splice_lines("a\nb"), "a\nb") } #[test] fn windows_line_ending() { assert_eq!(splice_lines("a\r\nb"), "a\nb") } #[test] fn reverse_windows_line_ending() { assert_eq!(splice_lines("a\n\rb"), "a\nb") } #[test] fn longest_sequence_first() { assert_eq!(splice_lines("a\r\n\rb"), "a\n\nb") } #[test] fn non_greedy() { assert_eq!(splice_lines("a\n\r\nb"), "a\n\nb") } } pub fn preprocess(_input: String) -> String { // let stream = TokenStream { // path: "/".into(), // tokenizer: OwningTokenizer::new(input), // }; // let mut file_stack = vec![Tokenizer::new(&input)]; // let mut current_token_stream = file_stack.last_mut().unwrap(); // //let ouput_token_stream = Vec::new(); // let current_row = Vec::new(); // let mut in_directive = false; // while file_stack.len() > 0 { // // Grab a single line of nput off the currently active token stream // loop { // match current_token_stream.get_next_token() { // Ok(tok) => { // match tok.token_type { // TokenType::Punctuator if tok.text == "#" => { // in_directive = true; // } // TokenType::EOL => { // current_row.push(tok); // break; // } // TokenType::EOF => break, // _ => current_row.push(tok), // } // } // Err(err) => { // unimplemented!(); // } // } // } // //Process the current line // } "".into() } struct TokenStream { path: PathBuf, tokenizer: OwningTokenizer, }