diff options
author | Jean-Luc Brouillet <jeanluc@google.com> | 2015-04-25 05:53:04 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-04-25 05:53:04 +0000 |
commit | d57865a769071ccde7acc5287fb25a0f31bd0a4d (patch) | |
tree | 5617848e1fd2f72afc04ed822b97e4b778eaad94 | |
parent | b0f2fe01d4807c8febae5c6efb3a4e5d18b82837 (diff) | |
parent | 995642feedc8009ebad48a35210e43740401166e (diff) | |
download | android_frameworks_rs-d57865a769071ccde7acc5287fb25a0f31bd0a4d.tar.gz android_frameworks_rs-d57865a769071ccde7acc5287fb25a0f31bd0a4d.tar.bz2 android_frameworks_rs-d57865a769071ccde7acc5287fb25a0f31bd0a4d.zip |
am 995642fe: am 28af516b: am 3682d65a: Merge "Update documentation generator to work with the Documentation system."
* commit '995642feedc8009ebad48a35210e43740401166e':
Update documentation generator to work with the Documentation system.
-rw-r--r-- | api/GenerateDocumentation.cpp (renamed from api/GenerateHtmlDocumentation.cpp) | 212 | ||||
-rw-r--r-- | api/Generator.cpp | 22 | ||||
-rw-r--r-- | api/Generator.h | 7 | ||||
-rw-r--r-- | api/Scanner.cpp | 6 | ||||
-rw-r--r-- | api/Scanner.h | 2 | ||||
-rw-r--r-- | api/Specification.cpp | 71 | ||||
-rw-r--r-- | api/Specification.h | 29 | ||||
-rwxr-xr-x | api/generate.sh | 25 | ||||
-rw-r--r-- | api/rs_core.spec | 15 | ||||
-rw-r--r-- | api/rs_object_types.spec | 15 | ||||
-rw-r--r-- | scriptc/rs_core.rsh | 14 | ||||
-rw-r--r-- | scriptc/rs_object_types.rsh | 15 |
12 files changed, 268 insertions, 165 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: "; 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 diff --git a/scriptc/rs_core.rsh b/scriptc/rs_core.rsh index be9f7fa0..f242890a 100644 --- a/scriptc/rs_core.rsh +++ b/scriptc/rs_core.rsh @@ -19,16 +19,18 @@ /* * rs_core.rsh: Overview * - * 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 android.renderscript package reference. + * * For more information on how to develop with RenderScript and how the runtime and * Android framework APIs interact, see the RenderScript developer guide * and the RenderScript samples. diff --git a/scriptc/rs_object_types.rsh b/scriptc/rs_object_types.rsh index 0fc5e4da..43c89db5 100644 --- a/scriptc/rs_object_types.rsh +++ b/scriptc/rs_object_types.rsh @@ -49,7 +49,8 @@ struct {\ * rs_element: Handle to an element * * Opaque handle to a RenderScript element. - * See: android.renderscript.Element + * + * See android.renderscript.Element. */ typedef _RS_HANDLE rs_element; @@ -57,7 +58,8 @@ typedef _RS_HANDLE rs_element; * rs_type: Handle to a Type * * Opaque handle to a RenderScript type. - * See: android.renderscript.Type + * + * See android.renderscript.Type. */ typedef _RS_HANDLE rs_type; @@ -65,7 +67,8 @@ typedef _RS_HANDLE rs_type; * rs_allocation: Handle to an allocation * * Opaque handle to a RenderScript allocation. - * See: android.renderscript.Allocation + * + * See android.renderscript.Allocation. */ typedef _RS_HANDLE rs_allocation; @@ -73,7 +76,8 @@ typedef _RS_HANDLE rs_allocation; * rs_sampler: Handle to a Sampler * * Opaque handle to a RenderScript sampler object. - * See: android.renderscript.Sampler + * + * See android.renderscript.Sampler. */ typedef _RS_HANDLE rs_sampler; @@ -81,7 +85,8 @@ typedef _RS_HANDLE rs_sampler; * rs_script: Handle to a Script * * Opaque handle to a RenderScript script object. - * See: android.renderscript.ScriptC + * + * See android.renderscript.ScriptC. */ typedef _RS_HANDLE rs_script; |