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