Created
February 19, 2019 18:06
-
-
Save xeioex/4f4ab80ff7286324332c69cb04dae3fa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # HG changeset patch | |
| # User Dmitry Volyntsev <[email protected]> | |
| # Date 1550599519 -10800 | |
| # Tue Feb 19 21:05:19 2019 +0300 | |
| # Node ID 175bc9cc32830302cc65d589cd428d26d1bbe07d | |
| # Parent bb8b8d00b96910dc55e958687d7258d312e05912 | |
| Introduced nxt_file_basename() and nxt_file_dirname(). | |
| diff --git a/njs/njs_shell.c b/njs/njs_shell.c | |
| --- a/njs/njs_shell.c | |
| +++ b/njs/njs_shell.c | |
| @@ -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 --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c | |
| --- a/njs/test/njs_unit_test.c | |
| +++ b/njs/test/njs_unit_test.c | |
| @@ -12009,6 +12009,96 @@ 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/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; | |
| @@ -12024,10 +12114,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 --git a/nxt/nxt_file.c b/nxt/nxt_file.c | |
| --- a/nxt/nxt_file.c | |
| +++ b/nxt/nxt_file.c | |
| @@ -14,20 +14,70 @@ | |
| 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; | |
| - length = strlen(path); | |
| + end = path->start + path->length; | |
| + p = end - 1; | |
| - for (p = path + length; p >= path; p--) { | |
| - if (*p == '/') { | |
| - p++; | |
| - break; | |
| + /* Stripping dir prefix. */ | |
| + | |
| + while (p >= path->start && *p != '/') { p--; } | |
| + | |
| + p++; | |
| + | |
| + name->start = (u_char *) p; | |
| + name->length = end - p; | |
| +} | |
| + | |
| + | |
| +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; | |
| + } | |
| + | |
| + p = path->start + path->length - 1; | |
| + | |
| + if (*p == '/') { | |
| + | |
| + /* Stripping trailing slashes. */ | |
| + | |
| + while (p >= path->start && *p == '/') { p--; } | |
| + | |
| + end = p + 1; | |
| + | |
| + if (end == path->start) { | |
| + *name = *path; | |
| + return; | |
| + } | |
| + | |
| + } else { | |
| + | |
| + /* Stripping basename. */ | |
| + | |
| + while (p >= path->start && *p != '/') { p--; } | |
| + | |
| + end = p + 1; | |
| + | |
| + if (end == path->start) { | |
| + *name = nxt_string_value(""); | |
| + return; | |
| + } | |
| + | |
| + while (p >= path->start && *p == '/') { p--; } | |
| + | |
| + if (p != path->start - 1) { | |
| + /* Parent dir exists: stripping last slash. */ | |
| + end--; | |
| } | |
| } | |
| - name->start = (u_char *) p; | |
| - name->length = length - (p - path); | |
| + name->start = path->start; | |
| + name->length = end - path->start; | |
| } | |
| diff --git a/nxt/nxt_file.h b/nxt/nxt_file.h | |
| --- a/nxt/nxt_file.h | |
| +++ b/nxt/nxt_file.h | |
| @@ -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_ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment