| 142 | #endif |
| 143 | |
| 144 | int |
| 145 | POPT_fprintf (FILE * stream, const char * format, ...) |
| 146 | { |
| 147 | char * b = NULL, * ob = NULL; |
| 148 | int rc; |
| 149 | va_list ap; |
| 150 | |
| 151 | #if defined(HAVE_VASPRINTF) |
| 152 | va_start(ap, format); |
| 153 | if ((rc = vasprintf(&b, format, ap)) < 0) |
| 154 | b = NULL; |
| 155 | va_end(ap); |
| 156 | #else |
| 157 | size_t nb = (size_t)1; |
| 158 | |
| 159 | /* HACK: add +1 to the realloc no. of bytes "just in case". */ |
| 160 | /* XXX Likely unneeded, the issues wrto vsnprintf(3) return b0rkage have |
| 161 | * to do with whether the final '\0' is counted (or not). The code |
| 162 | * below already adds +1 for the (possibly already counted) trailing NUL. |
| 163 | */ |
| 164 | while ((b = realloc(b, nb+1)) != NULL) { |
| 165 | va_start(ap, format); |
| 166 | rc = vsnprintf(b, nb, format, ap); |
| 167 | va_end(ap); |
| 168 | if (rc > -1) { /* glibc 2.1 */ |
| 169 | if ((size_t)rc < nb) |
| 170 | break; |
| 171 | nb = (size_t)(rc + 1); /* precise buffer length known */ |
| 172 | } else /* glibc 2.0 */ |
| 173 | nb += (nb < (size_t)100 ? (size_t)100 : nb); |
| 174 | ob = b; |
| 175 | } |
| 176 | #endif |
| 177 | |
| 178 | rc = 0; |
| 179 | if (b != NULL) { |
| 180 | #ifdef HAVE_ICONV |
| 181 | ob = strdup_locale_from_utf8(b); |
| 182 | if (ob != NULL) { |
| 183 | rc = fprintf(stream, "%s", ob); |
| 184 | free(ob); |
| 185 | } else |
| 186 | #endif |
| 187 | rc = fprintf(stream, "%s", b); |
| 188 | free (b); |
| 189 | } |
| 190 | |
| 191 | return rc; |
| 192 | } |
| 193 | |
| 194 | #endif /* !defined(POPT_fprintf) */ |
no test coverage detected