aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDavid M. Syzdek <david@syzdek.net>2022-05-31 21:15:24 -0800
committerDavid M. Syzdek <david@syzdek.net>2022-05-31 21:15:24 -0800
commit6027ce0f27f61f5b140351f994e4256922c3f10e (patch)
tree2201c01d45c99d4c46340213c21ad0a024a8ea35
parent438264cc803f38fa2b448a66df2b77b3a867824f (diff)
downloadbindletools-6027ce0f27f61f5b140351f994e4256922c3f10e.tar.gz
bindletools-6027ce0f27f61f5b140351f994e4256922c3f10e.tar.bz2
bindletools-6027ce0f27f61f5b140351f994e4256922c3f10e.tar.xz
bindletools-6027ce0f27f61f5b140351f994e4256922c3f10e.zip
libbindle: adding bindle_basename() and bindle_basename_r()
-rw-r--r--build-aux/makefile-libbindle.am11
-rw-r--r--checks/bindle-str-basename.c238
-rw-r--r--include/bindle.h12
-rw-r--r--lib/libbindle/lstring.c57
4 files changed, 318 insertions, 0 deletions
diff --git a/build-aux/makefile-libbindle.am b/build-aux/makefile-libbindle.am
index 48422e3..19a9089 100644
--- a/build-aux/makefile-libbindle.am
+++ b/build-aux/makefile-libbindle.am
@@ -31,6 +31,7 @@
31EXTRA_PROGRAMS += tests/bindle-array-queue \ 31EXTRA_PROGRAMS += tests/bindle-array-queue \
32 tests/bindle-array-sorted \ 32 tests/bindle-array-sorted \
33 tests/bindle-array-stack \ 33 tests/bindle-array-stack \
34 tests/bindle-str-basename \
34 tests/bindle-str-expand \ 35 tests/bindle-str-expand \
35 tests/bindle-str-split \ 36 tests/bindle-str-split \
36 tests/bindle-url-encoding \ 37 tests/bindle-url-encoding \
@@ -38,6 +39,7 @@ EXTRA_PROGRAMS += tests/bindle-array-queue \
38LIBBINDLE_TESTS = tests/bindle-array-queue \ 39LIBBINDLE_TESTS = tests/bindle-array-queue \
39 tests/bindle-array-sorted \ 40 tests/bindle-array-sorted \
40 tests/bindle-array-stack \ 41 tests/bindle-array-stack \
42 tests/bindle-str-basename \
41 tests/bindle-str-expand \ 43 tests/bindle-str-expand \
42 tests/bindle-str-split \ 44 tests/bindle-str-split \
43 tests/bindle-url-encoding \ 45 tests/bindle-url-encoding \
@@ -108,6 +110,15 @@ tests_bindle_array_stack_SOURCES = $(bindletools_srcdir)/include/bindle.h \
108 $(bindletools_srcdir)/checks/bindle-array-stack.c 110 $(bindletools_srcdir)/checks/bindle-array-stack.c
109 111
110 112
113# macros for tests/bindle-str-basename
114tests_bindle_str_basename_DEPENDENCIES = lib/libbindle.a
115tests_bindle_str_basename_LDADD = lib/libbindle.a
116tests_bindle_str_basename_SOURCES = $(bindletools_srcdir)/include/bindle.h \
117 $(bindletools_srcdir)/checks/bindle-tests.h \
118 $(bindletools_srcdir)/checks/bindle-tests.c \
119 $(bindletools_srcdir)/checks/bindle-str-basename.c
120
121
111# macros for tests/bindle-str-expand 122# macros for tests/bindle-str-expand
112tests_bindle_str_expand_DEPENDENCIES = lib/libbindle.a 123tests_bindle_str_expand_DEPENDENCIES = lib/libbindle.a
113tests_bindle_str_expand_LDADD = lib/libbindle.a 124tests_bindle_str_expand_LDADD = lib/libbindle.a
diff --git a/checks/bindle-str-basename.c b/checks/bindle-str-basename.c
new file mode 100644
index 0000000..849068e
--- /dev/null
+++ b/checks/bindle-str-basename.c
@@ -0,0 +1,238 @@
1/*
2 * Bindle Binaries Tools
3 * Copyright (C) 2022 David M. Syzdek <david@syzdek.net>.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of David M. Syzdek nor the
16 * names of its contributors may be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID M. SYZDEK BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31#define _CHECKS_BINDLE_STR_BASENAME_C 1
32
33
34///////////////
35// //
36// Headers //
37// //
38///////////////
39#pragma mark - Headers
40
41#include "bindle-tests.h"
42
43#include <stdio.h>
44#include <stdarg.h>
45#include <stdlib.h>
46#include <string.h>
47#include <strings.h>
48#include <unistd.h>
49#include <getopt.h>
50#include <assert.h>
51
52
53///////////////////
54// //
55// Definitions //
56// //
57///////////////////
58#pragma mark - Definitions
59
60#undef PROGRAM_NAME
61#define PROGRAM_NAME "bindle-str-basename"
62
63
64/////////////////
65// //
66// Datatypes //
67// //
68/////////////////
69#pragma mark - Datatypes
70
71typedef struct my_test_strings
72{
73 const char * origin;
74 const char * result;
75} my_test_strings_t;
76
77
78/////////////////
79// //
80// Variables //
81// //
82/////////////////
83#pragma mark - Variables
84
85static my_test_strings_t test_strings[] =
86{
87 { .origin = "/etc/passwd", .result = "passwd" },
88 { .origin = "passwd", .result = "passwd" },
89 { .origin = "/passwd", .result = "passwd" },
90 { .origin = "/passwd/", .result = "passwd" },
91 { .origin = "//passwd/", .result = "passwd" },
92 { .origin = "//passwd//", .result = "passwd" },
93 { .origin = "passwd/", .result = "passwd" },
94 { .origin = "passwd//", .result = "passwd" },
95 { .origin = "/////////", .result = "/" },
96 { .origin = "//", .result = "/" },
97 { .origin = "", .result = "." },
98 { .origin = NULL, .result = NULL }
99};
100
101
102//////////////////
103// //
104// Prototypes //
105// //
106//////////////////
107#pragma mark - Prototypes
108
109int
110main(
111 int argc,
112 char * argv[] );
113
114
115/////////////////
116// //
117// Functions //
118// //
119/////////////////
120#pragma mark - Functions
121
122int
123main(
124 int argc,
125 char * argv[] )
126{
127 int opt;
128 int c;
129 int opt_index;
130 size_t pos;
131 unsigned opts;
132 char * str;
133
134 // getopt options
135 static char short_opt[] = "dhVvq";
136 static struct option long_opt[] =
137 {
138 {"debug", no_argument, NULL, 'd' },
139 {"help", no_argument, NULL, 'h' },
140 {"quiet", no_argument, NULL, 'q' },
141 {"silent", no_argument, NULL, 'q' },
142 {"version", no_argument, NULL, 'V' },
143 {"verbose", no_argument, NULL, 'v' },
144 { NULL, 0, NULL, 0 }
145 };
146
147 bindle_tests_initialize(PROGRAM_NAME);
148
149 opts = 0;
150
151 while((c = getopt_long(argc, argv, short_opt, long_opt, &opt_index)) != -1)
152 {
153 switch(c)
154 {
155 case -1: /* no more arguments */
156 case 0: /* long options toggles */
157 break;
158
159 case 'd':
160 opt = BNDL_DEBUG_ANY;
161 bindle_set_option(NULL, BNDL_OPT_DEBUG_LEVEL, &opt);
162 break;
163
164 case 'h':
165 printf("Usage: %s [OPTIONS]\n", PROGRAM_NAME);
166 printf(" %s [OPTIONS] str1 [ str2 [ ... [ strN ] ] ]\n", PROGRAM_NAME);
167 printf("OPTIONS:\n");
168 printf(" -d, --debug print debug messages\n");
169 printf(" -h, --help print this help and exit\n");
170 printf(" -q, --quiet, --silent do not print messages\n");
171 printf(" -V, --version print version number and exit\n");
172 printf(" -v, --verbose print verbose messages\n");
173 printf("\n");
174 return(0);
175
176 case 'q':
177 opts |= BNDLTEST_OPT_QUIET;
178 opts &= ~BNDLTEST_OPT_VERBOSE;
179 break;
180
181 case 'V':
182 bindle_tests_version();
183 return(0);
184
185 case 'v':
186 opts |= BNDLTEST_OPT_VERBOSE;
187 opts &= ~BNDLTEST_OPT_QUIET;
188 break;
189
190 case '?':
191 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
192 return(1);
193
194 default:
195 fprintf(stderr, "%s: unrecognized option `--%c'\n", PROGRAM_NAME, c);
196 fprintf(stderr, "Try `%s --help' for more information.\n", PROGRAM_NAME);
197 return(1);
198 };
199 };
200
201 // expand custom strings
202 if (optind < argc)
203 {
204 while (optind < argc)
205 {
206 bindle_tests_verbose(opts, "test string: %s", argv[optind]);
207 str = bindle_basename(argv[optind]);
208 if (!(opts & BNDLTEST_OPT_VERBOSE))
209 bindle_tests_print(opts, "%s", str);
210 bindle_tests_verbose(opts, " ==> %s", str);
211 optind++;
212 if (optind < argc)
213 bindle_tests_verbose(opts, "");
214 };
215 return(0);
216 };
217
218 // expand and verify test strings
219 for(pos = 0; ((test_strings[pos].origin)); pos++)
220 {
221 bindle_tests_verbose(opts, "test string: \"%s\"", test_strings[pos].origin);
222 str = bindle_basename(test_strings[pos].origin);
223 bindle_tests_verbose(opts, " expected ==> \"%s\"", test_strings[pos].result);
224 bindle_tests_verbose(opts, " result ==> \"%s\"", str);
225 if ((strcmp(test_strings[pos].result, str)))
226 {
227 bindle_tests_error(opts, NULL, "basename does not match expected result");
228 return(1);
229 };
230 bindle_tests_verbose(opts, "");
231 };
232
233 return(0);
234}
235
236
237/* end of source */
238
diff --git a/include/bindle.h b/include/bindle.h
index 0c8a9e9..d4e55df 100644
--- a/include/bindle.h
+++ b/include/bindle.h
@@ -405,6 +405,18 @@ bindle_set_option(
405#pragma mark string prototypes 405#pragma mark string prototypes
406 406
407_BINDLE_F char * 407_BINDLE_F char *
408bindle_basename(
409 const char * path );
410
411
412_BINDLE_F char *
413bindle_basename_r(
414 const char * path,
415 char * bname,
416 size_t bnamelen );
417
418
419_BINDLE_F char *
408bindle_strdup( 420bindle_strdup(
409 const char * s1 ); 421 const char * s1 );
410 422
diff --git a/lib/libbindle/lstring.c b/lib/libbindle/lstring.c
index d34dbc3..a24d46a 100644
--- a/lib/libbindle/lstring.c
+++ b/lib/libbindle/lstring.c
@@ -79,6 +79,63 @@
79#pragma mark - Functions 79#pragma mark - Functions
80 80
81char * 81char *
82bindle_basename(
83 const char * path )
84{
85 static char bname[512];
86 return(bindle_basename_r(path, bname, sizeof(bname)));
87}
88
89
90char *
91bindle_basename_r(
92 const char * path,
93 char * bname,
94 size_t bnamelen )
95{
96 size_t pos;
97 size_t slash;
98 size_t len;
99
100 assert(bname != NULL);
101 assert(bnamelen > 2);
102
103 // handle empty strings
104 if ( (!(path)) || (path[0] == '\0') )
105 {
106 bindle_strlcpy(bname, ".", bnamelen);
107 return(bname);
108 };
109
110 // skip leading '/' chars
111 while (path[0] == '/')
112 path = &path[1];
113 if (path[0] == '\0')
114 {
115 bindle_strlcpy(bname, "/", bnamelen);
116 return(bname);
117 };
118
119 // find start of trailing slashes, if any
120 for(pos = strlen(path) - 1; (path[pos] == '/'); pos--);
121 slash = pos + 1;
122
123 // find last slash before basename
124 for(pos = slash - 1; ((pos > 0) && (path[pos] != '/')); pos--);
125 if (path[pos] == '/')
126 pos++;
127
128 // copy string
129 len = slash - pos + 1;
130 bnamelen = (len > bnamelen) ? bnamelen : len;
131 bindle_strlcpy(bname, &path[pos], bnamelen);
132
133
134 return(bname);
135}
136
137
138char *
82bindle_strdup( 139bindle_strdup(
83 const char * s1 ) 140 const char * s1 )
84{ 141{