diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 17:20:00 +0000 |
commit | 8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch) | |
tree | 4099e8021376c7d8c05bdf8503093d80e9c7bad0 /third_party/popt/poptint.c | |
parent | Initial commit. (diff) | |
download | samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip |
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/popt/poptint.c')
-rw-r--r-- | third_party/popt/poptint.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/third_party/popt/poptint.c b/third_party/popt/poptint.c new file mode 100644 index 0000000..1af46ff --- /dev/null +++ b/third_party/popt/poptint.c @@ -0,0 +1,199 @@ +#include "system.h" +#include <stdarg.h> +#include "poptint.h" + +/* Any pair of 32 bit hashes can be used. lookup3.c generates pairs, will do. */ +#define _JLU3_jlu32lpair 1 +#define jlu32lpair poptJlu32lpair +#include "lookup3.c" + +/*@-varuse +charint +ignoresigns @*/ +/*@unchecked@*/ /*@observer@*/ +static const unsigned char utf8_skip_data[256] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 +}; +/*@=varuse =charint =ignoresigns @*/ + +const char * +POPT_prev_char (const char *str) +{ + const char *p = str; + + while (1) { + p--; + if (((unsigned)*p & 0xc0) != (unsigned)0x80) + return p; + } +} + +const char * +POPT_next_char (const char *str) +{ + const char *p = str; + + while (*p != '\0') { + p++; + if (((unsigned)*p & 0xc0) != (unsigned)0x80) + break; + } + return p; +} + +#if !defined(POPT_fprintf) /* XXX lose all the goop ... */ + +#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__) +/* + * Rebind a "UTF-8" codeset for popt's internal use. + */ +char * +POPT_dgettext(const char * dom, const char * str) +{ + char * codeset = NULL; + char * retval = NULL; + + if (!dom) + dom = textdomain(NULL); + codeset = bind_textdomain_codeset(dom, NULL); + bind_textdomain_codeset(dom, "UTF-8"); + retval = dgettext(dom, str); + bind_textdomain_codeset(dom, codeset); + + return retval; +} +#endif + +#ifdef HAVE_ICONV +/** + * Return malloc'd string converted from UTF-8 to current locale. + * @param istr input string (UTF-8 encoding assumed) + * @return localized string + */ +static /*@only@*/ /*@null@*/ char * +strdup_locale_from_utf8 (/*@null@*/ char * istr) + /*@*/ +{ + char * codeset = NULL; + char * ostr = NULL; + iconv_t cd; + + if (istr == NULL) + return NULL; + +#ifdef HAVE_LANGINFO_H + codeset = nl_langinfo ((nl_item)CODESET); +#endif + + if (codeset != NULL && strcmp(codeset, "UTF-8") != 0 + && (cd = iconv_open(codeset, "UTF-8")) != (iconv_t)-1) + { + char * shift_pin = NULL; + size_t db = strlen(istr); +/*@owned@*/ + char * dstr = malloc((db + 1) * sizeof(*dstr)); + char * pin = istr; + char * pout = dstr; + size_t ib = db; + size_t ob = db; + size_t err; + + if (dstr == NULL) + return NULL; + err = iconv(cd, NULL, NULL, NULL, NULL); + while (1) { + *pout = '\0'; + err = iconv(cd, &pin, &ib, &pout, &ob); + if (err != (size_t)-1) { + if (shift_pin == NULL) { + shift_pin = pin; + pin = NULL; + ib = 0; + continue; + } + } else + switch (errno) { + case E2BIG: + { size_t used = (size_t)(pout - dstr); + db *= 2; + dstr = realloc(dstr, (db + 1) * sizeof(*dstr)); + if (dstr != NULL) { + pout = dstr + used; + ob = db - used; + continue; + } + } /*@switchbreak@*/ break; + case EINVAL: + case EILSEQ: + default: + /*@switchbreak@*/ break; + } + break; + } + (void) iconv_close(cd); + *pout = '\0'; + ostr = xstrdup(dstr); + free(dstr); + } else + ostr = xstrdup(istr); + + return ostr; +} +#endif + +int +POPT_fprintf (FILE * stream, const char * format, ...) +{ + char * b = NULL, * ob = NULL; + int rc; + va_list ap; + +#if defined(HAVE_VASPRINTF) && !defined(__LCLINT__) + va_start(ap, format); + if ((rc = vasprintf(&b, format, ap)) < 0) + b = NULL; + va_end(ap); +#else + size_t nb = (size_t)1; + + /* HACK: add +1 to the realloc no. of bytes "just in case". */ + /* XXX Likely unneeded, the issues wrto vsnprintf(3) return b0rkage have + * to do with whether the final '\0' is counted (or not). The code + * below already adds +1 for the (possibly already counted) trailing NUL. + */ + while ((b = realloc(b, nb+1)) != NULL) { + va_start(ap, format); + rc = vsnprintf(b, nb, format, ap); + va_end(ap); + if (rc > -1) { /* glibc 2.1 */ + if ((size_t)rc < nb) + break; + nb = (size_t)(rc + 1); /* precise buffer length known */ + } else /* glibc 2.0 */ + nb += (nb < (size_t)100 ? (size_t)100 : nb); + ob = b; + } +#endif + + rc = 0; + if (b != NULL) { +#ifdef HAVE_ICONV + ob = strdup_locale_from_utf8(b); + if (ob != NULL) { + rc = fprintf(stream, "%s", ob); + free(ob); + } else +#endif + rc = fprintf(stream, "%s", b); + free (b); + } + + return rc; +} + +#endif /* !defined(POPT_fprintf) */ |