diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/t-common.h | 29 | ||||
-rw-r--r-- | tests/t-stringutils.c | 282 |
3 files changed, 312 insertions, 1 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index ea02da1..39ca241 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -28,7 +28,7 @@ endif gpg_error_lib = ../src/libgpg-error.la TESTS = t-version t-strerror t-syserror t-lock t-printf t-poll t-b64 \ - t-argparse t-logging + t-argparse t-logging t-stringutils AM_CPPFLAGS = -I$(top_builddir)/src $(extra_includes) diff --git a/tests/t-common.h b/tests/t-common.h index e70e04d..db496e2 100644 --- a/tests/t-common.h +++ b/tests/t-common.h @@ -39,6 +39,33 @@ static void fail (const char *format, ...) GPGRT_ATTR_PRINTF(1,2); static void show (const char *format, ...) GPGRT_ATTR_PRINTF(1,2); +static void * +xmalloc (size_t n) +{ + char *p = gpgrt_malloc (n); + if (!p) + die ("out of core\n"); + return p; +} + +static char * +xstrdup (const char *s) +{ + char *p = gpgrt_strdup (s); + if (!p) + die ("out of core\n"); + return p; +} + +static void +xfree (void *p) +{ + if (p) + gpgrt_free (p); +} + + + static void die (const char *format, ...) { @@ -57,6 +84,8 @@ die (const char *format, ...) #ifdef HAVE_FLOCKFILE funlockfile (stderr); #endif + xfree (xstrdup ("")); /* To avoid compiler warnings. */ + xfree (xmalloc (16)); /* To avoid compiler warnings. */ exit (1); } diff --git a/tests/t-stringutils.c b/tests/t-stringutils.c new file mode 100644 index 0000000..01094bf --- /dev/null +++ b/tests/t-stringutils.c @@ -0,0 +1,282 @@ +/* t-stringutils.c - Check some string utilities + * Copyright (C) 2020 g10 Code GmbH + * + * This file is part of Libgpg-error. + * + * Libgpg-error is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgpg-error is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see <https://www.gnu.org/licenses/>. + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <unistd.h> +#ifdef HAVE_STAT +# include <sys/stat.h> +#endif +#include <sys/types.h> +#ifdef HAVE_PWD_H +# include <pwd.h> +#endif +#include <errno.h> + +#define PGM "t-stringutils" +#include "t-common.h" + + +static const char * +my_strusage (int level) +{ + const char *p; + + switch (level) + { + case 9: p = "LGPL-2.1-or-later"; break; + case 11: p = PGM; break; + default: p = NULL; + } + return p; +} + + +const char * +mygethome (void) +{ + static char *home_buffer; + + if (!home_buffer) + { + char *home = getenv("HOME"); + + if(home) + home_buffer = xstrdup (home); +#if defined(HAVE_GETPWUID) && defined(HAVE_PWD_H) + else + { + struct passwd *pwd; + + pwd = getpwuid (getuid()); + if (pwd) + home_buffer = xstrdup (pwd->pw_dir); + } +#endif + } + return home_buffer; +} + + +static char * +mygetcwd (void) +{ + char *buffer; + size_t size = 100; + + for (;;) + { + buffer = xmalloc (size+1); + if (getcwd (buffer, size) == buffer) + return buffer; + xfree (buffer); + if (errno != ERANGE) + die ("error getting current cwd: %s\n", strerror (errno)); + size *= 2; + } +} + + +static void +check_fnameconcat (void) +{ + char *out; + const char *home = mygethome (); + size_t homelen = home? strlen (home):0; + + out = gpgrt_fnameconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", NULL); + if (out) + fail ("fnameconcat succeeded but should not at line %d\n", __LINE__); + else if (errno != EINVAL) + fail ("fnameconcat return wrong error at line %d\n", __LINE__); + xfree (out); + + out = gpgrt_fnameconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", NULL); + if (out) + fail ("fnameconcat succeeded but should not at line %d\n", __LINE__); + else if (errno != EINVAL) + fail ("fnameconcat return wrong error at line %d\n", __LINE__); + xfree (out); + + out = gpgrt_fnameconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", NULL); + if (!out || strcmp (out, + "1/2/3/4/5/6/7/8/9/10/" + "1/2/3/4/5/6/7/8/9/10/" + "1/2/3/4/5/6/7/8/9/10/" + "1/2")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("foo", "~/bar", "baz/cde", NULL); + if (!out || strcmp (out, "foo/~/bar/baz/cde")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("foo", "~/bar", "baz/cde/", NULL); + if (!out || strcmp (out, "foo/~/bar/baz/cde/")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("/foo", "~/bar", "baz/cde/", NULL); + if (!out || strcmp (out, "/foo/~/bar/baz/cde/")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("//foo", "~/bar", "baz/cde/", NULL); + if (!out || strcmp (out, "//foo/~/bar/baz/cde/")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("", "~/bar", "baz/cde", NULL); + if (!out || strcmp (out, "/~/bar/baz/cde")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("~/foo", "bar", NULL); + if (!out) + fail ("fnameconcat failed at line %d\n", __LINE__); + else if (home) + { + if (strlen (out) < homelen + 7) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strncmp (out, home, homelen)) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strcmp (out+homelen, "/foo/bar")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + } + else + { + if (strcmp (out, "~/foo/bar")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + } + xfree (out); + + out = gpgrt_fnameconcat ("~", "bar", NULL); + if (!out) + fail ("fnameconcat failed at line %d\n", __LINE__); + else if (home) + { + if (strlen (out) < homelen + 3) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strncmp (out, home, homelen)) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strcmp (out+homelen, "/bar")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + } + else + { + if (strcmp (out, "~/bar")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + } + xfree (out); +} + + +static void +check_absfnameconcat (void) +{ + char *out; + char *cwd = mygetcwd (); + size_t cwdlen = strlen (cwd); + + out = gpgrt_absfnameconcat ("foo", "bar", NULL); + if (!out) + fail ("fnameconcat failed at line %d\n", __LINE__); + else if (strlen (out) < cwdlen + 7) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strncmp (out, cwd, cwdlen)) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strcmp (out+cwdlen, "/foo/bar")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_absfnameconcat ("./foo", NULL); + if (!out) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strlen (out) < cwdlen + 5) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strncmp (out, cwd, cwdlen)) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strcmp (out+cwdlen, "/./foo")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_absfnameconcat (".", NULL); + if (!out) + fail ("fnameconcat failed at line %d\n", __LINE__); + else if (strlen (out) < cwdlen) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strncmp (out, cwd, cwdlen)) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strcmp (out+cwdlen, "")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + xfree (cwd); +} + + +int +main (int argc, char **argv) +{ + gpgrt_opt_t opts[] = { + ARGPARSE_x ('v', "verbose", NONE, 0, "Print more diagnostics"), + ARGPARSE_s_n('d', "debug", "Flyswatter"), + ARGPARSE_end() + }; + gpgrt_argparse_t pargs = { &argc, &argv, 0 }; + + gpgrt_set_strusage (my_strusage); + gpgrt_log_set_prefix (gpgrt_strusage (11), GPGRT_LOG_WITH_PREFIX); + + while (gpgrt_argparse (NULL, &pargs, opts)) + { + switch (pargs.r_opt) + { + case 'v': verbose++; break; + case 'd': debug++; break; + default : pargs.err = ARGPARSE_PRINT_ERROR; break; + } + } + gpgrt_argparse (NULL, &pargs, NULL); + + show ("testing string utilities\n"); + + check_fnameconcat (); + check_absfnameconcat (); + + show ("testing string utilities finished\n"); + return !!errorcount; +} |