coan  6.0.1
A C/C++ Configuration Analyzer
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
unexplained_expansion.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 #include "unexplained_expansion.h"
37 #include "diagnostic.h"
38 
43 
45 using namespace std;
46 
48 {
49  unsigned edits = 0;
50  if (args()) {
51  for ( auto i = seek_expandable_arg();
52  i < args().size(); ++_cur_arg,
53  i = seek_expandable_arg()) {
54  edits += expand(args()[i]);
55  }
56  edits += substitute();
57  } else if (!callee()->defn()) {
58  _value = "0";
59  ++edits;
60  } else if (callee()->defn()->empty()) {
61  _value = "";
62  ++edits;
63  }
64  else {
65  _value = callee()->format()->str();
66  ++edits;
67  }
68  return edits += expand(_value);
69 }
70 
71 unsigned unexplained_expansion::expand(string & str)
72 {
73  unsigned edits = 0;
74  symbol::locator sym;
75  size_t off;
76  chewer<string> chew(chew_mode::plaintext,str);
77  for ( ;(sym = symbol::find_any_in(chew,off)),sym; chew.sync()) {
78  reference ref(sym,chew,this);
79  if (!sym->configured() && !sym->in_progress()) {
80  chew = off + sym->id().length();
81  continue;
82  }
83  unexplained_expansion e(ref);
84  try {
85  if (!e.expand()) {
86  continue;
87  }
88  }
89  catch(expansion_base const & eb) {
91  << "Macro expansion of \"" << eb.reference::invocation()
92  << "\" abandoned. Will exceed max expansion size "
93  << max_expansion_size() << " bytes" << emit();
94  throw_self();
95  }
96  size_t len = size_t(chew) - off;
97  if (len && str.compare(off,len,e.value()) == 0) {
98  continue;
99  }
100  edit(str,off,size_t(chew) - off,e.value());
101  ++edits;
102  edits += edit_buf(str,e,off + e.invocation().size());
103  edits += edit_trailing_args(e,_cur_arg + 1);
104  }
105  return edits;
106 }
107 
109 
110 //EOF
struct unexplained_expansion encapsulates macro-expansion of a reference where the --explain option i...
struct symbol::locator encapsulates a symbol table entry.
Definition: symbol.h:79
bool in_progress() const
Say whether a determination the symbol's state is in progress.
Definition: symbol.h:297
static locator find_any_in(chewer< CharSeq > &chew, size_t &off)
Search a terminal portion of a CharSeq for any known symbol name.
std::string const & id() const
Get the name of the symbol.
Definition: symbol.h:172
bool configured() const
Say whether the symbol is configured.
Definition: symbol.h:258
warning_msg< 35 > warning_incomplete_expansion
Report a macro reference not fully expanded.
Definition: diagnostic.h:721
The tag class is inserted in a diagnostic_base to tell it to emit itself.
Definition: diagnostic.h:77
`template struct chewer<CharSeq> is a cursor-like type that is associated with a character-sequence t...
Definition: chew.h:248
struct expansion_base is an abstract base for classes that encapsulate a mode of macro-expansion of a...
unsigned expand() override
Perform the unexplained expansion of the reference.