lib.rs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. //! string implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/string.h.html
  2. #![feature(compiler_builtins_lib)]
  3. #![no_std]
  4. extern crate compiler_builtins;
  5. extern crate errno;
  6. extern crate platform;
  7. extern crate stdlib;
  8. use platform::types::*;
  9. use errno::*;
  10. use core::cmp;
  11. use core::usize;
  12. use core::ptr;
  13. #[no_mangle]
  14. pub unsafe extern "C" fn memccpy(
  15. dest: *mut c_void,
  16. src: *const c_void,
  17. c: c_int,
  18. n: usize,
  19. ) -> *mut c_void {
  20. use compiler_builtins::mem::memcpy;
  21. let dest = dest as *mut u8;
  22. let to = memchr(src, c, n);
  23. if to.is_null() {
  24. return to;
  25. }
  26. let src = src as *mut u8;
  27. let dist = (to as usize) - (src as usize);
  28. if memcpy(dest, src, dist).is_null() {
  29. return ptr::null_mut();
  30. }
  31. dest.offset(dist as isize + 1) as *mut c_void
  32. }
  33. #[no_mangle]
  34. pub unsafe extern "C" fn memchr(s: *const c_void, c: c_int, n: usize) -> *mut c_void {
  35. let s = s as *mut u8;
  36. let c = c as u8;
  37. for i in 0..n {
  38. if *s.offset(i as isize) == c {
  39. return s.offset(i as isize) as *mut c_void;
  40. }
  41. }
  42. ptr::null_mut()
  43. }
  44. // #[no_mangle]
  45. // pub extern "C" fn memcmp(
  46. // s1: *const c_void,
  47. // s2: *const c_void,
  48. // n: usize,
  49. // ) -> c_int {
  50. // unimplemented!();
  51. // }
  52. // #[no_mangle]
  53. // pub extern "C" fn memcpy(
  54. // s1: *mut c_void,
  55. // s2: *const c_void,
  56. // n: usize,
  57. // ) -> *mut c_void {
  58. // unimplemented!();
  59. // }
  60. // #[no_mangle]
  61. // pub extern "C" fn memmove(
  62. // s1: *mut c_void,
  63. // s2: *const c_void,
  64. // n: usize,
  65. // ) -> *mut c_void {
  66. // unimplemented!();
  67. // }
  68. // #[no_mangle]
  69. // pub extern "C" fn memset(
  70. // s: *mut c_void,
  71. // c: c_int,
  72. // n: usize,
  73. // ) -> *mut c_void {
  74. // unimplemented!();
  75. // }
  76. #[no_mangle]
  77. pub unsafe extern "C" fn strcat(s1: *mut c_char, s2: *const c_char) -> *mut c_char {
  78. strncat(s1, s2, usize::MAX)
  79. }
  80. #[no_mangle]
  81. pub unsafe extern "C" fn strchr(s: *const c_char, c: c_int) -> *mut c_char {
  82. let c = c as i8;
  83. let mut i = 0;
  84. while *s.offset(i) != 0 {
  85. if *s.offset(i) == c {
  86. return s.offset(i) as *mut c_char;
  87. }
  88. i += 1;
  89. }
  90. ptr::null_mut()
  91. }
  92. #[no_mangle]
  93. pub unsafe extern "C" fn strcmp(s1: *const c_char, s2: *const c_char) -> c_int {
  94. strncmp(s1, s2, usize::MAX)
  95. }
  96. #[no_mangle]
  97. pub extern "C" fn strcoll(s1: *const c_char, s2: *const c_char) -> c_int {
  98. unimplemented!();
  99. }
  100. #[no_mangle]
  101. pub unsafe extern "C" fn strcpy(s1: *mut c_char, s2: *const c_char) -> *mut c_char {
  102. strncpy(s1, s2, usize::MAX)
  103. }
  104. #[no_mangle]
  105. pub unsafe extern "C" fn strcspn(s1: *const c_char, s2: *const c_char) -> c_ulong {
  106. use core::mem;
  107. let s1 = s1 as *const u8;
  108. let s2 = s2 as *const u8;
  109. // The below logic is effectively ripped from the musl implementation
  110. let mut byteset = [0u8; 32 / mem::size_of::<usize>()];
  111. let mut i = 0;
  112. while *s2.offset(i) != 0 {
  113. byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::<usize>())] |=
  114. 1 << (*s2.offset(i) as usize % (8 * mem::size_of::<usize>()));
  115. i += 1;
  116. }
  117. i = 0; // reset
  118. while *s2.offset(i) != 0 {
  119. if byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::<usize>())]
  120. & 1 << (*s2.offset(i) as usize % (8 * mem::size_of::<usize>())) > 0
  121. {
  122. break;
  123. }
  124. i += 1;
  125. }
  126. i as u64
  127. }
  128. #[no_mangle]
  129. pub unsafe extern "C" fn strdup(s1: *const c_char) -> *mut c_char {
  130. strndup(s1, usize::MAX)
  131. }
  132. #[no_mangle]
  133. pub unsafe extern "C" fn strndup(s1: *const c_char, size: usize) -> *mut c_char {
  134. let len = strnlen(s1, size);
  135. // the "+ 1" is to account for the NUL byte
  136. let buffer = stdlib::malloc(len + 1) as *mut c_char;
  137. if buffer.is_null() {
  138. platform::errno = ENOMEM as c_int;
  139. } else {
  140. //memcpy(buffer, s1, len)
  141. for i in 0..len as isize {
  142. *buffer.offset(i) = *s1.offset(i);
  143. }
  144. *buffer.offset(len as isize) = 0;
  145. }
  146. buffer
  147. }
  148. #[no_mangle]
  149. pub unsafe extern "C" fn strerror(errnum: c_int) -> *mut c_char {
  150. use core::fmt::Write;
  151. static mut strerror_buf: [u8; 256] = [0; 256];
  152. let mut w = platform::StringWriter(strerror_buf.as_mut_ptr(), strerror_buf.len());
  153. if errnum >= 0 && errnum < STR_ERROR.len() as c_int {
  154. w.write_str(STR_ERROR[errnum as usize]);
  155. } else {
  156. w.write_fmt(format_args!("Unknown error {}", errnum));
  157. }
  158. strerror_buf.as_mut_ptr() as *mut c_char
  159. }
  160. #[no_mangle]
  161. pub unsafe extern "C" fn strlen(s: *const c_char) -> size_t {
  162. strnlen(s, usize::MAX)
  163. }
  164. #[no_mangle]
  165. pub unsafe extern "C" fn strnlen(s: *const c_char, size: usize) -> size_t {
  166. platform::c_str_n(s, size).len() as size_t
  167. }
  168. #[no_mangle]
  169. pub unsafe extern "C" fn strncat(s1: *mut c_char, s2: *const c_char, n: usize) -> *mut c_char {
  170. let mut idx = strlen(s1 as *const _) as isize;
  171. for i in 0..n as isize {
  172. if *s2.offset(i) == 0 {
  173. break;
  174. }
  175. *s1.offset(idx) = *s2.offset(i);
  176. idx += 1;
  177. }
  178. *s1.offset(idx) = 0;
  179. s1
  180. }
  181. #[no_mangle]
  182. pub unsafe extern "C" fn strncmp(s1: *const c_char, s2: *const c_char, n: usize) -> c_int {
  183. let s1 = core::slice::from_raw_parts(s1 as *const c_uchar, n);
  184. let s2 = core::slice::from_raw_parts(s2 as *const c_uchar, n);
  185. for (&a, &b) in s1.iter().zip(s2.iter()) {
  186. let val = (a as c_int) - (b as c_int);
  187. if a != b || a == 0 {
  188. return val;
  189. }
  190. }
  191. 0
  192. }
  193. #[no_mangle]
  194. pub unsafe extern "C" fn strncpy(s1: *mut c_char, s2: *const c_char, n: usize) -> *mut c_char {
  195. let s2_slice = platform::c_str_n(s2, n);
  196. let s2_len = s2_slice.len();
  197. //memcpy(s1 as *mut _, s2 as *const _, cmp::min(n, s2_len));
  198. let mut idx = 0;
  199. for _ in 0..cmp::min(n, s2_len) {
  200. *s1.offset(idx as isize) = s2_slice[idx] as c_char;
  201. idx += 1;
  202. }
  203. // if length of s2 < n, pad s1 with zeroes
  204. for _ in cmp::min(n, s2_len)..n {
  205. *s1.offset(idx as isize) = 0;
  206. idx += 1;
  207. }
  208. s1
  209. }
  210. #[no_mangle]
  211. pub extern "C" fn strpbrk(s1: *const c_char, s2: *const c_char) -> *mut c_char {
  212. unimplemented!();
  213. }
  214. #[no_mangle]
  215. pub unsafe extern "C" fn strrchr(s: *const c_char, c: c_int) -> *mut c_char {
  216. let len = strlen(s) as isize;
  217. let c = c as i8;
  218. let mut i = len - 1;
  219. while *s.offset(i) != 0 && i >= 0 {
  220. if *s.offset(i) == c {
  221. return s.offset(i) as *mut c_char;
  222. }
  223. i -= 1;
  224. }
  225. ptr::null_mut()
  226. }
  227. #[no_mangle]
  228. pub unsafe extern "C" fn strspn(s1: *const c_char, s2: *const c_char) -> c_ulong {
  229. use core::mem;
  230. let s1 = s1 as *const u8;
  231. let s2 = s2 as *const u8;
  232. // The below logic is effectively ripped from the musl implementation
  233. let mut byteset = [0u8; 32 / mem::size_of::<usize>()];
  234. let mut i = 0;
  235. while *s2.offset(i) != 0 {
  236. byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::<usize>())] |=
  237. 1 << (*s2.offset(i) as usize % (8 * mem::size_of::<usize>()));
  238. i += 1;
  239. }
  240. i = 0; // reset
  241. while *s2.offset(i) != 0 {
  242. if byteset[(*s2.offset(i) as usize) / (8 * mem::size_of::<usize>())]
  243. & 1 << (*s2.offset(i) as usize % (8 * mem::size_of::<usize>())) < 1
  244. {
  245. break;
  246. }
  247. i += 1;
  248. }
  249. i as u64
  250. }
  251. #[no_mangle]
  252. pub extern "C" fn strstr(s1: *const c_char, s2: *const c_char) -> *mut c_char {
  253. unimplemented!();
  254. }
  255. #[no_mangle]
  256. pub extern "C" fn strtok(s1: *mut c_char, s2: *const c_char) -> *mut c_char {
  257. unimplemented!();
  258. }
  259. #[no_mangle]
  260. pub extern "C" fn strtok_r(
  261. s: *mut c_char,
  262. sep: *const c_char,
  263. lasts: *mut *mut c_char,
  264. ) -> *mut c_char {
  265. unimplemented!();
  266. }
  267. #[no_mangle]
  268. pub extern "C" fn strxfrm(s1: *mut c_char, s2: *const c_char, n: usize) -> c_ulong {
  269. unimplemented!();
  270. }
  271. /*
  272. #[no_mangle]
  273. pub extern "C" fn func(args) -> c_int {
  274. unimplemented!();
  275. }
  276. */