1use std::cmp::Ordering;
2use std::ffi::{c_char, c_int};
3use std::ptr;
4
5use pkgcraft::dep::{Cpv, Version};
6use pkgcraft::pkg::Pkg;
7use pkgcraft::repo::{PkgRepository, Repo, RepoFormat, Repository};
8use pkgcraft::restrict::Restrict;
9use pkgcraft::traits::Contains;
10use pkgcraft::utils::hash;
11
12use crate::macros::*;
13use crate::panic::ffi_catch_panic;
14use crate::types::{RepoIter, RepoIterCpv, RepoIterRestrict};
15use crate::utils::{boxed, str_to_raw};
16
17pub mod ebuild;
18pub mod ebuild_temp;
19pub mod fake;
20pub mod set;
21
22#[no_mangle]
29pub unsafe extern "C" fn pkgcraft_repo_from_path(
30 id: *const c_char,
31 priority: c_int,
32 path: *const c_char,
33 finalize: bool,
34) -> *mut Repo {
35 ffi_catch_panic! {
36 let path = try_str_from_ptr!(path);
37 let id = if id.is_null() {
38 path
39 } else {
40 try_str_from_ptr!(id)
41 };
42
43 let repo = unwrap_or_panic!(Repo::from_path(id, path, priority, finalize));
44 Box::into_raw(Box::new(repo))
45 }
46}
47
48#[no_mangle]
55pub unsafe extern "C" fn pkgcraft_repo_from_format(
56 format: RepoFormat,
57 id: *const c_char,
58 priority: c_int,
59 path: *const c_char,
60 finalize: bool,
61) -> *mut Repo {
62 ffi_catch_panic! {
63 let path = try_str_from_ptr!(path);
64 let id = if id.is_null() {
65 path
66 } else {
67 try_str_from_ptr!(id)
68 };
69
70 let repo = unwrap_or_panic!(format.load_from_path(id, path, priority, finalize));
71 Box::into_raw(Box::new(repo))
72 }
73}
74
75#[no_mangle]
80pub unsafe extern "C" fn pkgcraft_repo_format(r: *mut Repo) -> RepoFormat {
81 let repo = try_ref_from_ptr!(r);
82 repo.format()
83}
84
85#[no_mangle]
90pub unsafe extern "C" fn pkgcraft_repo_id(r: *mut Repo) -> *mut c_char {
91 let repo = try_ref_from_ptr!(r);
92 try_ptr_from_str!(repo.id())
93}
94
95#[no_mangle]
100pub unsafe extern "C" fn pkgcraft_repo_path(r: *mut Repo) -> *mut c_char {
101 let repo = try_ref_from_ptr!(r);
102 try_ptr_from_str!(repo.path().as_str())
103}
104
105#[no_mangle]
110pub unsafe extern "C" fn pkgcraft_repo_len(r: *mut Repo) -> usize {
111 let repo = try_ref_from_ptr!(r);
112 repo.len()
113}
114
115#[no_mangle]
120pub unsafe extern "C" fn pkgcraft_repo_is_empty(r: *mut Repo) -> bool {
121 let repo = try_ref_from_ptr!(r);
122 repo.is_empty()
123}
124
125#[no_mangle]
130pub unsafe extern "C" fn pkgcraft_repo_categories(
131 r: *mut Repo,
132 len: *mut usize,
133) -> *mut *mut c_char {
134 let repo = try_ref_from_ptr!(r);
135 iter_to_array!(repo.categories().iter(), len, str_to_raw)
136}
137
138#[no_mangle]
143pub unsafe extern "C" fn pkgcraft_repo_packages(
144 r: *mut Repo,
145 cat: *const c_char,
146 len: *mut usize,
147) -> *mut *mut c_char {
148 let repo = try_ref_from_ptr!(r);
149 let cat = try_str_from_ptr!(cat);
150 iter_to_array!(repo.packages(cat).iter(), len, str_to_raw)
151}
152
153#[no_mangle]
158pub unsafe extern "C" fn pkgcraft_repo_versions(
159 r: *mut Repo,
160 cat: *const c_char,
161 pkg: *const c_char,
162 len: *mut usize,
163) -> *mut *mut Version {
164 let repo = try_ref_from_ptr!(r);
165 let cat = try_str_from_ptr!(cat);
166 let pkg = try_str_from_ptr!(pkg);
167 iter_to_array!(repo.versions(cat, pkg).into_iter(), len, boxed)
168}
169
170#[no_mangle]
176pub unsafe extern "C" fn pkgcraft_repo_cmp(r1: *mut Repo, r2: *mut Repo) -> c_int {
177 let repo1 = try_ref_from_ptr!(r1);
178 let repo2 = try_ref_from_ptr!(r2);
179
180 match repo1.cmp(repo2) {
181 Ordering::Less => -1,
182 Ordering::Equal => 0,
183 Ordering::Greater => 1,
184 }
185}
186
187#[no_mangle]
192pub unsafe extern "C" fn pkgcraft_repo_hash(r: *mut Repo) -> u64 {
193 let repo = try_ref_from_ptr!(r);
194 hash(repo)
195}
196
197#[no_mangle]
202pub unsafe extern "C" fn pkgcraft_repo_contains_path(r: *mut Repo, path: *const c_char) -> bool {
203 let repo = try_ref_from_ptr!(r);
204 let path = try_str_from_ptr!(path);
205 repo.contains(path)
206}
207
208#[no_mangle]
213pub unsafe extern "C" fn pkgcraft_repo_free(r: *mut Repo) {
214 if !r.is_null() {
215 unsafe { drop(Box::from_raw(r)) };
216 }
217}
218
219#[no_mangle]
224pub unsafe extern "C" fn pkgcraft_repo_iter_cpv<'a>(r: *mut Repo) -> *mut RepoIterCpv<'a> {
225 let repo = try_ref_from_ptr!(r);
226 Box::into_raw(Box::new(repo.iter_cpv()))
227}
228
229#[no_mangle]
236pub unsafe extern "C" fn pkgcraft_repo_iter_cpv_next(i: *mut RepoIterCpv) -> *mut Cpv {
237 let iter = try_mut_from_ptr!(i);
238 iter.next().map(boxed).unwrap_or(ptr::null_mut())
239}
240
241#[no_mangle]
246pub unsafe extern "C" fn pkgcraft_repo_iter_cpv_free(i: *mut RepoIterCpv) {
247 if !i.is_null() {
248 unsafe { drop(Box::from_raw(i)) };
249 }
250}
251
252#[no_mangle]
257pub unsafe extern "C" fn pkgcraft_repo_iter<'a>(r: *mut Repo) -> *mut RepoIter<'a> {
258 let repo = try_ref_from_ptr!(r);
259 Box::into_raw(Box::new(repo.iter()))
260}
261
262#[no_mangle]
269pub unsafe extern "C" fn pkgcraft_repo_iter_next(i: *mut RepoIter) -> *mut Pkg {
270 let iter = try_mut_from_ptr!(i);
271 iter.next().map(boxed).unwrap_or(ptr::null_mut())
272}
273
274#[no_mangle]
279pub unsafe extern "C" fn pkgcraft_repo_iter_free(i: *mut RepoIter) {
280 if !i.is_null() {
281 unsafe { drop(Box::from_raw(i)) };
282 }
283}
284
285#[no_mangle]
291pub unsafe extern "C" fn pkgcraft_repo_iter_restrict<'a>(
292 repo: *mut Repo,
293 restrict: *mut Restrict,
294) -> *mut RepoIterRestrict<'a> {
295 let repo = try_ref_from_ptr!(repo);
296 let restrict = try_ref_from_ptr!(restrict);
297 Box::into_raw(Box::new(repo.iter_restrict(restrict.clone())))
298}
299
300#[no_mangle]
307pub unsafe extern "C" fn pkgcraft_repo_iter_restrict_next(i: *mut RepoIterRestrict) -> *mut Pkg {
308 let iter = try_mut_from_ptr!(i);
309 iter.next().map(boxed).unwrap_or(ptr::null_mut())
310}
311
312#[no_mangle]
317pub unsafe extern "C" fn pkgcraft_repo_iter_restrict_free(i: *mut RepoIterRestrict) {
318 if !i.is_null() {
319 unsafe { drop(Box::from_raw(i)) };
320 }
321}