pkgcraft/
config.rs

1use std::ffi::{c_char, c_int};
2
3use pkgcraft::config::Config;
4use pkgcraft::repo::set::RepoSet;
5use pkgcraft::repo::{Repo, RepoFormat};
6
7use crate::macros::*;
8use crate::panic::ffi_catch_panic;
9
10/// Create an empty pkgcraft config.
11#[no_mangle]
12pub extern "C" fn pkgcraft_config_new() -> *mut Config {
13    let config = Config::new("pkgcraft", "");
14    Box::into_raw(Box::new(config))
15}
16
17/// Add local repo from filesystem path.
18///
19/// Returns NULL on error.
20///
21/// # Safety
22/// The path argument should be a valid path on the system.
23#[no_mangle]
24pub unsafe extern "C" fn pkgcraft_config_add_repo_path(
25    c: *mut Config,
26    id: *const c_char,
27    priority: c_int,
28    path: *const c_char,
29    external: bool,
30) -> *mut Repo {
31    ffi_catch_panic! {
32        let path = try_str_from_ptr!(path);
33        let id = if id.is_null() {
34            path
35        } else {
36            try_str_from_ptr!(id)
37        };
38
39        let config = try_mut_from_ptr!(c);
40        let repo = unwrap_or_panic!(config.add_repo_path(id, path, priority, external));
41        Box::into_raw(Box::new(repo))
42    }
43}
44
45/// Add an external Repo to the config.
46///
47/// Returns NULL on error.
48///
49/// # Safety
50/// The arguments must be valid Config and Repo pointers.
51#[no_mangle]
52pub unsafe extern "C" fn pkgcraft_config_add_repo(
53    c: *mut Config,
54    r: *mut Repo,
55    external: bool,
56) -> *mut Repo {
57    ffi_catch_panic! {
58        let config = try_mut_from_ptr!(c);
59        let repo = try_ref_from_ptr!(r);
60        unwrap_or_panic!(config.add_repo(repo, external));
61        r
62    }
63}
64
65/// Load the system config.
66///
67/// Returns NULL on error.
68///
69/// # Safety
70/// A valid pkgcraft (or portage config) directory should be located on the system.
71#[no_mangle]
72pub unsafe extern "C" fn pkgcraft_config_load(c: *mut Config) -> *mut Config {
73    ffi_catch_panic! {
74        let config = try_mut_from_ptr!(c);
75        unwrap_or_panic!(config.load());
76        c
77    }
78}
79
80/// Load the portage config from a given path, use NULL for the default system paths.
81///
82/// Returns NULL on error.
83///
84/// # Safety
85/// The path argument should be a valid path on the system.
86#[no_mangle]
87pub unsafe extern "C" fn pkgcraft_config_load_portage_conf(
88    c: *mut Config,
89    path: *const c_char,
90) -> *mut Config {
91    ffi_catch_panic! {
92        let path = try_opt_str_from_ptr!(path);
93        let config = try_mut_from_ptr!(c);
94        unwrap_or_panic!(config.load_portage_conf(path));
95        c
96    }
97}
98
99/// Return the repos for a config.
100///
101/// # Safety
102/// The config argument must be a non-null Config pointer.
103#[no_mangle]
104pub unsafe extern "C" fn pkgcraft_config_repos(
105    c: *mut Config,
106    len: *mut usize,
107) -> *mut *const Repo {
108    // TODO: switch from usize to std::os::raw::c_size_t when it's stable.
109    let config = try_ref_from_ptr!(c);
110    iter_to_array!(config.repos.into_iter(), len, |(_, r)| { r as *const _ })
111}
112
113/// Return the RepoSet for a given repo format.
114///
115/// Use a null pointer format argument to return the set of all repos.
116///
117/// # Safety
118/// The config argument must be a non-null Config pointer.
119#[no_mangle]
120pub unsafe extern "C" fn pkgcraft_config_repos_set(
121    c: *mut Config,
122    format: *const RepoFormat,
123) -> *mut RepoSet {
124    let config = try_ref_from_ptr!(c);
125    let set = match unsafe { format.as_ref() } {
126        Some(f) => config.repos.set(Some(*f)),
127        None => config.repos.set(None),
128    };
129    Box::into_raw(Box::new(set))
130}
131
132/// Free a config.
133///
134/// # Safety
135/// The argument must be a Config pointer or NULL.
136#[no_mangle]
137pub unsafe extern "C" fn pkgcraft_config_free(c: *mut Config) {
138    if !c.is_null() {
139        unsafe { drop(Box::from_raw(c)) };
140    }
141}