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/tal/grab_file/grab_file.h>
18 * #include <ccan/tal/tal.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.
28 * input = grab_file(NULL, NULL);
30 * err(1, "Error reading input");
31 * if (!utf8_validate(input, tal_count(input)-1)) {
32 * fprintf(stderr, "Input contains invalid UTF-8\n");
35 * if (strlen(input) != tal_count(input)-1) {
36 * fprintf(stderr, "Input contains null characters\n");
40 * print_json_string(input);
46 * static void print_json_string(const char *s)
48 * char output_buffer[4];
50 * // Skip leading whitespace
51 * while (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')
55 * fprintf(stderr, "Expected JSON string literal surrounded by double quotes.\n");
60 * unsigned char c = *s++;
61 * char *b = output_buffer;
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;
77 * unsigned int uc, lc;
79 * if (!parse_hex16(&s, &uc))
82 * if (uc >= 0xD800 && uc <= 0xDFFF) {
83 * // Handle UTF-16 surrogate pair (e.g. "\uD834\uDD1E").
86 * if (*s++ != '\\' || *s++ != 'u' || !parse_hex16(&s, &lc))
89 * unicode = from_surrogate_pair(uc, lc);
90 * if (unicode == REPLACEMENT_CHARACTER) {
91 * fprintf(stderr, "Invalid surrogate pair.\n");
95 * b += utf8_write_char(unicode, b);
97 * // Handle ordinary Unicode escape (e.g. "\u266B").
98 * b += utf8_write_char(uc, b);
106 * } else if (c <= 0x1F) {
107 * // Control characters are not allowed in string literals.
113 * fwrite(output_buffer, 1, b - output_buffer, stdout);
120 * fprintf(stderr, "Syntax error in JSON string literal.\n");
121 * exit(EXIT_FAILURE);
124 * static bool parse_hex16(const char **sp, unsigned int *out)
126 * const char *s = *sp;
127 * unsigned int ret = 0;
132 * for (i = 0; i < 4; i++)
135 * if (c >= '0' && c <= '9')
137 * else if (c >= 'A' && c <= 'F')
138 * tmp = c - 'A' + 10;
139 * else if (c >= 'a' && c <= 'f')
140 * tmp = c - 'a' + 10;
153 * Author: Joey Adams <joeyadams3.14159@gmail.com>
157 int main(int argc, char *argv[])
159 /* Expect exactly one argument */
163 if (strcmp(argv[1], "depends") == 0) {
168 if (strcmp(argv[1], "libs") == 0) {
169 printf("m\n"); /* Needed for the pow() invocation in run.c */