xref: /aosp_15_r20/frameworks/rs/script_api/Utilities.cpp (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
1*e1eccf28SAndroid Build Coastguard Worker /*
2*e1eccf28SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*e1eccf28SAndroid Build Coastguard Worker  *
4*e1eccf28SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e1eccf28SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e1eccf28SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e1eccf28SAndroid Build Coastguard Worker  *
8*e1eccf28SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*e1eccf28SAndroid Build Coastguard Worker  *
10*e1eccf28SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e1eccf28SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e1eccf28SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1eccf28SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e1eccf28SAndroid Build Coastguard Worker  * limitations under the License.
15*e1eccf28SAndroid Build Coastguard Worker  */
16*e1eccf28SAndroid Build Coastguard Worker 
17*e1eccf28SAndroid Build Coastguard Worker #include <algorithm>
18*e1eccf28SAndroid Build Coastguard Worker #include <iostream>
19*e1eccf28SAndroid Build Coastguard Worker #include <sstream>
20*e1eccf28SAndroid Build Coastguard Worker 
21*e1eccf28SAndroid Build Coastguard Worker #include "Utilities.h"
22*e1eccf28SAndroid Build Coastguard Worker 
23*e1eccf28SAndroid Build Coastguard Worker using namespace std;
24*e1eccf28SAndroid Build Coastguard Worker 
25*e1eccf28SAndroid Build Coastguard Worker const char LEGAL_NOTICE[] =
26*e1eccf28SAndroid Build Coastguard Worker             "/*\n"
27*e1eccf28SAndroid Build Coastguard Worker             " * Copyright (C) 2016 The Android Open Source Project\n"
28*e1eccf28SAndroid Build Coastguard Worker             " *\n"
29*e1eccf28SAndroid Build Coastguard Worker             " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
30*e1eccf28SAndroid Build Coastguard Worker             " * you may not use this file except in compliance with the License.\n"
31*e1eccf28SAndroid Build Coastguard Worker             " * You may obtain a copy of the License at\n"
32*e1eccf28SAndroid Build Coastguard Worker             " *\n"
33*e1eccf28SAndroid Build Coastguard Worker             " *      http://www.apache.org/licenses/LICENSE-2.0\n"
34*e1eccf28SAndroid Build Coastguard Worker             " *\n"
35*e1eccf28SAndroid Build Coastguard Worker             " * Unless required by applicable law or agreed to in writing, software\n"
36*e1eccf28SAndroid Build Coastguard Worker             " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
37*e1eccf28SAndroid Build Coastguard Worker             " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
38*e1eccf28SAndroid Build Coastguard Worker             " * See the License for the specific language governing permissions and\n"
39*e1eccf28SAndroid Build Coastguard Worker             " * limitations under the License.\n"
40*e1eccf28SAndroid Build Coastguard Worker             " */\n\n";
41*e1eccf28SAndroid Build Coastguard Worker 
42*e1eccf28SAndroid Build Coastguard Worker const char AUTO_GENERATED_WARNING[] =
43*e1eccf28SAndroid Build Coastguard Worker             "Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.";
44*e1eccf28SAndroid Build Coastguard Worker 
capitalize(const string & source)45*e1eccf28SAndroid Build Coastguard Worker string capitalize(const string& source) {
46*e1eccf28SAndroid Build Coastguard Worker     int length = source.length();
47*e1eccf28SAndroid Build Coastguard Worker     string result;
48*e1eccf28SAndroid Build Coastguard Worker     bool capitalize = true;
49*e1eccf28SAndroid Build Coastguard Worker     for (int s = 0; s < length; s++) {
50*e1eccf28SAndroid Build Coastguard Worker         if (source[s] == '_') {
51*e1eccf28SAndroid Build Coastguard Worker             capitalize = true;
52*e1eccf28SAndroid Build Coastguard Worker         } else if (capitalize) {
53*e1eccf28SAndroid Build Coastguard Worker             result += toupper(source[s]);
54*e1eccf28SAndroid Build Coastguard Worker             capitalize = false;
55*e1eccf28SAndroid Build Coastguard Worker         } else {
56*e1eccf28SAndroid Build Coastguard Worker             result += source[s];
57*e1eccf28SAndroid Build Coastguard Worker         }
58*e1eccf28SAndroid Build Coastguard Worker     }
59*e1eccf28SAndroid Build Coastguard Worker     return result;
60*e1eccf28SAndroid Build Coastguard Worker }
61*e1eccf28SAndroid Build Coastguard Worker 
trimSpaces(string * s)62*e1eccf28SAndroid Build Coastguard Worker void trimSpaces(string* s) {
63*e1eccf28SAndroid Build Coastguard Worker     const size_t end = s->find_last_not_of(" ");
64*e1eccf28SAndroid Build Coastguard Worker     if (end == string::npos) {
65*e1eccf28SAndroid Build Coastguard Worker         // All spaces
66*e1eccf28SAndroid Build Coastguard Worker         s->erase();
67*e1eccf28SAndroid Build Coastguard Worker         return;
68*e1eccf28SAndroid Build Coastguard Worker     } else {
69*e1eccf28SAndroid Build Coastguard Worker         s->erase(end + 1);
70*e1eccf28SAndroid Build Coastguard Worker     }
71*e1eccf28SAndroid Build Coastguard Worker     const size_t start = s->find_first_not_of(" ");
72*e1eccf28SAndroid Build Coastguard Worker     if (start > 0) {
73*e1eccf28SAndroid Build Coastguard Worker         s->erase(0, start);
74*e1eccf28SAndroid Build Coastguard Worker     }
75*e1eccf28SAndroid Build Coastguard Worker }
76*e1eccf28SAndroid Build Coastguard Worker 
stringReplace(string s,string match,string rep)77*e1eccf28SAndroid Build Coastguard Worker string stringReplace(string s, string match, string rep) {
78*e1eccf28SAndroid Build Coastguard Worker     while (1) {
79*e1eccf28SAndroid Build Coastguard Worker         // This is not efficient but we don't care, as this program runs very rarely.
80*e1eccf28SAndroid Build Coastguard Worker         size_t p = s.find(match);
81*e1eccf28SAndroid Build Coastguard Worker         if (p == string::npos) break;
82*e1eccf28SAndroid Build Coastguard Worker 
83*e1eccf28SAndroid Build Coastguard Worker         s.erase(p, match.size());
84*e1eccf28SAndroid Build Coastguard Worker         s.insert(p, rep);
85*e1eccf28SAndroid Build Coastguard Worker     }
86*e1eccf28SAndroid Build Coastguard Worker     return s;
87*e1eccf28SAndroid Build Coastguard Worker }
88*e1eccf28SAndroid Build Coastguard Worker 
charRemoved(char c,string * s)89*e1eccf28SAndroid Build Coastguard Worker bool charRemoved(char c, string* s) {
90*e1eccf28SAndroid Build Coastguard Worker     size_t p = s->find(c);
91*e1eccf28SAndroid Build Coastguard Worker     if (p != string::npos) {
92*e1eccf28SAndroid Build Coastguard Worker         s->erase(p, 1);
93*e1eccf28SAndroid Build Coastguard Worker         return true;
94*e1eccf28SAndroid Build Coastguard Worker     }
95*e1eccf28SAndroid Build Coastguard Worker     return false;
96*e1eccf28SAndroid Build Coastguard Worker }
97*e1eccf28SAndroid Build Coastguard Worker 
stripHtml(const string & html)98*e1eccf28SAndroid Build Coastguard Worker string stripHtml(const string& html) {
99*e1eccf28SAndroid Build Coastguard Worker     string in = stringReplace(html, "<li>", "- ");
100*e1eccf28SAndroid Build Coastguard Worker     string out;
101*e1eccf28SAndroid Build Coastguard Worker     for (size_t start = 0; start < in.size(); start++) {
102*e1eccf28SAndroid Build Coastguard Worker         size_t lt = in.find('<', start);
103*e1eccf28SAndroid Build Coastguard Worker         if (lt == string::npos) {
104*e1eccf28SAndroid Build Coastguard Worker             out += in.substr(start);
105*e1eccf28SAndroid Build Coastguard Worker             break;
106*e1eccf28SAndroid Build Coastguard Worker         }
107*e1eccf28SAndroid Build Coastguard Worker         out += in.substr(start, lt - start);
108*e1eccf28SAndroid Build Coastguard Worker         if (isalpha(in[lt + 1]) || in[lt + 1] == '/') {
109*e1eccf28SAndroid Build Coastguard Worker             // It's an HTML tag.  Search for the end.
110*e1eccf28SAndroid Build Coastguard Worker             start = in.find('>', lt + 1);
111*e1eccf28SAndroid Build Coastguard Worker             if (start == string::npos) {
112*e1eccf28SAndroid Build Coastguard Worker                 break;
113*e1eccf28SAndroid Build Coastguard Worker             }
114*e1eccf28SAndroid Build Coastguard Worker         } else {
115*e1eccf28SAndroid Build Coastguard Worker             out += '<';
116*e1eccf28SAndroid Build Coastguard Worker         }
117*e1eccf28SAndroid Build Coastguard Worker     }
118*e1eccf28SAndroid Build Coastguard Worker     out = stringReplace(out, "&gt;", ">");
119*e1eccf28SAndroid Build Coastguard Worker     out = stringReplace(out, "&lt;", "<");
120*e1eccf28SAndroid Build Coastguard Worker     out = stringReplace(out, "&nbsp;", " ");
121*e1eccf28SAndroid Build Coastguard Worker     out = stringReplace(out, "&amp;", "&");
122*e1eccf28SAndroid Build Coastguard Worker     return out;
123*e1eccf28SAndroid Build Coastguard Worker }
124*e1eccf28SAndroid Build Coastguard Worker 
hashString(const string & s)125*e1eccf28SAndroid Build Coastguard Worker string hashString(const string& s) {
126*e1eccf28SAndroid Build Coastguard Worker     long hash = 0;
127*e1eccf28SAndroid Build Coastguard Worker     for (size_t i = 0; i < s.length(); i++) {
128*e1eccf28SAndroid Build Coastguard Worker         hash = hash * 43 + s[i];
129*e1eccf28SAndroid Build Coastguard Worker     }
130*e1eccf28SAndroid Build Coastguard Worker     stringstream stream;
131*e1eccf28SAndroid Build Coastguard Worker     stream << "0x" << std::hex << hash << "l";
132*e1eccf28SAndroid Build Coastguard Worker     return stream.str();
133*e1eccf28SAndroid Build Coastguard Worker }
134*e1eccf28SAndroid Build Coastguard Worker 
testAndSet(const string & flag,set<string> * set)135*e1eccf28SAndroid Build Coastguard Worker bool testAndSet(const string& flag, set<string>* set) {
136*e1eccf28SAndroid Build Coastguard Worker     if (set->find(flag) == set->end()) {
137*e1eccf28SAndroid Build Coastguard Worker         set->insert(flag);
138*e1eccf28SAndroid Build Coastguard Worker         return false;
139*e1eccf28SAndroid Build Coastguard Worker     }
140*e1eccf28SAndroid Build Coastguard Worker     return true;
141*e1eccf28SAndroid Build Coastguard Worker }
142*e1eccf28SAndroid Build Coastguard Worker 
maxDoubleForInteger(int numberOfIntegerBits,int mantissaSize)143*e1eccf28SAndroid Build Coastguard Worker double maxDoubleForInteger(int numberOfIntegerBits, int mantissaSize) {
144*e1eccf28SAndroid Build Coastguard Worker     /* Double has only 52 bits of precision (53 implied). So for longs, we want
145*e1eccf28SAndroid Build Coastguard Worker      * to create smaller values to avoid a round up.  Same for floats and halfs.
146*e1eccf28SAndroid Build Coastguard Worker      */
147*e1eccf28SAndroid Build Coastguard Worker     int lowZeroBits = max(0, numberOfIntegerBits - mantissaSize);
148*e1eccf28SAndroid Build Coastguard Worker     uint64_t l = (0xffffffffffffffff >> (64 - numberOfIntegerBits + lowZeroBits))
149*e1eccf28SAndroid Build Coastguard Worker                  << lowZeroBits;
150*e1eccf28SAndroid Build Coastguard Worker     return (double)l;
151*e1eccf28SAndroid Build Coastguard Worker }
152*e1eccf28SAndroid Build Coastguard Worker 
153*e1eccf28SAndroid Build Coastguard Worker // Add the value to the stream, prefixed with a ", " if needed.
addCommaSeparated(const string & value,ostringstream * stream,bool * needComma)154*e1eccf28SAndroid Build Coastguard Worker static void addCommaSeparated(const string& value, ostringstream* stream, bool* needComma) {
155*e1eccf28SAndroid Build Coastguard Worker     if (value.empty()) {
156*e1eccf28SAndroid Build Coastguard Worker         return;
157*e1eccf28SAndroid Build Coastguard Worker     }
158*e1eccf28SAndroid Build Coastguard Worker     if (*needComma) {
159*e1eccf28SAndroid Build Coastguard Worker         *stream << ", ";
160*e1eccf28SAndroid Build Coastguard Worker     }
161*e1eccf28SAndroid Build Coastguard Worker     *stream << value;
162*e1eccf28SAndroid Build Coastguard Worker     *needComma = true;
163*e1eccf28SAndroid Build Coastguard Worker }
164*e1eccf28SAndroid Build Coastguard Worker 
makeAttributeTag(const string & userAttribute,const string & additionalAttribute,unsigned int deprecatedApiLevel,const string & deprecatedMessage)165*e1eccf28SAndroid Build Coastguard Worker string makeAttributeTag(const string& userAttribute, const string& additionalAttribute,
166*e1eccf28SAndroid Build Coastguard Worker                         unsigned int deprecatedApiLevel, const string& deprecatedMessage) {
167*e1eccf28SAndroid Build Coastguard Worker     ostringstream stream;
168*e1eccf28SAndroid Build Coastguard Worker     bool needComma = false;
169*e1eccf28SAndroid Build Coastguard Worker     if (userAttribute[0] == '=') {
170*e1eccf28SAndroid Build Coastguard Worker         /* If starts with an equal, we don't automatically add additionalAttribute.
171*e1eccf28SAndroid Build Coastguard Worker          * This is because of the error we made defining rsUnpackColor8888().
172*e1eccf28SAndroid Build Coastguard Worker          */
173*e1eccf28SAndroid Build Coastguard Worker         addCommaSeparated(userAttribute.substr(1), &stream, &needComma);
174*e1eccf28SAndroid Build Coastguard Worker     } else {
175*e1eccf28SAndroid Build Coastguard Worker         addCommaSeparated(userAttribute, &stream, &needComma);
176*e1eccf28SAndroid Build Coastguard Worker         addCommaSeparated(additionalAttribute, &stream, &needComma);
177*e1eccf28SAndroid Build Coastguard Worker     }
178*e1eccf28SAndroid Build Coastguard Worker     if (deprecatedApiLevel > 0) {
179*e1eccf28SAndroid Build Coastguard Worker         stream << "\n#if (defined(RS_VERSION) && (RS_VERSION >= " << deprecatedApiLevel << "))\n";
180*e1eccf28SAndroid Build Coastguard Worker         addCommaSeparated("deprecated", &stream, &needComma);
181*e1eccf28SAndroid Build Coastguard Worker         if (!deprecatedMessage.empty()) {
182*e1eccf28SAndroid Build Coastguard Worker             // Remove any @ that's used for generating documentation cross references.
183*e1eccf28SAndroid Build Coastguard Worker             string s = deprecatedMessage;
184*e1eccf28SAndroid Build Coastguard Worker             s.erase(std::remove(s.begin(), s.end(), '@'), s.end());
185*e1eccf28SAndroid Build Coastguard Worker             stream << "(\"" << s << "\")";
186*e1eccf28SAndroid Build Coastguard Worker         }
187*e1eccf28SAndroid Build Coastguard Worker         stream << "\n#endif\n";
188*e1eccf28SAndroid Build Coastguard Worker     }
189*e1eccf28SAndroid Build Coastguard Worker     if (stream.tellp() == 0) {
190*e1eccf28SAndroid Build Coastguard Worker         return "";
191*e1eccf28SAndroid Build Coastguard Worker     }
192*e1eccf28SAndroid Build Coastguard Worker     return " __attribute__((" + stream.str() + "))";
193*e1eccf28SAndroid Build Coastguard Worker }
194*e1eccf28SAndroid Build Coastguard Worker 
195*e1eccf28SAndroid Build Coastguard Worker // Opens the stream.  Reports an error if it can't.
start(const string & directory,const string & name)196*e1eccf28SAndroid Build Coastguard Worker bool GeneratedFile::start(const string& directory, const string& name) {
197*e1eccf28SAndroid Build Coastguard Worker     const string path = directory + "/" + name;
198*e1eccf28SAndroid Build Coastguard Worker     open(path.c_str(), ios::out | ios::trunc);
199*e1eccf28SAndroid Build Coastguard Worker     if (!is_open()) {
200*e1eccf28SAndroid Build Coastguard Worker         cerr << "Error.  Can't open the output file: " << path << "\n";
201*e1eccf28SAndroid Build Coastguard Worker         return false;
202*e1eccf28SAndroid Build Coastguard Worker     }
203*e1eccf28SAndroid Build Coastguard Worker     return true;
204*e1eccf28SAndroid Build Coastguard Worker }
205*e1eccf28SAndroid Build Coastguard Worker 
writeNotices()206*e1eccf28SAndroid Build Coastguard Worker void GeneratedFile::writeNotices() {
207*e1eccf28SAndroid Build Coastguard Worker     *this << LEGAL_NOTICE;
208*e1eccf28SAndroid Build Coastguard Worker     *this << "// " << AUTO_GENERATED_WARNING << "\n\n";
209*e1eccf28SAndroid Build Coastguard Worker }
210*e1eccf28SAndroid Build Coastguard Worker 
increaseIndent()211*e1eccf28SAndroid Build Coastguard Worker void GeneratedFile::increaseIndent() {
212*e1eccf28SAndroid Build Coastguard Worker     mIndent.append(string(TAB_SIZE, ' '));
213*e1eccf28SAndroid Build Coastguard Worker }
214*e1eccf28SAndroid Build Coastguard Worker 
decreaseIndent()215*e1eccf28SAndroid Build Coastguard Worker void GeneratedFile::decreaseIndent() {
216*e1eccf28SAndroid Build Coastguard Worker     mIndent.erase(0, TAB_SIZE);
217*e1eccf28SAndroid Build Coastguard Worker }
218