Merge branch 'refactor/riir' into refactor/wutil-rs
This commit is contained in:
+1
-1
@@ -39,7 +39,7 @@ ACLOCAL_AMFLAGS = -I m4
|
||||
AM_DISTCHECK_CONFIGURE_FLAGS = --enable-silent-rules LINGUAS='*'
|
||||
|
||||
|
||||
SUBDIRS = wrlib wutil-rs WINGs wmaker-rs src util po WindowMaker wmlib WPrefs.app doc
|
||||
SUBDIRS = wrlib wutil-rs wings-rs WINGs wmaker-rs src util po WindowMaker wmlib WPrefs.app doc
|
||||
DIST_SUBDIRS = $(SUBDIRS) test
|
||||
|
||||
EXTRA_DIST = TODO BUGS BUGFORM FAQ INSTALL \
|
||||
|
||||
+4
-9
@@ -156,12 +156,7 @@ typedef struct {
|
||||
|
||||
|
||||
|
||||
/* DO NOT ACCESS THE CONTENTS OF THIS STRUCT */
|
||||
typedef struct {
|
||||
void *table;
|
||||
void *nextItem;
|
||||
int index;
|
||||
} WMHashEnumerator;
|
||||
typedef struct WMHashEnumerator WMHashEnumerator;
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -329,7 +324,7 @@ void WMDeleteInputHandler(WMHandlerID handlerID);
|
||||
|
||||
void WHandleEvents(void);
|
||||
|
||||
/* ---[ WINGs/hashtable.c ]----------------------------------------------- */
|
||||
/* ---[ wutil-rs/src/hash_table.rs ]----------------------------------------------- */
|
||||
|
||||
|
||||
WMHashTable* WMCreateIdentityHashTable();
|
||||
@@ -361,7 +356,7 @@ void* WMHashInsert(WMHashTable *table, const void *key, const void *data);
|
||||
void WMHashRemove(WMHashTable *table, const void *key);
|
||||
|
||||
/* warning: do not manipulate the table while using the enumerator functions */
|
||||
WMHashEnumerator WMEnumerateHashTable(WMHashTable *table);
|
||||
WMHashEnumerator* WMEnumerateHashTable(WMHashTable *table);
|
||||
|
||||
void* WMNextHashEnumeratorItem(WMHashEnumerator *enumerator);
|
||||
|
||||
@@ -376,7 +371,7 @@ Bool WMNextHashEnumeratorItemAndKey(WMHashEnumerator *enumerator,
|
||||
void **item, void **key);
|
||||
|
||||
|
||||
|
||||
void WMFreeHashEnumerator(WMHashEnumerator *enumerator);
|
||||
|
||||
/* some predefined callback sets */
|
||||
|
||||
|
||||
+4
-2
@@ -456,12 +456,12 @@ static void handleEvents(XEvent * event, void *data)
|
||||
|
||||
static void destroyBalloon(Balloon * bPtr)
|
||||
{
|
||||
WMHashEnumerator e;
|
||||
WMHashEnumerator *e;
|
||||
char *str;
|
||||
|
||||
e = WMEnumerateHashTable(bPtr->table);
|
||||
|
||||
while ((str = WMNextHashEnumeratorItem(&e))) {
|
||||
while ((str = WMNextHashEnumeratorItem(e))) {
|
||||
wfree(str);
|
||||
}
|
||||
WMFreeHashTable(bPtr->table);
|
||||
@@ -472,5 +472,7 @@ static void destroyBalloon(Balloon * bPtr)
|
||||
if (bPtr->font)
|
||||
WMReleaseFont(bPtr->font);
|
||||
|
||||
WMFreeHashEnumerator(e);
|
||||
|
||||
wfree(bPtr);
|
||||
}
|
||||
|
||||
+3
-2
@@ -520,7 +520,7 @@ static void listFamilies(WMScreen * scr, WMFontPanel * panel)
|
||||
FcFontSet *fs;
|
||||
FcPattern *pat;
|
||||
WMHashTable *families;
|
||||
WMHashEnumerator enumer;
|
||||
WMHashEnumerator *enumer;
|
||||
WMArray *array;
|
||||
int i;
|
||||
|
||||
@@ -551,7 +551,8 @@ static void listFamilies(WMScreen * scr, WMFontPanel * panel)
|
||||
|
||||
enumer = WMEnumerateHashTable(families);
|
||||
|
||||
while ((array = WMNextHashEnumeratorItem(&enumer))) {
|
||||
while ((array = WMNextHashEnumeratorItem(enumer))) {
|
||||
printf("listFamilies: got family with %d items\n", WMGetArrayItemCount(array));
|
||||
WMArrayIterator i;
|
||||
Family *fam;
|
||||
char buffer[256];
|
||||
|
||||
@@ -926,6 +926,7 @@ AC_CONFIG_FILES(
|
||||
|
||||
dnl Rust implementation of WINGs libraries
|
||||
wutil-rs/Makefile
|
||||
wings-rs/Makefile
|
||||
|
||||
dnl WINGs toolkit
|
||||
WINGs/Makefile WINGs/WINGs/Makefile WINGs/po/Makefile
|
||||
|
||||
@@ -89,6 +89,8 @@ Xephyr -screen 640x480 "$xephyr_display" &
|
||||
xephyr_pid=$!
|
||||
DISPLAY="$xephyr_display" gdb \
|
||||
--directory "$project_base" \
|
||||
--directory "$HOME/src/libX11-1.5.0/build/src" \
|
||||
--quiet \
|
||||
--fullname \
|
||||
--args "$WindowMaker" -display "$xephyr_display" --for-real "$@"
|
||||
kill $xephyr_pid
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "wings-rs"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
wutil-rs = { path = "../wutil-rs" }
|
||||
@@ -0,0 +1,19 @@
|
||||
AUTOMAKE_OPTIONS =
|
||||
|
||||
RUST_SOURCES = \
|
||||
src/lib.rs
|
||||
|
||||
RUST_EXTRA = \
|
||||
Cargo.lock \
|
||||
Cargo.toml
|
||||
|
||||
target/debug/libwings_rs.a: $(RUST_SOURCES) $(RUST_EXTRA)
|
||||
$(CARGO) build
|
||||
|
||||
check-local:
|
||||
$(CARGO) test
|
||||
|
||||
clean-local:
|
||||
$(CARGO) clean
|
||||
|
||||
all: target/debug/libwings_rs.a
|
||||
@@ -0,0 +1,14 @@
|
||||
pub fn add(left: u64, right: u64) -> u64 {
|
||||
left + right
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
||||
+32
-36
@@ -1,7 +1,7 @@
|
||||
use std::{ffi::c_void, ptr::NonNull};
|
||||
use std::ffi::c_void;
|
||||
|
||||
pub struct Array {
|
||||
items: Vec<NonNull<c_void>>,
|
||||
items: Vec<usize>,
|
||||
destructor: Option<unsafe extern "C" fn(x: *mut c_void)>,
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ pub mod ffi {
|
||||
|
||||
use std::{
|
||||
ffi::{c_int, c_void},
|
||||
ptr::{self, NonNull},
|
||||
ptr,
|
||||
};
|
||||
|
||||
pub const NOT_FOUND: c_int = -1;
|
||||
@@ -64,7 +64,7 @@ pub mod ffi {
|
||||
let array = unsafe { &mut *array };
|
||||
if let Some(f) = array.destructor {
|
||||
for item in &mut array.items {
|
||||
unsafe { (f)(item.as_ptr()) }
|
||||
unsafe { (f)(*item as *mut c_void) }
|
||||
}
|
||||
}
|
||||
array.items.clear();
|
||||
@@ -94,10 +94,8 @@ pub mod ffi {
|
||||
if array.is_null() {
|
||||
return;
|
||||
}
|
||||
if let Some(item) = NonNull::new(item) {
|
||||
unsafe {
|
||||
(*array).items.push(item);
|
||||
}
|
||||
unsafe {
|
||||
(*array).items.push(item.addr());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,9 +112,7 @@ pub mod ffi {
|
||||
if index >= array.len() {
|
||||
return;
|
||||
}
|
||||
if let Some(item) = NonNull::new(item) {
|
||||
array.insert(index, item);
|
||||
}
|
||||
array.insert(index, item.addr());
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
@@ -141,15 +137,11 @@ pub mod ffi {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
let item = match NonNull::new(item) {
|
||||
Some(x) => x,
|
||||
None => return ptr::null_mut(),
|
||||
};
|
||||
let array = unsafe { &mut (*array).items };
|
||||
|
||||
let old = array[index];
|
||||
array[index] = item;
|
||||
old.as_ptr()
|
||||
array[index] = item.addr();
|
||||
old as *mut c_void
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
@@ -168,7 +160,7 @@ pub mod ffi {
|
||||
let old = array.items.remove(index);
|
||||
if let Some(f) = array.destructor {
|
||||
unsafe {
|
||||
(f)(old.as_ptr());
|
||||
(f)(old as *mut c_void);
|
||||
}
|
||||
}
|
||||
1
|
||||
@@ -192,8 +184,8 @@ pub mod ffi {
|
||||
let array = unsafe { &mut *array };
|
||||
let original_len = array.items.len();
|
||||
match pred {
|
||||
Some(f) => array.items.retain(|x| unsafe { f(x.as_ptr(), cdata) != 0 }),
|
||||
None => array.items.retain(|x| ptr::eq(x.as_ptr(), cdata)),
|
||||
Some(f) => array.items.retain(|x| unsafe { f(*x as *const c_void, cdata) != 0 }),
|
||||
None => array.items.retain(|x| ptr::eq(*x as *mut c_void, cdata)),
|
||||
}
|
||||
(original_len - array.items.len()) as c_int
|
||||
}
|
||||
@@ -207,7 +199,7 @@ pub mod ffi {
|
||||
(&(*array))
|
||||
.items
|
||||
.get(index as usize)
|
||||
.map(|p| p.as_ptr())
|
||||
.map(|p| *p as *mut c_void)
|
||||
.unwrap_or(ptr::null_mut())
|
||||
}
|
||||
}
|
||||
@@ -226,7 +218,7 @@ pub mod ffi {
|
||||
(*array)
|
||||
.items
|
||||
.pop()
|
||||
.map(|p| p.as_ptr())
|
||||
.map(|p| p as *mut c_void)
|
||||
.unwrap_or(ptr::null_mut())
|
||||
}
|
||||
}
|
||||
@@ -246,7 +238,7 @@ pub mod ffi {
|
||||
.items
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, item)| unsafe { f(item.as_ptr(), cdata) != 0 })
|
||||
.find(|(_, item)| unsafe { f(**item as *const c_void, cdata) != 0 })
|
||||
.map(|(i, _)| i as c_int)
|
||||
.unwrap_or(NOT_FOUND)
|
||||
} else {
|
||||
@@ -254,7 +246,7 @@ pub mod ffi {
|
||||
.items
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, item)| ptr::eq(item.as_ptr(), cdata))
|
||||
.find(|(_, item)| ptr::eq(**item as *const c_void, cdata))
|
||||
.map(|(i, _)| i as c_int)
|
||||
.unwrap_or(NOT_FOUND)
|
||||
}
|
||||
@@ -269,7 +261,7 @@ pub mod ffi {
|
||||
array
|
||||
.items
|
||||
.iter()
|
||||
.filter(|x| ptr::eq(x.as_ptr(), item))
|
||||
.filter(|x| ptr::eq(**x as *const c_void, item))
|
||||
.count() as c_int
|
||||
}
|
||||
|
||||
@@ -284,13 +276,17 @@ pub mod ffi {
|
||||
unsafe {
|
||||
(*array)
|
||||
.items
|
||||
.sort_by(|&a, &b| match comparator(a.as_ptr(), b.as_ptr()).signum() {
|
||||
-1 => std::cmp::Ordering::Less,
|
||||
0 => std::cmp::Ordering::Equal,
|
||||
1 => std::cmp::Ordering::Greater,
|
||||
_ => unreachable!(),
|
||||
.sort_by(|a, b| {
|
||||
let a = a as *const _ as *const c_void;
|
||||
let b = b as *const _ as *const c_void;
|
||||
match comparator(a, b).signum() {
|
||||
-1 => std::cmp::Ordering::Less,
|
||||
0 => std::cmp::Ordering::Equal,
|
||||
1 => std::cmp::Ordering::Greater,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
@@ -304,7 +300,7 @@ pub mod ffi {
|
||||
}
|
||||
unsafe {
|
||||
for a in &mut (*array).items {
|
||||
(f)(a.as_ptr(), data);
|
||||
(f)(*a as *mut c_void, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -326,7 +322,7 @@ pub mod ffi {
|
||||
unsafe {
|
||||
*iter = 0;
|
||||
}
|
||||
x.as_ptr()
|
||||
*x as *mut c_void
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,7 +344,7 @@ pub mod ffi {
|
||||
unsafe {
|
||||
*iter = (array.items.len() - 1) as c_int;
|
||||
}
|
||||
x.as_ptr()
|
||||
*x as *mut c_void
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -368,7 +364,7 @@ pub mod ffi {
|
||||
unsafe {
|
||||
*iter += 1;
|
||||
}
|
||||
i.as_ptr()
|
||||
*i as *mut c_void
|
||||
}
|
||||
None => {
|
||||
unsafe {
|
||||
@@ -394,7 +390,7 @@ pub mod ffi {
|
||||
unsafe {
|
||||
*iter -= 1;
|
||||
}
|
||||
i.as_ptr()
|
||||
*i as *mut c_void
|
||||
}
|
||||
None => {
|
||||
unsafe {
|
||||
|
||||
@@ -69,7 +69,6 @@ impl HashTable {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
pub struct StringKey(*const u8);
|
||||
|
||||
@@ -85,6 +84,12 @@ impl PartialEq for StringKey {
|
||||
|
||||
impl Eq for StringKey {}
|
||||
|
||||
impl std::fmt::Debug for StringKey {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "StringKey({:?})", unsafe { std::ffi::CStr::from_ptr(self.0) })
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for StringKey {
|
||||
fn hash<H: Hasher>(&self, h: &mut H) {
|
||||
if self.0.is_null() {
|
||||
@@ -291,4 +296,43 @@ pub mod ffi {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
use std::{ffi::CString, ptr};
|
||||
|
||||
#[test]
|
||||
fn enumerate_nonempty() {
|
||||
unsafe {
|
||||
let table = WMCreateStringHashTable();
|
||||
let k1 = CString::new("hello").unwrap().into_raw();
|
||||
let v1 = CString::new("world").unwrap().into_raw();
|
||||
let k2 = CString::new("foo").unwrap().into_raw();
|
||||
let v2 = CString::new("bar").unwrap().into_raw();
|
||||
WMHashInsert(table, k1.cast(), v1.cast());
|
||||
WMHashInsert(table, k2.cast(), v2.cast());
|
||||
|
||||
let i = WMEnumerateHashTable(table);
|
||||
|
||||
let v = WMNextHashEnumeratorItem(i);
|
||||
assert_ne!(v, ptr::null_mut());
|
||||
assert!(v == v1.cast() || v == v2.cast());
|
||||
|
||||
let v = WMNextHashEnumeratorItem(i);
|
||||
assert_ne!(v, ptr::null_mut());
|
||||
assert!(v == v1.cast() || v == v2.cast());
|
||||
|
||||
let v = WMNextHashEnumeratorItem(i);
|
||||
assert_eq!(v, ptr::null_mut());
|
||||
WMFreeHashEnumerator(i);
|
||||
|
||||
let _ = CString::from_raw(k1);
|
||||
let _ = CString::from_raw(v1);
|
||||
let _ = CString::from_raw(k2);
|
||||
let _ = CString::from_raw(v2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user