printable_string.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Unicode support routines.
  4. *
  5. * Copyright (C) 2010 Denys Vlasenko
  6. *
  7. * Licensed under GPL version 2, see file LICENSE in this tarball for details.
  8. */
  9. #include "libbb.h"
  10. #include "unicode.h"
  11. const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str)
  12. {
  13. static char *saved[4];
  14. static unsigned cur_saved; /* = 0 */
  15. char *dst;
  16. const char *s;
  17. s = str;
  18. while (1) {
  19. unsigned char c = *s;
  20. if (c == '\0') {
  21. /* 99+% of inputs do not need conversion */
  22. if (stats) {
  23. stats->byte_count = (s - str);
  24. stats->unicode_count = (s - str);
  25. stats->unicode_width = (s - str);
  26. }
  27. return str;
  28. }
  29. if (c < ' ')
  30. break;
  31. if (c >= 0x7f)
  32. break;
  33. s++;
  34. }
  35. #if ENABLE_UNICODE_SUPPORT
  36. dst = unicode_conv_to_printable(stats, str);
  37. #else
  38. {
  39. char *d = dst = xstrdup(str);
  40. while (1) {
  41. unsigned char c = *d;
  42. if (c == '\0')
  43. break;
  44. if (c < ' ' || c >= 0x7f)
  45. *d = '?';
  46. d++;
  47. }
  48. if (stats) {
  49. stats->byte_count = (d - dst);
  50. stats->unicode_count = (d - dst);
  51. stats->unicode_width = (d - dst);
  52. }
  53. }
  54. #endif
  55. free(saved[cur_saved]);
  56. saved[cur_saved] = dst;
  57. cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1);
  58. return dst;
  59. }