libgir/
update_version.rs

1use crate::{
2    config::Config,
3    library::{self, Function, Parameter, Type, MAIN_NAMESPACE},
4    version::Version,
5    Library,
6};
7
8pub fn apply_config(library: &mut Library, cfg: &Config) {
9    fix_versions_by_config(library, cfg);
10}
11
12pub fn check_function_real_version(library: &mut Library) {
13    // In order to avoid the borrow checker to annoy us...
14    let library2 = library as *const Library;
15    for typ in &mut library.namespace_mut(MAIN_NAMESPACE).types {
16        match typ {
17            Some(Type::Class(c)) => update_function_version(&mut c.functions, library2),
18            Some(Type::Interface(i)) => update_function_version(&mut i.functions, library2),
19            Some(Type::Union(u)) => update_function_version(&mut u.functions, library2),
20            Some(Type::Record(r)) => update_function_version(&mut r.functions, library2),
21            Some(Type::Bitfield(b)) => update_function_version(&mut b.functions, library2),
22            Some(Type::Enumeration(e)) => update_function_version(&mut e.functions, library2),
23            _ => {}
24        }
25    }
26    update_function_version(
27        &mut library.namespace_mut(MAIN_NAMESPACE).functions,
28        library2,
29    );
30}
31
32fn check_versions(param: &Parameter, current_version: &mut Option<Version>, lib: *const Library) {
33    if param.typ.ns_id != MAIN_NAMESPACE {
34        return;
35    }
36    let ty_version = match unsafe { (*lib).type_(param.typ) } {
37        library::Type::Class(c) => c.version,
38        library::Type::Enumeration(c) => c.version,
39        library::Type::Bitfield(c) => c.version,
40        library::Type::Record(c) => c.version,
41        library::Type::Interface(c) => c.version,
42        _ => None,
43    };
44    let new_version = match (*current_version, ty_version) {
45        (Some(current_version), Some(ty_version)) => {
46            if current_version < ty_version {
47                Some(ty_version)
48            } else {
49                None
50            }
51        }
52        (None, Some(ty_version)) => Some(ty_version),
53        _ => None,
54    };
55    if let Some(new_version) = new_version {
56        *current_version = Some(new_version);
57    }
58}
59
60fn update_function_version(functions: &mut Vec<Function>, lib: *const Library) {
61    for function in functions {
62        let mut current_version = None;
63        for parameter in &function.parameters {
64            check_versions(parameter, &mut current_version, lib);
65        }
66        check_versions(&function.ret, &mut current_version, lib);
67        if match (current_version, function.version) {
68            (Some(cur_ver), Some(lib_ver)) => cur_ver > lib_ver,
69            (Some(_), None) => true,
70            _ => false,
71        } {
72            function.version = current_version;
73        }
74    }
75}
76
77fn fix_versions_by_config(library: &mut Library, cfg: &Config) {
78    use crate::library::Type::*;
79    for obj in cfg.objects.values() {
80        if obj.status.ignored() {
81            continue;
82        }
83        if obj.version.is_none() {
84            continue;
85        }
86        let version = obj.version;
87
88        let Some(tid) = library.find_type(0, &obj.name) else {
89            continue;
90        };
91        match library.type_mut(tid) {
92            Class(class) => class.version = version,
93            Interface(interface) => interface.version = version,
94            Record(record) => record.version = version,
95            Bitfield(flags) => flags.version = version,
96            Enumeration(enum_) => enum_.version = version,
97            _ => (),
98        }
99    }
100}