• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012, 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 <sys/stat.h>
18 
19 #include <cstdarg>
20 #include <cctype>
21 
22 #include <algorithm>
23 #include <limits>
24 #include <sstream>
25 #include <string>
26 #include <utility>
27 
28 #include "os_sep.h"
29 #include "slang_rs_context.h"
30 #include "slang_rs_export_var.h"
31 #include "slang_rs_export_foreach.h"
32 #include "slang_rs_export_func.h"
33 #include "slang_rs_reflect_utils.h"
34 #include "slang_version.h"
35 #include "slang_utils.h"
36 
37 #include "slang_rs_reflection_base.h"
38 
39 
40 
41 using namespace std;
42 
43 namespace slang {
44 
45 static const char *const gApacheLicenseNote =
46 "/*\n"
47 " * Copyright (C) 2012 The Android Open Source Project\n"
48 " *\n"
49 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
50 " * you may not use this file except in compliance with the License.\n"
51 " * You may obtain a copy of the License at\n"
52 " *\n"
53 " *      http://www.apache.org/licenses/LICENSE-2.0\n"
54 " *\n"
55 " * Unless required by applicable law or agreed to in writing, software\n"
56 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
57 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
58 " * See the License for the specific language governing permissions and\n"
59 " * limitations under the License.\n"
60 " */\n"
61 "\n";
62 
63 
RSReflectionBase(const RSContext * con)64 RSReflectionBase::RSReflectionBase(const RSContext *con)
65   : mVerbose(true) {
66   mRSContext = con;
67   mLicenseNote = gApacheLicenseNote;
68 
69 }
70 
~RSReflectionBase()71 RSReflectionBase::~RSReflectionBase() {
72 
73 }
74 
75 /*
76 bool RSReflectionBase::openFile(const string &name, string &errorMsg) {
77     if(!mUseStdout) {
78         mOF.clear();
79         if(!SlangUtils::CreateDirectoryWithParents(mOutputPath, &errorMsg)) {
80             return false;
81         }
82 
83         string cf(mOutputPath + OS_PATH_SEPARATOR_STR + name);
84         mOF.open(cf.c_str());
85         if(!mOF.good()) {
86             errorMsg = "failed to open file '" + cf + "' for write";
87             return false;
88         }
89     }
90     return true;
91 }
92 */
93 
startFile(const string & filename)94 void RSReflectionBase::startFile(const string &filename) {
95   if(mVerbose) {
96     printf("Generating %s\n", filename.c_str());
97   }
98 
99   // License
100   write(mLicenseNote);
101 
102   // Notice of generated file
103   write("/*");
104   write(" * This file is auto-generated. DO NOT MODIFY!");
105   write(" * The source Renderscript file: " + mInputFileName);
106   write(" */");
107   write("");
108 }
109 
110 // remove path plus .rs from filename to generate class name
stripRS(const string & s) const111 string RSReflectionBase::stripRS(const string &s) const {
112   string tmp(s);
113   size_t pos = tmp.rfind(".rs");
114   if(pos != string::npos) {
115     tmp.erase(pos);
116   }
117   pos = tmp.rfind("/");
118   if (pos != string::npos) {
119     tmp.erase(0, pos+1);
120   }
121   return tmp;
122 }
123 
write(const std::string & t)124 void RSReflectionBase::write(const std::string &t) {
125   //printf("%s%s\n", mIndent.c_str(), t.c_str());
126   mText.push_back(mIndent + t);
127 }
128 
write(const std::stringstream & t)129 void RSReflectionBase::write(const std::stringstream &t) {
130   mText.push_back(mIndent + t.str());
131 }
132 
133 
incIndent()134 void RSReflectionBase::incIndent() {
135   mIndent.append("    ");
136 }
137 
decIndent()138 void RSReflectionBase::decIndent() {
139   mIndent.erase(0, 4);
140 }
141 
writeFile(const string & filename,const vector<string> & txt)142 bool RSReflectionBase::writeFile(const string &filename, const vector< string > &txt) {
143   FILE *pfin = fopen((mOutputPath + filename).c_str(), "wt");
144   if (pfin == NULL) {
145     fprintf(stderr, "Error: could not write file %s\n", filename.c_str());
146     return false;
147   }
148 
149   for(size_t ct=0; ct < txt.size(); ct++) {
150     fprintf(pfin, "%s\n", txt[ct].c_str());
151   }
152   fclose(pfin);
153   return true;
154 }
155 
156 
genInitValue(const clang::APValue & Val,bool asBool)157 string RSReflectionBase::genInitValue(const clang::APValue &Val, bool asBool) {
158   stringstream tmp;
159   switch (Val.getKind()) {
160     case clang::APValue::Int: {
161       llvm::APInt api = Val.getInt();
162       if(asBool) {
163         tmp << ((api.getSExtValue() == 0) ? "false" : "true");
164       } else {
165         // TODO: Handle unsigned possibly for C++ API.
166         tmp << api.getSExtValue();
167         if (api.getBitWidth() > 32) {
168           tmp << "L";
169         }
170       }
171       break;
172     }
173 
174     case clang::APValue::Float: {
175       llvm::APFloat apf = Val.getFloat();
176       llvm::SmallString<30> s;
177       apf.toString(s);
178       tmp << s.c_str();
179       if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) {
180         if (s.count('.') == 0) {
181           tmp << ".f";
182         } else {
183           tmp << "f";
184         }
185       }
186       break;
187     }
188 
189     case clang::APValue::ComplexInt:
190     case clang::APValue::ComplexFloat:
191     case clang::APValue::LValue:
192     case clang::APValue::Vector: {
193       slangAssert(false && "Primitive type cannot have such kind of initializer");
194       break;
195     }
196 
197     default: {
198       slangAssert(false && "Unknown kind of initializer");
199     }
200   }
201   return tmp.str();
202 }
203 
addTypeNameForElement(const std::string & TypeName)204 bool RSReflectionBase::addTypeNameForElement(
205     const std::string &TypeName) {
206   if (mTypesToCheck.find(TypeName) == mTypesToCheck.end()) {
207     mTypesToCheck.insert(TypeName);
208     return true;
209   } else {
210     return false;
211   }
212 }
213 
getVectorAccessor(unsigned Index)214 const char *RSReflectionBase::getVectorAccessor(unsigned Index) {
215   static const char *VectorAccessorMap[] = {
216     /* 0 */ "x",
217     /* 1 */ "y",
218     /* 2 */ "z",
219     /* 3 */ "w",
220   };
221 
222   slangAssert((Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) &&
223               "Out-of-bound index to access vector member");
224 
225   return VectorAccessorMap[Index];
226 }
227 
228 }
229