Merge pull request #29 from dlrobertson/add_functions

Add ctype functions and atoi/atol
This commit is contained in:
Jeremy Soller
2018-03-08 07:34:14 -07:00
committed by GitHub
11 changed files with 224 additions and 112 deletions
Generated
+1
View File
@@ -453,6 +453,7 @@ name = "stdlib"
version = "0.1.0"
dependencies = [
"cbindgen 0.5.0",
"ctype 0.1.0",
"platform 0.1.0",
"ralloc 1.0.0",
]
+17 -9
View File
@@ -8,17 +8,17 @@ use platform::types::*;
#[no_mangle]
pub extern "C" fn isalnum(c: c_int) -> c_int {
unimplemented!();
(isdigit(c) != 0 || isalpha(c) != 0) as c_int
}
#[no_mangle]
pub extern "C" fn isalpha(c: c_int) -> c_int {
unimplemented!();
(islower(c) != 0 || isupper(c) != 0) as c_int
}
#[no_mangle]
pub extern "C" fn isascii(c: c_int) -> c_int {
unimplemented!();
(!(c & !0x7f)) as c_int
}
#[no_mangle]
@@ -28,7 +28,7 @@ pub extern "C" fn iscntrl(c: c_int) -> c_int {
#[no_mangle]
pub extern "C" fn isdigit(c: c_int) -> c_int {
unimplemented!();
(((c - 0x30) as c_uint) < 10) as c_int
}
#[no_mangle]
@@ -38,7 +38,7 @@ pub extern "C" fn isgraph(c: c_int) -> c_int {
#[no_mangle]
pub extern "C" fn islower(c: c_int) -> c_int {
unimplemented!();
(((c - 0x61) as c_uint) < 26) as c_int
}
#[no_mangle]
@@ -53,12 +53,12 @@ pub extern "C" fn ispunct(c: c_int) -> c_int {
#[no_mangle]
pub extern "C" fn isspace(c: c_int) -> c_int {
unimplemented!();
(c == 0x20) as c_int
}
#[no_mangle]
pub extern "C" fn isupper(c: c_int) -> c_int {
unimplemented!();
(((c - 0x41) as c_uint) < 26) as c_int
}
#[no_mangle]
@@ -73,10 +73,18 @@ pub extern "C" fn toascii(c: c_int) -> c_int {
#[no_mangle]
pub extern "C" fn tolower(c: c_int) -> c_int {
unimplemented!();
if isupper(c) != 0 {
c + 0x20
} else {
c
}
}
#[no_mangle]
pub extern "C" fn toupper(c: c_int) -> c_int {
unimplemented!();
if islower(c) != 0 {
c - 0x20
} else {
c
}
}
+99 -99
View File
@@ -6,105 +6,105 @@ extern crate platform;
use platform::types::*;
pub const EPERM: c_int = 1; /* Operation not permitted */
pub const ENOENT: c_int = 2; /* No such file or directory */
pub const ESRCH: c_int = 3; /* No such process */
pub const EINTR: c_int = 4; /* Interrupted system call */
pub const EIO: c_int = 5; /* I/O error */
pub const ENXIO: c_int = 6; /* No such device or address */
pub const E2BIG: c_int = 7; /* Argument list too long */
pub const ENOEXEC: c_int = 8; /* Exec format error */
pub const EBADF: c_int = 9; /* Bad file number */
pub const ECHILD: c_int = 10; /* No child processes */
pub const EAGAIN: c_int = 11; /* Try again */
pub const ENOMEM: c_int = 12; /* Out of memory */
pub const EACCES: c_int = 13; /* Permission denied */
pub const EFAULT: c_int = 14; /* Bad address */
pub const ENOTBLK: c_int = 15; /* Block device required */
pub const EBUSY: c_int = 16; /* Device or resource busy */
pub const EEXIST: c_int = 17; /* File exists */
pub const EXDEV: c_int = 18; /* Cross-device link */
pub const ENODEV: c_int = 19; /* No such device */
pub const ENOTDIR: c_int = 20; /* Not a directory */
pub const EISDIR: c_int = 21; /* Is a directory */
pub const EINVAL: c_int = 22; /* Invalid argument */
pub const ENFILE: c_int = 23; /* File table overflow */
pub const EMFILE: c_int = 24; /* Too many open files */
pub const ENOTTY: c_int = 25; /* Not a typewriter */
pub const ETXTBSY: c_int = 26; /* Text file busy */
pub const EFBIG: c_int = 27; /* File too large */
pub const ENOSPC: c_int = 28; /* No space left on device */
pub const ESPIPE: c_int = 29; /* Illegal seek */
pub const EROFS: c_int = 30; /* Read-only file system */
pub const EMLINK: c_int = 31; /* Too many links */
pub const EPIPE: c_int = 32; /* Broken pipe */
pub const EDOM: c_int = 33; /* Math argument out of domain of func */
pub const ERANGE: c_int = 34; /* Math result not representable */
pub const EDEADLK: c_int = 35; /* Resource deadlock would occur */
pub const ENAMETOOLONG: c_int = 36; /* File name too long */
pub const ENOLCK: c_int = 37; /* No record locks available */
pub const ENOSYS: c_int = 38; /* Function not implemented */
pub const ENOTEMPTY: c_int = 39; /* Directory not empty */
pub const ELOOP: c_int = 40; /* Too many symbolic links encountered */
pub const EWOULDBLOCK: c_int = 41; /* Operation would block */
pub const ENOMSG: c_int = 42; /* No message of desired type */
pub const EIDRM: c_int = 43; /* Identifier removed */
pub const ECHRNG: c_int = 44; /* Channel number out of range */
pub const EL2NSYNC: c_int = 45; /* Level 2 not synchronized */
pub const EL3HLT: c_int = 46; /* Level 3 halted */
pub const EL3RST: c_int = 47; /* Level 3 reset */
pub const ELNRNG: c_int = 48; /* Link number out of range */
pub const EUNATCH: c_int = 49; /* Protocol driver not attached */
pub const ENOCSI: c_int = 50; /* No CSI structure available */
pub const EL2HLT: c_int = 51; /* Level 2 halted */
pub const EBADE: c_int = 52; /* Invalid exchange */
pub const EBADR: c_int = 53; /* Invalid request descriptor */
pub const EXFULL: c_int = 54; /* Exchange full */
pub const ENOANO: c_int = 55; /* No anode */
pub const EBADRQC: c_int = 56; /* Invalid request code */
pub const EBADSLT: c_int = 57; /* Invalid slot */
pub const EPERM: c_int = 1; /* Operation not permitted */
pub const ENOENT: c_int = 2; /* No such file or directory */
pub const ESRCH: c_int = 3; /* No such process */
pub const EINTR: c_int = 4; /* Interrupted system call */
pub const EIO: c_int = 5; /* I/O error */
pub const ENXIO: c_int = 6; /* No such device or address */
pub const E2BIG: c_int = 7; /* Argument list too long */
pub const ENOEXEC: c_int = 8; /* Exec format error */
pub const EBADF: c_int = 9; /* Bad file number */
pub const ECHILD: c_int = 10; /* No child processes */
pub const EAGAIN: c_int = 11; /* Try again */
pub const ENOMEM: c_int = 12; /* Out of memory */
pub const EACCES: c_int = 13; /* Permission denied */
pub const EFAULT: c_int = 14; /* Bad address */
pub const ENOTBLK: c_int = 15; /* Block device required */
pub const EBUSY: c_int = 16; /* Device or resource busy */
pub const EEXIST: c_int = 17; /* File exists */
pub const EXDEV: c_int = 18; /* Cross-device link */
pub const ENODEV: c_int = 19; /* No such device */
pub const ENOTDIR: c_int = 20; /* Not a directory */
pub const EISDIR: c_int = 21; /* Is a directory */
pub const EINVAL: c_int = 22; /* Invalid argument */
pub const ENFILE: c_int = 23; /* File table overflow */
pub const EMFILE: c_int = 24; /* Too many open files */
pub const ENOTTY: c_int = 25; /* Not a typewriter */
pub const ETXTBSY: c_int = 26; /* Text file busy */
pub const EFBIG: c_int = 27; /* File too large */
pub const ENOSPC: c_int = 28; /* No space left on device */
pub const ESPIPE: c_int = 29; /* Illegal seek */
pub const EROFS: c_int = 30; /* Read-only file system */
pub const EMLINK: c_int = 31; /* Too many links */
pub const EPIPE: c_int = 32; /* Broken pipe */
pub const EDOM: c_int = 33; /* Math argument out of domain of func */
pub const ERANGE: c_int = 34; /* Math result not representable */
pub const EDEADLK: c_int = 35; /* Resource deadlock would occur */
pub const ENAMETOOLONG: c_int = 36; /* File name too long */
pub const ENOLCK: c_int = 37; /* No record locks available */
pub const ENOSYS: c_int = 38; /* Function not implemented */
pub const ENOTEMPTY: c_int = 39; /* Directory not empty */
pub const ELOOP: c_int = 40; /* Too many symbolic links encountered */
pub const EWOULDBLOCK: c_int = 41; /* Operation would block */
pub const ENOMSG: c_int = 42; /* No message of desired type */
pub const EIDRM: c_int = 43; /* Identifier removed */
pub const ECHRNG: c_int = 44; /* Channel number out of range */
pub const EL2NSYNC: c_int = 45; /* Level 2 not synchronized */
pub const EL3HLT: c_int = 46; /* Level 3 halted */
pub const EL3RST: c_int = 47; /* Level 3 reset */
pub const ELNRNG: c_int = 48; /* Link number out of range */
pub const EUNATCH: c_int = 49; /* Protocol driver not attached */
pub const ENOCSI: c_int = 50; /* No CSI structure available */
pub const EL2HLT: c_int = 51; /* Level 2 halted */
pub const EBADE: c_int = 52; /* Invalid exchange */
pub const EBADR: c_int = 53; /* Invalid request descriptor */
pub const EXFULL: c_int = 54; /* Exchange full */
pub const ENOANO: c_int = 55; /* No anode */
pub const EBADRQC: c_int = 56; /* Invalid request code */
pub const EBADSLT: c_int = 57; /* Invalid slot */
pub const EDEADLOCK: c_int = 58; /* Resource deadlock would occur */
pub const EBFONT: c_int = 59; /* Bad font file format */
pub const ENOSTR: c_int = 60; /* Device not a stream */
pub const ENODATA: c_int = 61; /* No data available */
pub const ETIME: c_int = 62; /* Timer expired */
pub const ENOSR: c_int = 63; /* Out of streams resources */
pub const ENONET: c_int = 64; /* Machine is not on the network */
pub const ENOPKG: c_int = 65; /* Package not installed */
pub const EREMOTE: c_int = 66; /* Object is remote */
pub const ENOLINK: c_int = 67; /* Link has been severed */
pub const EADV: c_int = 68; /* Advertise error */
pub const ESRMNT: c_int = 69; /* Srmount error */
pub const ECOMM: c_int = 70; /* Communication error on send */
pub const EPROTO: c_int = 71; /* Protocol error */
pub const EMULTIHOP: c_int = 72; /* Multihop attempted */
pub const EDOTDOT: c_int = 73; /* RFS specific error */
pub const EBADMSG: c_int = 74; /* Not a data message */
pub const EOVERFLOW: c_int = 75; /* Value too large for defined data type */
pub const ENOTUNIQ: c_int = 76; /* Name not unique on network */
pub const EBADFD: c_int = 77; /* File descriptor in bad state */
pub const EREMCHG: c_int = 78; /* Remote address changed */
pub const ELIBACC: c_int = 79; /* Can not access a needed shared library */
pub const ELIBBAD: c_int = 80; /* Accessing a corrupted shared library */
pub const ELIBSCN: c_int = 81; /* .lib section in a.out corrupted */
pub const ELIBMAX: c_int = 82; /* Attempting to link in too many shared libraries */
pub const ELIBEXEC: c_int = 83; /* Cannot exec a shared library directly */
pub const EILSEQ: c_int = 84; /* Illegal byte sequence */
pub const ERESTART: c_int = 85; /* Interrupted system call should be restarted */
pub const ESTRPIPE: c_int = 86; /* Streams pipe error */
pub const EUSERS: c_int = 87; /* Too many users */
pub const ENOTSOCK: c_int = 88; /* Socket operation on non-socket */
pub const EDESTADDRREQ: c_int = 89; /* Destination address required */
pub const EMSGSIZE: c_int = 90; /* Message too long */
pub const EPROTOTYPE: c_int = 91; /* Protocol wrong type for socket */
pub const ENOPROTOOPT: c_int = 92; /* Protocol not available */
pub const EPROTONOSUPPORT: c_int = 93; /* Protocol not supported */
pub const ESOCKTNOSUPPORT: c_int = 94; /* Socket type not supported */
pub const EOPNOTSUPP: c_int = 95; /* Operation not supported on transport endpoint */
pub const EPFNOSUPPORT: c_int = 96; /* Protocol family not supported */
pub const EAFNOSUPPORT: c_int = 97; /* Address family not supported by protocol */
pub const EADDRINUSE: c_int = 98; /* Address already in use */
pub const EADDRNOTAVAIL: c_int = 99; /* Cannot assign requested address */
pub const EBFONT: c_int = 59; /* Bad font file format */
pub const ENOSTR: c_int = 60; /* Device not a stream */
pub const ENODATA: c_int = 61; /* No data available */
pub const ETIME: c_int = 62; /* Timer expired */
pub const ENOSR: c_int = 63; /* Out of streams resources */
pub const ENONET: c_int = 64; /* Machine is not on the network */
pub const ENOPKG: c_int = 65; /* Package not installed */
pub const EREMOTE: c_int = 66; /* Object is remote */
pub const ENOLINK: c_int = 67; /* Link has been severed */
pub const EADV: c_int = 68; /* Advertise error */
pub const ESRMNT: c_int = 69; /* Srmount error */
pub const ECOMM: c_int = 70; /* Communication error on send */
pub const EPROTO: c_int = 71; /* Protocol error */
pub const EMULTIHOP: c_int = 72; /* Multihop attempted */
pub const EDOTDOT: c_int = 73; /* RFS specific error */
pub const EBADMSG: c_int = 74; /* Not a data message */
pub const EOVERFLOW: c_int = 75; /* Value too large for defined data type */
pub const ENOTUNIQ: c_int = 76; /* Name not unique on network */
pub const EBADFD: c_int = 77; /* File descriptor in bad state */
pub const EREMCHG: c_int = 78; /* Remote address changed */
pub const ELIBACC: c_int = 79; /* Can not access a needed shared library */
pub const ELIBBAD: c_int = 80; /* Accessing a corrupted shared library */
pub const ELIBSCN: c_int = 81; /* .lib section in a.out corrupted */
pub const ELIBMAX: c_int = 82; /* Attempting to link in too many shared libraries */
pub const ELIBEXEC: c_int = 83; /* Cannot exec a shared library directly */
pub const EILSEQ: c_int = 84; /* Illegal byte sequence */
pub const ERESTART: c_int = 85; /* Interrupted system call should be restarted */
pub const ESTRPIPE: c_int = 86; /* Streams pipe error */
pub const EUSERS: c_int = 87; /* Too many users */
pub const ENOTSOCK: c_int = 88; /* Socket operation on non-socket */
pub const EDESTADDRREQ: c_int = 89; /* Destination address required */
pub const EMSGSIZE: c_int = 90; /* Message too long */
pub const EPROTOTYPE: c_int = 91; /* Protocol wrong type for socket */
pub const ENOPROTOOPT: c_int = 92; /* Protocol not available */
pub const EPROTONOSUPPORT: c_int = 93; /* Protocol not supported */
pub const ESOCKTNOSUPPORT: c_int = 94; /* Socket type not supported */
pub const EOPNOTSUPP: c_int = 95; /* Operation not supported on transport endpoint */
pub const EPFNOSUPPORT: c_int = 96; /* Protocol family not supported */
pub const EAFNOSUPPORT: c_int = 97; /* Address family not supported by protocol */
pub const EADDRINUSE: c_int = 98; /* Address already in use */
pub const EADDRNOTAVAIL: c_int = 99; /* Cannot assign requested address */
pub const ENETDOWN: c_int = 100; /* Network is down */
pub const ENETUNREACH: c_int = 101; /* Network is unreachable */
pub const ENETRESET: c_int = 102; /* Network dropped connection because of reset */
@@ -270,5 +270,5 @@ pub static STR_ERROR: [&'static str; 132] = [
"Key has been revoked",
"Key was rejected by service",
"Owner died",
"State not recoverable"
"State not recoverable",
];
+1
View File
@@ -29,6 +29,7 @@ use core::fmt;
use types::*;
//TODO #[thread_local]
#[allow(non_upper_case_globals)]
#[no_mangle]
pub static mut errno: c_int = 0;
+2
View File
@@ -20,9 +20,11 @@ pub type fpos_t = off_t;
pub struct FILE;
#[allow(non_upper_case_globals)]
#[no_mangle]
pub static mut stdout: *mut FILE = 1 as *mut FILE;
#[allow(non_upper_case_globals)]
#[no_mangle]
pub static mut stderr: *mut FILE = 2 as *mut FILE;
+1
View File
@@ -10,3 +10,4 @@ cbindgen = { path = "../../cbindgen" }
[dependencies]
platform = { path = "../platform" }
ralloc = { path = "../../ralloc", default-features = false }
ctype = { path = "../ctype" }
+41 -4
View File
@@ -4,6 +4,7 @@
#![feature(core_intrinsics)]
#![feature(global_allocator)]
extern crate ctype;
extern crate platform;
extern crate ralloc;
@@ -55,14 +56,52 @@ pub extern "C" fn atof(s: *const c_char) -> c_double {
unimplemented!();
}
macro_rules! dec_num_from_ascii {
($s: expr, $t: ty) => {
unsafe {
let mut s = $s;
// Iterate past whitespace
while ctype::isspace(*s as c_int) != 0 {
s = s.offset(1);
}
// Find out if there is a - sign
let neg_sign = match *s {
0x2d => {
s = s.offset(1);
true
}
// '+' increment s and continue parsing
0x2b => {
s = s.offset(1);
false
}
_ => false,
};
let mut n: $t = 0;
while ctype::isdigit(*s as c_int) != 0 {
n = 10 * n - (*s as $t - 0x30);
s = s.offset(1);
}
if neg_sign {
n
} else {
-n
}
}
};
}
#[no_mangle]
pub extern "C" fn atoi(s: *const c_char) -> c_int {
unimplemented!();
dec_num_from_ascii!(s, c_int)
}
#[no_mangle]
pub extern "C" fn atol(s: *const c_char) -> c_long {
unimplemented!();
dec_num_from_ascii!(s, c_long)
}
#[no_mangle]
@@ -124,8 +163,6 @@ pub extern "C" fn erand(xsubi: [c_ushort; 3]) -> c_double {
#[no_mangle]
pub unsafe extern "C" fn exit(status: c_int) {
use core::mem;
for i in (0..ATEXIT_FUNCS.len()).rev() {
if let Some(func) = ATEXIT_FUNCS[i] {
(func)();
+2
View File
@@ -1,9 +1,11 @@
/alloc
/args
/atoi
/brk
/chdir
/create
/create.out
/ctype
/dup
/dup.out
/error
+2
View File
@@ -1,9 +1,11 @@
BINS=\
alloc \
atoi \
brk \
args \
chdir \
create \
ctype \
dup \
error \
fchdir \
+12
View File
@@ -0,0 +1,12 @@
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
printf("%d\n", atoi(" -42"));
printf("%d\n", atoi(" +555"));
printf("%d\n", atoi(" 1234567890 "));
printf("%ld\n", atol(" -42"));
printf("%ld\n", atol(" +555"));
printf("%ld\n", atol(" 1234567890 "));
return 0;
}
+46
View File
@@ -0,0 +1,46 @@
#include <ctype.h>
#include <stdio.h>
struct test_case {
char c;
int isalnum;
int isalpha;
int isascii;
int isdigit;
int islower;
int isspace;
int isupper;
} test_cases[] = {
{ 'A', 1, 1, 1, 0, 0, 0, 1},
{ 'z', 1, 1, 1, 0, 1, 0, 0},
{ ' ', 0, 0, 1, 0, 0, 1, 0},
{ '1', 1, 0, 1, 1, 0, 0, 0},
{ '9', 1, 0, 1, 1, 0, 0, 0},
{0x80, 0, 0, 0, 0, 0, 0, 0}
};
size_t num_test_cases = sizeof(test_cases)/sizeof(struct test_case);
#define CHECK_TEST(tc, fn, retval) \
if (fn(tc.c) != tc.fn) { \
retval = -1; \
printf("Unexpected result: " #fn "('%c') != %d\n", tc.c, tc.fn); \
}
int main(int argc, char* argv[]) {
int retval = 0;
for(int i = 0; i < num_test_cases; ++i) {
struct test_case tc = test_cases[i];
CHECK_TEST(tc, isalnum, retval);
CHECK_TEST(tc, isalpha, retval);
CHECK_TEST(tc, isascii, retval);
CHECK_TEST(tc, isdigit, retval);
CHECK_TEST(tc, islower, retval);
CHECK_TEST(tc, isspace, retval);
CHECK_TEST(tc, isupper, retval);
}
if (!retval) {
printf("Success: %d\n", retval);
} else {
printf("Failure: %d\n", retval);
}
return retval;
}