Expand description
§Includium - Complete C Preprocessor
Includium is a C preprocessor implementation that processes C/C++ source code with advanced macro expansion, conditional compilation, and includes. It emulates the behavior of battle-tested C/C++ compilers (Clang and GCC mainly) on a best-effort basis while being standard-compliant.
It supports target-specific preprocessing for different operating systems and compilers with advanced error reporting and exhaustive customization options.
§Features
- Complete macro expansion with object-like and function-like macros
- Variadic macro support with
__VA_ARGS__ - Stringification (
#) and token pasting (##) operators - Full conditional compilation with nested
#if,#ifdef,#ifndef,#else,#elif,#endifblocks - Include processing with custom resolvers and
#pragma oncesupport - Predefined macros:
__FILE__,__LINE__,__DATE__,__TIME__ - Built-in compiler intrinsics and sizeof stubs
- Target-specific preprocessing for Linux, Windows, and macOS
- Compiler-specific macro definitions (GCC, Clang, MSVC)
- Comprehensive error reporting with location context and source line display
- Include cycle detection and recursion protection
- Expression evaluation with full operator precedence
- C FFI API for integration with other languages
§Quick Start
use includium::PreprocessorConfig;
let code = r#"
#define PI 3.14
#ifdef __linux__
const char* platform = "Linux";
#endif
"#;
let config = PreprocessorConfig::for_linux();
let result = includium::process(code, &config).unwrap();
println!("{}", result);§Advanced Usage
The PreprocessorDriver provides full control over preprocessing:
use includium::{PreprocessorDriver, PreprocessorConfig, Compiler};
use std::rc::Rc;
let mut pp = PreprocessorDriver::new()
.with_include_resolver(|path, kind, context| {
match path {
"config.h" => Some("#define CONFIG_ENABLED 1\n".to_string()),
"version.h" => Some("#define VERSION \"1.0.0\"\n".to_string()),
_ => None,
}
});
// Apply configuration for Windows with MSVC
let config = PreprocessorConfig::for_windows().with_compiler(Compiler::MSVC);
pp.apply_config(&config);
// Programmatic macro definition
pp.define("DEBUG", None, "1", false);
pp.define("SQUARE", Some(vec!["x".to_string()]), "((x) * (x))", false);
let code = r#"
#include "config.h"
#ifdef DEBUG
#define LOG(msg) printf("Debug: %s\n", msg)
#else
#define LOG(msg)
#endif
int result = SQUARE(5);
LOG("Processing complete");
"#;
let result = pp.process(code).unwrap();
println!("{}", result);
// Macro introspection
println!("Defined macros: {:?}", pp.get_macros().keys().collect::<Vec<_>>());§Configuration
Choose your target platform and compiler:
use includium::{PreprocessorConfig, Compiler};
// Linux + GCC (default)
let linux_config = PreprocessorConfig::for_linux();
// Windows + MSVC
let windows_config = PreprocessorConfig::for_windows().with_compiler(Compiler::MSVC);
// macOS + Clang
let macos_config = PreprocessorConfig::for_macos().with_compiler(Compiler::Clang);
// Custom configuration with warning handler
let warning_handler = Rc::new(|msg: &str| {
eprintln!("Warning: {}", msg);
});
let custom_config = PreprocessorConfig::for_linux()
.with_compiler(Compiler::GCC)
.with_warning_handler(warning_handler);§Error Handling
The preprocessor provides detailed error information with location context:
use includium::PreprocessorConfig;
let code = r#"
#define
int x = 1;
"#;
let result = includium::process(code, &PreprocessorConfig::default());
match result {
Ok(output) => println!("{}", output),
Err(e) => {
eprintln!("Preprocessing error: {}", e);
// Error includes file, line, column, and source line context
}
}§Variadic Macros
Support for variadic macros with __VA_ARGS__:
use includium::PreprocessorConfig;
let code = r#"
#define LOG(fmt, ...) printf(fmt, __VA_ARGS__)
#define DEBUG(...) printf("DEBUG: " __VA_ARGS__)
LOG("Hello %s\n", "world");
DEBUG("Processing item %d", 42);
"#;
let result = includium::process(code, &PreprocessorConfig::default()).unwrap();
println!("{}", result);§Stringification and Token Pasting
use includium::PreprocessorConfig;
let code = r#"
#define STR(x) #x
#define PASTE(a, b) a##b
#define MAKE_VAR(name, type) type PASTE(var_, name)
const char* file = STR(__FILE__);
int x1 = PASTE(x, 1);
MAKE_VAR(count, int) = 42;
"#;
let result = includium::process(code, &PreprocessorConfig::default()).unwrap();
println!("{}", result);§C API
Includium also provides a C FFI API for integration with other languages.
See the c_api module for available C functions.
Re-exports§
pub use PreprocessorDriver as Preprocessor;
Structs§
- Include
Context - Context for include resolution
- Macro
- A preprocessor macro definition
- Preprocess
Error - Errors that can occur during preprocessing, with location information
- Preprocessor
Config - Configuration for the C preprocessor
- Preprocessor
Context - Context containing all state for preprocessor operations
- Preprocessor
Driver - Public API driver for C preprocessing
Enums§
- Compiler
- Compiler dialect for preprocessing
- Include
Kind - Kind of include directive
- Preprocess
Error Kind - Semantic error kinds that can occur during preprocessing
- Target
- Target operating system for preprocessing
Functions§
- preprocess_
c_ file_ to_ string - Preprocess a C file and return the result as a string
- process
- Preprocess C code with the given configuration. This automatically defines target and compiler-specific macros.
- process_
file - Preprocess a C file and write the result to another file
Type Aliases§
- Include
Resolver - Type alias for include resolver function
- Warning
Handler - Type alias for warning handler function