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 static char *
00069 strdup_locale_from_utf8 ( char *buffer)
00070
00071 {
00072 char *codeset = NULL;
00073 char *dest_str;
00074 iconv_t fd;
00075
00076 if (buffer == NULL)
00077 return NULL;
00078
00079 #ifdef HAVE_LANGINFO_H
00080
00081 codeset = nl_langinfo (CODESET);
00082
00083 #endif
00084
00085 if (codeset != NULL && strcmp(codeset, "UTF-8") != 0
00086 && (fd = iconv_open(codeset, "UTF-8")) != (iconv_t)-1)
00087 {
00088 char *pin = buffer;
00089 char *pout = NULL;
00090 size_t ib, ob, dest_size;
00091 int done;
00092 int is_error;
00093 size_t err;
00094 char *shift_pin = NULL;
00095 int xx;
00096
00097 err = iconv(fd, NULL, &ib, &pout, &ob);
00098 dest_size = ob = ib = strlen(buffer);
00099 dest_str = pout = malloc((dest_size + 1) * sizeof(*dest_str));
00100 if (dest_str)
00101 *dest_str = '\0';
00102 done = is_error = 0;
00103 if (pout != NULL)
00104 while (done == 0 && is_error == 0) {
00105 err = iconv(fd, &pin, &ib, &pout, &ob);
00106
00107 if (err == (size_t)-1) {
00108 switch (errno) {
00109 case EINVAL:
00110 done = 1;
00111 break;
00112 case E2BIG:
00113 { size_t used = (size_t)(pout - dest_str);
00114 dest_size *= 2;
00115 dest_str = realloc(dest_str, (dest_size + 1) * sizeof(*dest_str));
00116 if (dest_str == NULL) {
00117 is_error = 1;
00118 continue;
00119 }
00120 pout = dest_str + used;
00121 ob = dest_size - used;
00122 } break;
00123 case EILSEQ:
00124 is_error = 1;
00125 break;
00126 default:
00127 is_error = 1;
00128 break;
00129 }
00130 } else {
00131 if (shift_pin == NULL) {
00132 shift_pin = pin;
00133 pin = NULL;
00134 ib = 0;
00135 } else {
00136 done = 1;
00137 }
00138 }
00139 }
00140 xx = iconv_close(fd);
00141 if (pout)
00142 *pout = '\0';
00143 if (dest_str != NULL)
00144 dest_str = xstrdup(dest_str);
00145 } else {
00146 dest_str = xstrdup(buffer);
00147 }
00148
00149 return dest_str;
00150 }
00151 #endif
00152
00153 int
00154 POPT_fprintf (FILE * stream, const char * format, ...)
00155 {
00156 char * b = NULL, * ob = NULL;
00157 int rc;
00158 va_list ap;
00159
00160 #if defined(HAVE_VASPRINTF) && !defined(__LCLINT__)
00161 va_start(ap, format);
00162 if ((rc = vasprintf(&b, format, ap)) < 0)
00163 b = NULL;
00164 va_end(ap);
00165 #else
00166 size_t nb = (size_t)1;
00167
00168
00169
00170
00171
00172
00173 while ((b = realloc(b, nb+1)) != NULL) {
00174 va_start(ap, format);
00175 rc = vsnprintf(b, nb, format, ap);
00176 va_end(ap);
00177 if (rc > -1) {
00178 if ((size_t)rc < nb)
00179 break;
00180 nb = (size_t)(rc + 1);
00181 } else
00182 nb += (nb < (size_t)100 ? (size_t)100 : nb);
00183 ob = b;
00184 }
00185 #endif
00186
00187 rc = 0;
00188 if (b != NULL) {
00189 #ifdef HAVE_ICONV
00190 ob = strdup_locale_from_utf8(b);
00191 if (ob != NULL) {
00192 rc = fprintf(stream, "%s", ob);
00193 free(ob);
00194 } else
00195 #endif
00196 rc = fprintf(stream, "%s", b);
00197 free (b);
00198 } else if (ob != NULL)
00199 free(ob);
00200
00201 return rc;
00202 }
00203
00204 #endif