This repository has been archived by the owner on Apr 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathStringUtils.cpp
executable file
·206 lines (167 loc) · 7.39 KB
/
StringUtils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
//=====================================================================
// Copyright 2007-2016 (c), Advanced Micro Devices, Inc. All rights reserved.
//
/// \author AMD Developer Tools Team
/// \file StringUtils.cpp
///
//=====================================================================
//=====================================================================
// $Id: //devtools/main/Common/Src/ShaderUtils/StringUtils.cpp#4 $
//
// Last checkin: $DateTime: 2016/04/18 06:01:26 $
// Last edited by: $Author: AMD Developer Tools Team
//=====================================================================
#include <cstring>
#include "StringUtils.h"
size_t StringUtils::SplitStringIntoLines(const std::string& strString, std::vector<std::string>& vLines, bool bTrimLines)
{
size_t nLineBegin = 0;
size_t nLineEnd = 0;
do
{
nLineEnd = strString.find('\n', nLineBegin);
std::string strLine(strString, nLineBegin, nLineEnd - nLineBegin);
if (bTrimLines)
{
TrimString(strLine);
}
vLines.push_back(strLine);
nLineBegin = nLineEnd + 1;
}
while (nLineEnd != std::string::npos);
return vLines.size();
}
void StringUtils::TrimString(std::string& strString)
{
const char* pszWhiteSpace = " \t\r\n";
size_t nStartPos = strString.find_first_not_of(pszWhiteSpace);
if ((nStartPos == std::string::npos))
{
strString = "";
}
else
{
size_t nEndPos = strString.find_last_not_of(pszWhiteSpace);
strString = strString.substr(nStartPos, nEndPos + 1);
}
}
size_t StringUtils::FindFunctionEntryInString(const std::string& strFunctionEntry, const std::string& strSource)
{
std::vector<std::string> lines;
size_t nLines = StringUtils::SplitStringIntoLines(strSource, lines);
int scopeLevel = 0;
// The algorithm to find the function definition goes as follows:
// 1. Scan the source line by line to find the function name.
// 2. If the function name is found, this line contains the function definition only if
// the scope level is equal to 0 (at the top level).
// 3. Use the open and closing brackets to compute the scope level.
// 4. Skip C and C++ comments as necessary.
// Note we don't take account for preprocessing yet.
bool bCommentLine = false;
for (size_t i = 0; i < nLines; ++i)
{
std::string line(lines[ i ]);
//-------------------- HANDLING C comment blocks -----------------------------
size_t foundEndComment = line.find("*/");
if (bCommentLine && std::string::npos != foundEndComment)
{
bCommentLine = false;
line.erase(0, foundEndComment + 2); // chop out the string until the */ tag
}
if (bCommentLine)
{
// this entire line is part of the C comment line, skip it
continue;
}
// let's chop out the substring in between all C comment tags(/* and */)
bool bLoop = true;
while (bLoop)
{
bLoop = false;
size_t foundStartComment = line.find("/*");
if (std::string::npos != foundStartComment)
{
foundEndComment = line.find("*/", foundStartComment + 2);
if (std::string::npos != foundEndComment)
{
// chop out the string from /* till */ tags
line.erase(foundStartComment, foundEndComment - foundStartComment + 2);
bLoop = true;
}
else
{
bCommentLine = true;
// chop out the string from the /* tag till the end of the line
line.erase(foundStartComment);
}
}
}
//--------------- END OF HANDLING C comment blocks ---------------------------
size_t foundComment = line.find("//");
if (std::string::npos != foundComment)
{
// chop out the C++ comment block
line.erase(foundComment);
}
if (line.empty())
{
continue;
}
size_t startPos = 0;
size_t foundFunction = std::string::npos;
// loop over the line once for each time the func name appears.
// here's an exmaple of a problematic line: "HS_CONTROL_POINT_OUTPUT HS( InputPatch<VS_OUTPUT_HS_INPUT, 3> inputPatch,"
while ((foundFunction = line.find(strFunctionEntry, startPos)) != std::string::npos)
{
// the func name was found, but it may be a substring of a different string
// need to make sure the character before and after are expected // preceeding character:
if (((foundFunction == 0) || // func name is the first word on the line OR
(foundFunction > 0 && line.at(foundFunction - 1) == ' ')) && // preceding character is a space
// following character:
((line.length() == foundFunction + strFunctionEntry.length()) || // function name ends at end of line OR
(strchr(" (", line.at(foundFunction + strFunctionEntry.length())) != NULL))) // char after func name is space or '('
{
// make sure we calculate the scope level prior to the function name at the same line
size_t foundOpenBracket = line.find_first_of("{", startPos);
// count the open bracket prior to the function name and update the scope level
while (std::string::npos != foundOpenBracket &&
foundOpenBracket < foundFunction)
{
++scopeLevel;
foundOpenBracket = line.find_first_of("{", foundOpenBracket + 1);
}
size_t foundCloseBracket = line.find_first_of("}", startPos);
// count the closing bracket prior to the function name and update the scope level
while (std::string::npos != foundCloseBracket &&
foundCloseBracket < foundFunction)
{
--scopeLevel;
foundCloseBracket = line.find_first_of("}", foundCloseBracket + 1);
}
// the function name is at the top level so it must be the function definition and not a call to the function
if (0 == scopeLevel)
{
// this is the function definition, because it is at the top scope level
return (i + 1);
}
}
// update the start position so we don't match the same funcname instance again
startPos = foundFunction + 1;
}
size_t foundOpenBracket = line.find_first_of("{", startPos);
// count the open bracket and update the scope level
while (std::string::npos != foundOpenBracket)
{
++scopeLevel;
foundOpenBracket = line.find_first_of("{", foundOpenBracket + 1);
}
size_t foundCloseBracket = line.find_first_of("}", startPos);
// count the closing bracket and update the scope level
while (std::string::npos != foundCloseBracket)
{
--scopeLevel;
foundCloseBracket = line.find_first_of("}", foundCloseBracket + 1);
}
}
return 0;
}