Skip to content

Commit

Permalink
Improve enum expr parsing
Browse files Browse the repository at this point in the history
This should make it easier for things to work on 32-bit platforms
  • Loading branch information
madsmtm committed Oct 31, 2022
1 parent f4cb72a commit 2d381b0
Show file tree
Hide file tree
Showing 102 changed files with 1,059 additions and 974 deletions.
1 change: 0 additions & 1 deletion header-translator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@ clang = { version = "2.0", features = ["runtime", "clang_10_0"] }
toml = "0.5.9"
serde = { version = "1.0.144", features = ["derive"] }
apple-sdk = { version = "0.2.0" }
cexpr = "0.6.0"
145 changes: 75 additions & 70 deletions header-translator/src/expr.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@
use std::collections::HashMap;
use std::fmt;
use std::num::Wrapping;
use std::fmt::Write;

use cexpr::expr::EvalResult;
use clang::token::{Token, TokenKind};
use clang::token::TokenKind;
use clang::{Entity, EntityKind, EntityVisitResult};

use crate::unexposed_macro::UnexposedMacro;

#[derive(Clone, Debug, PartialEq)]
pub enum Expr {
Parsed(EvalResult),
DeclRef(String),
Todo,
pub struct Expr {
s: String,
}

pub type Identifiers = HashMap<Vec<u8>, EvalResult>;

impl Expr {
pub fn parse(entity: &Entity<'_>, identifiers: &Identifiers) -> Option<Self> {
pub fn from_val((signed, unsigned): (i64, u64), is_signed: bool) -> Self {
let s = if is_signed {
format!("{}", signed)
} else {
format!("{}", unsigned)
};
Expr { s }
}

pub fn parse_enum_constant(entity: &Entity<'_>) -> Option<Self> {
let mut declaration_references = Vec::new();

entity.visit_children(|entity, _parent| {
if let EntityKind::DeclRefExpr = entity.get_kind() {
let name = entity.get_name().expect("expr decl ref name");
declaration_references.push(name);
}
EntityVisitResult::Recurse
});

let mut res = None;

entity.visit_children(|entity, _parent| {
Expand All @@ -28,77 +41,69 @@ impl Expr {
panic!("parsed macro in expr: {macro_:?}, {entity:?}");
}
}
EntityKind::UnexposedExpr => {
return EntityVisitResult::Recurse;
}
EntityKind::UnaryOperator
| EntityKind::IntegerLiteral
| EntityKind::ParenExpr
| EntityKind::BinaryOperator => {
if res.is_some() {
panic!("found multiple matching children in expr");
}
let range = entity.get_range().expect("expr range");
let tokens = range.tokenize();
let tokens: Vec<_> = tokens.into_iter().filter_map(as_cexpr_token).collect();
let parser = cexpr::expr::IdentifierParser::new(identifiers);
match parser.expr(&tokens) {
Ok((remaining_tokens, evaluated)) if remaining_tokens.is_empty() => {
res = Some(Self::Parsed(evaluated));
}
_ => res = Some(Self::Todo),
}
}
EntityKind::DeclRefExpr => {
if res.is_some() {
panic!("found multiple matching children in expr");
_ => {
if res.is_none() {
res = Self::parse(&entity, &declaration_references);
} else {
panic!("found multiple expressions where one was expected");
}
let name = entity.get_name().expect("expr decl ref");
res = Some(Self::DeclRef(name));
}
kind => panic!("unknown expr kind {kind:?}"),
}
EntityVisitResult::Continue
});

res
}
}

impl fmt::Display for Expr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Parsed(evaluated) => match evaluated {
EvalResult::Int(Wrapping(n)) => write!(f, "{n}"),
EvalResult::Float(n) => write!(f, "{n}"),
rest => panic!("invalid expr eval result {rest:?}"),
},
Self::DeclRef(s) => write!(f, "Self::{}", s),
Self::Todo => write!(f, "todo"),
pub fn parse(entity: &Entity<'_>, declaration_references: &[String]) -> Option<Self> {
let range = entity.get_range().expect("expr range");
let tokens = range.tokenize();

if tokens.is_empty() {
// TODO: Find a better way to parse macros
return None;
}
}
}

/// Converts a clang::Token to a `cexpr` token if possible.
///
/// Taken from `bindgen`.
pub fn as_cexpr_token(t: Token<'_>) -> Option<cexpr::token::Token> {
use cexpr::token;
let mut s = String::new();

let kind = match t.get_kind() {
TokenKind::Punctuation => token::Kind::Punctuation,
TokenKind::Literal => token::Kind::Literal,
TokenKind::Identifier => token::Kind::Identifier,
TokenKind::Keyword => token::Kind::Keyword,
// NB: cexpr is not too happy about comments inside
// expressions, so we strip them down here.
TokenKind::Comment => return None,
};
for token in &tokens {
match (token.get_kind(), token.get_spelling()) {
(TokenKind::Identifier, ident) => {
if declaration_references.contains(&ident) {
// TODO: Handle these specially when we need to
}
write!(s, "{}", ident).unwrap();
}
(TokenKind::Literal, lit) => {
let lit = lit
.trim_end_matches("UL")
.trim_end_matches("L")
.trim_end_matches("u")
.trim_end_matches("U");
let lit = lit.replace("0X", "0x");
write!(s, "{}", lit).unwrap();
}
(TokenKind::Punctuation, punct) => {
match &*punct {
// These have the same semantics in C and Rust
"(" | ")" | "<<" | "-" | "+" | "|" | "&" | "^" => {
write!(s, "{}", punct).unwrap()
}
// Bitwise not
"~" => write!(s, "!").unwrap(),
punct => panic!("unknown expr punctuation {punct}"),
}
}
(kind, spelling) => panic!("unknown expr token {kind:?}/{spelling}"),
}
}

let spelling: Vec<u8> = t.get_spelling().into();
Some(Self { s })
}
}

Some(token::Token {
kind,
raw: spelling.into_boxed_slice(),
})
impl fmt::Display for Expr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.s)
}
}
20 changes: 11 additions & 9 deletions header-translator/src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ pub enum Stmt {
name: Option<String>,
ty: RustType,
kind: Option<UnexposedMacro>,
variants: Vec<(String, (i64, u64))>,
variants: Vec<(String, Expr)>,
},
/// typedef Type TypedefName;
AliasDecl { name: String, type_: RustType },
Expand Down Expand Up @@ -377,8 +377,9 @@ impl Stmt {
}

let name = entity.get_name();
let ty =
RustType::parse_enum(entity.get_enum_underlying_type().expect("enum type"));
let ty = entity.get_enum_underlying_type().expect("enum type");
let is_signed = ty.is_signed_integer();
let ty = RustType::parse_enum(ty);
let mut kind = None;
let mut variants = Vec::new();

Expand All @@ -389,8 +390,9 @@ impl Stmt {
let val = entity
.get_enum_constant_value()
.expect("enum constant value");
let _expr = Expr::parse(&entity, &std::collections::HashMap::new());
variants.push((name, val));
let expr = Expr::parse_enum_constant(&entity)
.unwrap_or_else(|| Expr::from_val(val, is_signed));
variants.push((name, expr));
}
EntityKind::UnexposedAttr => {
if let Some(macro_) = UnexposedMacro::parse(&entity) {
Expand Down Expand Up @@ -580,12 +582,12 @@ impl fmt::Display for Stmt {
} => {
if let Some(name) = name {
writeln!(f, "pub type {name} = {ty};")?;
for (variant_name, (signed_val, _unsigned_val)) in variants {
writeln!(f, "pub const {variant_name}: {name} = {signed_val};")?;
for (variant_name, expr) in variants {
writeln!(f, "pub const {variant_name}: {name} = {expr};")?;
}
} else {
for (variant_name, (signed_val, _unsigned_val)) in variants {
writeln!(f, "pub const {variant_name}: i32 = {signed_val};")?;
for (variant_name, expr) in variants {
writeln!(f, "pub const {variant_name}: i32 = {expr};")?;
}
}
}
Expand Down
44 changes: 23 additions & 21 deletions icrate/src/AppKit/generated/NSApplication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,30 @@ pub const NSUpdateWindowsRunLoopOrdering: i32 = 500000;

pub type NSApplicationPresentationOptions = NSUInteger;
pub const NSApplicationPresentationDefault: NSApplicationPresentationOptions = 0;
pub const NSApplicationPresentationAutoHideDock: NSApplicationPresentationOptions = 1;
pub const NSApplicationPresentationHideDock: NSApplicationPresentationOptions = 2;
pub const NSApplicationPresentationAutoHideMenuBar: NSApplicationPresentationOptions = 4;
pub const NSApplicationPresentationHideMenuBar: NSApplicationPresentationOptions = 8;
pub const NSApplicationPresentationDisableAppleMenu: NSApplicationPresentationOptions = 16;
pub const NSApplicationPresentationDisableProcessSwitching: NSApplicationPresentationOptions = 32;
pub const NSApplicationPresentationDisableForceQuit: NSApplicationPresentationOptions = 64;
pub const NSApplicationPresentationAutoHideDock: NSApplicationPresentationOptions = (1 << 0);
pub const NSApplicationPresentationHideDock: NSApplicationPresentationOptions = (1 << 1);
pub const NSApplicationPresentationAutoHideMenuBar: NSApplicationPresentationOptions = (1 << 2);
pub const NSApplicationPresentationHideMenuBar: NSApplicationPresentationOptions = (1 << 3);
pub const NSApplicationPresentationDisableAppleMenu: NSApplicationPresentationOptions = (1 << 4);
pub const NSApplicationPresentationDisableProcessSwitching: NSApplicationPresentationOptions =
(1 << 5);
pub const NSApplicationPresentationDisableForceQuit: NSApplicationPresentationOptions = (1 << 6);
pub const NSApplicationPresentationDisableSessionTermination: NSApplicationPresentationOptions =
128;
pub const NSApplicationPresentationDisableHideApplication: NSApplicationPresentationOptions = 256;
(1 << 7);
pub const NSApplicationPresentationDisableHideApplication: NSApplicationPresentationOptions =
(1 << 8);
pub const NSApplicationPresentationDisableMenuBarTransparency: NSApplicationPresentationOptions =
512;
pub const NSApplicationPresentationFullScreen: NSApplicationPresentationOptions = 1024;
pub const NSApplicationPresentationAutoHideToolbar: NSApplicationPresentationOptions = 2048;
(1 << 9);
pub const NSApplicationPresentationFullScreen: NSApplicationPresentationOptions = (1 << 10);
pub const NSApplicationPresentationAutoHideToolbar: NSApplicationPresentationOptions = (1 << 11);
pub const NSApplicationPresentationDisableCursorLocationAssistance:
NSApplicationPresentationOptions = 4096;
NSApplicationPresentationOptions = (1 << 12);

pub type NSApplicationOcclusionState = NSUInteger;
pub const NSApplicationOcclusionStateVisible: NSApplicationOcclusionState = 2;
pub const NSApplicationOcclusionStateVisible: NSApplicationOcclusionState = 1 << 1;

pub type NSWindowListOptions = NSInteger;
pub const NSWindowListOrderedFrontToBack: NSWindowListOptions = 1;
pub const NSWindowListOrderedFrontToBack: NSWindowListOptions = (1 << 0);

pub type NSRequestUserAttentionType = NSUInteger;
pub const NSCriticalRequest: NSRequestUserAttentionType = 0;
Expand Down Expand Up @@ -444,9 +446,9 @@ extern_methods!(

pub type NSRemoteNotificationType = NSUInteger;
pub const NSRemoteNotificationTypeNone: NSRemoteNotificationType = 0;
pub const NSRemoteNotificationTypeBadge: NSRemoteNotificationType = 1;
pub const NSRemoteNotificationTypeSound: NSRemoteNotificationType = 2;
pub const NSRemoteNotificationTypeAlert: NSRemoteNotificationType = 4;
pub const NSRemoteNotificationTypeBadge: NSRemoteNotificationType = 1 << 0;
pub const NSRemoteNotificationTypeSound: NSRemoteNotificationType = 1 << 1;
pub const NSRemoteNotificationTypeAlert: NSRemoteNotificationType = 1 << 2;

extern_methods!(
/// NSRemoteNotifications
Expand All @@ -470,9 +472,9 @@ extern_methods!(

pub type NSServiceProviderName = NSString;

pub const NSRunStoppedResponse: i32 = -1000;
pub const NSRunAbortedResponse: i32 = -1001;
pub const NSRunContinuesResponse: i32 = -1002;
pub const NSRunStoppedResponse: i32 = (-1000);
pub const NSRunAbortedResponse: i32 = (-1001);
pub const NSRunContinuesResponse: i32 = (-1002);

extern_methods!(
/// NSDeprecated
Expand Down
28 changes: 14 additions & 14 deletions icrate/src/AppKit/generated/NSAttributedString.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,26 @@ use objc2::rc::{Id, Shared};
use objc2::{extern_class, extern_methods, ClassType};

pub type NSUnderlineStyle = NSInteger;
pub const NSUnderlineStyleNone: NSUnderlineStyle = 0;
pub const NSUnderlineStyleSingle: NSUnderlineStyle = 1;
pub const NSUnderlineStyleThick: NSUnderlineStyle = 2;
pub const NSUnderlineStyleDouble: NSUnderlineStyle = 9;
pub const NSUnderlineStylePatternSolid: NSUnderlineStyle = 0;
pub const NSUnderlineStylePatternDot: NSUnderlineStyle = 256;
pub const NSUnderlineStylePatternDash: NSUnderlineStyle = 512;
pub const NSUnderlineStylePatternDashDot: NSUnderlineStyle = 768;
pub const NSUnderlineStylePatternDashDotDot: NSUnderlineStyle = 1024;
pub const NSUnderlineStyleByWord: NSUnderlineStyle = 32768;
pub const NSUnderlineStyleNone: NSUnderlineStyle = 0x00;
pub const NSUnderlineStyleSingle: NSUnderlineStyle = 0x01;
pub const NSUnderlineStyleThick: NSUnderlineStyle = 0x02;
pub const NSUnderlineStyleDouble: NSUnderlineStyle = 0x09;
pub const NSUnderlineStylePatternSolid: NSUnderlineStyle = 0x0000;
pub const NSUnderlineStylePatternDot: NSUnderlineStyle = 0x0100;
pub const NSUnderlineStylePatternDash: NSUnderlineStyle = 0x0200;
pub const NSUnderlineStylePatternDashDot: NSUnderlineStyle = 0x0300;
pub const NSUnderlineStylePatternDashDotDot: NSUnderlineStyle = 0x0400;
pub const NSUnderlineStyleByWord: NSUnderlineStyle = 0x8000;

pub type NSWritingDirectionFormatType = NSInteger;
pub const NSWritingDirectionEmbedding: NSWritingDirectionFormatType = 0;
pub const NSWritingDirectionOverride: NSWritingDirectionFormatType = 2;
pub const NSWritingDirectionEmbedding: NSWritingDirectionFormatType = (0 << 1);
pub const NSWritingDirectionOverride: NSWritingDirectionFormatType = (1 << 1);

pub type NSTextEffectStyle = NSString;

pub type NSSpellingState = NSInteger;
pub const NSSpellingStateSpellingFlag: NSSpellingState = 1;
pub const NSSpellingStateGrammarFlag: NSSpellingState = 2;
pub const NSSpellingStateSpellingFlag: NSSpellingState = (1 << 0);
pub const NSSpellingStateGrammarFlag: NSSpellingState = (1 << 1);

extern_methods!(
/// NSAttributedStringAttributeFixing
Expand Down
14 changes: 7 additions & 7 deletions icrate/src/AppKit/generated/NSBitmapImageRep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ pub const NSImageRepLoadStatusUnexpectedEOF: NSImageRepLoadStatus = -5;
pub const NSImageRepLoadStatusCompleted: NSImageRepLoadStatus = -6;

pub type NSBitmapFormat = NSUInteger;
pub const NSBitmapFormatAlphaFirst: NSBitmapFormat = 1;
pub const NSBitmapFormatAlphaNonpremultiplied: NSBitmapFormat = 2;
pub const NSBitmapFormatFloatingPointSamples: NSBitmapFormat = 4;
pub const NSBitmapFormatSixteenBitLittleEndian: NSBitmapFormat = 256;
pub const NSBitmapFormatThirtyTwoBitLittleEndian: NSBitmapFormat = 512;
pub const NSBitmapFormatSixteenBitBigEndian: NSBitmapFormat = 1024;
pub const NSBitmapFormatThirtyTwoBitBigEndian: NSBitmapFormat = 2048;
pub const NSBitmapFormatAlphaFirst: NSBitmapFormat = 1 << 0;
pub const NSBitmapFormatAlphaNonpremultiplied: NSBitmapFormat = 1 << 1;
pub const NSBitmapFormatFloatingPointSamples: NSBitmapFormat = 1 << 2;
pub const NSBitmapFormatSixteenBitLittleEndian: NSBitmapFormat = (1 << 8);
pub const NSBitmapFormatThirtyTwoBitLittleEndian: NSBitmapFormat = (1 << 9);
pub const NSBitmapFormatSixteenBitBigEndian: NSBitmapFormat = (1 << 10);
pub const NSBitmapFormatThirtyTwoBitBigEndian: NSBitmapFormat = (1 << 11);

pub type NSBitmapImageRepPropertyKey = NSString;

Expand Down
6 changes: 3 additions & 3 deletions icrate/src/AppKit/generated/NSCell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,9 +583,9 @@ extern_methods!(

pub type NSCellHitResult = NSUInteger;
pub const NSCellHitNone: NSCellHitResult = 0;
pub const NSCellHitContentArea: NSCellHitResult = 1;
pub const NSCellHitEditableTextArea: NSCellHitResult = 2;
pub const NSCellHitTrackableArea: NSCellHitResult = 4;
pub const NSCellHitContentArea: NSCellHitResult = 1 << 0;
pub const NSCellHitEditableTextArea: NSCellHitResult = 1 << 1;
pub const NSCellHitTrackableArea: NSCellHitResult = 1 << 2;

extern_methods!(
/// NSCellHitTest
Expand Down
Loading

0 comments on commit 2d381b0

Please sign in to comment.