pytest:samba-tool: add a flag to print more in runcmd
[samba.git] / third_party / popt / poptint.c
blob1af46ff8c7bf087e942e457e0d470179f722687d
1 #include "system.h"
2 #include <stdarg.h>
3 #include "poptint.h"
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"
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
22 /*@=varuse =charint =ignoresigns @*/
24 const char *
25 POPT_prev_char (const char *str)
27 const char *p = str;
29 while (1) {
30 p--;
31 if (((unsigned)*p & 0xc0) != (unsigned)0x80)
32 return p;
36 const char *
37 POPT_next_char (const char *str)
39 const char *p = str;
41 while (*p != '\0') {
42 p++;
43 if (((unsigned)*p & 0xc0) != (unsigned)0x80)
44 break;
46 return p;
49 #if !defined(POPT_fprintf) /* XXX lose all the goop ... */
51 #if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__)
53 * Rebind a "UTF-8" codeset for popt's internal use.
55 char *
56 POPT_dgettext(const char * dom, const char * str)
58 char * codeset = NULL;
59 char * retval = NULL;
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);
68 return retval;
70 #endif
72 #ifdef HAVE_ICONV
73 /**
74 * Return malloc'd string converted from UTF-8 to current locale.
75 * @param istr input string (UTF-8 encoding assumed)
76 * @return localized string
78 static /*@only@*/ /*@null@*/ char *
79 strdup_locale_from_utf8 (/*@null@*/ char * istr)
80 /*@*/
82 char * codeset = NULL;
83 char * ostr = NULL;
84 iconv_t cd;
86 if (istr == NULL)
87 return NULL;
89 #ifdef HAVE_LANGINFO_H
90 codeset = nl_langinfo ((nl_item)CODESET);
91 #endif
93 if (codeset != NULL && strcmp(codeset, "UTF-8") != 0
94 && (cd = iconv_open(codeset, "UTF-8")) != (iconv_t)-1)
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;
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;
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;
130 } /*@switchbreak@*/ break;
131 case EINVAL:
132 case EILSEQ:
133 default:
134 /*@switchbreak@*/ break;
136 break;
138 (void) iconv_close(cd);
139 *pout = '\0';
140 ostr = xstrdup(dstr);
141 free(dstr);
142 } else
143 ostr = xstrdup(istr);
145 return ostr;
147 #endif
150 POPT_fprintf (FILE * stream, const char * format, ...)
152 char * b = NULL, * ob = NULL;
153 int rc;
154 va_list ap;
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;
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.
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;
181 #endif
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);
196 return rc;
199 #endif /* !defined(POPT_fprintf) */