μHAL (v2.6.5)
Part of the IPbus software repository
GccOutputCleaner.cpp
Go to the documentation of this file.
1 
2 /*
3 ---------------------------------------------------------------------------
4 
5  This file is part of uHAL.
6 
7  uHAL is a hardware access library and programming framework
8  originally developed for upgrades of the Level-1 trigger of the CMS
9  experiment at CERN.
10 
11  uHAL is free software: you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  uHAL is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with uHAL. If not, see <http://www.gnu.org/licenses/>.
23 
24 
25  Andrew Rose, Imperial College, London
26  email: awr01 <AT> imperial.ac.uk
27 
28  Marc Magrans de Abril, CERN
29  email: marc.magrans.de.abril <AT> cern.ch
30 
31 ---------------------------------------------------------------------------
32 */
33 
35 
36 #include <algorithm>
37 #include <sstream>
38 
39 
40 std::string GccOutputCleaner::SquareBracketStyle ( const uint32_t& aIndex )
41 {
42  std::stringstream lStr;
43  lStr << "[" << aIndex << "]";
44  return lStr.str();
45 }
46 
47 std::string GccOutputCleaner::HashStyle ( const uint32_t& aIndex )
48 {
49  std::stringstream lStr;
50  lStr << "#" << aIndex;
51  return lStr.str();
52 }
53 
54 std::string GccOutputCleaner::TStyle ( const uint32_t& aIndex )
55 {
56  std::stringstream lStr;
57  lStr << "T" << aIndex;
58  return lStr.str();
59 }
60 
61 GccOutputCleaner::GccOutputCleaner ( const uint32_t& aIndent , std::string ( *aStyling ) ( const uint32_t& ) ) : mTypes() , mIndent ( aIndent , ' ' ) , mStyling ( aStyling )
62 {
63  mTypes.reserve ( 256 );
64 }
65 
67 
68 
69 std::string GccOutputCleaner::operator() ( const std::string& aStr )
70 {
71  mTypes.clear();
72  // Helpful local variables
73  std::stringstream lStr;
74  RecursiveClean ( aStr.begin() , aStr.end() );
75  std::vector< std::string >::iterator lTypesIt ( mTypes.end() );
76  lStr << * ( --lTypesIt );
77 
78  while ( --lTypesIt >= mTypes.begin() )
79  {
80  lStr << "\n" << mIndent << ( *mStyling ) ( lTypesIt - mTypes.begin() ) << " = " << *lTypesIt;
81  }
82 
83  return lStr.str();
84 }
85 
86 
87 uint32_t GccOutputCleaner::RecursiveClean ( std::string::const_iterator aIt , std::string::const_iterator aEnd )
88 {
89  // Strip leading and trailing spaces
90  while ( * ( aEnd-1 ) == ' ' )
91  {
92  aEnd--;
93  }
94 
95  while ( *aIt == ' ' )
96  {
97  aIt++;
98  }
99 
100  // Helpful local variables
101  std::stringstream lStr;
102  std::string::const_iterator lStart;
103  uint32_t lCounter ( 0 );
104 
105  // Run the iteration
106  for ( ; aIt != aEnd ; ++aIt )
107  {
108  switch ( *aIt )
109  {
110  case '(' : // We are starting a function argument list
111  case '<' : // We are starting a new template child
112 
113  if ( lCounter++ == 0 )
114  {
115  lStart = aIt+1;
116  lStr << *aIt;
117  }
118 
119  break;
120  case ')' : // We are finishing function argument list
121  case '>' : // We are finishing template children
122 
123  if ( --lCounter == 0 )
124  {
125  if ( aIt - lStart > 1 )
126  {
127  lStr << " " << ( *mStyling ) ( RecursiveClean ( lStart, aIt ) ) << " ";
128  }
129 
130  lStr << *aIt;
131  }
132 
133  break;
134  case ',' :
135 
136  if ( lCounter == 1 ) // We have finished one template child or function argument and are about to start another
137  {
138  if ( aIt - lStart > 1 )
139  {
140  lStr << " " << ( *mStyling ) ( RecursiveClean ( lStart, aIt ) ) << " ";
141  }
142 
143  lStr << ",";
144  lStart = aIt+2;
145  }
146 
147  break;
148  case '*' :
149  case '&' :
150 
151  if ( lCounter == 1 ) // We have finished one template child and about to start another
152  {
153  lStr << " " << ( *mStyling ) ( RecursiveClean ( lStart, aIt ) ) << *aIt << " ";
154  lStart = aIt;
155  }
156 
157  break;
158  default: // We are a regular character
159 
160  if ( lCounter == 0 )
161  {
162  if ( ( *aIt != ' ' ) || ( aIt+1 == aEnd ) || ( * ( aIt+1 ) != ' ' ) ) // Reduce multiple spaces down to 1
163  {
164  lStr << *aIt;
165  }
166  }
167 
168  break;
169  }
170  }
171 
172  // If the string we have constructed is not in the list, add it, otherwise return the index into the vector.
173  std::string lTemp ( lStr.str() );
174  std::vector< std::string >::iterator lTypesIt = std::find ( mTypes.begin() , mTypes.end() , lTemp );
175 
176  if ( lTypesIt != mTypes.end() )
177  {
178  return lTypesIt - mTypes.begin();
179  }
180  else
181  {
182  mTypes.push_back ( lTemp );
183  return mTypes.size() -1;
184  }
185 }
186 
GccOutputCleaner(const uint32_t &aIndent=2, std::string(*aStyling)(const uint32_t &)=&GccOutputCleaner::SquareBracketStyle)
Constructor.
static std::string TStyle(const uint32_t &aIndex)
Prefix the type-substitution index with a T
std::vector< std::string > mTypes
A vector of known types, the position of which into this list becomes the substitution index...
std::string(* mStyling)(const uint32_t &)
The functor for styling the type-substitution index.
virtual ~GccOutputCleaner()
Destructor.
uint32_t RecursiveClean(std::string::const_iterator aIt, std::string::const_iterator aEnd)
Recursively perform sub-term extraction from the string.
static std::string HashStyle(const uint32_t &aIndex)
Prefix the type-substitution index with a #
std::string mIndent
The number of spaces by which to indent the lines.
std::string operator()(const std::string &aStr)
Functor implementation.
static std::string SquareBracketStyle(const uint32_t &aIndex)
Wrap the type-substitution index in square braces.