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