blob: 38b05769eac5937e635d1b8891fbaec969561901 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package parser
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.system.exitProcess
const val LOG_NAME = "[hidl-doc]"
fun printUsage() {
println("""
Usage: hidl-doc [-i path]
-i=path Add input HAL file or directory to parse
-o=dir Output directory of generated HTML
-x=path Exclude file or directory from files to parse
-v Verbose mode, print parsing info
-h Print this help and exit
Error modes:
-w Warn on errors instead of exiting
-l Lint. Warn-only and do not generate files
""".trim())
}
object config {
val files = mutableListOf<File>()
lateinit var outDir: Path
var verbose = false
var lintMode = false
var warnOnly = false
override fun toString(): String {
return """
verbose: $verbose
warnOnly: $warnOnly
outDir: $outDir
files: $files
"""
}
private const val HAL_EXTENSION = ".hal"
fun parseArgs(args: Array<String>) {
if (args.isEmpty()) {
printUsage()
exitProcess(1)
}
val dirPathArgs = mutableListOf<Path>()
val filePathArgs = mutableListOf<Path>()
val excludedPathArgs = mutableListOf<Path>()
var maybeOutDir: Path? = null
val iter = args.iterator()
//parse command-line arguments
while (iter.hasNext()) {
var arg = iter.next()
when (arg) {
"-i" -> {
val path = Paths.get(iter.next())
if (Files.isDirectory(path)) dirPathArgs.add(path) else filePathArgs.add(path)
}
"-x" -> excludedPathArgs.add(Paths.get(iter.next()).toAbsolutePath())
"-o" -> maybeOutDir = Paths.get(iter.next())
"-v" -> verbose = true
"-l" -> { lintMode = true; warnOnly = true }
"-w" -> warnOnly = true
"-h" -> {
printUsage()
exitProcess(0)
}
else -> {
System.err.println("Unknown option: $arg")
printUsage()
exitProcess(1)
}
}
}
if (maybeOutDir == null) {
System.err.println("Error: No output directory supplied (-o)")
exitProcess(1)
}
outDir = maybeOutDir
//collect files (explicitly passed and search directories)
val allFiles = mutableListOf<File>()
//add individual files
filePathArgs.filterNot { excludedPathArgs.contains(it.toAbsolutePath()) }
.map { it.toFile() }.map { fp ->
if (!fp.isFile || !fp.canRead() || !fp.absolutePath.toLowerCase().endsWith(HAL_EXTENSION)) {
System.err.println("Error: Invalid $HAL_EXTENSION file: ${fp.path}")
exitProcess(1)
}
fp
}.map { allFiles.add(it) }
//check directory args
dirPathArgs.map { it.toFile() }
.map { findFiles(it, allFiles, HAL_EXTENSION, excludedPathArgs) }
//consolidate duplicates
allFiles.distinctBy { it.canonicalPath }
.forEach { files.add(it) }
if (files.isEmpty()) {
System.err.println("Error: Can't find any $HAL_EXTENSION files")
exitProcess(1)
}
}
/**
* Recursively search for files in a directory matching an extension and add to files.
*/
private fun findFiles(dir: File, files: MutableList<File>, ext: String, excludedPaths: List<Path>) {
if (!dir.isDirectory || !dir.canRead()) {
System.err.println("Invalid directory: ${dir.path}, aborting")
exitProcess(1)
}
dir.listFiles()
.filterNot { excludedPaths.contains(it.toPath().toAbsolutePath()) }
.forEach { fp ->
if (fp.isDirectory) {
findFiles(fp, files, ext, excludedPaths)
} else if (fp.absolutePath.toLowerCase().endsWith(ext)) {
files.add(fp)
}
}
}
}