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"
258c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang
268d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael#include "os_sep.h"
2744d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines#include "slang_assert.h"
288c6d9b2d36ed2d6d811279fd9bddc05fffe16803Zonr Chang#include "slang_utils.h"
293f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
303f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangnamespace slang {
313f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
323f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wangusing std::string;
333f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
342ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstring RSSlangReflectUtils::GetFileNameStem(const char *fileName) {
352ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  const char *dot = fileName + strlen(fileName);
362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  const char *slash = dot - 1;
372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  while (slash >= fileName) {
382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (*slash == OS_PATH_SEPARATOR) {
392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      break;
40dba3111408b307d8454830107ff61089ab7c5d6dYing Wang    }
412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if ((*slash == '.') && (*dot == 0)) {
422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      dot = slash;
432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    --slash;
452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  ++slash;
472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  return string(slash, dot - slash);
48dba3111408b307d8454830107ff61089ab7c5d6dYing Wang}
49dba3111408b307d8454830107ff61089ab7c5d6dYing Wang
502ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstring RSSlangReflectUtils::ComputePackagedPath(const char *prefixPath,
512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                                const char *packageName) {
522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  string packaged_path(prefixPath);
532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  if (!packaged_path.empty() &&
542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      (packaged_path[packaged_path.length() - 1] != OS_PATH_SEPARATOR)) {
552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    packaged_path += OS_PATH_SEPARATOR_STR;
562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  size_t s = packaged_path.length();
582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  packaged_path += packageName;
592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  while (s < packaged_path.length()) {
602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (packaged_path[s] == '.') {
612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      packaged_path[s] = OS_PATH_SEPARATOR;
623f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    ++s;
642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  return packaged_path;
663f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
673f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
686315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrstatic string InternalFileNameConvert(const char *rsFileName, bool toLower) {
692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  const char *dot = rsFileName + strlen(rsFileName);
702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  const char *slash = dot - 1;
712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  while (slash >= rsFileName) {
722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (*slash == OS_PATH_SEPARATOR) {
732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      break;
742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if ((*slash == '.') && (*dot == 0)) {
762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      dot = slash;
773f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    --slash;
792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  ++slash;
812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  char ret[256];
822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  int i = 0;
832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  for (; (i < 255) && (slash < dot); ++slash) {
842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (isalnum(*slash) || *slash == '_') {
852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      if (toLower) {
862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        ret[i] = tolower(*slash);
872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      } else {
882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        ret[i] = *slash;
892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      }
902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      ++i;
913f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang    }
922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  ret[i] = 0;
942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  return string(ret);
953f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
963f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstd::string
982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc BrouilletRSSlangReflectUtils::JavaClassNameFromRSFileName(const char *rsFileName) {
992ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  return InternalFileNameConvert(rsFileName, false);
1003f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
1013f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
102efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouilletstd::string RootNameFromRSFileName(const std::string &rsFileName) {
103efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet  return InternalFileNameConvert(rsFileName.c_str(), false);
104efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet}
105efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1062ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstd::string
1072ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc BrouilletRSSlangReflectUtils::BCFileNameFromRSFileName(const char *rsFileName) {
1082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  return InternalFileNameConvert(rsFileName, true);
1093f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
1103f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
11144d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hinesstd::string RSSlangReflectUtils::JavaBitcodeClassNameFromRSFileName(
11244d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines    const char *rsFileName) {
1132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  std::string tmp(InternalFileNameConvert(rsFileName, false));
1142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  return tmp.append("BitCode");
11544d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines}
1160877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
117129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletstatic bool GenerateAccessorMethod(
118129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    const RSSlangReflectUtils::BitCodeAccessorContext &context,
1199ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    int bitwidth, GeneratedFile &out) {
1202ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // the prototype of the accessor method
1219ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  out.indent() << "// return byte array representation of the " << bitwidth
1229ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines               << "-bit bitcode.\n";
1239ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  out.indent() << "public static byte[] getBitCode" << bitwidth << "()";
124129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.startBlock();
1259ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  out.indent() << "return getBitCode" << bitwidth << "Internal();\n";
126129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.endBlock(true);
1272ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  return true;
1280877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang}
1290877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1300877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang// Java method size must not exceed 64k,
1310877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang// so we have to split the bitcode into multiple segments.
1329ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesstatic bool GenerateSegmentMethod(const char *buff, int blen, int bitwidth,
1339ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines                                  int seg_num, GeneratedFile &out) {
1349ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  out.indent() << "private static byte[] getSegment" << bitwidth << "_"
1359ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines               << seg_num << "()";
136129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.startBlock();
137129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.indent() << "byte[] data = {";
138129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.increaseIndent();
139129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
140129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  const int kEntriesPerLine = 16;
141129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  int position = kEntriesPerLine;  // We start with a new line and indent.
142129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  for (int written = 0; written < blen; written++) {
143129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    if (++position >= kEntriesPerLine) {
144129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet      out << "\n";
145129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet      out.indent();
146129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet      position = 0;
147129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    } else {
148129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet      out << " ";
1490877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang    }
150129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    out << std::setw(4) << static_cast<int>(buff[written]) << ",";
1512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
152129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out << "\n";
1530877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
154129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.decreaseIndent();
155129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.indent() << "};\n";
156129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.indent() << "return data;\n";
157129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.endBlock();
1583f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang
1592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  return true;
1600877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang}
1610877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
1629ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesstatic bool GenerateJavaCodeAccessorMethodForBitwidth(
163129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    const RSSlangReflectUtils::BitCodeAccessorContext &context,
1649ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    int bitwidth, GeneratedFile &out) {
1659ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1669ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  std::string filename(context.bc32FileName);
1679ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  if (bitwidth == 64) {
1689ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    filename = context.bc64FileName;
1699ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
1709ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
1719ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  FILE *pfin = fopen(filename.c_str(), "rb");
1722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  if (pfin == NULL) {
1739ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    fprintf(stderr, "Error: could not read file %s\n", filename.c_str());
1742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return false;
1752ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
1762ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // start the accessor method
1789ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  GenerateAccessorMethod(context, bitwidth, out);
1792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // output the data
1812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // make sure the generated function for a segment won't break the Javac
1822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // size limitation (64K).
1832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  static const int SEG_SIZE = 0x2000;
1842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  char *buff = new char[SEG_SIZE];
1852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  int read_length;
1862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  int seg_num = 0;
1872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  int total_length = 0;
1882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  while ((read_length = fread(buff, 1, SEG_SIZE, pfin)) > 0) {
1899ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    GenerateSegmentMethod(buff, read_length, bitwidth, seg_num, out);
1902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    ++seg_num;
1912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    total_length += read_length;
1922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
1932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  delete[] buff;
1942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  fclose(pfin);
1952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // output the internal accessor method
1979ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  out.indent() << "private static int bitCode" << bitwidth << "Length = "
1989ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines               << total_length << ";\n\n";
1999ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  out.indent() << "private static byte[] getBitCode" << bitwidth
2009ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines               << "Internal()";
201129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.startBlock();
2029ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  out.indent() << "byte[] bc = new byte[bitCode" << bitwidth << "Length];\n";
203129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.indent() << "int offset = 0;\n";
204129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.indent() << "byte[] seg;\n";
2052ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  for (int i = 0; i < seg_num; ++i) {
2069ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    out.indent() << "seg = getSegment" << bitwidth << "_" << i << "();\n";
207129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    out.indent() << "System.arraycopy(seg, 0, bc, offset, seg.length);\n";
208129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    out.indent() << "offset += seg.length;\n";
2092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
210129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.indent() << "return bc;\n";
211129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.endBlock();
2120877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
2132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  return true;
2140877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang}
2150877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
2169ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hinesstatic bool GenerateJavaCodeAccessorMethod(
2179ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    const RSSlangReflectUtils::BitCodeAccessorContext &context,
2189ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    GeneratedFile &out) {
2199ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  if (!GenerateJavaCodeAccessorMethodForBitwidth(context, 32, out)) {
2209ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    slangAssert(false && "Couldn't generate 32-bit embedded bitcode!");
2219ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    return false;
2229ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
2239ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  if (!GenerateJavaCodeAccessorMethodForBitwidth(context, 64, out)) {
2249ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    slangAssert(false && "Couldn't generate 64-bit embedded bitcode!");
2259ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    return false;
2269ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  }
2279ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
2289ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines  return true;
2299ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines}
2309ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines
2310877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wangstatic bool GenerateAccessorClass(
2326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const RSSlangReflectUtils::BitCodeAccessorContext &context,
233129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    const char *clazz_name, GeneratedFile &out) {
2342ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // begin the class.
235129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out << "/**\n";
236129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out << " * @hide\n";
237129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out << " */\n";
238129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out << "public class " << clazz_name;
239129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.startBlock();
2402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  bool ret = true;
2422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  switch (context.bcStorage) {
2432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case BCST_APK_RESOURCE:
2442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    slangAssert(false &&
2452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                "Invalid generation of bitcode accessor with resource");
2462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
2472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  case BCST_JAVA_CODE:
248129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    ret = GenerateJavaCodeAccessorMethod(context, out);
2492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    break;
2502ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  default:
2512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    ret = false;
2522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  // end the class.
255129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.endBlock();
2562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  return ret;
2580877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang}
2590877f0557e5c406fc8ff33c928a8ae969a5f4905Ying Wang
260129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletbool RSSlangReflectUtils::GenerateJavaBitCodeAccessor(
2616315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    const BitCodeAccessorContext &context) {
2622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  string output_path =
2632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      ComputePackagedPath(context.reflectPath, context.packageName);
2642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  if (!SlangUtils::CreateDirectoryWithParents(llvm::StringRef(output_path),
2652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                              NULL)) {
2662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    fprintf(stderr, "Error: could not create dir %s\n", output_path.c_str());
2672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return false;
2682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  string clazz_name(JavaBitcodeClassNameFromRSFileName(context.rsFileName));
2712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  string filename(clazz_name);
2722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  filename += ".java";
2732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
274129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  GeneratedFile out;
275129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  if (!out.startFile(output_path, filename, context.rsFileName,
276fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                     context.licenseNote, true, context.verbose)) {
2772ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return false;
2782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  }
2792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
280129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out << "package " << context.packageName << ";\n\n";
2812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
282129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  bool ret = GenerateAccessorClass(context, clazz_name.c_str(), out);
283129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
284129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  out.closeFile();
2852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet  return ret;
2863f8b44dba57685b437cecc208f2a20a4ed93ed36Ying Wang}
287129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
288129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletstd::string JoinPath(const std::string &path1, const std::string &path2) {
289129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  if (path1.empty()) {
290129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    return path2;
291129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  }
292129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  if (path2.empty()) {
293129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    return path1;
294129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  }
295129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  std::string fullPath = path1;
296129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  if (fullPath[fullPath.length() - 1] != OS_PATH_SEPARATOR) {
297129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    fullPath += OS_PATH_SEPARATOR;
298129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  }
299129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  if (path2[0] == OS_PATH_SEPARATOR) {
300129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    fullPath += path2.substr(1, string::npos);
301129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  } else {
302129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    fullPath += path2;
303129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  }
304129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  return fullPath;
305129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet}
306129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
307f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet// Replace all instances of "\" with "\\" in a single string to prevent
308f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet// formatting errors.  In Java, this can happen even within comments, as
309f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet// Java processes \u before the comments are stripped.  E.g. if the generated
310f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet// file in Windows contains the note:
311f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet//     /* Do not modify!  Generated from \Users\MyName\MyDir\foo.cs */
312f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet// Java will think that \U tells of a Unicode character.
313f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletstatic void SanitizeString(std::string *s) {
314f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  size_t p = 0;
315f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  while ((p = s->find('\\', p)) != std::string::npos) {
316f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    s->replace(p, 1, "\\\\");
317f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    p += 2;
318f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  }
319f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet}
320f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
321129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletstatic const char *const gApacheLicenseNote =
322129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    "/*\n"
323129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " * Copyright (C) 2011-2014 The Android Open Source Project\n"
324129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " *\n"
325129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
326129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " * you may not use this file except in compliance with the License.\n"
327129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " * You may obtain a copy of the License at\n"
328129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " *\n"
329129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " *      http://www.apache.org/licenses/LICENSE-2.0\n"
330129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " *\n"
331129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " * Unless required by applicable law or agreed to in writing, software\n"
332129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
333129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or "
334129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    "implied.\n"
335129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " * See the License for the specific language governing permissions and\n"
336129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " * limitations under the License.\n"
337129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    " */\n"
338129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    "\n";
339129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
340129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletbool GeneratedFile::startFile(const string &outDirectory,
341129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet                              const string &outFileName,
342129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet                              const string &sourceFileName,
343fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                              const string *optionalLicense, bool isJava,
344fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines                              bool verbose) {
345fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines  if (verbose) {
346fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines    printf("Generating %s\n", outFileName.c_str());
347fc4f78b9c7941132fb048a83f0e4ba528c3b4fd0Stephen Hines  }
348129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
349129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  // Create the parent directories.
350129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  if (!outDirectory.empty()) {
351129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    std::string errorMsg;
352129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    if (!SlangUtils::CreateDirectoryWithParents(outDirectory, &errorMsg)) {
353129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet      fprintf(stderr, "Error: %s\n", errorMsg.c_str());
354129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet      return false;
355129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    }
356129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  }
357129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
358129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  std::string FilePath = JoinPath(outDirectory, outFileName);
359129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
360129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  // Open the file.
361129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  open(FilePath.c_str());
362129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  if (!good()) {
363129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    fprintf(stderr, "Error: could not write file %s\n", outFileName.c_str());
364129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    return false;
365129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  }
366129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
367129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  // Write the license.
368129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  if (optionalLicense != NULL) {
369129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    *this << *optionalLicense;
370129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  } else {
371129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet    *this << gApacheLicenseNote;
372129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  }
373129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
374129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  // Write a notice that this is a generated file.
375f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  std::string source(sourceFileName);
376f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  if (isJava) {
377f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    SanitizeString(&source);
378f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet  }
379f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
380129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  *this << "/*\n"
381129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet        << " * This file is auto-generated. DO NOT MODIFY!\n"
382f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        << " * The source Renderscript file: " << source << "\n"
383129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet        << " */\n\n";
384129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
385129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  return true;
386129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet}
387129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
388129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletvoid GeneratedFile::closeFile() { close(); }
389129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
390129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletvoid GeneratedFile::increaseIndent() { mIndent.append("    "); }
391129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
392129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouilletvoid GeneratedFile::decreaseIndent() {
393129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  slangAssert(!mIndent.empty() && "No indent");
394129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet  mIndent.erase(0, 4);
395129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet}
396129fd8228cd04592a20c3d5009805a23585f2479Jean-Luc Brouillet
397f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouilletvoid GeneratedFile::comment(const std::string &s) {
398f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  indent() << "/* ";
399f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  // +3 for the " * " starting each line.
400f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  std::size_t indentLength = mIndent.length() + 3;
401f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  std::size_t lengthOfCommentOnLine = 0;
402f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  const std::size_t maxPerLine = 80;
403f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  for (std::size_t start = 0, length = s.length(), nextStart = 0;
404f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet       start < length; start = nextStart) {
405f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    std::size_t p = s.find_first_of(" \n", start);
406f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    std::size_t toCopy = 1;
407f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    bool forceBreak = false;
408f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    if (p == std::string::npos) {
409f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      toCopy = length - start;
410f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      nextStart = length;
411f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    } else {
412f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      toCopy = p - start;
413f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      nextStart = p + 1;
414f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      forceBreak = s[p] == '\n';
415f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    }
416f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    if (lengthOfCommentOnLine > 0) {
417f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      if (indentLength + lengthOfCommentOnLine + toCopy >= maxPerLine) {
418f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet        *this << "\n";
419f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet        indent() << " * ";
420f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet        lengthOfCommentOnLine = 0;
421f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      } else {
422f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet        *this << " ";
423f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      }
424f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    }
425f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet
426f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    *this << s.substr(start, toCopy);
427f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    if (forceBreak) {
428f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      lengthOfCommentOnLine = maxPerLine;
429f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    } else {
430f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet      lengthOfCommentOnLine += toCopy;
431f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet    }
432f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  }
433f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  *this << "\n";
434f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet  indent() << " */\n";
435f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet}
436f5ab7e790bb4a2d5d6495d37b0855005d48f91c3Jean-Luc Brouillet
4372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet} // namespace slang
438