Merged master into master
This commit is contained in:
@@ -1 +1,2 @@
|
||||
/target/
|
||||
.idea/
|
||||
|
||||
+8
-3
@@ -1,12 +1,17 @@
|
||||
language: rust
|
||||
env:
|
||||
-
|
||||
- TARGET=aarch64-unknown-linux-gnu
|
||||
- TARGET=x86_64-unknown-redox
|
||||
rust:
|
||||
- nightly
|
||||
cache: cargo
|
||||
before_script:
|
||||
- rustup component add rustfmt-preview
|
||||
- rustup target add x86_64-unknown-redox
|
||||
- rustup target add aarch64-unknown-linux-gnu
|
||||
- if [ -n "$TARGET" ]; then rustup target add $TARGET; fi
|
||||
script:
|
||||
- bash ./ci.sh
|
||||
- ./fmt.sh -- --write-mode=diff
|
||||
- cargo build $([ -n "$TARGET" ] && echo --target="$TARGET")
|
||||
- if [ -z "$TARGET" ]; then ./test.sh; fi
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
Generated
+25
@@ -139,6 +139,14 @@ dependencies = [
|
||||
"platform 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "in_h"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cbindgen 0.5.2",
|
||||
"platform 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.3.4"
|
||||
@@ -182,6 +190,13 @@ dependencies = [
|
||||
"platform 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "netinet"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"in_h 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.1"
|
||||
@@ -259,10 +274,12 @@ dependencies = [
|
||||
"float 0.1.0",
|
||||
"grp 0.1.0",
|
||||
"mman 0.1.0",
|
||||
"netinet 0.1.0",
|
||||
"platform 0.1.0",
|
||||
"resource 0.1.0",
|
||||
"semaphore 0.1.0",
|
||||
"signal 0.1.0",
|
||||
"socket 0.1.0",
|
||||
"stat 0.1.0",
|
||||
"stdio 0.1.0",
|
||||
"stdlib 0.1.0",
|
||||
@@ -351,6 +368,14 @@ dependencies = [
|
||||
"platform 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cbindgen 0.5.2",
|
||||
"platform 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "standalone-quote"
|
||||
version = "0.5.0"
|
||||
|
||||
@@ -19,10 +19,12 @@ fenv = { path = "src/fenv" }
|
||||
float = { path = "src/float" }
|
||||
grp = { path = "src/grp" }
|
||||
mman = { path = "src/mman" }
|
||||
netinet = { path = "src/netinet" }
|
||||
platform = { path = "src/platform" }
|
||||
resource = { path = "src/resource" }
|
||||
semaphore = { path = "src/semaphore" }
|
||||
signal = { path = "src/signal" }
|
||||
socket = { path = "src/socket" }
|
||||
stat = { path = "src/stat" }
|
||||
stdio = { path = "src/stdio" }
|
||||
stdlib = { path = "src/stdlib" }
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
./fmt.sh -- --write-mode=diff
|
||||
./test.sh
|
||||
cargo build --target=x86_64-unknown-redox
|
||||
if [ $(arch) == "x86_64" ]
|
||||
then
|
||||
cargo build --target=aarch64-unknown-linux-gnu
|
||||
else
|
||||
cargo build --target=x86_64-unknown-linux-gnu
|
||||
fi
|
||||
@@ -11,8 +11,10 @@ extern crate fenv;
|
||||
extern crate float;
|
||||
extern crate grp;
|
||||
extern crate mman;
|
||||
extern crate netinet;
|
||||
extern crate resource;
|
||||
extern crate semaphore;
|
||||
extern crate socket;
|
||||
extern crate stat;
|
||||
extern crate stdio;
|
||||
extern crate stdlib;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "netinet"
|
||||
version = "0.1.0"
|
||||
authors = ["Dan Robertson <danlrobertson89@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
in_h = { path = "in" }
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "in_h"
|
||||
version = "0.1.0"
|
||||
authors = ["Dan Robertson <danlrobertson89@gmail.com>"]
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = { path = "../../../cbindgen" }
|
||||
|
||||
[dependencies]
|
||||
platform = { path = "../../platform" }
|
||||
socket = { path = "../../socket" }
|
||||
@@ -0,0 +1,12 @@
|
||||
extern crate cbindgen;
|
||||
|
||||
use std::{env, fs};
|
||||
|
||||
fn main() {
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
|
||||
fs::create_dir_all("../../../target/include").expect("failed to create include directory");
|
||||
fs::create_dir_all("../../../target/include/netinet").expect("failed to create include directory");
|
||||
cbindgen::generate(crate_dir)
|
||||
.expect("failed to generate bindings")
|
||||
.write_to_file("../../../target/include/netinet/in.h");
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
sys_includes = ["sys/types.h", "sys/socket.h"]
|
||||
include_guard = "_NETINET_IN_H"
|
||||
style = "Tag"
|
||||
language = "C"
|
||||
|
||||
[export]
|
||||
include = ["sockaddr_in6", "sockaddr_in", "ipv6_mreq"]
|
||||
|
||||
[enum]
|
||||
prefix_with_name = true
|
||||
@@ -0,0 +1,58 @@
|
||||
#![no_std]
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
extern crate platform;
|
||||
extern crate socket;
|
||||
|
||||
use platform::types::*;
|
||||
use socket::sa_family_t;
|
||||
|
||||
pub type in_addr_t = u32;
|
||||
pub type in_port_t = u16;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct in_addr {
|
||||
pub s_addr: in_addr_t
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct in6_addr {
|
||||
pub s6_addr: [u8; 16]
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sockaddr_in {
|
||||
pub sa_family: sa_family_t,
|
||||
pub sin_port: in_port_t,
|
||||
pub sin_addr: in_addr
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sockaddr_in6 {
|
||||
pub sin6_family: sa_family_t,
|
||||
pub sin6_port: in_port_t,
|
||||
pub sin6_flowinfo: u32,
|
||||
pub sin6_addr: in6_addr,
|
||||
pub sin6_scope_id: u32
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ipv6_mreq {
|
||||
pub ipv6mr_multiaddr: in6_addr,
|
||||
pub ipv6mr_interface: u32,
|
||||
}
|
||||
|
||||
// Address String Lengths
|
||||
pub const INET_ADDRSTRLEN: c_int = 16;
|
||||
pub const INET6_ADDRSTRLEN: c_int = 46;
|
||||
|
||||
// Protocol Numbers
|
||||
pub const IPPROTO_IP: u8 = 0x00;
|
||||
pub const IPPROTO_ICMP: u8 = 0x01;
|
||||
pub const IPPROTO_TCP: u8 = 0x06;
|
||||
pub const IPPROTO_UDP: u8 = 0x11;
|
||||
pub const IPPROTO_IPV6: u8 = 0x29;
|
||||
pub const IPPROTO_RAW: u8 = 0xff;
|
||||
pub const IPPROTO_MAX: u8 = 0xff;
|
||||
@@ -0,0 +1,3 @@
|
||||
#![no_std]
|
||||
|
||||
extern crate in_h;
|
||||
@@ -146,27 +146,23 @@ pub fn mkdir(path: *const c_char, mode: mode_t) -> c_int {
|
||||
}
|
||||
|
||||
pub fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
|
||||
unsafe {
|
||||
let redox_rqtp = redox_timespec {
|
||||
tv_sec: (*rqtp).tv_sec,
|
||||
tv_nsec: (*rqtp).tv_nsec as i32,
|
||||
};
|
||||
let mut redox_rmtp: redox_timespec;
|
||||
if rmtp.is_null() {
|
||||
redox_rmtp = redox_timespec::default();
|
||||
} else {
|
||||
redox_rmtp = redox_timespec {
|
||||
tv_sec: (*rmtp).tv_sec,
|
||||
tv_nsec: (*rmtp).tv_nsec as i32,
|
||||
};
|
||||
}
|
||||
match e(syscall::nanosleep(&redox_rqtp, &mut redox_rmtp)) as c_int {
|
||||
-1 => -1,
|
||||
_ => {
|
||||
(*rmtp).tv_sec = redox_rmtp.tv_sec;
|
||||
(*rmtp).tv_nsec = redox_rmtp.tv_nsec as i64;
|
||||
0
|
||||
let redox_rqtp = unsafe { redox_timespec::from(&*rqtp) };
|
||||
let mut redox_rmtp: redox_timespec;
|
||||
if rmtp.is_null() {
|
||||
redox_rmtp = redox_timespec::default();
|
||||
} else {
|
||||
redox_rmtp = unsafe { redox_timespec::from(&*rmtp) };
|
||||
}
|
||||
match e(syscall::nanosleep(&redox_rqtp, &mut redox_rmtp)) as c_int {
|
||||
-1 => -1,
|
||||
_ => {
|
||||
unsafe {
|
||||
if !rmtp.is_null() {
|
||||
(*rmtp).tv_sec = redox_rmtp.tv_sec;
|
||||
(*rmtp).tv_nsec = redox_rmtp.tv_nsec as i64;
|
||||
}
|
||||
}
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#[cfg(target_os = "redox")]
|
||||
use syscall::data::TimeSpec as redox_timespec;
|
||||
// Use repr(u8) as LLVM expects `void*` to be the same as `i8*` to help enable
|
||||
// more optimization opportunities around it recognizing things like
|
||||
// malloc/free.
|
||||
@@ -70,3 +72,13 @@ pub struct timespec {
|
||||
pub tv_sec: time_t,
|
||||
pub tv_nsec: c_long,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "redox")]
|
||||
impl<'a> From<&'a timespec> for redox_timespec {
|
||||
fn from(tp: ×pec) -> redox_timespec {
|
||||
redox_timespec {
|
||||
tv_sec: tp.tv_sec,
|
||||
tv_nsec: tp.tv_nsec as i32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "socket"
|
||||
version = "0.1.0"
|
||||
authors = ["Dan Robertson <danlrobertson89@gmail.com>"]
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
cbindgen = { path = "../../cbindgen" }
|
||||
|
||||
[dependencies]
|
||||
platform = { path = "../platform" }
|
||||
@@ -0,0 +1,11 @@
|
||||
extern crate cbindgen;
|
||||
|
||||
use std::{env, fs};
|
||||
|
||||
fn main() {
|
||||
let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
|
||||
fs::create_dir_all("../../target/include").expect("failed to create include directory");
|
||||
cbindgen::generate(crate_dir)
|
||||
.expect("failed to generate bindings")
|
||||
.write_to_file("../../target/include/sys/socket.h");
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
sys_includes = ["sys/types.h"]
|
||||
include_guard = "_SYS_SOCKET_H"
|
||||
style = "Tag"
|
||||
language = "C"
|
||||
|
||||
[defines]
|
||||
"target_os=linux" = "__linux__"
|
||||
"target_os=redox" = "__redox__"
|
||||
|
||||
[enum]
|
||||
prefix_with_name = true
|
||||
@@ -0,0 +1,153 @@
|
||||
//! socket implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xns/syssocket.h.html
|
||||
|
||||
#![no_std]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
extern crate platform;
|
||||
|
||||
use platform::types::*;
|
||||
|
||||
pub type sa_family_t = u16;
|
||||
pub type socklen_t = u32;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sockaddr {
|
||||
pub sa_family: sa_family_t,
|
||||
pub sa_data: [c_char; 14],
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn accept(
|
||||
socket: c_int,
|
||||
address: *mut sockaddr,
|
||||
address_len: *mut socklen_t,
|
||||
) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn bind(
|
||||
socket: c_int,
|
||||
address: *const sockaddr,
|
||||
address_len: socklen_t,
|
||||
) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn connect(
|
||||
socket: c_int,
|
||||
address: *const sockaddr,
|
||||
address_len: socklen_t,
|
||||
) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn getpeername(
|
||||
socket: c_int,
|
||||
address: *const sockaddr,
|
||||
address_len: socklen_t,
|
||||
) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn getsockname(
|
||||
socket: c_int,
|
||||
address: *mut sockaddr,
|
||||
address_len: *mut socklen_t,
|
||||
) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn getsockopt(
|
||||
socket: c_int,
|
||||
level: c_int,
|
||||
option_name: c_int,
|
||||
option_value: *mut c_void,
|
||||
option_len: *mut socklen_t,
|
||||
) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn listen(socket: c_int, backlog: c_int) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn recv(
|
||||
socket: c_int,
|
||||
buffer: *mut c_void,
|
||||
length: size_t,
|
||||
flags: c_int,
|
||||
) -> ssize_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn recvfrom(
|
||||
socket: c_int,
|
||||
buffer: *mut c_void,
|
||||
length: size_t,
|
||||
flags: c_int,
|
||||
address: *mut sockaddr,
|
||||
address_len: *mut socklen_t,
|
||||
) -> ssize_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn send(
|
||||
socket: c_int,
|
||||
message: *const c_void,
|
||||
length: size_t,
|
||||
flags: c_int,
|
||||
) -> ssize_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sento(
|
||||
socket: c_int,
|
||||
message: *const c_void,
|
||||
length: size_t,
|
||||
flags: c_int,
|
||||
dest_addr: *const sockaddr,
|
||||
dest_len: socklen_t,
|
||||
) -> ssize_t {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn setsockopt(
|
||||
socket: c_int,
|
||||
level: c_int,
|
||||
option_name: c_int,
|
||||
option_value: *const c_void,
|
||||
option_len: socklen_t,
|
||||
) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn shutdown(socket: c_int, how: c_int) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn socket(domain: c_int, _type: c_int, protocol: c_int) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn socketpair(
|
||||
domain: c_int,
|
||||
_type: c_int,
|
||||
protocol: c_int,
|
||||
socket_vector: [c_int; 2],
|
||||
) -> c_int {
|
||||
unimplemented!();
|
||||
}
|
||||
+21
-3
@@ -130,15 +130,33 @@ pub extern "C" fn atol(s: *const c_char) -> c_long {
|
||||
dec_num_from_ascii!(s, c_long)
|
||||
}
|
||||
|
||||
unsafe extern "C" fn void_cmp(a: *const c_void, b: *const c_void) -> c_int {
|
||||
return *(a as *const i32) - *(b as *const i32) as c_int;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn bsearch(
|
||||
pub unsafe extern "C" fn bsearch(
|
||||
key: *const c_void,
|
||||
base: *const c_void,
|
||||
nel: size_t,
|
||||
width: size_t,
|
||||
compar: Option<extern "C" fn(*const c_void, *const c_void) -> c_int>,
|
||||
compar: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
|
||||
) -> *mut c_void {
|
||||
unimplemented!();
|
||||
let mut start = base;
|
||||
let mut len = nel;
|
||||
let cmp_fn = compar.unwrap_or(void_cmp);
|
||||
while len > 0 {
|
||||
let med = (start as size_t + (len >> 1) * width) as *const c_void;
|
||||
let diff = cmp_fn(key, med);
|
||||
if diff == 0 {
|
||||
return med as *mut c_void;
|
||||
} else if diff > 0 {
|
||||
start = (med as usize + width) as *const c_void;
|
||||
len -= 1;
|
||||
}
|
||||
len >>= 1;
|
||||
}
|
||||
ptr::null_mut()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
+36
-4
@@ -323,17 +323,49 @@ pub unsafe extern "C" fn strstr(s1: *const c_char, s2: *const c_char) -> *mut c_
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn strtok(s1: *mut c_char, s2: *const c_char) -> *mut c_char {
|
||||
unimplemented!();
|
||||
pub extern "C" fn strtok(s1: *mut c_char, delimiter: *const c_char) -> *mut c_char {
|
||||
static mut HAYSTACK: *mut c_char = ptr::null_mut();
|
||||
unsafe {
|
||||
return strtok_r(s1, delimiter, &mut HAYSTACK);
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn strtok_r(
|
||||
s: *mut c_char,
|
||||
sep: *const c_char,
|
||||
delimiter: *const c_char,
|
||||
lasts: *mut *mut c_char,
|
||||
) -> *mut c_char {
|
||||
unimplemented!();
|
||||
// Loosely based on GLIBC implementation
|
||||
unsafe {
|
||||
let mut haystack = s;
|
||||
if haystack.is_null() {
|
||||
if (*lasts).is_null() {
|
||||
return ptr::null_mut();
|
||||
}
|
||||
haystack = *lasts;
|
||||
}
|
||||
|
||||
// Skip past any extra delimiter left over from previous call
|
||||
haystack = haystack.add(strspn(haystack, delimiter));
|
||||
if *haystack == 0 {
|
||||
*lasts = ptr::null_mut();
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
// Build token by injecting null byte into delimiter
|
||||
let token = haystack;
|
||||
haystack = strpbrk(token, delimiter);
|
||||
if !haystack.is_null() {
|
||||
haystack.write(0);
|
||||
haystack = haystack.add(1);
|
||||
*lasts = haystack;
|
||||
} else {
|
||||
*lasts = ptr::null_mut();
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
/rmdir
|
||||
/setid
|
||||
/sprintf
|
||||
/stdlib/bsearch
|
||||
/stdlib/strtol
|
||||
/stdlib/a64l
|
||||
/stdio/fwrite
|
||||
|
||||
@@ -25,6 +25,7 @@ EXPECT_BINS=\
|
||||
stdio/fwrite \
|
||||
stdio/all \
|
||||
stdio/freopen \
|
||||
stdlib/bsearch \
|
||||
stdlib/strtol \
|
||||
stdlib/a64l \
|
||||
string/strncmp \
|
||||
@@ -34,6 +35,8 @@ EXPECT_BINS=\
|
||||
string/strspn \
|
||||
string/strstr \
|
||||
string/strpbrk \
|
||||
string/strtok \
|
||||
string/strtok_r \
|
||||
unlink \
|
||||
waitpid \
|
||||
write
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
I'd_just_like_to_interject_for_a_moment.__What_you're_referring_to_as_Linux,
|
||||
is_in_fact,_GNU/Linux,_or_as_I've_recently_taken_to_calling_it,_GNU_plus_Linux.
|
||||
@@ -0,0 +1,2 @@
|
||||
I'd_just_like_to_interject_for_a_moment.__What_you're_referring_to_as_Linux,
|
||||
is_in_fact,_GNU/Linux,_or_as_I've_recently_taken_to_calling_it,_GNU_plus_Linux.
|
||||
@@ -0,0 +1,55 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int int_cmp(const void* a, const void* b) {
|
||||
return *(const int*) a - *(const int*) b;
|
||||
}
|
||||
|
||||
#define BSEARCH_TEST_INT(key, arr, len, expect) \
|
||||
do { \
|
||||
void* res = bsearch((const void*) &key, (void*) arr, len, sizeof(int), int_cmp); \
|
||||
if (res != expect) { \
|
||||
printf("FAIL bsearch for %d in [", key); \
|
||||
size_t i = 0; \
|
||||
for (; i < len; ++i) printf("%d,", arr[i]); \
|
||||
printf("] expected %p but got %p\n", (void*) expect, res); \
|
||||
return 1; \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int x = 0;
|
||||
int y = 1024;
|
||||
int empty[] = {};
|
||||
BSEARCH_TEST_INT(x, empty, 0, NULL);
|
||||
|
||||
int singleton[] = {42};
|
||||
printf("%p\n%p\n", singleton, &singleton[1]);
|
||||
BSEARCH_TEST_INT(x, singleton, 1, NULL);
|
||||
BSEARCH_TEST_INT(singleton[0], singleton, 1, &singleton[0]);
|
||||
BSEARCH_TEST_INT(y, singleton, 1, NULL);
|
||||
|
||||
int two[] = {14, 42};
|
||||
BSEARCH_TEST_INT(x, two, 2, NULL);
|
||||
BSEARCH_TEST_INT(y, two, 2, NULL);
|
||||
BSEARCH_TEST_INT(two[0], two, 2, &two[0]);
|
||||
BSEARCH_TEST_INT(two[0], two, 1, &two[0]);
|
||||
BSEARCH_TEST_INT(two[1], two, 2, &two[1]);
|
||||
BSEARCH_TEST_INT(two[1], two, 1, NULL);
|
||||
|
||||
int three[] = {-5, -1, 4};
|
||||
BSEARCH_TEST_INT(three[0], three, 3, &three[0]);
|
||||
BSEARCH_TEST_INT(three[1], three, 3, &three[1]);
|
||||
BSEARCH_TEST_INT(three[2], three, 3, &three[2]);
|
||||
|
||||
int big[] = {-19, -13, -7, -3, 2, 5, 11};
|
||||
BSEARCH_TEST_INT(big[0], big, 7, big);
|
||||
BSEARCH_TEST_INT(big[6], big, 7, &big[6]);
|
||||
BSEARCH_TEST_INT(big[3], big, 7, &big[3]);
|
||||
BSEARCH_TEST_INT(x, big, 7, NULL);
|
||||
|
||||
printf("PASS bsearch\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char source[] = "I'd just like to interject for a moment. What you're referring to as Linux, "
|
||||
"is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux.\n";
|
||||
|
||||
char* token = strtok(source, " ");
|
||||
while (token) {
|
||||
printf("%s", token);
|
||||
if (token = strtok(NULL, " ")) {
|
||||
printf("_");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
char source[] = "I'd just like to interject for a moment. What you're referring to as Linux, "
|
||||
"is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux.\n";
|
||||
char* sp;
|
||||
|
||||
char* token = strtok_r(source, " ", &sp);
|
||||
while (token) {
|
||||
printf("%s", token);
|
||||
if (token = strtok_r(NULL, " ", &sp)) {
|
||||
printf("_");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user