Mirror of :pserver:cvs@cvs.fefe.de:/cvs libowfat https://www.fefe.de/libowfat/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

87 lines
2.2 KiB

  1. #include "fmt.h"
  2. #ifdef UNITTEST
  3. #include "fmt_tohex.c"
  4. #endif
  5. static void fmt_oct3(char* dest,uint8_t w) {
  6. dest[2]=(char)((w&7)+'0'); w>>=3;
  7. dest[1]=(char)((w&7)+'0'); w>>=3;
  8. dest[0]=(char)((w&7)+'0');
  9. }
  10. size_t fmt_escapecharc(char* dest,uint32_t ch) {
  11. char c;
  12. if (ch>0xff) {
  13. if (dest) {
  14. unsigned int i;
  15. dest[0]='\\';
  16. if (ch>0xffff) {
  17. dest[1]='U';
  18. dest[2]=fmt_tohex((ch>>28)&0xf);
  19. dest[3]=fmt_tohex((ch>>24)&0xf);
  20. dest[4]=fmt_tohex((ch>>20)&0xf);
  21. dest[5]=fmt_tohex((ch>>16)&0xf);
  22. i=6;
  23. } else {
  24. dest[1]='u';
  25. i=2;
  26. }
  27. dest[i]=fmt_tohex((ch>>12)&0xf);
  28. dest[i+1]=fmt_tohex((ch>>8)&0xf);
  29. dest[i+2]=fmt_tohex((ch>>4)&0xf);
  30. dest[i+3]=fmt_tohex(ch&0xf);
  31. }
  32. return (ch>0xffff ? 10 : 6);
  33. }
  34. switch (ch) {
  35. case '\a': c='a'; goto doescape;
  36. case '\b': c='b'; goto doescape;
  37. case 0x1b: c='e'; goto doescape;
  38. case '\f': c='f'; goto doescape;
  39. case '\n': c='n'; goto doescape;
  40. case '\r': c='r'; goto doescape;
  41. case '\t': c='t'; goto doescape;
  42. case '\v': c='v'; goto doescape;
  43. case '\\':
  44. c='\\';
  45. doescape:
  46. if (dest) {
  47. dest[0]='\\';
  48. dest[1]=c;
  49. }
  50. return 2;
  51. default:
  52. if (dest) {
  53. dest[0]='\\';
  54. fmt_oct3(dest+1,ch&0xff);
  55. }
  56. return 4;
  57. }
  58. }
  59. #ifdef UNITTEST
  60. #include <assert.h>
  61. #include <string.h>
  62. #include <stdio.h>
  63. int main() {
  64. char buf[100];
  65. assert(fmt_escapecharc(buf,0)==4 && !memcmp(buf,"\\000",4));
  66. assert(fmt_escapecharc(buf,'\a')==2 && !memcmp(buf,"\\a",2));
  67. assert(fmt_escapecharc(buf,'\b')==2 && !memcmp(buf,"\\b",2));
  68. assert(fmt_escapecharc(buf,'\f')==2 && !memcmp(buf,"\\f",2));
  69. assert(fmt_escapecharc(buf,'\n')==2 && !memcmp(buf,"\\n",2));
  70. assert(fmt_escapecharc(buf,'\r')==2 && !memcmp(buf,"\\r",2));
  71. assert(fmt_escapecharc(buf,0x1b)==2 && !memcmp(buf,"\\e",2));
  72. assert(fmt_escapecharc(buf,'\t')==2 && !memcmp(buf,"\\t",2));
  73. assert(fmt_escapecharc(buf,'\v')==2 && !memcmp(buf,"\\v",2));
  74. assert(fmt_escapecharc(buf,'\\')==2 && !memcmp(buf,"\\\\",2));
  75. assert(fmt_escapecharc(buf,'1')==4 && !memcmp(buf,"\\001",2));
  76. assert(fmt_escapecharc(buf,0xfefe)==6 && !memcmp(buf,"\\ufefe",6));
  77. assert(fmt_escapecharc(buf,0xfefec0de)==10 && !memcmp(buf,"\\Ufefec0de",10));
  78. return 0;
  79. }
  80. #endif