///|
/// A C declarator shape retained before deciding whether its ABI is supported.
priv struct CTypeModel {
base : String
pointer_depth : Int
pointee_const : Bool
pointer_const : Bool
array : Bool
function_pointer : Bool
record : Bool
enumeration : Bool
}
///|
fn c_type_model(raw : String) -> CTypeModel {
let spelling = raw.trim().to_owned()
let function_pointer = spelling.contains("(*") || spelling.contains("( *")
let array = spelling.contains("[") && spelling.has_suffix("]")
let mut source = spelling.replace_all(old=" ", new=" ")
let mut pointer_const = false
if source.has_suffix(" const") {
pointer_const = true
source = source[:source.length() - 6].trim().to_owned()
}
let mut pointer_depth = 0
if !function_pointer && !array {
while source.has_suffix("*") {
pointer_depth += 1
source = source[:source.length() - 1].trim().to_owned()
}
}
let mut pointee_const = false
if source.has_prefix("const ") {
pointee_const = true
source = source[6:].trim().to_owned()
}
if source.has_prefix("volatile ") {
source = source[9:].trim().to_owned()
}
let record = source.has_prefix("struct ") || source.has_prefix("union ")
let enumeration = source.has_prefix("enum ")
{
base: source,
pointer_depth,
pointee_const,
pointer_const,
array,
function_pointer,
record,
enumeration,
}
}
///|
fn is_v2_byte_pointer(raw : String, const_required~ : Bool) -> Bool {
let shape = c_type_model(raw)
shape.pointer_depth == 1 &&
!shape.array &&
!shape.function_pointer &&
!shape.pointer_const &&
!shape.record &&
!shape.enumeration &&
(
shape.base == "void" ||
shape.base == "char" ||
shape.base == "signed char" ||
shape.base == "unsigned char"
) &&
shape.pointee_const == const_required
}
///|
fn is_v2_callback_pointer(raw : String) -> Bool {
c_type_model(raw).function_pointer
}