popt  1.16
poptint.c
Go to the documentation of this file.
1 #include "system.h"
2 #include <stdarg.h>
3 #include "poptint.h"
4 
5 /* Any pair of 32 bit hashes can be used. lookup3.c generates pairs, will do. */
6 #define _JLU3_jlu32lpair 1
7 #define jlu32lpair poptJlu32lpair
8 #include "lookup3.c"
9 
10 /*@-varuse +charint +ignoresigns @*/
11 /*@unchecked@*/ /*@observer@*/
12 static const unsigned char utf8_skip_data[256] = {
13  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
14  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
15  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
16  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
17  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
18  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
19  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,
20  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
21 };
22 /*@=varuse =charint =ignoresigns @*/
23 
24 const char *
25 POPT_prev_char (const char *str)
26 {
27  const char *p = str;
28 
29  while (1) {
30  p--;
31  if (((unsigned)*p & 0xc0) != (unsigned)0x80)
32  return p;
33  }
34 }
35 
36 const char *
37 POPT_next_char (const char *str)
38 {
39  const char *p = str;
40 
41  while (*p != '\0') {
42  p++;
43  if (((unsigned)*p & 0xc0) != (unsigned)0x80)
44  break;
45  }
46  return p;
47 }
48 
49 #if !defined(POPT_fprintf) /* XXX lose all the goop ... */
50 
51 #if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__)
52 /*
53  * Rebind a "UTF-8" codeset for popt's internal use.
54  */
55 char *
56 POPT_dgettext(const char * dom, const char * str)
57 {
58  char * codeset = NULL;
59  char * retval = NULL;
60 
61  if (!dom)
62  dom = textdomain(NULL);
63  codeset = bind_textdomain_codeset(dom, NULL);
64  bind_textdomain_codeset(dom, "UTF-8");
65  retval = dgettext(dom, str);
66  bind_textdomain_codeset(dom, codeset);
67 
68  return retval;
69 }
70 #endif
71 
72 #ifdef HAVE_ICONV
73 
78 static /*@only@*/ /*@null@*/ char *
79 strdup_locale_from_utf8 (/*@null@*/ char * istr)
80  /*@*/
81 {
82  char * codeset = NULL;
83  char * ostr = NULL;
84  iconv_t cd;
85 
86  if (istr == NULL)
87  return NULL;
88 
89 #ifdef HAVE_LANGINFO_H
90  codeset = nl_langinfo ((nl_item)CODESET);
91 #endif
92 
93  if (codeset != NULL && strcmp(codeset, "UTF-8") != 0
94  && (cd = iconv_open(codeset, "UTF-8")) != (iconv_t)-1)
95  {
96  char * shift_pin = NULL;
97  size_t db = strlen(istr);
98 /*@owned@*/
99  char * dstr = malloc((db + 1) * sizeof(*dstr));
100  char * pin = istr;
101  char * pout = dstr;
102  size_t ib = db;
103  size_t ob = db;
104  size_t err;
105 
106  if (dstr == NULL)
107  return NULL;
108  err = iconv(cd, NULL, NULL, NULL, NULL);
109  while (1) {
110  *pout = '\0';
111  err = iconv(cd, &pin, &ib, &pout, &ob);
112  if (err != (size_t)-1) {
113  if (shift_pin == NULL) {
114  shift_pin = pin;
115  pin = NULL;
116  ib = 0;
117  continue;
118  }
119  } else
120  switch (errno) {
121  case E2BIG:
122  { size_t used = (size_t)(pout - dstr);
123  db *= 2;
124  dstr = realloc(dstr, (db + 1) * sizeof(*dstr));
125  if (dstr != NULL) {
126  pout = dstr + used;
127  ob = db - used;
128  continue;
129  }
130  } /*@switchbreak@*/ break;
131  case EINVAL:
132  case EILSEQ:
133  default:
134  /*@switchbreak@*/ break;
135  }
136  break;
137  }
138  (void) iconv_close(cd);
139  *pout = '\0';
140  ostr = xstrdup(dstr);
141  free(dstr);
142  } else
143  ostr = xstrdup(istr);
144 
145  return ostr;
146 }
147 #endif
148 
149 int
150 POPT_fprintf (FILE * stream, const char * format, ...)
151 {
152  char * b = NULL, * ob = NULL;
153  int rc;
154  va_list ap;
155 
156 #if defined(HAVE_VASPRINTF) && !defined(__LCLINT__)
157  va_start(ap, format);
158  if ((rc = vasprintf(&b, format, ap)) < 0)
159  b = NULL;
160  va_end(ap);
161 #else
162  size_t nb = (size_t)1;
163 
164  /* HACK: add +1 to the realloc no. of bytes "just in case". */
165  /* XXX Likely unneeded, the issues wrto vsnprintf(3) return b0rkage have
166  * to do with whether the final '\0' is counted (or not). The code
167  * below already adds +1 for the (possibly already counted) trailing NUL.
168  */
169  while ((b = realloc(b, nb+1)) != NULL) {
170  va_start(ap, format);
171  rc = vsnprintf(b, nb, format, ap);
172  va_end(ap);
173  if (rc > -1) { /* glibc 2.1 */
174  if ((size_t)rc < nb)
175  break;
176  nb = (size_t)(rc + 1); /* precise buffer length known */
177  } else /* glibc 2.0 */
178  nb += (nb < (size_t)100 ? (size_t)100 : nb);
179  ob = b;
180  }
181 #endif
182 
183  rc = 0;
184  if (b != NULL) {
185 #ifdef HAVE_ICONV
186  ob = strdup_locale_from_utf8(b);
187  if (ob != NULL) {
188  rc = fprintf(stream, "%s", ob);
189  free(ob);
190  } else
191 #endif
192  rc = fprintf(stream, "%s", b);
193  free (b);
194  }
195 
196  return rc;
197 }
198 
199 #endif /* !defined(POPT_fprintf) */
const char * POPT_next_char(const char *str)
Definition: poptint.c:37
static const unsigned char utf8_skip_data[256]
Definition: poptint.c:12
int POPT_fprintf(FILE *stream, const char *format,...)
Definition: poptint.c:150
const char * POPT_prev_char(const char *str)
Definition: poptint.c:25
char * xstrdup(const char *str)

Generated for popt by  doxygen 1.8.13