6 * charset - character set conversion and validation routines
8 * This module provides a collection of well-tested routines
9 * for dealing with character set nonsense.
16 * #include <ccan/charset/charset.h>
17 * #include <ccan/grab_file/grab_file.h>
18 * #include <ccan/talloc/talloc.h>
20 * static void print_json_string(const char *s);
21 * static bool parse_hex16(const char **sp, unsigned int *out);
23 * // Take a JSON-encoded string on input and print its literal value.
29 * input = grab_file(NULL, NULL, &length);
31 * err(1, "Error reading input");
32 * if (!utf8_validate(input, length)) {
33 * fprintf(stderr, "Input contains invalid UTF-8\n");
36 * if (strlen(input) != length) {
37 * fprintf(stderr, "Input contains null characters\n");
41 * print_json_string(input);
47 * static void print_json_string(const char *s)
49 * char output_buffer[4];
51 * // Skip leading whitespace
52 * while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')
56 * fprintf(stderr, "Expected JSON string literal surrounded by double quotes.\n");
61 * unsigned char c = *s++;
62 * char *b = output_buffer;
72 * case 'b': *b++ = '\b'; break;
73 * case 'f': *b++ = '\f'; break;
74 * case 'n': *b++ = '\n'; break;
75 * case 'r': *b++ = '\r'; break;
76 * case 't': *b++ = '\t'; break;
78 * unsigned int uc, lc;
80 * if (!parse_hex16(&s, &uc))
83 * if (uc >= 0xD800 && uc <= 0xDFFF) {
84 * // Handle UTF-16 surrogate pair (e.g. "\uD834\uDD1E").
87 * if (*s++ != '\\' || *s++ != 'u' || !parse_hex16(&s, &lc))
90 * unicode = from_surrogate_pair(uc, lc);
91 * if (unicode == REPLACEMENT_CHARACTER) {
92 * fprintf(stderr, "Invalid surrogate pair.\n");
96 * b += utf8_write_char(unicode, b);
98 * // Handle ordinary Unicode escape (e.g. "\u266B").
99 * b += utf8_write_char(uc, b);
107 * } else if (c <= 0x1F) {
108 * // Control characters are not allowed in string literals.
114 * fwrite(output_buffer, 1, b - output_buffer, stdout);
121 * fprintf(stderr, "Syntax error in JSON string literal.\n");
122 * exit(EXIT_FAILURE);
125 * static bool parse_hex16(const char **sp, unsigned int *out)
127 * const char *s = *sp;
128 * unsigned int ret = 0;
133 * for (i = 0; i < 4; i++)
136 * if (c >= '0' && c <= '9')
138 * else if (c >= 'A' && c <= 'F')
139 * tmp = c - 'A' + 10;
140 * else if (c >= 'a' && c <= 'f')
141 * tmp = c - 'a' + 10;
154 * Author: Joey Adams <joeyadams3.14159@gmail.com>
158 int main(int argc, char *argv[])
160 /* Expect exactly one argument */
164 if (strcmp(argv[1], "depends") == 0) {
169 if (strcmp(argv[1], "libs") == 0) {
170 printf("m\n"); /* Needed for the pow() invocation in run.c */