00001 #include "system.h"
00002 #include <stdarg.h>
00003 #include "poptint.h"
00004
00005
00006
00007 static const unsigned char utf8_skip_data[256] = {
00008 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00009 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00010 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00011 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00012 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00013 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00014 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,
00015 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
00016 };
00017
00018
00019 const char *
00020 POPT_prev_char (const char *str)
00021 {
00022 const char *p = str;
00023
00024 while (1) {
00025 p--;
00026 if (((unsigned)*p & 0xc0) != (unsigned)0x80)
00027 return p;
00028 }
00029 }
00030
00031 const char *
00032 POPT_next_char (const char *str)
00033 {
00034 const char *p = str;
00035
00036 while (*p != '\0') {
00037 p++;
00038 if (((unsigned)*p & 0xc0) != (unsigned)0x80)
00039 break;
00040 }
00041 return p;
00042 }
00043
00044 #if !defined(POPT_fprintf)
00045
00046 #if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__)
00047
00048
00049
00050 char *
00051 POPT_dgettext(const char * dom, const char * str)
00052 {
00053 char * codeset = NULL;
00054 char * retval = NULL;
00055
00056 if (!dom)
00057 dom = textdomain(NULL);
00058 codeset = bind_textdomain_codeset(dom, NULL);
00059 bind_textdomain_codeset(dom, "UTF-8");
00060 retval = dgettext(dom, str);
00061 bind_textdomain_codeset(dom, codeset);
00062
00063 return retval;
00064 }
00065 #endif
00066
00067 #ifdef HAVE_ICONV
00068
00073 static char *
00074 strdup_locale_from_utf8 ( char * istr)
00075
00076 {
00077 char * codeset = NULL;
00078 char * ostr = NULL;
00079 iconv_t cd;
00080
00081 if (istr == NULL)
00082 return NULL;
00083
00084 #ifdef HAVE_LANGINFO_H
00085 codeset = nl_langinfo ((nl_item)CODESET);
00086 #endif
00087
00088 if (codeset != NULL && strcmp(codeset, "UTF-8") != 0
00089 && (cd = iconv_open(codeset, "UTF-8")) != (iconv_t)-1)
00090 {
00091 char * shift_pin = NULL;
00092 size_t db = strlen(istr);
00093
00094 char * dstr = malloc((db + 1) * sizeof(*dstr));
00095 char * pin = istr;
00096 char * pout = dstr;
00097 size_t ib = db;
00098 size_t ob = db;
00099 size_t err;
00100
00101 if (dstr == NULL)
00102 return NULL;
00103 err = iconv(cd, NULL, NULL, NULL, NULL);
00104 while (1) {
00105 *pout = '\0';
00106 err = iconv(cd, &pin, &ib, &pout, &ob);
00107 if (err != (size_t)-1) {
00108 if (shift_pin == NULL) {
00109 shift_pin = pin;
00110 pin = NULL;
00111 ib = 0;
00112 continue;
00113 }
00114 } else
00115 switch (errno) {
00116 case E2BIG:
00117 { size_t used = (size_t)(pout - dstr);
00118 db *= 2;
00119 dstr = realloc(dstr, (db + 1) * sizeof(*dstr));
00120 if (dstr != NULL) {
00121 pout = dstr + used;
00122 ob = db - used;
00123 continue;
00124 }
00125 } break;
00126 case EINVAL:
00127 case EILSEQ:
00128 default:
00129 break;
00130 }
00131 break;
00132 }
00133 (void) iconv_close(cd);
00134 *pout = '\0';
00135 ostr = xstrdup(dstr);
00136 free(dstr);
00137 } else
00138 ostr = xstrdup(istr);
00139
00140 return ostr;
00141 }
00142 #endif
00143
00144 int
00145 POPT_fprintf (FILE * stream, const char * format, ...)
00146 {
00147 char * b = NULL, * ob = NULL;
00148 int rc;
00149 va_list ap;
00150
00151 #if defined(HAVE_VASPRINTF) && !defined(__LCLINT__)
00152 va_start(ap, format);
00153 if ((rc = vasprintf(&b, format, ap)) < 0)
00154 b = NULL;
00155 va_end(ap);
00156 #else
00157 size_t nb = (size_t)1;
00158
00159
00160
00161
00162
00163
00164 while ((b = realloc(b, nb+1)) != NULL) {
00165 va_start(ap, format);
00166 rc = vsnprintf(b, nb, format, ap);
00167 va_end(ap);
00168 if (rc > -1) {
00169 if ((size_t)rc < nb)
00170 break;
00171 nb = (size_t)(rc + 1);
00172 } else
00173 nb += (nb < (size_t)100 ? (size_t)100 : nb);
00174 ob = b;
00175 }
00176 #endif
00177
00178 rc = 0;
00179 if (b != NULL) {
00180 #ifdef HAVE_ICONV
00181 ob = strdup_locale_from_utf8(b);
00182 if (ob != NULL) {
00183 rc = fprintf(stream, "%s", ob);
00184 free(ob);
00185 } else
00186 #endif
00187 rc = fprintf(stream, "%s", b);
00188 free (b);
00189 }
00190
00191 return rc;
00192 }
00193
00194 #endif