• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Ortham / libloadorder / 14680640716

26 Apr 2025 11:08AM UTC coverage: 93.244% (+0.2%) from 93.009%
14680640716

push

github

Ortham
Deny a lot of extra lints and fix their errors

541 of 606 new or added lines in 21 files covered. (89.27%)

3 existing lines in 3 files now uncovered.

10599 of 11367 relevant lines covered (93.24%)

1119406.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/ffi/src/active_plugins.rs
1
/*
2
 * This file is part of libloadorder
3
 *
4
 * Copyright (C) 2017 Oliver Hamlet
5
 *
6
 * libloadorder is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * libloadorder is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with libloadorder. If not, see <http://www.gnu.org/licenses/>.
18
 */
19

20
use std::ffi::{c_char, c_uint};
21
use std::panic::catch_unwind;
22
use std::ptr;
23

24
use libc::size_t;
25

26
use super::lo_game_handle;
27
use crate::constants::{
28
    LIBLO_ERROR_INVALID_ARGS, LIBLO_ERROR_PANICKED, LIBLO_ERROR_POISONED_THREAD_LOCK, LIBLO_OK,
29
};
30
use crate::helpers::{error, handle_error, to_c_string_array, to_str, to_str_vec};
31

32
/// Gets the list of currently active plugins.
33
///
34
/// If no plugins are active, the value pointed to by `plugins` will be null and `num_plugins` will
35
/// point to zero.
36
///
37
/// Returns `LIBLO_OK` if successful, otherwise a `LIBLO_ERROR_*` code is returned.
38
///
39
/// # Safety
40
///
41
/// - `handle` must be a value that was previously set by `lo_create_handle()` and that has not been
42
///   destroyed using `lo_destroy_handle()`.
43
/// - `plugins` must be a dereferenceable pointer.
44
/// - `num_plugins` must be a dereferenceable pointer.
45
#[no_mangle]
46
pub unsafe extern "C" fn lo_get_active_plugins(
×
47
    handle: lo_game_handle,
×
48
    plugins: *mut *mut *mut c_char,
×
49
    num_plugins: *mut size_t,
×
50
) -> c_uint {
×
51
    catch_unwind(|| {
×
52
        if handle.is_null() || plugins.is_null() || num_plugins.is_null() {
×
53
            return error(LIBLO_ERROR_INVALID_ARGS, "Null pointer passed");
×
54
        }
×
55

56
        let handle = match (*handle).read() {
×
57
            Err(e) => return error(LIBLO_ERROR_POISONED_THREAD_LOCK, &e.to_string()),
×
58
            Ok(h) => h,
×
59
        };
×
60

×
61
        *plugins = ptr::null_mut();
×
62
        *num_plugins = 0;
×
63

×
64
        let active_plugins = handle.active_plugin_names();
×
65

×
66
        if active_plugins.is_empty() {
×
67
            return LIBLO_OK;
×
68
        }
×
69

×
70
        match to_c_string_array(&active_plugins) {
×
71
            Ok((pointer, size)) => {
×
72
                *plugins = pointer;
×
73
                *num_plugins = size;
×
74
            }
×
75
            Err(x) => return error(x, "A filename contained a null byte"),
×
76
        }
77

78
        LIBLO_OK
×
79
    })
×
80
    .unwrap_or(LIBLO_ERROR_PANICKED)
×
81
}
×
82

83
/// Sets the list of currently active plugins.
84
///
85
/// Replaces the current active plugins list with the plugins in the given array. The replacement
86
/// list must be valid. If, for Skyrim or Fallout 4, a plugin to be activated does not have a
87
/// defined load order position, this function will append it to the load order. If multiple such
88
/// plugins exist, they are appended in the order they are given.
89
///
90
/// Returns `LIBLO_OK` if successful, otherwise a `LIBLO_ERROR_*` code is returned.
91
///
92
/// # Safety
93
///
94
/// - `handle` must be a value that was previously set by `lo_create_handle()` and that has not been
95
///   destroyed using `lo_destroy_handle()`.
96
/// - `plugins` must be a non-null aligned pointer to a sequence of `num_plugins` initialised C
97
///   strings within a single allocated object.
98
/// - `num_plugins * std::mem::size_of::<*const c_char>()` must be no larger than `isize::MAX`.
99
#[no_mangle]
100
pub unsafe extern "C" fn lo_set_active_plugins(
×
101
    handle: lo_game_handle,
×
102
    plugins: *const *const c_char,
×
103
    num_plugins: size_t,
×
104
) -> c_uint {
×
105
    catch_unwind(|| {
×
106
        if handle.is_null() || plugins.is_null() {
×
107
            return error(LIBLO_ERROR_INVALID_ARGS, "Null pointer passed");
×
108
        }
×
109

110
        let mut handle = match (*handle).write() {
×
111
            Err(e) => return error(LIBLO_ERROR_POISONED_THREAD_LOCK, &e.to_string()),
×
112
            Ok(h) => h,
×
113
        };
114

115
        let plugins: Vec<&str> = match to_str_vec(plugins, num_plugins) {
×
116
            Ok(x) => x,
×
117
            Err(x) => return error(x, "A filename contained a null byte"),
×
118
        };
119

120
        if let Err(x) = handle.set_active_plugins(&plugins) {
×
NEW
121
            return handle_error(&x);
×
122
        }
×
123

124
        if let Err(x) = handle.save() {
×
NEW
125
            return handle_error(&x);
×
126
        }
×
127

×
128
        LIBLO_OK
×
129
    })
×
130
    .unwrap_or(LIBLO_ERROR_PANICKED)
×
131
}
×
132

133
/// Activates or deactivates a given plugin.
134
///
135
/// If `active` is true, the plugin will be activated. If `active` is false, the plugin will be
136
/// deactivated.
137
///
138
/// When activating a plugin that is ghosted, the ".ghost" extension is removed. If a plugin is
139
/// already in its target state, ie. a plugin to be activated is already activate, or a plugin to
140
/// be deactivated is already inactive, no changes are made.
141
///
142
/// Returns `LIBLO_OK` if successful, otherwise a `LIBLO_ERROR_*` code is returned.
143
///
144
/// # Safety
145
///
146
/// - `handle` must be a value that was previously set by `lo_create_handle()` and that has not been
147
///   destroyed using `lo_destroy_handle()`.
148
/// - `plugin` must be a null-terminated string contained within a single allocation.
149
#[no_mangle]
150
pub unsafe extern "C" fn lo_set_plugin_active(
×
151
    handle: lo_game_handle,
×
152
    plugin: *const c_char,
×
153
    active: bool,
×
154
) -> c_uint {
×
155
    catch_unwind(|| {
×
156
        if handle.is_null() || plugin.is_null() {
×
157
            return error(LIBLO_ERROR_INVALID_ARGS, "Null pointer passed");
×
158
        }
×
159

160
        let mut handle = match (*handle).write() {
×
161
            Err(e) => return error(LIBLO_ERROR_POISONED_THREAD_LOCK, &e.to_string()),
×
162
            Ok(h) => h,
×
163
        };
164

165
        let plugin = match to_str(plugin) {
×
166
            Ok(x) => x,
×
167
            Err(x) => return error(x, "The filename contained a null byte"),
×
168
        };
169

170
        let result = if active {
×
171
            handle.activate(plugin)
×
172
        } else {
173
            handle.deactivate(plugin)
×
174
        };
175

176
        if let Err(x) = result {
×
NEW
177
            return handle_error(&x);
×
178
        }
×
179

180
        if let Err(x) = handle.save() {
×
NEW
181
            return handle_error(&x);
×
182
        }
×
183

×
184
        LIBLO_OK
×
185
    })
×
186
    .unwrap_or(LIBLO_ERROR_PANICKED)
×
187
}
×
188

189
/// Checks if a given plugin is active.
190
///
191
/// Outputs `true` if the plugin is active, and false otherwise.
192
///
193
/// Returns `LIBLO_OK` if successful, otherwise a `LIBLO_ERROR_*` code is returned.
194
///
195
/// # Safety
196
///
197
/// - `handle` must be a value that was previously set by `lo_create_handle()` and that has not been
198
///   destroyed using `lo_destroy_handle()`.
199
/// - `plugin` must be a null-terminated string contained within a single allocation.
200
/// - `result` must be a dereferenceable pointer.
201
#[no_mangle]
202
pub unsafe extern "C" fn lo_get_plugin_active(
×
203
    handle: lo_game_handle,
×
204
    plugin: *const c_char,
×
205
    result: *mut bool,
×
206
) -> c_uint {
×
207
    catch_unwind(|| {
×
208
        if handle.is_null() || plugin.is_null() || result.is_null() {
×
209
            return error(LIBLO_ERROR_INVALID_ARGS, "Null pointer passed");
×
210
        }
×
211

212
        let handle = match (*handle).read() {
×
213
            Err(e) => return error(LIBLO_ERROR_POISONED_THREAD_LOCK, &e.to_string()),
×
214
            Ok(h) => h,
×
215
        };
216

217
        let plugin = match to_str(plugin) {
×
218
            Ok(x) => x,
×
219
            Err(x) => return error(x, "The filename contained a null byte"),
×
220
        };
221

222
        *result = handle.is_active(plugin);
×
223

×
224
        LIBLO_OK
×
225
    })
×
226
    .unwrap_or(LIBLO_ERROR_PANICKED)
×
227
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc