summaryrefslogtreecommitdiff
path: root/api
diff options
context:
space:
mode:
authorJean-Luc Brouillet <jeanluc@google.com>2015-04-24 14:41:48 -0700
committerJean-Luc Brouillet <jeanluc@google.com>2015-04-24 16:27:09 -0700
commit2217eb7b12e598e5b435a732207647918c171560 (patch)
treec5fb5e279f839fdd1a7f2580e7e26ae136364568 /api
parent54950687ea8bdde7d1498690433b069924f58044 (diff)
downloadrs-2217eb7b12e598e5b435a732207647918c171560.tar.gz
Update documentation generator to work with the Documentation system.
Also added this flag to the generator: -H Now that we generate by default .jd files rather than .html files, you can use this flag to revert to generating .html files. This is useful when verifying doc changes locally. And modified the -v flag to specify the API level for all file generation rather than just the testing files. Change-Id: Ic9e35ad6779b9fbc6b23228dded2e2be864393ff
Diffstat (limited to 'api')
-rw-r--r--api/GenerateDocumentation.cpp (renamed from api/GenerateHtmlDocumentation.cpp)212
-rw-r--r--api/Generator.cpp22
-rw-r--r--api/Generator.h7
-rw-r--r--api/Scanner.cpp6
-rw-r--r--api/Scanner.h2
-rw-r--r--api/Specification.cpp71
-rw-r--r--api/Specification.h29
-rwxr-xr-xapi/generate.sh25
-rw-r--r--api/rs_core.spec15
-rw-r--r--api/rs_object_types.spec15
10 files changed, 250 insertions, 154 deletions
diff --git a/api/GenerateHtmlDocumentation.cpp b/api/GenerateDocumentation.cpp
index 1de53289..eab1889a 100644
--- a/api/GenerateHtmlDocumentation.cpp
+++ b/api/GenerateDocumentation.cpp
@@ -28,61 +28,75 @@ struct DetailedFunctionEntry {
string htmlDeclaration;
};
-static void writeHtmlHeader(GeneratedFile* file) {
- *file << "<!DOCTYPE html>\n";
- *file << "<!-- " << AUTO_GENERATED_WARNING << "-->\n";
-
- *file << "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>\n"
- "<meta name='viewport' content='width=device-width'>\n"
- "<link rel='shortcut icon' type='image/x-icon' "
- "href='http://developer.android.com/favicon.ico'>\n"
- "<title>android.renderscript | Android Developers</title>\n"
- "<!-- STYLESHEETS -->\n"
- "<link rel='stylesheet' "
- "href='http://fonts.googleapis.com/css?family=Roboto+Condensed'>\n"
- "<link rel='stylesheet' href='http://fonts.googleapis.com/"
- "css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold' "
- "title='roboto'>\n"
- "<link href='./test_files/default.css' rel='stylesheet' type='text/css'>\n"
- "<!-- FULLSCREEN STYLESHEET -->\n"
- "<link href='./test_files/fullscreen.css' rel='stylesheet' class='fullscreen' "
- "type='text/css'>\n"
- "<!-- JAVASCRIPT -->\n"
- "<script src='./test_files/cb=gapi.loaded_0' async=''></script><script "
- "type='text/javascript' async='' src='./test_files/plusone.js' "
- "gapi_processed='true'></script><script async='' "
- "src='./test_files/analytics.js'></script><script src='./test_files/jsapi' "
- "type='text/javascript'></script>\n"
- "<script src='./test_files/android_3p-bundle.js' type='text/javascript'></script>\n"
- "<script type='text/javascript'>\n"
- " var toRoot = '/';\n"
- " var metaTags = [];\n"
- " var devsite = false;\n"
- "</script>\n"
- "<script src='./test_files/docs.js' type='text/javascript'></script><script "
- "type='text/javascript' src='./test_files/saved_resource'></script>\n"
- "<script>\n"
- " (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n"
- " (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n"
- " m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n"
- " })(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n"
- " ga('create', 'UA-5831155-1', 'android.com');\n"
- " ga('create', 'UA-49880327-2', 'android.com', {'name': 'universal'}); // New "
- "tracker);\n"
- " ga('send', 'pageview');\n"
- " ga('universal.send', 'pageview'); // Send page view for new tracker.\n"
- "</script>\n"
- "<link type='text/css' href='./test_files/default+en.css' rel='stylesheet'><script "
- "type='text/javascript' src='./test_files/default+en.I.js'></script></head>\n"
- "<body class='gc-documentation\n"
- " develop reference'>\n";
- //" <div id='doc-api-level' class='11' style='display:none'></div>\n"
- //" <a name='top'></a>\n";
+static const char OVERVIEW_HTML_FILE_NAME[] = "overview.html";
+static const char OVERVIEW_JD_FILE_NAME[] = "overview.jd";
+static const char INDEX_HTML_FILE_NAME[] = "index.html";
+static const char INDEX_JD_FILE_NAME[] = "index.jd";
+
+static void writeHeader(GeneratedFile* file, bool forVerification, const string& title) {
+ if (forVerification) {
+ *file << "<!DOCTYPE html>\n";
+ *file << "<!-- " << AUTO_GENERATED_WARNING << "-->\n";
+
+ *file << "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>\n"
+ "<meta name='viewport' content='width=device-width'>\n"
+ "<link rel='shortcut icon' type='image/x-icon' "
+ "href='http://developer.android.com/favicon.ico'>\n"
+ "<title>android.renderscript | Android Developers</title>\n"
+ "<!-- STYLESHEETS -->\n"
+ "<link rel='stylesheet' "
+ "href='http://fonts.googleapis.com/css?family=Roboto+Condensed'>\n"
+ "<link rel='stylesheet' href='http://fonts.googleapis.com/"
+ "css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold' "
+ "title='roboto'>\n"
+ "<link href='./test_files/default.css' rel='stylesheet' type='text/css'>\n"
+ "<!-- FULLSCREEN STYLESHEET -->\n"
+ "<link href='./test_files/fullscreen.css' rel='stylesheet' class='fullscreen' "
+ "type='text/css'>\n"
+ "<!-- JAVASCRIPT -->\n"
+ "<script src='./test_files/cb=gapi.loaded_0' async=''></script><script "
+ "type='text/javascript' async='' src='./test_files/plusone.js' "
+ "gapi_processed='true'></script><script async='' "
+ "src='./test_files/analytics.js'></script><script src='./test_files/jsapi' "
+ "type='text/javascript'></script>\n"
+ "<script src='./test_files/android_3p-bundle.js' "
+ "type='text/javascript'></script>\n"
+ "<script type='text/javascript'>\n"
+ " var toRoot = '/';\n"
+ " var metaTags = [];\n"
+ " var devsite = false;\n"
+ "</script>\n"
+ "<script src='./test_files/docs.js' type='text/javascript'></script><script "
+ "type='text/javascript' src='./test_files/saved_resource'></script>\n"
+ "<script>\n"
+ " (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n"
+ " (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new "
+ "Date();a=s.createElement(o),\n"
+ " "
+ "m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n"
+ " })(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n"
+ " ga('create', 'UA-5831155-1', 'android.com');\n"
+ " ga('create', 'UA-49880327-2', 'android.com', {'name': 'universal'}); // New "
+ "tracker);\n"
+ " ga('send', 'pageview');\n"
+ " ga('universal.send', 'pageview'); // Send page view for new tracker.\n"
+ "</script>\n"
+ "<link type='text/css' href='./test_files/default+en.css' "
+ "rel='stylesheet'><script "
+ "type='text/javascript' src='./test_files/default+en.I.js'></script></head>\n"
+ "<body class='gc-documentation\n"
+ " develop reference'>\n\n";
+ *file << "<h1>" << title << "</h1>\n";
+ } else {
+ *file << "page.title=RenderScript " << title << "\n\n";
+ *file << "@jd:body\n\n";
+ }
}
-static void writeHtmlFooter(GeneratedFile* file) {
- //*file << "</div>n"
- *file << "<!-- end body-content -->\n</body></html>\n";
+static void writeFooter(GeneratedFile* file, bool forVerification) {
+ if (forVerification) {
+ *file << "<!-- end body-content -->\n</body></html>\n";
+ }
}
// If prefix starts input, copy it to stream and remove it from input.
@@ -277,7 +291,8 @@ static void writeSummaryTableEntry(ostream* stream, Definition* definition,
*stream << " <tr class='alt-color api apilevel-1'>\n";
*stream << " <td class='jd-linkcol'>\n";
- *stream << " <a href='" << definition->getUrl() << "'>" << definition->getName() << "</a>\n";
+ *stream << " <a href='" << definition->getUrl() << "'>" << definition->getName()
+ << "</a>\n";
*stream << " </td>\n";
*stream << " <td class='jd-descrcol' width='100%'>\n";
*stream << " ";
@@ -356,13 +371,10 @@ static void writeHtmlVersionTag(GeneratedFile* file, VersionInfo info) {
}
const string s = stream.str();
if (!s.empty()) {
- // TODO simplify
- //*file << " <p>" << s << "</p>\n";
*file << " " << s << "\n";
}
}
-
static void writeDetailedTypeSpecification(GeneratedFile* file, const TypeSpecification* type) {
switch (type->getKind()) {
case SIMPLE:
@@ -390,7 +402,6 @@ static void writeDetailedTypeSpecification(GeneratedFile* file, const TypeSpecif
break;
}
case STRUCT: {
- // TODO string mStructName; // The name found after the struct keyword
*file << "<p>A structure with the following fields:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
writeHtmlVersionTag(file, type->getVersionInfo());
*file << "</p>\n";
@@ -434,15 +445,14 @@ static bool writeOverviewForFile(GeneratedFile* file, const SpecFile& specFile)
return success;
}
-static bool generateOverview(const string& directory) {
+static bool generateOverview(const string& directory, bool forVerification) {
GeneratedFile file;
- if (!file.start(directory, "index.html")) {
+ if (!file.start(directory, forVerification ? OVERVIEW_HTML_FILE_NAME : OVERVIEW_JD_FILE_NAME)) {
return false;
}
bool success = true;
- writeHtmlHeader(&file);
- file << "<h1>Overview</h1>\n";
+ writeHeader(&file, forVerification, "Overview");
for (auto specFile : systemSpecification.getSpecFiles()) {
if (!writeOverviewForFile(&file, *specFile)) {
@@ -450,17 +460,17 @@ static bool generateOverview(const string& directory) {
}
}
- writeHtmlFooter(&file);
+ writeFooter(&file, forVerification);
file.close();
return success;
}
-static bool generateAlphabeticalIndex(const string& directory) {
+static bool generateAlphabeticalIndex(const string& directory, bool forVerification) {
GeneratedFile file;
- if (!file.start(directory, "alpha_index.html")) {
+ if (!file.start(directory, forVerification ? INDEX_HTML_FILE_NAME : INDEX_JD_FILE_NAME)) {
return false;
}
- writeHtmlHeader(&file);
+ writeHeader(&file, forVerification, "Index");
writeSummaryTables(&file, systemSpecification.getConstants(), systemSpecification.getTypes(),
systemSpecification.getFunctions(), NON_DEPRECATED_ONLY, true);
@@ -468,7 +478,7 @@ static bool generateAlphabeticalIndex(const string& directory) {
writeSummaryTables(&file, systemSpecification.getConstants(), systemSpecification.getTypes(),
systemSpecification.getFunctions(), DEPRECATED_ONLY, true);
- writeHtmlFooter(&file);
+ writeFooter(&file, forVerification);
file.close();
return true;
}
@@ -493,8 +503,6 @@ static bool writeDetailedConstant(GeneratedFile* file, Constant* constant) {
}
const string& name = constant->getName();
- // TODO need names that distinguish fn.const. type
- // TODO had attr_android:...
*file << "<a id='android_rs:" << name << "'></a>\n";
*file << "<div class='jd-details'>\n";
*file << " <h4 class='jd-details-title'>\n";
@@ -534,8 +542,6 @@ static bool writeDetailedType(GeneratedFile* file, Type* type) {
}
const string& name = type->getName();
- // TODO need names that distinguish fn.const. type
- // TODO had attr_android:...
*file << "<a id='android_rs:" << name << "'></a>\n";
*file << "<div class='jd-details'>\n";
*file << " <h4 class='jd-details-title'>\n";
@@ -562,8 +568,6 @@ static bool writeDetailedType(GeneratedFile* file, Type* type) {
static bool writeDetailedFunction(GeneratedFile* file, Function* function) {
const string& name = function->getName();
- // TODO need names that distinguish fn.const. type
- // TODO had attr_android:...
*file << "<a id='android_rs:" << name << "'></a>\n";
*file << "<div class='jd-details'>\n";
*file << " <h4 class='jd-details-title'>\n";
@@ -621,19 +625,23 @@ static bool writeDetailedFunction(GeneratedFile* file, Function* function) {
return true;
}
-static bool writeDetailedDocumentationFile(const string& directory, const SpecFile& specFile) {
+static bool writeDetailedDocumentationFile(const string& directory, const SpecFile& specFile,
+ bool forVerification) {
+ if (!specFile.hasSpecifications()) {
+ // This is true for rs_core.spec
+ return true;
+ }
+
GeneratedFile file;
- const string htmlFileName = stringReplace(specFile.getSpecFileName(), ".spec", ".html");
- if (!file.start(directory, htmlFileName)) {
+ const string fileName = stringReplace(specFile.getSpecFileName(), ".spec",
+ forVerification ? ".html" : ".jd");
+ if (!file.start(directory, fileName)) {
return false;
}
bool success = true;
- writeHtmlHeader(&file);
- file << "<br/>";
-
- // Write the file documentation.
- file << "<h1>" << specFile.getBriefDescription() << "</h1>\n";
+ string title = specFile.getBriefDescription();
+ writeHeader(&file, forVerification, title);
file << "<h2>Overview</h2>\n";
if (!generateHtmlParagraphs(&file, specFile.getFullDescription())) {
@@ -675,20 +683,52 @@ static bool writeDetailedDocumentationFile(const string& directory, const SpecFi
}
}
- writeHtmlFooter(&file);
+ writeFooter(&file, forVerification);
file.close();
if (!success) {
// If in error, write a final message to make it easier to figure out which file failed.
- cerr << htmlFileName << ": Failed due to errors.\n";
+ cerr << fileName << ": Failed due to errors.\n";
}
return success;
}
-bool generateHtmlDocumentation(const string& directory) {
- bool success = generateOverview(directory) && generateAlphabeticalIndex(directory);
+static void generateSnippet(GeneratedFile* file, const string& fileName, const string& title) {
+ const char offset[] = " ";
+ *file << offset << "<li><a href=\"<?cs var:toroot ?>guide/topics/renderscript/reference/"
+ << fileName << "\">\n";
+ *file << offset << " <span class=\"en\">" << title << "</span>\n";
+ *file << offset << "</a></li>\n";
+}
+
+/* Generate a partial file of links that should be cut & pasted into the proper section of the
+ * guide_toc.cs file.
+ */
+static bool generateAndroidTableOfContentSnippet(const string& directory) {
+ GeneratedFile file;
+ if (!file.start(directory, "guide_toc.cs")) {
+ return false;
+ }
+ file << "<!-- Copy and paste the following lines into the RenderScript section of\n";
+ file << " platform/frameworks/base/docs/html/guide/guide_toc.cs\n\n";
+
+ generateSnippet(&file, OVERVIEW_HTML_FILE_NAME, "Overview");
+ for (auto specFile : systemSpecification.getSpecFiles()) {
+ if (specFile->hasSpecifications()) {
+ const string fileName = stringReplace(specFile->getSpecFileName(), ".spec", ".html");
+ generateSnippet(&file, fileName, specFile->getBriefDescription());
+ }
+ }
+ generateSnippet(&file, INDEX_HTML_FILE_NAME, "Index");
+ return true;
+}
+
+bool generateDocumentation(const string& directory, bool forVerification) {
+ bool success = generateOverview(directory, forVerification) &&
+ generateAlphabeticalIndex(directory, forVerification) &&
+ generateAndroidTableOfContentSnippet(directory);
for (auto specFile : systemSpecification.getSpecFiles()) {
- if (!writeDetailedDocumentationFile(directory, *specFile)) {
+ if (!writeDetailedDocumentationFile(directory, *specFile, forVerification)) {
success = false;
}
}
diff --git a/api/Generator.cpp b/api/Generator.cpp
index dbd179bd..c44c9958 100644
--- a/api/Generator.cpp
+++ b/api/Generator.cpp
@@ -25,8 +25,9 @@
*
* Finally, this program generates HTML documentation files.
*
- * This program takes an optional -v parameter, the RS version to target the
- * test files for. The header file will always contain all the functions.
+ * This program takes an optional -v parameter, the API level to target. The generated
+ * files will not contain APIs passed that API level. Note that this does not affect
+ * generic comments found in headers.
*
* This program contains five main classes:
* - SpecFile: Represents on spec file.
@@ -152,7 +153,7 @@
using namespace std;
-static bool parseCommandLine(int argc, char* argv[], int* versionOfTestFiles,
+static bool parseCommandLine(int argc, char* argv[], int* maxApiLevel, bool* forVerification,
vector<string>* specFileNames) {
for (int i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
@@ -160,7 +161,7 @@ static bool parseCommandLine(int argc, char* argv[], int* versionOfTestFiles,
i++;
if (i < argc) {
char* end;
- *versionOfTestFiles = strtol(argv[i], &end, 10);
+ *maxApiLevel = strtol(argv[i], &end, 10);
if (*end != '\0') {
cerr << "Error. Can't parse the version number" << argv[i] << "\n";
return false;
@@ -169,6 +170,8 @@ static bool parseCommandLine(int argc, char* argv[], int* versionOfTestFiles,
cerr << "Missing version number after -v\n";
return false;
}
+ } else if (argv[i][1] == 'H') {
+ *forVerification = true;
} else {
cerr << "Unrecognized flag %s\n" << argv[i] << "\n";
return false;
@@ -186,20 +189,21 @@ static bool parseCommandLine(int argc, char* argv[], int* versionOfTestFiles,
int main(int argc, char* argv[]) {
// If there's no restriction, generated test files for the very highest version.
- int versionOfTestFiles = 999999;
+ int maxApiLevel = 999999;
vector<string> specFileNames;
- if (!parseCommandLine(argc, argv, &versionOfTestFiles, &specFileNames)) {
- cout << "Usage: gen_runtime spec_file [spec_file...] [-v version_of_test_files]\n";
+ bool forVerification = false;
+ if (!parseCommandLine(argc, argv, &maxApiLevel, &forVerification, &specFileNames)) {
+ cout << "Usage: gen_runtime spec_file [spec_file...] [-v version_of_test_files][-H]\n";
return -1;
}
bool success = true;
for (auto i : specFileNames) {
- if (!systemSpecification.readSpecFile(i)) {
+ if (!systemSpecification.readSpecFile(i, maxApiLevel)) {
success = false;
}
}
if (success) {
- success = systemSpecification.generateFiles(versionOfTestFiles);
+ success = systemSpecification.generateFiles(forVerification, maxApiLevel);
}
return success ? 0 : -2;
}
diff --git a/api/Generator.h b/api/Generator.h
index 090a69f5..81988823 100644
--- a/api/Generator.h
+++ b/api/Generator.h
@@ -23,7 +23,10 @@ bool generateHeaderFiles(const std::string& directory);
// Generates the Java and RenderScript test files. The implementation is in GenerateTestFiles.cpp.
bool generateTestFiles(const std::string& directory, int versionOfTestFiles);
-// Generates all HTML documentation files. The implementation is in GenerateHtmlDocumentation.cpp.
-bool generateHtmlDocumentation(const std::string& director);
+/* Generates the documentation files. The implementation is in GenerateDocumentation.cpp.
+ * If forVerification is false (the default), we generate the .jd files needed by the
+ * documentation system. If it's true, we generate complete .html files for local debugging.
+ */
+bool generateDocumentation(const std::string& director, bool forVerification);
#endif // ANDROID_RS_API_GENERATOR_GENERATOR_H
diff --git a/api/Scanner.cpp b/api/Scanner.cpp
index 660dd242..84af5817 100644
--- a/api/Scanner.cpp
+++ b/api/Scanner.cpp
@@ -133,6 +133,12 @@ bool Scanner::findOptionalTag(const char* tag) {
return mTagConsumed;
}
+void Scanner::skipUntilTag(const char* tag) {
+ while(!findOptionalTag(tag)) {
+ mTagConsumed = true;
+ }
+}
+
void Scanner::checkNoValue() {
if (!mValue.empty()) {
error() << "Did not expect \"" << mValue << "\" after \"" << mTag << "\".\n";
diff --git a/api/Scanner.h b/api/Scanner.h
index c3d6f337..82a4e8fd 100644
--- a/api/Scanner.h
+++ b/api/Scanner.h
@@ -78,6 +78,8 @@ public:
bool findTag(const char* tag);
// Same as findTag but does not print an error if the tag is not found.
bool findOptionalTag(const char* tag);
+ // Keep reading from the stream until the tag is found.
+ void skipUntilTag(const char* tag);
// Verifies there's no value.
void checkNoValue();
diff --git a/api/Specification.cpp b/api/Specification.cpp
index 0dbaa736..b36acaeb 100644
--- a/api/Specification.cpp
+++ b/api/Specification.cpp
@@ -201,7 +201,7 @@ void ParameterDefinition::parseParameterDefinition(const string& type, const str
}
}
-void VersionInfo::scan(Scanner* scanner) {
+bool VersionInfo::scan(Scanner* scanner, int maxApiLevel) {
if (scanner->findOptionalTag("version:")) {
const string s = scanner->getValue();
sscanf(s.c_str(), "%i %i", &minVersion, &maxVersion);
@@ -218,6 +218,10 @@ void VersionInfo::scan(Scanner* scanner) {
if (scanner->findOptionalTag("size:")) {
sscanf(scanner->getValue().c_str(), "%i", &intSize);
}
+ if (maxVersion > maxApiLevel) {
+ maxVersion = maxApiLevel;
+ }
+ return minVersion == 0 || minVersion <= maxApiLevel;
}
Definition::Definition(const std::string& name) : mName(name), mDeprecated(false), mHidden(false) {
@@ -305,20 +309,23 @@ void Function::addReturn(ParameterEntry* entry, Scanner* scanner) {
mReturnDocumentation = entry->documentation;
}
-void Specification::scanVersionInfo(Scanner* scanner) {
- mVersionInfo.scan(scanner);
-}
-
-void ConstantSpecification::scanConstantSpecification(Scanner* scanner, SpecFile* specFile) {
+void ConstantSpecification::scanConstantSpecification(Scanner* scanner, SpecFile* specFile,
+ int maxApiLevel) {
string name = scanner->getValue();
+ VersionInfo info;
+ if (!info.scan(scanner, maxApiLevel)) {
+ cout << "Skipping some " << name << " definitions.\n";
+ scanner->skipUntilTag("end:");
+ return;
+ }
bool created = false;
Constant* constant = systemSpecification.findOrCreateConstant(name, &created);
ConstantSpecification* spec = new ConstantSpecification(constant);
constant->addSpecification(spec);
specFile->addConstantSpecification(spec, created);
+ spec->mVersionInfo = info;
- spec->scanVersionInfo(scanner);
if (scanner->findTag("value:")) {
spec->mValue = scanner->getValue();
}
@@ -327,16 +334,23 @@ void ConstantSpecification::scanConstantSpecification(Scanner* scanner, SpecFile
scanner->findTag("end:");
}
-void TypeSpecification::scanTypeSpecification(Scanner* scanner, SpecFile* specFile) {
+void TypeSpecification::scanTypeSpecification(Scanner* scanner, SpecFile* specFile,
+ int maxApiLevel) {
string name = scanner->getValue();
+ VersionInfo info;
+ if (!info.scan(scanner, maxApiLevel)) {
+ cout << "Skipping some " << name << " definitions.\n";
+ scanner->skipUntilTag("end:");
+ return;
+ }
bool created = false;
Type* type = systemSpecification.findOrCreateType(name, &created);
TypeSpecification* spec = new TypeSpecification(type);
type->addSpecification(spec);
specFile->addTypeSpecification(spec, created);
+ spec->mVersionInfo = info;
- spec->scanVersionInfo(scanner);
if (scanner->findOptionalTag("simple:")) {
spec->mKind = SIMPLE;
spec->mSimpleType = scanner->getValue();
@@ -483,9 +497,6 @@ void FunctionSpecification::parseTest(Scanner* scanner) {
}
bool FunctionSpecification::hasTests(int versionOfTestFiles) const {
- if (mVersionInfo.minVersion != 0 && mVersionInfo.minVersion > versionOfTestFiles) {
- return false;
- }
if (mVersionInfo.maxVersion != 0 && mVersionInfo.maxVersion < versionOfTestFiles) {
return false;
}
@@ -495,9 +506,11 @@ bool FunctionSpecification::hasTests(int versionOfTestFiles) const {
return true;
}
-void FunctionSpecification::scanFunctionSpecification(Scanner* scanner, SpecFile* specFile) {
+void FunctionSpecification::scanFunctionSpecification(Scanner* scanner, SpecFile* specFile,
+ int maxApiLevel) {
// Some functions like convert have # part of the name. Truncate at that point.
- string name = scanner->getValue();
+ const string& unexpandedName = scanner->getValue();
+ string name = unexpandedName;
size_t p = name.find('#');
if (p != string::npos) {
if (p > 0 && name[p - 1] == '_') {
@@ -505,6 +518,12 @@ void FunctionSpecification::scanFunctionSpecification(Scanner* scanner, SpecFile
}
name.erase(p);
}
+ VersionInfo info;
+ if (!info.scan(scanner, maxApiLevel)) {
+ cout << "Skipping some " << name << " definitions.\n";
+ scanner->skipUntilTag("end:");
+ return;
+ }
bool created = false;
Function* function = systemSpecification.findOrCreateFunction(name, &created);
@@ -512,10 +531,9 @@ void FunctionSpecification::scanFunctionSpecification(Scanner* scanner, SpecFile
function->addSpecification(spec);
specFile->addFunctionSpecification(spec, created);
- spec->mUnexpandedName = scanner->getValue();
+ spec->mUnexpandedName = unexpandedName;
spec->mTest = "scalar"; // default
-
- spec->scanVersionInfo(scanner);
+ spec->mVersionInfo = info;
if (scanner->findOptionalTag("attrib:")) {
spec->mAttribute = scanner->getValue();
@@ -666,7 +684,7 @@ void SpecFile::addFunctionSpecification(FunctionSpecification* spec, bool hasDoc
}
// Read the specification, adding the definitions to the global functions map.
-bool SpecFile::readSpecFile() {
+bool SpecFile::readSpecFile(int maxApiLevel) {
FILE* specFile = fopen(mSpecFileName.c_str(), "rt");
if (!specFile) {
cerr << "Error opening input file: " << mSpecFileName << "\n";
@@ -703,11 +721,11 @@ bool SpecFile::readSpecFile() {
}
const string tag = scanner.getNextTag();
if (tag == "function:") {
- FunctionSpecification::scanFunctionSpecification(&scanner, this);
+ FunctionSpecification::scanFunctionSpecification(&scanner, this, maxApiLevel);
} else if (tag == "type:") {
- TypeSpecification::scanTypeSpecification(&scanner, this);
+ TypeSpecification::scanTypeSpecification(&scanner, this, maxApiLevel);
} else if (tag == "constant:") {
- ConstantSpecification::scanConstantSpecification(&scanner, this);
+ ConstantSpecification::scanConstantSpecification(&scanner, this, maxApiLevel);
} else {
scanner.error() << "Expected function:, type:, or constant:. Found: " << tag << "\n";
return false;
@@ -759,9 +777,9 @@ Function* SystemSpecification::findOrCreateFunction(const string& name, bool* cr
return findOrCreate<Function>(name, &mFunctions, created);
}
-bool SystemSpecification::readSpecFile(const string& fileName) {
+bool SystemSpecification::readSpecFile(const string& fileName, int maxApiLevel) {
SpecFile* spec = new SpecFile(fileName);
- if (!spec->readSpecFile()) {
+ if (!spec->readSpecFile(maxApiLevel)) {
cerr << fileName << ": Failed to parse.\n";
return false;
}
@@ -769,9 +787,10 @@ bool SystemSpecification::readSpecFile(const string& fileName) {
return true;
}
-bool SystemSpecification::generateFiles(int versionOfTestFiles) const {
- bool success = generateHeaderFiles("scriptc") && generateHtmlDocumentation("html") &&
- generateTestFiles("test", versionOfTestFiles);
+bool SystemSpecification::generateFiles(bool forVerification, int maxApiLevel) const {
+ bool success = generateHeaderFiles("scriptc") &&
+ generateDocumentation("docs", forVerification) &&
+ generateTestFiles("test", maxApiLevel);
if (success) {
cout << "Successfully processed " << mTypes.size() << " types, " << mConstants.size()
<< " constants, and " << mFunctions.size() << " functions.\n";
diff --git a/api/Specification.h b/api/Specification.h
index abd9d9c1..e808e600 100644
--- a/api/Specification.h
+++ b/api/Specification.h
@@ -130,7 +130,11 @@ struct VersionInfo {
int intSize;
VersionInfo() : minVersion(0), maxVersion(0), intSize(0) {}
- void scan(Scanner* scanner);
+ /* Scan the version info from the spec file. maxApiLevel specifies the maximum level
+ * we are interested in. This may alter maxVersion. This method returns false if the
+ * minVersion is greater than the maxApiLevel.
+ */
+ bool scan(Scanner* scanner, int maxApiLevel);
};
// We have three type of definitions
@@ -249,7 +253,7 @@ public:
std::string getValue() const { return mValue; }
// Parse a constant specification and add it to specFile.
- static void scanConstantSpecification(Scanner* scanner, SpecFile* specFile);
+ static void scanConstantSpecification(Scanner* scanner, SpecFile* specFile, int maxApiLevel);
};
enum TypeKind {
@@ -295,7 +299,7 @@ public:
const std::vector<std::string>& getValueComments() const { return mValueComments; }
// Parse a type specification and add it to specFile.
- static void scanTypeSpecification(Scanner* scanner, SpecFile* specFile);
+ static void scanTypeSpecification(Scanner* scanner, SpecFile* specFile, int maxApiLevel);
};
// Maximum number of placeholders (like #1, #2) in function specifications.
@@ -344,7 +348,7 @@ private:
* This is the name with the #, e.g. convert_#1_#2
*/
std::string mUnexpandedName;
- ParameterEntry* mReturn; // The return type. The name should be empty. Owned.
+ ParameterEntry* mReturn; // The return type. The name should be empty. Owned.
std::vector<ParameterEntry*> mParameters; // The parameters. Owned.
std::vector<std::string> mInline; // The inline code to be included in the header
@@ -387,7 +391,7 @@ public:
bool hasTests(int versionOfTestFiles) const;
// Parse a function specification and add it to specFile.
- static void scanFunctionSpecification(Scanner* scanner, SpecFile* specFile);
+ static void scanFunctionSpecification(Scanner* scanner, SpecFile* specFile, int maxApiLevel);
};
/* A concrete version of a function specification, where all placeholders have been replaced by
@@ -494,7 +498,12 @@ public:
return mDocumentedFunctions;
}
- bool readSpecFile();
+ bool hasSpecifications() const {
+ return !mDocumentedConstants.empty() || !mDocumentedTypes.empty() ||
+ !mDocumentedFunctions.empty();
+ }
+
+ bool readSpecFile(int maxApiLevel);
/* These are called by the parser to keep track of the specifications defined in this file.
* hasDocumentation is true if this specification containes the documentation.
@@ -526,10 +535,12 @@ public:
Type* findOrCreateType(const std::string& name, bool* created);
Function* findOrCreateFunction(const std::string& name, bool* created);
- // Parse the spec file and create the object hierarchy, adding a pointer to mSpecFiles.
- bool readSpecFile(const std::string& fileName);
+ /* Parse the spec file and create the object hierarchy, adding a pointer to mSpecFiles.
+ * We won't include information passed the specified level.
+ */
+ bool readSpecFile(const std::string& fileName, int maxApiLevel);
// Generate all the files.
- bool generateFiles(int versionOfTestFiles) const;
+ bool generateFiles(bool forVerification, int maxApiLevel) const;
const std::vector<SpecFile*>& getSpecFiles() const { return mSpecFiles; }
const std::map<std::string, Constant*>& getConstants() const { return mConstants; }
diff --git a/api/generate.sh b/api/generate.sh
index e216e468..6dba16f2 100755
--- a/api/generate.sh
+++ b/api/generate.sh
@@ -16,25 +16,30 @@
#
set -e
-g++ Generator.cpp Specification.cpp GenerateHtmlDocumentation.cpp GenerateHeaderFiles.cpp GenerateTestFiles.cpp Scanner.cpp Utilities.cpp -g -std=c++11 -Wall -o generator
+g++ Generator.cpp Specification.cpp GenerateDocumentation.cpp GenerateHeaderFiles.cpp GenerateTestFiles.cpp Scanner.cpp Utilities.cpp -g -std=c++11 -Wall -o generator
mkdir -p test
mkdir -p scriptc
-mkdir -p html
+mkdir -p docs
-# Because rsIs/Clear/SetObject is documented in rs_object_info but also found in rs_graphics, the latter must appear
-# after the former.
-./generator rs_core.spec rs_value_types.spec rs_object_types.spec rs_allocation_data.spec rs_atomic.spec rs_convert.spec rs_debug.spec rs_for_each.spec rs_io.spec rs_math.spec rs_matrix.spec rs_object_info.spec rs_quaternion.spec rs_time.spec rs_vector_math.spec rs_graphics.spec
+# The order of the arguments passed to generator matter because:
+# 1. The overview is expected to be in the first file.
+# 2. The order specified will be the order they will show in the guide_toc.cs snippet.
+# This can be manually changed when cut&pasting the snippet into guide_toc.cs.
+# 3. rsIs/Clear/SetObject is documented in rs_object_info but also found in rs_graphics.
+# The latter must appear after the former.
+./generator rs_core.spec rs_value_types.spec rs_object_types.spec rs_convert.spec rs_math.spec rs_vector_math.spec rs_matrix.spec rs_quaternion.spec rs_atomic.spec rs_time.spec rs_allocation_data.spec rs_object_info.spec rs_for_each.spec rs_io.spec rs_debug.spec rs_graphics.spec
+
+rm generator
rm -f ../../../cts/tests/tests/renderscript/src/android/renderscript/cts/generated/*
mv test/* ../../../cts/tests/tests/renderscript/src/android/renderscript/cts/generated/
rmdir test
+rm -f ../scriptc/*.rsh
mv scriptc/*.rsh ../scriptc
rmdir scriptc
-# TODO handle the documentation files.
-rm html/*
-rmdir html
-
-rm generator
+rm -f ../../base/docs/html/guide/topics/renderscript/reference/*.jd
+mv docs/*.jd ../../base/docs/html/guide/topics/renderscript/reference/
+echo "Be sure to update platform/frameworks/base/docs/html/guide/guide_toc.cs if needed."
diff --git a/api/rs_core.spec b/api/rs_core.spec
index 51b5dd74..1643c453 100644
--- a/api/rs_core.spec
+++ b/api/rs_core.spec
@@ -17,17 +17,18 @@
header:
summary: Overview
description:
-# TODO move elsewhere?
- RenderScript is a high-performance runtime that provides
- compute operations at the native level. RenderScript code is compiled on devices
- at runtime to allow platform-independence as well.
- This reference documentation describes the RenderScript runtime APIs, which you
- can utilize to write RenderScript code in C99. The RenderScript compute header
- files are automatically included for you.
+ RenderScript is a high-performance runtime that provides compute operations at the native level.
+ RenderScript code is compiled on devices at runtime to allow platform-independence as well.
+
+ This reference documentation describes the RenderScript runtime APIs, which you can utilize
+ to write RenderScript code in C99. The RenderScript compute header files are automatically
+ included for you.
To use RenderScript, you need to utilize the RenderScript runtime APIs documented here
as well as the Android framework APIs for RenderScript.
+
For documentation on the Android framework APIs, see the <a target="_parent" href="http://developer.android.com/reference/android/renderscript/package-summary.html">android.renderscript</a> package reference.
+
For more information on how to develop with RenderScript and how the runtime and
Android framework APIs interact, see the <a target="_parent" href="http://developer.android.com/guide/topics/renderscript/index.html">RenderScript developer guide</a>
and the <a target="_parent" href="http://developer.android.com/resources/samples/RenderScript/index.html">RenderScript samples</a>.
diff --git a/api/rs_object_types.spec b/api/rs_object_types.spec
index d0317efa..e58cd042 100644
--- a/api/rs_object_types.spec
+++ b/api/rs_object_types.spec
@@ -45,7 +45,8 @@ simple: _RS_HANDLE
summary: Handle to an element
description:
Opaque handle to a RenderScript element.
- See: android.renderscript.Element
+
+ See <a href="http://developer.android.com/reference/android/renderscript/Element.html">android.renderscript.Element</a>.
end:
type: rs_type
@@ -53,7 +54,8 @@ simple: _RS_HANDLE
summary: Handle to a Type
description:
Opaque handle to a RenderScript type.
- See: android.renderscript.Type
+
+ See <a href="http://developer.android.com/reference/android/renderscript/Type.html">android.renderscript.Type</a>.
end:
type: rs_allocation
@@ -61,7 +63,8 @@ simple: _RS_HANDLE
summary: Handle to an allocation
description:
Opaque handle to a RenderScript allocation.
- See: android.renderscript.Allocation
+
+ See <a href="http://developer.android.com/reference/android/renderscript/Allocation.html">android.renderscript.Allocation</a>.
end:
type: rs_sampler
@@ -69,7 +72,8 @@ simple: _RS_HANDLE
summary: Handle to a Sampler
description:
Opaque handle to a RenderScript sampler object.
- See: android.renderscript.Sampler
+
+ See <a href="http://developer.android.com/reference/android/renderscript/Sampler.html">android.renderscript.Sampler</a>.
end:
type: rs_script
@@ -77,7 +81,8 @@ simple: _RS_HANDLE
summary: Handle to a Script
description:
Opaque handle to a RenderScript script object.
- See: android.renderscript.ScriptC
+
+ See <a href="http://developer.android.com/reference/android/renderscript/ScriptC.html">android.renderscript.ScriptC</a>.
end:
type: rs_allocation_cubemap_face