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