File Index
Files and directories
Sign in
FILE

helpers.rs

File preview with syntax highlighting.

linux-6.19.14/rust/macros/helpers.rs RUST
  1// SPDX-License-Identifier: GPL-2.0
  2
  3use proc_macro::{token_stream, Group, Ident, TokenStream, TokenTree};
  4
  5pub(crate) fn try_ident(it: &mut token_stream::IntoIter) -> Option<String> {
  6    if let Some(TokenTree::Ident(ident)) = it.next() {
  7        Some(ident.to_string())
  8    } else {
  9        None
 10    }
 11}
 12
 13pub(crate) fn try_sign(it: &mut token_stream::IntoIter) -> Option<char> {
 14    let peek = it.clone().next();
 15    match peek {
 16        Some(TokenTree::Punct(punct)) if punct.as_char() == '-' => {
 17            let _ = it.next();
 18            Some(punct.as_char())
 19        }
 20        _ => None,
 21    }
 22}
 23
 24pub(crate) fn try_literal(it: &mut token_stream::IntoIter) -> Option<String> {
 25    if let Some(TokenTree::Literal(literal)) = it.next() {
 26        Some(literal.to_string())
 27    } else {
 28        None
 29    }
 30}
 31
 32pub(crate) fn try_string(it: &mut token_stream::IntoIter) -> Option<String> {
 33    try_literal(it).and_then(|string| {
 34        if string.starts_with('\"') && string.ends_with('\"') {
 35            let content = &string[1..string.len() - 1];
 36            if content.contains('\\') {
 37                panic!("Escape sequences in string literals not yet handled");
 38            }
 39            Some(content.to_string())
 40        } else if string.starts_with("r\"") {
 41            panic!("Raw string literals are not yet handled");
 42        } else {
 43            None
 44        }
 45    })
 46}
 47
 48pub(crate) fn expect_ident(it: &mut token_stream::IntoIter) -> String {
 49    try_ident(it).expect("Expected Ident")
 50}
 51
 52pub(crate) fn expect_punct(it: &mut token_stream::IntoIter) -> char {
 53    if let TokenTree::Punct(punct) = it.next().expect("Reached end of token stream for Punct") {
 54        punct.as_char()
 55    } else {
 56        panic!("Expected Punct");
 57    }
 58}
 59
 60pub(crate) fn expect_string(it: &mut token_stream::IntoIter) -> String {
 61    try_string(it).expect("Expected string")
 62}
 63
 64pub(crate) fn expect_string_ascii(it: &mut token_stream::IntoIter) -> String {
 65    let string = try_string(it).expect("Expected string");
 66    assert!(string.is_ascii(), "Expected ASCII string");
 67    string
 68}
 69
 70pub(crate) fn expect_group(it: &mut token_stream::IntoIter) -> Group {
 71    if let TokenTree::Group(group) = it.next().expect("Reached end of token stream for Group") {
 72        group
 73    } else {
 74        panic!("Expected Group");
 75    }
 76}
 77
 78pub(crate) fn expect_end(it: &mut token_stream::IntoIter) {
 79    if it.next().is_some() {
 80        panic!("Expected end");
 81    }
 82}
 83
 84/// Given a function declaration, finds the name of the function.
 85pub(crate) fn function_name(input: TokenStream) -> Option<Ident> {
 86    let mut input = input.into_iter();
 87    while let Some(token) = input.next() {
 88        match token {
 89            TokenTree::Ident(i) if i.to_string() == "fn" => {
 90                if let Some(TokenTree::Ident(i)) = input.next() {
 91                    return Some(i);
 92                }
 93                return None;
 94            }
 95            _ => continue,
 96        }
 97    }
 98    None
 99}
100
101pub(crate) fn file() -> String {
102    #[cfg(not(CONFIG_RUSTC_HAS_SPAN_FILE))]
103    {
104        proc_macro::Span::call_site()
105            .source_file()
106            .path()
107            .to_string_lossy()
108            .into_owned()
109    }
110
111    #[cfg(CONFIG_RUSTC_HAS_SPAN_FILE)]
112    #[allow(clippy::incompatible_msrv)]
113    {
114        proc_macro::Span::call_site().file()
115    }
116}
117
118/// Parse a token stream of the form `expected_name: "value",` and return the
119/// string in the position of "value".
120///
121/// # Panics
122///
123/// - On parse error.
124pub(crate) fn expect_string_field(it: &mut token_stream::IntoIter, expected_name: &str) -> String {
125    assert_eq!(expect_ident(it), expected_name);
126    assert_eq!(expect_punct(it), ':');
127    let string = expect_string(it);
128    assert_eq!(expect_punct(it), ',');
129    string
130}
~/ Read-only file preview.