* Format a string into one or more "struct lineptr" lines. * lines[i].ptr == NULL indicates the end of the array. * * This MUST be kept in sync with pg_wcssize! */
| 291 | * This MUST be kept in sync with pg_wcssize! |
| 292 | */ |
| 293 | void |
| 294 | pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding, |
| 295 | struct lineptr *lines, int count) |
| 296 | { |
| 297 | int w, |
| 298 | chlen = 0; |
| 299 | int linewidth = 0; |
| 300 | unsigned char *ptr = lines->ptr; /* Pointer to data area */ |
| 301 | |
| 302 | for (; *pwcs && len > 0; pwcs += chlen) |
| 303 | { |
| 304 | chlen = PQmblen((const char *) pwcs, encoding); |
| 305 | if (len < (size_t) chlen) |
| 306 | break; |
| 307 | w = PQdsplen((const char *) pwcs, encoding); |
| 308 | |
| 309 | if (chlen == 1) /* single-byte char */ |
| 310 | { |
| 311 | if (*pwcs == '\n') /* Newline */ |
| 312 | { |
| 313 | *ptr++ = '\0'; |
| 314 | lines->width = linewidth; |
| 315 | linewidth = 0; |
| 316 | lines++; |
| 317 | count--; |
| 318 | if (count <= 0) |
| 319 | exit(1); /* Screwup */ |
| 320 | |
| 321 | /* make next line point to remaining memory */ |
| 322 | lines->ptr = ptr; |
| 323 | } |
| 324 | else if (*pwcs == '\r') /* Linefeed */ |
| 325 | { |
| 326 | strcpy((char *) ptr, "\\r"); |
| 327 | linewidth += 2; |
| 328 | ptr += 2; |
| 329 | } |
| 330 | else if (*pwcs == '\t') /* Tab */ |
| 331 | { |
| 332 | do |
| 333 | { |
| 334 | *ptr++ = ' '; |
| 335 | linewidth++; |
| 336 | } while (linewidth % 8 != 0); |
| 337 | } |
| 338 | else if (w < 0) /* Other control char */ |
| 339 | { |
| 340 | sprintf((char *) ptr, "\\x%02X", *pwcs); |
| 341 | linewidth += 4; |
| 342 | ptr += 4; |
| 343 | } |
| 344 | else /* Output it as-is */ |
| 345 | { |
| 346 | linewidth += w; |
| 347 | *ptr++ = *pwcs; |
| 348 | } |
| 349 | } |
| 350 | else if (w < 0) /* Non-ascii control char */ |
no test coverage detected