coan  6.0.1
A C/C++ Configuration Analyzer
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
identifier.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2007-2013 Mike Kinghan, imk@burroingroingjoing.com *
3  * All rights reserved. *
4  * *
5  * Contributed originally by Mike Kinghan, imk@burroingroingjoing.com *
6  * *
7  * Redistribution and use in source and binary forms, with or without *
8  * modification, are permitted provided that the following conditions *
9  * are met: *
10  * *
11  * Redistributions of source code must retain the above copyright *
12  * notice, this list of conditions and the following disclaimer. *
13  * *
14  * Redistributions in binary form must reproduce the above copyright *
15  * notice, this list of conditions and the following disclaimer in the *
16  * documentation and/or other materials provided with the distribution. *
17  * *
18  * Neither the name of Mike Kinghan nor the names of its contributors *
19  * may be used to endorse or promote products derived from this software *
20  * without specific prior written permission. *
21  * *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *
29  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED *
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,*
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF *
32  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
33  * DAMAGE. *
34  * *
35  **************************************************************************/
36 
37 #include "identifier.h"
38 #include "parse_buffer.h"
39 #include "canonical.h"
40 #include "diagnostic.h"
41 #include <cstring>
42 
47 
49 using namespace std;
50 
51 namespace identifier {
52 
53 template<class CharSeq>
54 string find_any_in(chewer<CharSeq> & chew, size_t & off)
55 {
57  for(chew(literal_space); chew; chew(+1,literal_space)) {
58  if (is_start_char(*chew)) {
59  off = size_t(chew);
60  string name(1,*chew);
61  for (++chew; chew && is_valid_char(*chew); name += *chew,++chew) {}
62  return name;
63  }
64  }
65  return string();
66 }
67 
68 template
69 string find_any_in(chewer<string> &, size_t &);
70 template
71 string find_any_in(chewer<parse_buffer> &, size_t &);
72 
73 template<class CharSeq>
74 size_t
76  string const & id,
77  chewer<CharSeq> & chew)
78 {
80  size_t len = id.length();
81  char prior = 0;
82  for(chew(literal_space); chew;
83  prior = *chew,chew(+1,literal_space)) {
84  if (!strncmp(&*chew,id.data(),len)) {
85  size_t where = size_t(chew);
86  chew += len;
87  if (!is_valid_char(prior) &&
88  (!chew || !is_valid_char(*chew))) {
89  return where;
90  }
91  --chew;
92  }
93  }
94  return string::npos;
95 }
96 
97 template
98 size_t find_first_in(string const &, chewer<string> &);
99 template
100 size_t find_first_in(string const &, chewer<parse_buffer> &);
101 
102 template<class CharSeq>
103 string read(chewer<CharSeq> & chew)
104 {
106  string symname = canonical<symbol>(chew);
107  if (!symname.length()) {
109  "Identifier needed instead of \""
110  << chew.buf().substr(size_t(chew)) << '\"' << emit();
111  }
112  return symname;
113 }
114 
115 template
116 string read(chewer<string> &);
117 template
118 string read(chewer<parse_buffer> &);
119 
120 } //namespace identifier
121 
123 
124 // EOF
template struct traits::is_random_access_char_sequence<T> exports a static const boolean member value...
Definition: traits.h:166
bool is_start_char(char ch)
Say whether a character can be the first of an identifier.
Definition: identifier.h:52
std::string find_any_in(chewer< CharSeq > &chew, size_t &off)
Search a terminal portion of a CharSeq for any identifier.
size_t find_first_in(std::string const &id, chewer< CharSeq > &chew)
Find the first occurrence of an identifier within a terminal segment a CharSeq
sequence_type & buf()
Get a [const] reference to the associated sequence_type
Definition: chew.h:413
std::string read(chewer< CharSeq > &chew)
Read an identifier from an chewer<CharSeq>
chew_mode::name const name
An exemplar chew_mode::name
Definition: chew.h:229
The tag class is inserted in a diagnostic_base to tell it to emit itself.
Definition: diagnostic.h:77
bool is_valid_char(char ch)
Say whether a character can occur in an identifier.
Definition: identifier.h:57
`template struct chewer<CharSeq> is a cursor-like type that is associated with a character-sequence t...
Definition: chew.h:248
error_msg< 13 > error_not_identifier
Report that a valid preprocessor identifier was not found where required.
Definition: diagnostic.h:750
template class canonical<What> encapsulates the canonical representation of values of type What...
Definition: canonical.h:82
chew_mode::literal_space const literal_space
An exemplar chew_mode::literal_space
Definition: chew.h:231