[njs] Introduced nxt_file_basename() and nxt_file_dirname().

Dmitry Volyntsev xeioex at nginx.com
Wed Feb 20 14:26:00 UTC 2019


details:   https://hg.nginx.org/njs/rev/8250061df72a
branches:  
changeset: 782:8250061df72a
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed Feb 20 16:16:30 2019 +0300
description:
Introduced nxt_file_basename() and nxt_file_dirname().

diffstat:

 njs/njs_shell.c          |    4 +-
 njs/test/njs_unit_test.c |  100 +++++++++++++++++++++++++++++++++++++++++++++-
 nxt/nxt_file.c           |   59 ++++++++++++++++++++++-----
 nxt/nxt_file.h           |    3 +-
 4 files changed, 150 insertions(+), 16 deletions(-)

diffs (217 lines):

diff -r 8c422e42448e -r 8250061df72a njs/njs_shell.c
--- a/njs/njs_shell.c	Thu Feb 14 21:19:51 2019 +0300
+++ b/njs/njs_shell.c	Wed Feb 20 16:16:30 2019 +0300
@@ -216,7 +216,9 @@ main(int argc, char **argv)
 
     if (!opts.quiet) {
         if (opts.file != NULL) {
-            nxt_file_name(&vm_options.file, opts.file);
+            vm_options.file.start = (u_char *) opts.file;
+            vm_options.file.length = strlen(opts.file);
+            nxt_file_basename(&vm_options.file, &vm_options.file);
 
         } else {
             vm_options.file = nxt_string_value("shell");
diff -r 8c422e42448e -r 8250061df72a njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Thu Feb 14 21:19:51 2019 +0300
+++ b/njs/test/njs_unit_test.c	Wed Feb 20 16:16:30 2019 +0300
@@ -11994,6 +11994,97 @@ njs_vm_object_alloc_test(njs_vm_t * vm, 
 }
 
 
+static nxt_int_t
+nxt_file_basename_test(njs_vm_t * vm, nxt_bool_t disassemble,
+    nxt_bool_t verbose)
+{
+    nxt_str_t   name;
+    nxt_bool_t  success;
+    nxt_uint_t  i;
+
+    static const struct {
+        nxt_str_t   path;
+        nxt_str_t   expected;
+    } tests[] = {
+        { nxt_string(""),            nxt_string("") },
+        { nxt_string("/"),           nxt_string("") },
+        { nxt_string("/a"),          nxt_string("a") },
+        { nxt_string("///"),         nxt_string("") },
+        { nxt_string("///a"),        nxt_string("a") },
+        { nxt_string("///a/"),       nxt_string("") },
+        { nxt_string("a"),           nxt_string("a") },
+        { nxt_string("a/"),          nxt_string("") },
+        { nxt_string("a//"),         nxt_string("") },
+        { nxt_string("path/name"),   nxt_string("name") },
+        { nxt_string("/path/name"),  nxt_string("name") },
+        { nxt_string("/path/name/"), nxt_string("") },
+    };
+
+    for (i = 0; i < nxt_nitems(tests); i++) {
+        nxt_file_basename(&tests[i].path, &name);
+
+        success = nxt_strstr_eq(&tests[i].expected, &name);
+
+        if (!success) {
+            printf("nxt_file_basename_test(\"%.*s\"):\n"
+                   "expected: \"%.*s\"\n     got: \"%.*s\"\n",
+                   (int) tests[i].path.length, tests[i].path.start,
+                   (int) tests[i].expected.length, tests[i].expected.start,
+                   (int) name.length, name.start);
+            return NXT_ERROR;
+        }
+    }
+
+    return NXT_OK;
+}
+
+
+static nxt_int_t
+nxt_file_dirname_test(njs_vm_t * vm, nxt_bool_t disassemble,
+    nxt_bool_t verbose)
+{
+    nxt_str_t   name;
+    nxt_bool_t  success;
+    nxt_uint_t  i;
+
+    static const struct {
+        nxt_str_t   path;
+        nxt_str_t   expected;
+    } tests[] = {
+        { nxt_string(""),               nxt_string("") },
+        { nxt_string("/"),              nxt_string("/") },
+        { nxt_string("/a"),             nxt_string("/") },
+        { nxt_string("///"),            nxt_string("///") },
+        { nxt_string("///a"),           nxt_string("///") },
+        { nxt_string("///a/"),          nxt_string("///a") },
+        { nxt_string("a"),              nxt_string("") },
+        { nxt_string("a/"),             nxt_string("a") },
+        { nxt_string("a//"),            nxt_string("a") },
+        { nxt_string("p1/p2/name"),     nxt_string("p1/p2") },
+        { nxt_string("/p1/p2/name"),    nxt_string("/p1/p2") },
+        { nxt_string("/p1/p2///name"),  nxt_string("/p1/p2") },
+        { nxt_string("/p1/p2/name/"),   nxt_string("/p1/p2/name") },
+    };
+
+    for (i = 0; i < nxt_nitems(tests); i++) {
+        nxt_file_dirname(&tests[i].path, &name);
+
+        success = nxt_strstr_eq(&tests[i].expected, &name);
+
+        if (!success) {
+            printf("nxt_file_dirname_test(\"%.*s\"):\n"
+                   "expected: \"%.*s\"\n     got: \"%.*s\"\n",
+                   (int) tests[i].path.length, tests[i].path.start,
+                   (int) tests[i].expected.length, tests[i].expected.start,
+                   (int) name.length, name.start);
+            return NXT_ERROR;
+        }
+    }
+
+    return NXT_OK;
+}
+
+
 typedef struct {
     nxt_int_t  (*test)(njs_vm_t *, nxt_bool_t, nxt_bool_t);
     nxt_str_t  name;
@@ -12009,10 +12100,13 @@ njs_api_test(nxt_bool_t disassemble, nxt
     njs_vm_opt_t    options;
     njs_api_test_t  *test;
 
-    static njs_api_test_t  njs_api_test[] =
-    {
+    static njs_api_test_t  njs_api_test[] = {
         { njs_vm_object_alloc_test,
-          nxt_string("njs_vm_object_alloc_test") }
+          nxt_string("njs_vm_object_alloc_test") },
+        { nxt_file_basename_test,
+          nxt_string("nxt_file_basename_test") },
+        { nxt_file_dirname_test,
+          nxt_string("nxt_file_dirname_test") },
     };
 
     rc = NXT_ERROR;
diff -r 8c422e42448e -r 8250061df72a nxt/nxt_file.c
--- a/nxt/nxt_file.c	Thu Feb 14 21:19:51 2019 +0300
+++ b/nxt/nxt_file.c	Wed Feb 20 16:16:30 2019 +0300
@@ -14,20 +14,57 @@
 
 
 void
-nxt_file_name(nxt_str_t *name, char *path)
+nxt_file_basename(const nxt_str_t *path, nxt_str_t *name)
 {
-    char  *p;
-    size_t  length;
+    const u_char  *p, *end;
+
+    end = path->start + path->length;
+    p = end - 1;
+
+    /* Stripping dir prefix. */
+
+    while (p >= path->start && *p != '/') { p--; }
+
+    p++;
 
-    length = strlen(path);
+    name->start = (u_char *) p;
+    name->length = end - p;
+}
+
 
-    for (p = path + length; p >= path; p--) {
-        if (*p == '/') {
-            p++;
-            break;
-        }
+void
+nxt_file_dirname(const nxt_str_t *path, nxt_str_t *name)
+{
+    const u_char  *p, *end;
+
+    if (path->length == 0) {
+        *name = nxt_string_value("");
+        return;
     }
 
-    name->start = (u_char *) p;
-    name->length = length - (p - path);
+    p = path->start + path->length - 1;
+
+    /* Stripping basename. */
+
+    while (p >= path->start && *p != '/') { p--; }
+
+    end = p + 1;
+
+    if (end == path->start) {
+        *name = nxt_string_value("");
+        return;
+    }
+
+    /* Stripping trailing slashes. */
+
+    while (p >= path->start && *p == '/') { p--; }
+
+    p++;
+
+    if (p == path->start) {
+        p = end;
+    }
+
+    name->start = path->start;
+    name->length = p - path->start;
 }
diff -r 8c422e42448e -r 8250061df72a nxt/nxt_file.h
--- a/nxt/nxt_file.h	Thu Feb 14 21:19:51 2019 +0300
+++ b/nxt/nxt_file.h	Wed Feb 20 16:16:30 2019 +0300
@@ -8,7 +8,8 @@
 #define _NXT_FILE_H_INCLUDED_
 
 
-void nxt_file_name(nxt_str_t *name, char *path);
+void nxt_file_basename(const nxt_str_t *path, nxt_str_t *name);
+void nxt_file_dirname(const nxt_str_t *path, nxt_str_t *name);
 
 
 #endif /* _NXT_FILE_H_INCLUDED_ */


More information about the nginx-devel mailing list