Skip to content
Snippets Groups Projects
Commit 75bac011 authored by jD91mZM2's avatar jD91mZM2
Browse files

Merge branch 'MaikuZ/libgen' into 'master'

Implement libgen.h

See merge request redox-os/relibc!175
parents 571b4d49 a7b71a31
No related branches found
No related tags found
1 merge request!175Implement libgen.h
Pipeline #1670 passed with warnings
sys_includes = []
include_guard = "_LIBGEN_H"
language = "C"
style = "Tag"
[enum]
prefix_with_name = true
//! libgen implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/libgen.h.html
use core::ptr;
use platform::types::c_char;
use header::string::strlen;
#[no_mangle]
pub unsafe extern "C" fn basename(str: *mut c_char) -> *mut c_char {
if str == ptr::null_mut() || strlen(str) == 0 {
return ".\0".as_ptr() as *mut c_char;
}
let mut end = strlen(str) as isize - 1;
while end >= 0 && *str.offset(end) == b'/' as c_char {
end -= 1;
}
if end == -1 {
return "/\0".as_ptr() as *mut c_char;
}
let mut begin = end;
while begin >= 0 && *str.offset(begin) != b'/' as c_char {
begin -= 1;
}
*str.offset(end + 1) = 0;
return str.offset(begin + 1) as *mut c_char;
}
#[no_mangle]
pub unsafe extern "C" fn dirname(str: *mut c_char) -> *mut c_char {
if str == ptr::null_mut() || strlen(str) == 0 {
return ".\0".as_ptr() as *mut c_char;
}
let mut end = strlen(str) as isize - 1;
while end > 0 && *str.offset(end) == b'/' as c_char {
end -= 1;
}
while end >= 0 && *str.offset(end) != b'/' as c_char {
end -= 1;
}
while end > 0 && *str.offset(end) == b'/' as c_char {
end -= 1;
}
if end == -1 {
return ".\0".as_ptr() as *mut c_char;
}
*str.offset(end + 1) = 0;
return str;
}
...@@ -12,6 +12,7 @@ pub mod getopt; ...@@ -12,6 +12,7 @@ pub mod getopt;
pub mod grp; pub mod grp;
pub mod inttypes; pub mod inttypes;
pub mod limits; pub mod limits;
pub mod libgen;
pub mod locale; pub mod locale;
pub mod netdb; pub mod netdb;
pub mod netinet_in; pub mod netinet_in;
......
...@@ -11,6 +11,7 @@ EXPECT_BINS=\ ...@@ -11,6 +11,7 @@ EXPECT_BINS=\
fcntl/create \ fcntl/create \
fcntl/fcntl \ fcntl/fcntl \
fnmatch \ fnmatch \
libgen \
locale \ locale \
math \ math \
netdb \ netdb \
......
Testing libgen.h
OK on basename(/usr/lib), expected: 'lib', got: 'lib'
OK on basename(//usr//lib//), expected: 'lib', got: 'lib'
OK on basename(/usr/), expected: 'usr', got: 'usr'
OK on basename(), expected: '.', got: '.'
OK on basename(/), expected: '/', got: '/'
OK on basename(///), expected: '/', got: '/'
OK on basename(NULL), expected: '.', got: '.'
OK on dirname(/usr/lib), expected: '/usr', got: '/usr'
OK on dirname(//usr//lib//), expected: '//usr', got: '//usr'
OK on dirname(/usr), expected: '/', got: '/'
OK on dirname(usr), expected: '.', got: '.'
OK on dirname(/), expected: '/', got: '/'
OK on dirname(///), expected: '/', got: '/'
OK on dirname(.), expected: '.', got: '.'
OK on dirname(..), expected: '.', got: '.'
OK on dirname(), expected: '.', got: '.'
OK on dirname(NULL), expected: '.', got: '.'
#include <libgen.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct {
char * in;
char * expected_out;
} test_case;
// API for basename and dirname allow the passed in string to
// be modified. This means we have to pass a modifiable copy.
char * get_mutable_string(char *str) {
if (str == NULL)
return NULL;
char * copy = malloc(sizeof(char) * (strlen(str) + 1));
copy = strcpy(copy, str);
return copy;
}
void test_basename() {
test_case test_cases[] =
{ {"/usr/lib", "lib"},
{"//usr//lib//", "lib"},
{"/usr/", "usr"},
{"", "."},
{"/", "/"},
{"///","/"},
{NULL, "."}
};
for (int i = 0;i < sizeof(test_cases)/sizeof(test_case);i++) {
char * in = get_mutable_string(test_cases[i].in);
char * out = basename(in);
if (!out) {
printf("Error on basename(%s), expected: '%s', got NULL\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out);
} else if (strcmp(out, test_cases[i].expected_out) != 0) {
printf("Error on basename(%s), expected: '%s', got: '%s'\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out, out);
} else {
printf("OK on basename(%s), expected: '%s', got: '%s'\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out, out);
}
if (!in)
free(in);
}
return;
}
void test_dirname() {
test_case test_cases[] =
{ {"/usr/lib", "/usr"},
{"//usr//lib//", "//usr"},
{"/usr", "/"},
{"usr", "."},
{"/", "/"},
{"///","/"},
{".", "."},
{"..", "."},
{"", "."},
{NULL, "."}
};
for (int i = 0;i < sizeof(test_cases)/sizeof(test_case);i++) {
char * in = get_mutable_string(test_cases[i].in);
char * out = dirname(in);
if (!out) {
printf("Error on dirname(%s), expected: '%s', got NULL\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out);
} else if (strcmp(out, test_cases[i].expected_out) != 0) {
printf("Error on dirname(%s), expected: '%s', got: '%s'\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out, out);
} else {
printf("OK on dirname(%s), expected: '%s', got: '%s'\n", test_cases[i].in != 0 ? test_cases[i].in : "NULL", test_cases[i].expected_out, out);
}
if (!in)
free(in);
}
return;
}
int main() {
printf("Testing libgen.h\n");
test_basename();
test_dirname();
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment