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 64 RSReflectionBase::RSReflectionBase(const RSContext *con) 65 : mVerbose(true) { 66 mRSContext = con; 67 mLicenseNote = gApacheLicenseNote; 68 69 } 70 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 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 111 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 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 129 void RSReflectionBase::write(const std::stringstream &t) { 130 mText.push_back(mIndent + t.str()); 131 } 132 133 134 void RSReflectionBase::incIndent() { 135 mIndent.append(" "); 136 } 137 138 void RSReflectionBase::decIndent() { 139 mIndent.erase(0, 4); 140 } 141 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 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 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 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