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