diff options
-rw-r--r-- | NEWS.md | 1 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/convert.c | 92 | ||||
-rw-r--r-- | src/convert.h | 23 | ||||
-rw-r--r-- | src/lexgrog_test.c | 12 | ||||
-rw-r--r-- | src/whatis.c | 57 |
6 files changed, 132 insertions, 57 deletions
@@ -14,6 +14,7 @@ Fixes: * Fix potential crash in path searching if `getcwd` fails for reasons other than running out of memory. * Fix crash in `globbing` test tool if run with no non-option arguments. + * `lexgrog` now produces output in the user's locale. Improvements: diff --git a/src/Makefile.am b/src/Makefile.am index c513bad3..74d790e5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -86,6 +86,8 @@ globbing_SOURCES = \ globbing_test.c lexgrog_SOURCES = \ compression.c \ + convert.c \ + convert.h \ decompress.c \ decompress.h \ descriptions.c \ @@ -167,6 +169,8 @@ manpath_SOURCES = \ manp.h \ manpath.c whatis_SOURCES = \ + convert.c \ + convert.h \ globbing.c \ globbing.h \ manp.c \ diff --git a/src/convert.c b/src/convert.c new file mode 100644 index 00000000..2649e9eb --- /dev/null +++ b/src/convert.c @@ -0,0 +1,92 @@ +/* + * convert.c: simple encoding conversions + * + * Copyright (C) 2007-2022 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <errno.h> +#include <stdbool.h> +#include <string.h> + +#ifdef HAVE_ICONV +# include <iconv.h> +#endif /* HAVE_ICONV */ + +#include "manconfig.h" + +#include "cleanup.h" +#include "encodings.h" + +#include "convert.h" + +#ifdef HAVE_ICONV +static bool conv_to_locale_initialized = false; +static iconv_t conv_to_locale = (iconv_t) -1; + +static void close_conv_to_locale (void *ignored _GL_UNUSED) +{ + iconv_close (conv_to_locale); +} + +char *convert_to_locale (char *string) +{ + if (!conv_to_locale_initialized) { + char *locale_charset = xasprintf + ("%s//IGNORE", get_locale_charset ()); + conv_to_locale = iconv_open (locale_charset, "UTF-8"); + free (locale_charset); + if (conv_to_locale != (iconv_t) -1) + push_cleanup (close_conv_to_locale, NULL, 0); + conv_to_locale_initialized = true; + } + + if (conv_to_locale != (iconv_t) -1) { + size_t string_conv_alloc = strlen (string) + 1; + char *string_conv = xmalloc (string_conv_alloc); + for (;;) { + char *inptr = string, *outptr = string_conv; + size_t inleft = strlen (string); + size_t outleft = string_conv_alloc - 1; + if (iconv (conv_to_locale, + (ICONV_CONST char **) &inptr, &inleft, + &outptr, &outleft) == (size_t) -1 && + errno == E2BIG) { + string_conv_alloc <<= 1; + string_conv = xrealloc (string_conv, + string_conv_alloc); + } else { + /* Either we succeeded, or we've done our + * best; go ahead and print what we've got. + */ + string_conv[string_conv_alloc - 1 - outleft] = + '\0'; + break; + } + } + return string_conv; + } else + return xstrdup (string); +} +#else /* !HAVE_ICONV */ +# define convert_to_locale(string) xstrdup (string) +#endif /* HAVE_ICONV */ diff --git a/src/convert.h b/src/convert.h new file mode 100644 index 00000000..962a6199 --- /dev/null +++ b/src/convert.h @@ -0,0 +1,23 @@ +/* + * convert.h: interface to simple encoding conversions + * + * Copyright (C) 2007-2022 Colin Watson. + * + * This file is part of man-db. + * + * man-db is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * man-db 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with man-db; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +char *convert_to_locale (char *string); diff --git a/src/lexgrog_test.c b/src/lexgrog_test.c index 05475081..77c9a134 100644 --- a/src/lexgrog_test.c +++ b/src/lexgrog_test.c @@ -50,6 +50,7 @@ #include "sandbox.h" #include "security.h" +#include "convert.h" #include "descriptions.h" #include "ult_src.h" @@ -217,9 +218,16 @@ int main (int argc, char **argv) printf ("%s", files[i]); if (show_filters) printf (" (%s)", lg.filters); - if (show_whatis) + if (show_whatis) { + char *name_conv = convert_to_locale + (desc->name); + char *whatis_conv = convert_to_locale + (desc->whatis); printf (": \"%s - %s\"", - desc->name, desc->whatis); + name_conv, whatis_conv); + free (whatis_conv); + free (name_conv); + } printf ("\n"); } gl_list_free (descs); diff --git a/src/whatis.c b/src/whatis.c index 2b979295..4c153c05 100644 --- a/src/whatis.c +++ b/src/whatis.c @@ -48,10 +48,6 @@ #define _(String) gettext (String) #define N_(String) gettext_noop (String) -#ifdef HAVE_ICONV -# include <iconv.h> -#endif /* HAVE_ICONV */ - #include <sys/types.h> #include <sys/stat.h> #include "regex.h" @@ -82,6 +78,7 @@ #include "mydbm.h" #include "db_storage.h" +#include "convert.h" #include "manp.h" static gl_list_t manpathlist; @@ -94,10 +91,6 @@ bool am_apropos; int quiet = 1; man_sandbox *sandbox; -#ifdef HAVE_ICONV -iconv_t conv_to_locale; -#endif /* HAVE_ICONV */ - static regex_t *preg; static bool regex_opt; static bool exact; @@ -284,39 +277,6 @@ static char *locale_manpath (const char *manpath) return new_manpath; } -#ifdef HAVE_ICONV -static char *simple_convert (iconv_t conv, char *string) -{ - if (conv != (iconv_t) -1) { - size_t string_conv_alloc = strlen (string) + 1; - char *string_conv = xmalloc (string_conv_alloc); - for (;;) { - char *inptr = string, *outptr = string_conv; - size_t inleft = strlen (string); - size_t outleft = string_conv_alloc - 1; - if (iconv (conv, (ICONV_CONST char **) &inptr, &inleft, - &outptr, &outleft) == (size_t) -1 && - errno == E2BIG) { - string_conv_alloc <<= 1; - string_conv = xrealloc (string_conv, - string_conv_alloc); - } else { - /* Either we succeeded, or we've done our - * best; go ahead and print what we've got. - */ - string_conv[string_conv_alloc - 1 - outleft] = - '\0'; - break; - } - } - return string_conv; - } else - return xstrdup (string); -} -#else /* !HAVE_ICONV */ -# define simple_convert(conv, string) xstrdup (string) -#endif /* HAVE_ICONV */ - /* Do the old thing, if we cannot find the relevant database. * This invokes grep once per argument; we can't do much about this because * we need to know which arguments failed. The only way to speed this up @@ -486,7 +446,7 @@ static void display (MYDBM_FILE dbf, struct mandata *info, const char *page) } else string = appendstr (string, whatis, "\n", (void *) 0); - string_conv = simple_convert (conv_to_locale, string); + string_conv = convert_to_locale (string); fputs (string_conv, stdout); free (string_conv); @@ -882,9 +842,6 @@ static bool search (const char * const *pages, int num_pages) int main (int argc, char *argv[]) { char *program_base_name; -#ifdef HAVE_ICONV - char *locale_charset; -#endif int status = OK; set_program_name (argv[0]); @@ -957,12 +914,6 @@ int main (int argc, char *argv[]) display_seen = new_string_set (GL_HASH_SET); -#ifdef HAVE_ICONV - locale_charset = xasprintf ("%s//IGNORE", get_locale_charset ()); - conv_to_locale = iconv_open (locale_charset, "UTF-8"); - free (locale_charset); -#endif /* HAVE_ICONV */ - if (regex_opt) { int i; preg = XNMALLOC (num_keywords, regex_t); @@ -981,10 +932,6 @@ int main (int argc, char *argv[]) free (preg); } -#ifdef HAVE_ICONV - if (conv_to_locale != (iconv_t) -1) - iconv_close (conv_to_locale); -#endif /* HAVE_ICONV */ gl_set_free (display_seen); free_pathlist (manpathlist); free (manp); |