aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormax99x <max99x@gmail.com>2011-07-16 14:09:00 +0300
committermax99x <max99x@gmail.com>2011-07-16 14:09:00 +0300
commit00b6ecfcee84834aa81656e1312b2838ccbdcd3f (patch)
treefc950ec0dafd71aacb4ba4b1472efe458221f80c
parent7784274c687ad7a867b485bf327d1a09f0db4111 (diff)
Implemented dirname() and basename() from libgen.h.
-rw-r--r--src/library.js62
-rw-r--r--tests/runner.py55
2 files changed, 117 insertions, 0 deletions
diff --git a/src/library.js b/src/library.js
index a60d5207..6b30f466 100644
--- a/src/library.js
+++ b/src/library.js
@@ -41,6 +41,7 @@ var Library = {
// Converts any path to an absolute path. Resolves embedded "." and ".."
// parts.
absolutePath: function(relative, base) {
+ // TODO: Check if slash escaping should be taken into account.
if (base === undefined) base = FS.currentPath;
else if (relative[0] == '/') base = '';
var full = base + '/' + relative;
@@ -317,6 +318,67 @@ var Library = {
}
}
},
+ // TODO: Check if we need to link any aliases.
+
+ // ==========================================================================
+ // libgen.h
+ // ==========================================================================
+
+ __libgenSplitName: function(path) {
+ if (path === 0 || {{{ makeGetValue('path', 0, 'i8') }}} === 0) {
+ // Null or empty results in '.'.
+ var me = ___libgenSplitName;
+ if (!me.ret) {
+ me.ret = allocate(['.'.charCodeAt(0), 0], 'i8', ALLOC_STATIC);
+ }
+ return [me.ret, -1];
+ } else {
+ var slash = '/'.charCodeAt(0);
+ var allSlashes = true;
+ var slashPositions = [];
+ for (var i = 0; {{{ makeGetValue('path', 'i', 'i8') }}} !== 0; i++) {
+ if ({{{ makeGetValue('path', 'i', 'i8') }}} === slash) {
+ slashPositions.push(i);
+ } else {
+ allSlashes = false;
+ }
+ }
+ var length = i;
+ if (allSlashes) {
+ // All slashes result in a single slash.
+ {{{ makeSetValue('path', '1', '0', 'i8') }}}
+ return [path, -1];
+ } else {
+ // Strip trailing slashes.
+ while (slashPositions.length &&
+ slashPositions[slashPositions.length - 1] == length - 1) {
+ {{{ makeSetValue('path', 'slashPositions.pop(i)', '0', 'i8') }}}
+ length--;
+ }
+ return [path, slashPositions.pop()];
+ }
+ }
+ },
+ basename__deps: ['__libgenSplitName'],
+ basename: function(path) {
+ // char *basename(char *path);
+ // http://pubs.opengroup.org/onlinepubs/007908799/xsh/basename.html
+ var result = ___libgenSplitName(path);
+ return result[0] + result[1] + 1;
+ },
+ __xpg_basename: 'basename',
+ dirname__deps: ['__libgenSplitName'],
+ dirname: function(path) {
+ // char *dirname(char *path);
+ // http://pubs.opengroup.org/onlinepubs/007908799/xsh/dirname.html
+ var result = ___libgenSplitName(path);
+ if (result[1] == 0) {
+ {{{ makeSetValue('result[0]', 1, '0', 'i8') }}}
+ } else if (result[1] !== -1) {
+ {{{ makeSetValue('result[0]', 'result[1]', '0', 'i8') }}}
+ }
+ return result[0];
+ },
// ==========================================================================
diff --git a/tests/runner.py b/tests/runner.py
index bd55a573..879c7022 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -2156,6 +2156,61 @@ if 'benchmark' not in sys.argv:
'''
self.do_test(src, re.sub('(^|\n)\s+', '\\1', expected), post_build=addPreRun)
+ def test_libgen(self):
+ src = r'''
+ #include <stdio.h>
+ #include <libgen.h>
+
+ int main() {
+ char p1[16] = "/usr/lib", p1x[16] = "/usr/lib";
+ printf("%s -> ", p1);
+ printf("%s : %s\n", dirname(p1x), basename(p1));
+
+ char p2[16] = "/usr", p2x[16] = "/usr";
+ printf("%s -> ", p2);
+ printf("%s : %s\n", dirname(p2x), basename(p2));
+
+ char p3[16] = "/usr/", p3x[16] = "/usr/";
+ printf("%s -> ", p3);
+ printf("%s : %s\n", dirname(p3x), basename(p3));
+
+ char p4[16] = "/usr/lib///", p4x[16] = "/usr/lib///";
+ printf("%s -> ", p4);
+ printf("%s : %s\n", dirname(p4x), basename(p4));
+
+ char p5[16] = "/", p5x[16] = "/";
+ printf("%s -> ", p5);
+ printf("%s : %s\n", dirname(p5x), basename(p5));
+
+ char p6[16] = "///", p6x[16] = "///";
+ printf("%s -> ", p6);
+ printf("%s : %s\n", dirname(p6x), basename(p6));
+
+ char p7[16] = "/usr/../lib/..", p7x[16] = "/usr/../lib/..";
+ printf("%s -> ", p7);
+ printf("%s : %s\n", dirname(p7x), basename(p7));
+
+ char p8[16] = "", p8x[16] = "";
+ printf("(empty) -> %s : %s\n", dirname(p8x), basename(p8));
+
+ printf("(null) -> %s : %s\n", dirname(0), basename(0));
+
+ return 0;
+ }
+ '''
+ expected = '''
+ /usr/lib -> /usr : lib
+ /usr -> / : usr
+ /usr/ -> / : usr
+ /usr/lib/// -> /usr : lib
+ / -> / : /
+ /// -> / : /
+ /usr/../lib/.. -> /usr/../lib : ..
+ (empty) -> . : .
+ (null) -> . : .
+ '''
+ self.do_test(src, re.sub('(^|\n)\s+', '\\1', expected))
+
### 'Big' tests
def test_fannkuch(self):