_info 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "config.h"
  4. /**
  5. * charset - character set conversion and validation routines
  6. *
  7. * This module provides a collection of well-tested routines
  8. * for dealing with character set nonsense.
  9. *
  10. * Example:
  11. * #include <err.h>
  12. * #include <stdio.h>
  13. * #include <stdlib.h>
  14. * #include <string.h>
  15. * #include <ccan/charset/charset.h>
  16. * #include <ccan/grab_file/grab_file.h>
  17. * #include <ccan/talloc/talloc.h>
  18. *
  19. * static void print_json_string(const char *s);
  20. * static bool parse_hex16(const char **sp, unsigned int *out);
  21. *
  22. * // Take a JSON-encoded string on input and print its literal value.
  23. * int main(void)
  24. * {
  25. * char *input;
  26. * size_t length;
  27. *
  28. * input = grab_file(NULL, NULL, &length);
  29. * if (!input)
  30. * err(1, "Error reading input");
  31. * if (!utf8_validate(input, length)) {
  32. * fprintf(stderr, "Input contains invalid UTF-8\n");
  33. * return 1;
  34. * }
  35. * if (strlen(input) != length) {
  36. * fprintf(stderr, "Input contains null characters\n");
  37. * return 1;
  38. * }
  39. *
  40. * print_json_string(input);
  41. *
  42. * talloc_free(input);
  43. * return 0;
  44. * }
  45. *
  46. * static void print_json_string(const char *s)
  47. * {
  48. * char output_buffer[4];
  49. *
  50. * // Skip leading whitespace
  51. * while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')
  52. * s++;
  53. *
  54. * if (*s++ != '"') {
  55. * fprintf(stderr, "Expected JSON string literal surrounded by double quotes.\n");
  56. * exit(EXIT_FAILURE);
  57. * }
  58. *
  59. * while (*s != '"') {
  60. * unsigned char c = *s++;
  61. * char *b = output_buffer;
  62. *
  63. * if (c == '\\') {
  64. * c = *s++;
  65. * switch (c) {
  66. * case '"':
  67. * case '\\':
  68. * case '/':
  69. * *b++ = c;
  70. * break;
  71. * case 'b': *b++ = '\b'; break;
  72. * case 'f': *b++ = '\f'; break;
  73. * case 'n': *b++ = '\n'; break;
  74. * case 'r': *b++ = '\r'; break;
  75. * case 't': *b++ = '\t'; break;
  76. * case 'u': {
  77. * unsigned int uc, lc;
  78. *
  79. * if (!parse_hex16(&s, &uc))
  80. * goto syntax_error;
  81. *
  82. * if (uc >= 0xD800 && uc <= 0xDFFF) {
  83. * // Handle UTF-16 surrogate pair (e.g. "\uD834\uDD1E").
  84. * uchar_t unicode;
  85. *
  86. * if (*s++ != '\\' || *s++ != 'u' || !parse_hex16(&s, &lc))
  87. * goto syntax_error;
  88. *
  89. * unicode = from_surrogate_pair(uc, lc);
  90. * if (unicode == REPLACEMENT_CHARACTER) {
  91. * fprintf(stderr, "Invalid surrogate pair.\n");
  92. * exit(EXIT_FAILURE);
  93. * }
  94. *
  95. * b += utf8_write_char(unicode, b);
  96. * } else {
  97. * // Handle ordinary Unicode escape (e.g. "\u266B").
  98. * b += utf8_write_char(uc, b);
  99. * }
  100. *
  101. * break;
  102. * }
  103. * default:
  104. * goto syntax_error;
  105. * }
  106. * } else if (c <= 0x1F) {
  107. * // Control characters are not allowed in string literals.
  108. * goto syntax_error;
  109. * } else {
  110. * *b++ = c;
  111. * }
  112. *
  113. * fwrite(output_buffer, 1, b - output_buffer, stdout);
  114. * }
  115. *
  116. * putchar('\n');
  117. * return;
  118. *
  119. * syntax_error:
  120. * fprintf(stderr, "Syntax error in JSON string literal.\n");
  121. * exit(EXIT_FAILURE);
  122. * }
  123. *
  124. * static bool parse_hex16(const char **sp, unsigned int *out)
  125. * {
  126. * const char *s = *sp;
  127. * unsigned int ret = 0;
  128. * unsigned int i;
  129. * unsigned int tmp;
  130. * char c;
  131. *
  132. * for (i = 0; i < 4; i++)
  133. * {
  134. * c = *s++;
  135. * if (c >= '0' && c <= '9')
  136. * tmp = c - '0';
  137. * else if (c >= 'A' && c <= 'F')
  138. * tmp = c - 'A' + 10;
  139. * else if (c >= 'a' && c <= 'f')
  140. * tmp = c - 'a' + 10;
  141. * else
  142. * return false;
  143. *
  144. * ret <<= 4;
  145. * ret += tmp;
  146. * }
  147. *
  148. * *out = ret;
  149. * *sp = s;
  150. * return true;
  151. * }
  152. *
  153. * Author: Joey Adams <joeyadams3.14159@gmail.com>
  154. * License: MIT
  155. * Version: 0.3
  156. */
  157. int main(int argc, char *argv[])
  158. {
  159. /* Expect exactly one argument */
  160. if (argc != 2)
  161. return 1;
  162. if (strcmp(argv[1], "depends") == 0) {
  163. /* Nothing */
  164. return 0;
  165. }
  166. if (strcmp(argv[1], "libs") == 0) {
  167. printf("m\n"); /* Needed for the pow() invocation in run.c */
  168. return 0;
  169. }
  170. return 1;
  171. }