71static void normal_path (std::string&
s)
73 std::string::iterator it(
s.begin ());
75 for (; it !=
s.end (); it++)
76 if (*it ==
'/' || *it ==
'\\') {
91 comment_char (cc), escape_char (ec),
99 "%s could not be opened for reading\n",
name);
109 : context_ (0), nlines_ (0), ntokens_ (0), escaped_newline_ (
false)
121 while (!context_stack_.empty ()) {
122 delete context_stack_.top ();
123 context_stack_.pop ();
142open (std::string
name,
char cc,
char ec)
147 context_stack_.push (context_);
155 if (!context_stack_.empty ()) {
156 context_ = context_stack_.top ();
157 context_stack_.pop ();
174 "%s: %u tokens, %u lines\n",
175 context_->
filename.c_str (), ntokens_, nlines_);
179 if (context_stack_.empty ())
182 context_ = context_stack_.top ();
183 context_stack_.pop ();
189process_token (
const char*
name)
195 case '0':
case '1':
case '2':
case '3':
196 case '4':
case '5':
case '6':
case '7':
210 static const struct {
309 int high =
sizeof tok_map /
sizeof *tok_map - 1;
313 while (low <= high) {
315 const int cur = (low + high) / 2;
319 return tok_map [
cur].token;
334 context_->
line_.clear ();
336 std::getline (context_->
file, context_->
line_);
338 context_->
line_ +=
'\n';
340 context_->
pos_ = context_->
line_.c_str ();
372 if (context_->
file.eof ()) {
378 if ( context_->
line_.size ()
379 <= std::size_t (context_->
pos_ - context_->
line_.c_str ())) {
390 const char*& next = context_->
pos_;
393 escaped_newline_ =
false;
397 const char* tok_begin = next++;
399 for (;
'>' != *next; ++next) {
405 next_tok.
name.append (tok_begin, next - tok_begin);
410 else if (
'\n' == *next) {
413 " unterminated symbolic name\n");
418 next_tok.
name.append (tok_begin, ++next - tok_begin);
421 if (next_tok.
name ==
"<code_set_name>") {
424 else if ( next_tok.
name ==
"<escape_char>"
425 || next_tok.
name ==
"<comment_char>") {
428 while (
' ' == *next ||
'\t' == *next) {
435 "missing value for %s\n",
436 next_tok.
name.c_str ());
439 if (next_tok.
name ==
"<escape_char>")
446 context_->
line_.c_str () + context_->
line_.size ();
452 else if (next_tok.
name ==
"<mb_cur_max>") {
455 else if (next_tok.
name ==
"<mb_cur_min>") {
463 else if (*next ==
' ' || *next ==
'\t' || *next ==
';') {
465 while (*next ==
' ' || *next ==
'\t' || *next ==
';') {
469 else if (*next ==
'\n') {
477 context_->
pos_ = context_->
line_.c_str () + context_->
line_.size ();
479 if (escaped_newline_)
483 next_tok.
name =
"\n";
486 else if (*next ==
'(') {
488 next_tok.
name.push_back (*next++);
491 while (*next !=
')') {
495 next_tok.
name.push_back (*next++);
497 while (*next !=
'\n') {
500 next_tok.
name.push_back (*next++);
501 next_tok.
name.push_back (*next++);
507 next_tok.
name.push_back (*next);
512 next_tok.
name.push_back (*next++);
518 " unterminated symbolic name");
524 next_tok.
name.push_back (*next++);
529 " unterminated grouping ");
532 next_tok.
name.push_back (*next++);
536 else if (*next ==
'.') {
538 int ellipsis_count = 0;
540 while (*next ==
'.') {
541 next_tok.
name.push_back (*next++);
545 switch (ellipsis_count) {
547 const char*
tmp = next;
548 if (*
tmp++ ==
'(' && *
tmp++ ==
'2' && *
tmp++ ==
')'
549 && *
tmp++ ==
'.' && *
tmp++ ==
'.') {
577 else if (*next ==
'\"') {
580 next_tok.
name.push_back (*next++);
583 while (next[0] !=
'\n') {
586 if (next [0] == ec && next [1] ==
'\n') {
593 next_tok.
name.push_back (*next++);
594 next_tok.
name.push_back (*next++);
598 if (next [0] ==
'\"') {
599 next_tok.
name.push_back (*next);
604 next_tok.
name.push_back (*next++);
619 if (next [1] ==
'\n') {
622 context_->
line_.c_str () + context_->
line_.size ();
624 escaped_newline_ =
true;
629 while ( *next !=
' ' && *next !=
'\t'
630 && *next !=
';' && *next !=
'\n') {
631 next_tok.
name.push_back (*next++);
635 next_tok.
token = process_token (next_tok.
name.c_str ());
643 if ( (next [0] == ec && next [1] ==
'\n')
647 || next [0] ==
';') {
653 next_tok.
name.push_back (*next++);
661 next_tok.
token = process_token (next_tok.
name.c_str ());
670 while (
' ' == *next ||
'\t' == *next) {
677 "unterminated statement");
687 context_->
line_.c_str () + context_->
line_.size ();
715 "expected the escape character ('%c'), got \"%s\"\n",
718 unsigned long value = 0;
720 for (
const char *
s = esc; ; ) {
723 const char *basename =
"octal";
727 case 'd': ++
s;
base = 10; basename =
"decimal";
break;
728 case 'x': ++
s;
base = 16; basename =
"hexadecimal";
break;
731 case '0':
case '1':
case '2':
case '3':
732 case '4':
case '5':
case '6':
case '7':
737 "one of { 'o', 'd', 'x' } expected following "
738 "the escape character: %s\n", esc);
743 const unsigned long byte = std::strtoul (
s, &
end,
base);
753 "%s constant expected: %s\n", basename, esc);
757 "%s byte value must be in the range [0, %d]: %s\n",
765 if (**
pend != escape || !multi)
#define _RWSTD_CONST_CAST(T, x)
void open(std::string, char='#', char='\\')
unsigned long convert_escape(const char *, const char **=0, bool=false) const
@ tok_reorder_section_end
bool issue_diag(int type, bool, const Scanner::token_t *token, const char *fmt,...)
ScannerContext(const char *, char='#', char='\\')