123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- #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) */
|