Skip to content

Commit

Permalink
preprocessor: prevent usage of unsupported macros
Browse files Browse the repository at this point in the history
  • Loading branch information
BrettMayson committed Nov 9, 2024
1 parent 41d3ad5 commit 06fe031
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 43 deletions.
31 changes: 0 additions & 31 deletions libs/preprocessor/README.md

This file was deleted.

10 changes: 2 additions & 8 deletions libs/preprocessor/src/codes/pe25_exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,9 @@ use hemtt_workspace::reporting::{Code, Token};
use crate::Error;

#[allow(unused)]
/// The EOI was reached while reading an `#if` [`IfState`]
///
/// ```cpp
/// #if 1
/// #else
/// EOI
/// ```
/// __EXEC is not a supported macro
pub struct ExecNotSupported {
/// The [`Token`] of the last `#if`
/// The [`Token`] of the __EXEC macro
token: Box<Token>,
}

Expand Down
42 changes: 42 additions & 0 deletions libs/preprocessor/src/codes/pe26_unsupported_builtin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use std::sync::Arc;

use hemtt_workspace::reporting::{Code, Token};

use crate::Error;

#[allow(unused)]
/// Built-in macro is not supported by HEMTT
pub struct BuiltInNotSupported {
/// The [`Token`] of the built-in macro
token: Box<Token>,
}

impl Code for BuiltInNotSupported {
fn ident(&self) -> &'static str {
"PE26"
}

fn token(&self) -> Option<&Token> {
Some(&self.token)
}

fn message(&self) -> String {
format!("built-in macro `{}` is not supported by HEMTT", self.token.symbol())
}

fn note(&self) -> Option<String> {
Some("certain built-in macros can not be rapified at build time\nHEMTT does not support them to prevent unexpected behaviour".to_string())
}
}

impl BuiltInNotSupported {
#[must_use]
pub const fn new(token: Box<Token>) -> Self {
Self { token }
}

#[must_use]
pub fn code(token: Token) -> Error {
Error::Code(Arc::new(Self::new(Box::new(token))))
}
}
15 changes: 12 additions & 3 deletions libs/preprocessor/src/defines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ type InnerDefines = HashMap<Arc<str>, (Arc<Token>, Definition, DefineSource)>;
pub struct Defines {
global: InnerDefines,
stack: Vec<(Arc<str>, InnerDefines)>,

counter: u16,
}

Expand All @@ -40,14 +39,20 @@ const BUILTIN_GEN: [&str; 6] = [
"__LINE__",
];

/// Built-in macros that HEMTT supports, special cases
const BUILTIN_SPECIAL: [&str; 1] = ["__EVAL"];

/// Built-in macros that HEMTT intentionally does not support
const BUILTIN_PROTEST: [&str; 16] = [
const BUILTIN_PROTEST: [&str; 18] = [
"__DATE_ARR__",
"__DATE_STR__",
"__DATE_STR_ISO8601__",
"__TIME__",
"__TIME_UTC__",
"__TIMESTAMP_UTC__",
"__DAY__",
"__MONTH__",
"__YEAR__",
"__RAND_INT*__",
"__RAND_UINT*__",
"__GAME_VER__",
Expand All @@ -57,16 +62,20 @@ const BUILTIN_PROTEST: [&str; 16] = [
"__A3_DIAG__",
"__A3_DEBUG__",
"__EXEC",
"__EVAL",
];

impl Defines {
pub fn is_builtin(key: &str) -> bool {
BUILTIN_GEN.contains(&key)
|| BUILTIN_SPECIAL.contains(&key)
|| BUILTIN_PROTEST.contains(&key)
|| BUILTIN_CONST.iter().any(|(k, _)| *k == key)
}

pub fn is_unsupported_builtin(key: &str) -> bool {
BUILTIN_PROTEST.contains(&key)
}

pub fn contains_key(&self, key: &str) -> bool {
if BUILTIN_GEN.contains(&key) {
return true;
Expand Down
5 changes: 4 additions & 1 deletion libs/preprocessor/src/processor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use hemtt_workspace::{
};
use peekmore::{PeekMore, PeekMoreIterator};

use crate::codes::pe2_unexpected_eof::UnexpectedEOF;
use crate::codes::{pe26_unsupported_builtin::BuiltInNotSupported, pe2_unexpected_eof::UnexpectedEOF};
use crate::codes::pe3_expected_ident::ExpectedIdent;
use crate::codes::pw2_invalid_config_case::InvalidConfigCase;
use crate::codes::{pe18_eoi_ifstate::EoiIfState, pe25_exec::ExecNotSupported};
Expand Down Expand Up @@ -154,6 +154,9 @@ impl Processor {
if w == "__EXEC" {
return Err(ExecNotSupported::code((**token).clone()));
}
if Defines::is_unsupported_builtin(w) {
return Err(BuiltInNotSupported::code((**token).clone()));
}
just_whitespace = false;
if Some(w.as_str()) != in_macro && self.defines.contains_key(w) {
let token = token.clone();
Expand Down
1 change: 1 addition & 0 deletions libs/preprocessor/tests/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,4 @@ bootstrap!(pe22_pragma_invalid_flag);
bootstrap!(pe23_if_has_include);
bootstrap!(pe24_parsing_failed);
bootstrap!(pe25_exec);
bootstrap!(pe26_unsupported_builtin);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Date {
day = __DAY__;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[PE26]: built-in macro `__DAY__` is not supported by HEMTT
┌─ source.hpp:2:11
│
2 │ day = __DAY__;
│ ^^^^^^^ built-in macro `__DAY__` is not supported by HEMTT
│
= note: certain built-in macros can not be rapified at build time
HEMTT does not support them to prevent unexpected behaviour

0 comments on commit 06fe031

Please sign in to comment.