1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 2129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet * Copyright 2010-2014, The Android Open Source Project 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License. 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License. 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */ 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_reflect_utils.h" 183f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 193f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang#include <cstdio> 20b1980a2eedc56df92786afc291e00f26659a60adMike Lockwood#include <cstring> 21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <string> 22129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet#include <iomanip> 233f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 248c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang#include "llvm/ADT/StringRef.h" 253eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines#include "llvm/Support/FileSystem.h" 263eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines#include "llvm/Support/Path.h" 278c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang 288d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael#include "os_sep.h" 2944d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines#include "slang_assert.h" 303f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 313f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangnamespace slang { 323f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 333f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangusing std::string; 343f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 352ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstring RSSlangReflectUtils::GetFileNameStem(const char *fileName) { 362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet const char *dot = fileName + strlen(fileName); 372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet const char *slash = dot - 1; 382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet while (slash >= fileName) { 392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet if (*slash == OS_PATH_SEPARATOR) { 402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet break; 41dba3111408b307d8454830107ff61089ab7c5d6dYing Wang } 422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet if ((*slash == '.') && (*dot == 0)) { 432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet dot = slash; 442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet --slash; 462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet ++slash; 482ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return string(slash, dot - slash); 49dba3111408b307d8454830107ff61089ab7c5d6dYing Wang} 50dba3111408b307d8454830107ff61089ab7c5d6dYing Wang 512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstring RSSlangReflectUtils::ComputePackagedPath(const char *prefixPath, 522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet const char *packageName) { 532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet string packaged_path(prefixPath); 542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet if (!packaged_path.empty() && 552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet (packaged_path[packaged_path.length() - 1] != OS_PATH_SEPARATOR)) { 562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet packaged_path += OS_PATH_SEPARATOR_STR; 572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet size_t s = packaged_path.length(); 592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet packaged_path += packageName; 602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet while (s < packaged_path.length()) { 612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet if (packaged_path[s] == '.') { 622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet packaged_path[s] = OS_PATH_SEPARATOR; 633f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet ++s; 652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return packaged_path; 673f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 683f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 696315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrstatic string InternalFileNameConvert(const char *rsFileName, bool toLower) { 702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet const char *dot = rsFileName + strlen(rsFileName); 712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet const char *slash = dot - 1; 722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet while (slash >= rsFileName) { 732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet if (*slash == OS_PATH_SEPARATOR) { 742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet break; 752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet if ((*slash == '.') && (*dot == 0)) { 772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet dot = slash; 783f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet --slash; 802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet ++slash; 822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet char ret[256]; 832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet int i = 0; 842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet for (; (i < 255) && (slash < dot); ++slash) { 852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet if (isalnum(*slash) || *slash == '_') { 862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet if (toLower) { 872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet ret[i] = tolower(*slash); 882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } else { 892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet ret[i] = *slash; 902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet ++i; 923f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang } 932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet ret[i] = 0; 952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return string(ret); 963f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 973f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstd::string 992ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc BrouilletRSSlangReflectUtils::JavaClassNameFromRSFileName(const char *rsFileName) { 1002ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return InternalFileNameConvert(rsFileName, false); 1013f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 1023f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 103efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouilletstd::string RootNameFromRSFileName(const std::string &rsFileName) { 104efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet return InternalFileNameConvert(rsFileName.c_str(), false); 105efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet} 106efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet 1072ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstd::string 1082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc BrouilletRSSlangReflectUtils::BCFileNameFromRSFileName(const char *rsFileName) { 1092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return InternalFileNameConvert(rsFileName, true); 1103f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 1113f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 11244d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hinesstd::string RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName( 11344d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines const char *rsFileName) { 1142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet std::string tmp(InternalFileNameConvert(rsFileName, false)); 1152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return tmp.append("BitCode"); 11644d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines} 1170877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang 118129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletstatic bool GenerateAccessorMethod( 119129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet const RSSlangReflectUtils::BitCodeAccessorContext &context, 1209ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines int bitwidth, GeneratedFile &out) { 1212ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet // the prototype of the accessor method 1229ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines out.indent() << "// return byte array representation of the " << bitwidth 1239ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines << "-bit bitcode.\n"; 1249ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines out.indent() << "public static byte[] getBitCode" << bitwidth << "()"; 125129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.startBlock(); 1269ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines out.indent() << "return getBitCode" << bitwidth << "Internal();\n"; 127129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.endBlock(true); 1282ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return true; 1290877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang} 1300877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang 1310877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang// Java method size must not exceed 64k, 1320877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang// so we have to split the bitcode into multiple segments. 1339ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesstatic bool GenerateSegmentMethod(const char *buff, int blen, int bitwidth, 1349ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines int seg_num, GeneratedFile &out) { 1359ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines out.indent() << "private static byte[] getSegment" << bitwidth << "_" 1369ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines << seg_num << "()"; 137129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.startBlock(); 138129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.indent() << "byte[] data = {"; 139129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.increaseIndent(); 140129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 141129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet const int kEntriesPerLine = 16; 142129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet int position = kEntriesPerLine; // We start with a new line and indent. 143129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet for (int written = 0; written < blen; written++) { 144129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet if (++position >= kEntriesPerLine) { 145129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out << "\n"; 146129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.indent(); 147129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet position = 0; 148129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet } else { 149129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out << " "; 1500877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang } 151129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out << std::setw(4) << static_cast<int>(buff[written]) << ","; 1522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 153129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out << "\n"; 1540877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang 155129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.decreaseIndent(); 156129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.indent() << "};\n"; 157129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.indent() << "return data;\n"; 158129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.endBlock(); 1593f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang 1602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return true; 1610877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang} 1620877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang 1639ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesstatic bool GenerateJavaCodeAccessorMethodForBitwidth( 164129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet const RSSlangReflectUtils::BitCodeAccessorContext &context, 1659ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines int bitwidth, GeneratedFile &out) { 1669ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 1679ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines std::string filename(context.bc32FileName); 1689ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines if (bitwidth == 64) { 1699ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines filename = context.bc64FileName; 1709ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } 1719ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 1729ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines FILE *pfin = fopen(filename.c_str(), "rb"); 1735abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (pfin == nullptr) { 1749ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines fprintf(stderr, "Error: could not read file %s\n", filename.c_str()); 1752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return false; 1762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 1772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet 1782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet // start the accessor method 1799ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines GenerateAccessorMethod(context, bitwidth, out); 1802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet 1812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet // output the data 1822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet // make sure the generated function for a segment won't break the Javac 1832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet // size limitation (64K). 1842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet static const int SEG_SIZE = 0x2000; 1852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet char *buff = new char[SEG_SIZE]; 1862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet int read_length; 1872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet int seg_num = 0; 1882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet int total_length = 0; 1892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet while ((read_length = fread(buff, 1, SEG_SIZE, pfin)) > 0) { 1909ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines GenerateSegmentMethod(buff, read_length, bitwidth, seg_num, out); 1912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet ++seg_num; 1922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet total_length += read_length; 1932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 1942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet delete[] buff; 1952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet fclose(pfin); 1962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet 1972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet // output the internal accessor method 1989ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines out.indent() << "private static int bitCode" << bitwidth << "Length = " 1999ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines << total_length << ";\n\n"; 2009ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines out.indent() << "private static byte[] getBitCode" << bitwidth 2019ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines << "Internal()"; 202129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.startBlock(); 2039ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines out.indent() << "byte[] bc = new byte[bitCode" << bitwidth << "Length];\n"; 204129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.indent() << "int offset = 0;\n"; 205129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.indent() << "byte[] seg;\n"; 2062ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet for (int i = 0; i < seg_num; ++i) { 2079ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines out.indent() << "seg = getSegment" << bitwidth << "_" << i << "();\n"; 208129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.indent() << "System.arraycopy(seg, 0, bc, offset, seg.length);\n"; 209129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.indent() << "offset += seg.length;\n"; 2102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 211129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.indent() << "return bc;\n"; 212129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.endBlock(); 2130877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang 2142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return true; 2150877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang} 2160877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang 2179ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesstatic bool GenerateJavaCodeAccessorMethod( 2189ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines const RSSlangReflectUtils::BitCodeAccessorContext &context, 2199ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines GeneratedFile &out) { 2209ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines if (!GenerateJavaCodeAccessorMethodForBitwidth(context, 32, out)) { 2219ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines slangAssert(false && "Couldn't generate 32-bit embedded bitcode!"); 2229ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines return false; 2239ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } 2249ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines if (!GenerateJavaCodeAccessorMethodForBitwidth(context, 64, out)) { 2259ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines slangAssert(false && "Couldn't generate 64-bit embedded bitcode!"); 2269ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines return false; 2279ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines } 2289ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 2299ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines return true; 2309ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines} 2319ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines 2320877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wangstatic bool GenerateAccessorClass( 2336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr const RSSlangReflectUtils::BitCodeAccessorContext &context, 234129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet const char *clazz_name, GeneratedFile &out) { 2352ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet // begin the class. 236129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out << "/**\n"; 237129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out << " * @hide\n"; 238129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out << " */\n"; 239129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out << "public class " << clazz_name; 240129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.startBlock(); 2412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet 2422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet bool ret = true; 2432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet switch (context.bcStorage) { 2442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet case BCST_APK_RESOURCE: 2452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet slangAssert(false && 2462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet "Invalid generation of bitcode accessor with resource"); 2472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet break; 2482ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet case BCST_JAVA_CODE: 249129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet ret = GenerateJavaCodeAccessorMethod(context, out); 2502ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet break; 2512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet default: 2522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet ret = false; 2532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 2542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet 2552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet // end the class. 256129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.endBlock(); 2572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet 2582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return ret; 2590877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang} 2600877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang 261129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletbool RSSlangReflectUtils::GenerateJavaBitCodeAccessor( 2626315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr const BitCodeAccessorContext &context) { 2632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet string output_path = 2642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet ComputePackagedPath(context.reflectPath, context.packageName); 2653eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines if (std::error_code EC = llvm::sys::fs::create_directories( 2663eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines llvm::sys::path::parent_path(output_path))) { 2673eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines fprintf(stderr, "Error: could not create dir %s: %s\n", 2683eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines output_path.c_str(), EC.message().c_str()); 2692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return false; 2702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 2712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet 2722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet string clazz_name(JavaBitcodeClassNameFromRSFileName(context.rsFileName)); 2732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet string filename(clazz_name); 2742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet filename += ".java"; 2752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet 276129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet GeneratedFile out; 277129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet if (!out.startFile(output_path, filename, context.rsFileName, 278fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines context.licenseNote, true, context.verbose)) { 2792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return false; 2802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet } 2812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet 282129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out << "package " << context.packageName << ";\n\n"; 2832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet 284129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet bool ret = GenerateAccessorClass(context, clazz_name.c_str(), out); 285129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 286129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet out.closeFile(); 2872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet return ret; 2883f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang} 289129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 290129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletstd::string JoinPath(const std::string &path1, const std::string &path2) { 291129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet if (path1.empty()) { 292129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet return path2; 293129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet } 294129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet if (path2.empty()) { 295129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet return path1; 296129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet } 297129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet std::string fullPath = path1; 298129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet if (fullPath[fullPath.length() - 1] != OS_PATH_SEPARATOR) { 299129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet fullPath += OS_PATH_SEPARATOR; 300129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet } 301129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet if (path2[0] == OS_PATH_SEPARATOR) { 302129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet fullPath += path2.substr(1, string::npos); 303129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet } else { 304129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet fullPath += path2; 305129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet } 306129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet return fullPath; 307129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet} 308129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 309f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet// Replace all instances of "\" with "\\" in a single string to prevent 310f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet// formatting errors. In Java, this can happen even within comments, as 311f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet// Java processes \u before the comments are stripped. E.g. if the generated 312f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet// file in Windows contains the note: 313f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet// /* Do not modify! Generated from \Users\MyName\MyDir\foo.cs */ 314f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet// Java will think that \U tells of a Unicode character. 315f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletstatic void SanitizeString(std::string *s) { 316f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet size_t p = 0; 317f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet while ((p = s->find('\\', p)) != std::string::npos) { 318f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet s->replace(p, 1, "\\\\"); 319f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet p += 2; 320f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet } 321f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet} 322f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet 323129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletstatic const char *const gApacheLicenseNote = 324129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet "/*\n" 325129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " * Copyright (C) 2011-2014 The Android Open Source Project\n" 326129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " *\n" 327129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" 328129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " * you may not use this file except in compliance with the License.\n" 329129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " * You may obtain a copy of the License at\n" 330129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " *\n" 331129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " * http://www.apache.org/licenses/LICENSE-2.0\n" 332129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " *\n" 333129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " * Unless required by applicable law or agreed to in writing, software\n" 334129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" 335129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or " 336129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet "implied.\n" 337129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " * See the License for the specific language governing permissions and\n" 338129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " * limitations under the License.\n" 339129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet " */\n" 340129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet "\n"; 341129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 342129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletbool GeneratedFile::startFile(const string &outDirectory, 343129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet const string &outFileName, 344129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet const string &sourceFileName, 345fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines const string *optionalLicense, bool isJava, 346fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines bool verbose) { 347fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines if (verbose) { 348fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines printf("Generating %s\n", outFileName.c_str()); 349fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines } 350129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 351129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet // Create the parent directories. 352129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet if (!outDirectory.empty()) { 3533eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines if (std::error_code EC = llvm::sys::fs::create_directories( 3543eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines llvm::sys::path::parent_path(outDirectory))) { 3553eb819ad8beec566a73b288204f9b75c2bb1d4e6Stephen Hines fprintf(stderr, "Error: %s\n", EC.message().c_str()); 356129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet return false; 357129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet } 358129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet } 359129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 360129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet std::string FilePath = JoinPath(outDirectory, outFileName); 361129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 362129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet // Open the file. 363129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet open(FilePath.c_str()); 364129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet if (!good()) { 365129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet fprintf(stderr, "Error: could not write file %s\n", outFileName.c_str()); 366129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet return false; 367129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet } 368129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 369129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet // Write the license. 3705abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes if (optionalLicense != nullptr) { 371129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet *this << *optionalLicense; 372129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet } else { 373129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet *this << gApacheLicenseNote; 374129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet } 375129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 376129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet // Write a notice that this is a generated file. 377f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet std::string source(sourceFileName); 378f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet if (isJava) { 379f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet SanitizeString(&source); 380f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet } 381f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet 382129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet *this << "/*\n" 383129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet << " * This file is auto-generated. DO NOT MODIFY!\n" 384f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet << " * The source Renderscript file: " << source << "\n" 385129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet << " */\n\n"; 386129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 387129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet return true; 388129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet} 389129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 390129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletvoid GeneratedFile::closeFile() { close(); } 391129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 392129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletvoid GeneratedFile::increaseIndent() { mIndent.append(" "); } 393129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 394129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletvoid GeneratedFile::decreaseIndent() { 395129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet slangAssert(!mIndent.empty() && "No indent"); 396129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet mIndent.erase(0, 4); 397129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet} 398129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet 399c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouilletvoid GeneratedFile::comment(const std::string &s) { 400c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet indent() << "/* "; 401c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet // +3 for the " * " starting each line. 402c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet std::size_t indentLength = mIndent.length() + 3; 403c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet std::size_t lengthOfCommentOnLine = 0; 404c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet const std::size_t maxPerLine = 80; 405c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet for (std::size_t start = 0, length = s.length(), nextStart = 0; 406c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet start < length; start = nextStart) { 407c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet std::size_t p = s.find_first_of(" \n", start); 408c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet std::size_t toCopy = 1; 409c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet bool forceBreak = false; 410c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet if (p == std::string::npos) { 411c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet toCopy = length - start; 412c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet nextStart = length; 413c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet } else { 414c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet toCopy = p - start; 415c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet nextStart = p + 1; 416c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet forceBreak = s[p] == '\n'; 417c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet } 418c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet if (lengthOfCommentOnLine > 0) { 419c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet if (indentLength + lengthOfCommentOnLine + toCopy >= maxPerLine) { 420c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet *this << "\n"; 421c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet indent() << " * "; 422c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet lengthOfCommentOnLine = 0; 423c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet } else { 424c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet *this << " "; 425c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet } 426c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet } 427c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet 428c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet *this << s.substr(start, toCopy); 429c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet if (forceBreak) { 430c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet lengthOfCommentOnLine = maxPerLine; 431c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet } else { 432c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet lengthOfCommentOnLine += toCopy; 433c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet } 434c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet } 435c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet *this << "\n"; 436c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet indent() << " */\n"; 437c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet} 438c83b790079083da626cb64e37c38221bac1c8e8aJean-Luc Brouillet 4392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet} // namespace slang 440