1 #include "ccan_tokenizer.h"
3 static char *strdup_rng(const char *s, const char *e) {
4 char *ret = malloc(e-s+1);
10 #define MESSAGE_PATH "tokenize/read_cstring/"
12 //Reads a C string starting at s until quoteChar is found or e is reached
13 // Returns the pointer to the terminating quote character or e if none was found
14 char *read_cstring(array_char *out, const char *s, const char *e, char quoteChar, tok_message_queue *mq) {
15 const char * const tokstart = s;
17 int has_endquote=0, has_newlines=0;
19 //tok_msg_debug(called, s, "Called read_cstring on `%s`", s);
21 #define append(startptr,endptr) array_append_items(*out, startptr, (endptr)-(startptr))
22 #define append_char(theChar) array_append(*out, theChar)
23 #define append_zero() do {array_append(*out, 0); out->size--;} while(0)
33 tok_msg_error(ended_in_backslash, p-1,
34 "read_cstring input ended in backslash");
38 if (c>='0' && c<='9') {
39 unsigned int octal = c-'0';
40 size_t digit_count = 0;
41 while (p<e && *p>='0' && *p<='9') {
43 octal += (*p++) - '0';
44 if (++digit_count >= 2)
47 if (p<e && *p>='0' && *p<='9') {
48 tok_msg_info(ambiguous_octal, s-2,
49 "Octal followed by digit");
52 tok_msg_warn(octal_overflow, s-2,
53 "Octal out of range");
59 size_t digit_count = 0;
60 size_t zero_count = 0;
62 while (p<e && *p=='0') p++, zero_count++;
63 for (;p<e;digit_count++) {
67 else if (c>='A' && c<='F')
69 else if (c>='a' && c<='f')
78 if (zero_count+digit_count > 2) {
79 char *hex_string = strdup_rng(s-2, p);
80 tok_msg_warn(ambiguous_hex, s-2,
81 "Hex escape '%s' is ambiguous", hex_string);
83 tok_msg_warn(hex_overflow, s-2,
84 "Hex escape '%s' out of range", hex_string);
118 if (c=='\'' && quoteChar=='"') {
119 /* tok_msg_info(escaped_single_quote, s-2,
120 "Single quote characters need not be escaped within double quotes"); */
123 if (c=='"' && quoteChar=='\'') {
124 /* tok_msg_info(escaped_double_quote, s-2,
125 "Double quote characters need not be escaped within single quotes"); */
128 if (c=='?') // \? is needed in some situations to avoid building a trigraph
130 tok_msg_warn(unknown_escape, s-2,
131 "Unknown escape sequence '\\%c'", c);
137 } else if (c == quoteChar) {
141 } else if (creturn(c)) {
148 tok_msg_error(missing_endquote, tokstart,
149 "Missing endquote on %s literal",
150 quoteChar=='\'' ? "character" : "string");
151 } else if (has_newlines) {
152 tok_msg_warn(quote_newlines, tokstart,
153 "%s literal contains newline character(s)",
154 quoteChar=='\'' ? "Character" : "String");