diff --git a/usr.bin/dtc/input_buffer.hh b/usr.bin/dtc/input_buffer.hh --- a/usr.bin/dtc/input_buffer.hh +++ b/usr.bin/dtc/input_buffer.hh @@ -193,6 +193,13 @@ * current point in the input. */ bool consume(const char *str); + /** + * Reads unsigned from char literal. Returns true and advances + * the cursor to next char. + * + * The parsed value is returned via the argument. + */ + bool consume_char_literal(unsigned long long &outInt); /** * Reads an integer in base 8, 10, or 16. Returns true and advances * the cursor to the end of the integer if the cursor points to an @@ -412,6 +419,21 @@ } return input_stack.top()->consume(str); } + /** + * Converts next char into unsigned + * + * The parsed value is returned via the argument. + * + * This method does not scan between files. + */ + bool consume_char_literal(unsigned long long &outInt) + { + if (input_stack.empty()) + { + return false; + } + return input_stack.top()->consume_char_literal(outInt); + } /** * Reads an integer in base 8, 10, or 16. Returns true and advances * the cursor to the end of the integer if the cursor points to an diff --git a/usr.bin/dtc/input_buffer.cc b/usr.bin/dtc/input_buffer.cc --- a/usr.bin/dtc/input_buffer.cc +++ b/usr.bin/dtc/input_buffer.cc @@ -337,6 +337,47 @@ return false; } +bool +input_buffer::consume_char_literal(unsigned long long &outInt) +{ + outInt = (unsigned char)((*this)[0]); + cursor++; + + if(outInt != '\\') + { + return true; + } + else if(cursor >= size) + { + return false; + } + + outInt = (unsigned char)((*this)[0]); + cursor++; + + switch (outInt) { + default: + return false; + case 'n': + outInt = (unsigned char)'\n'; + break; + case 'r': + outInt = (unsigned char)'\r'; + break; + case 't': + outInt = (unsigned char)'\t'; + break; + case '0': + outInt = 0; + break; + case '\'': + case '\\': + break; + } + + return true; +} + bool input_buffer::consume_integer(unsigned long long &outInt) { @@ -874,6 +915,18 @@ source_location l = location(); switch (*(*this)) { + case '\'': + consume('\''); + if(!consume_char_literal(leftVal)) + { + return nullptr; + } + if (!consume('\'')) + { + return nullptr; + } + lhs.reset(new terminal_expr(l, leftVal)); + break; case '0'...'9': if (!consume_integer(leftVal)) {