1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.hoststubgen
17 
18 /**
19  * Name of this executable. Set it in the main method.
20  */
21 var executableName = "[command name not set]"
22 
23 /**
24  * A regex that maches whitespate.
25  */
26 val whitespaceRegex = """\s+""".toRegex()
27 
28 /**
29  * Remove the comment ('#' and following) and surrounding whitespace from a line.
30  */
normalizeTextLinenull31 fun normalizeTextLine(s: String): String {
32     // Remove # and after. (comment)
33     val pos = s.indexOf('#')
34     val uncommented = if (pos < 0) s else s.substring(0, pos)
35 
36     // Remove surrounding whitespace.
37     return uncommented.trim()
38 }
39 
40 /**
41  * Concatenate list [a] and [b] and return it. As an optimization, it returns an input
42  * [List] as-is if the other [List] is empty, so do not modify input [List]'s.
43  */
addListsnull44 fun <T> addLists(a: List<T>, b: List<T>): List<T> {
45     if (a.isEmpty()) {
46         return b
47     }
48     if (b.isEmpty()) {
49         return a
50     }
51     return a + b
52 }
53 
54 /**
55  * Add element [b] to list [a] if [b] is not null. Otherwise, just return [a].
56  * (because the method may return [a] as-is, do not modify it after passing it.)
57  */
addNonNullElementnull58 fun <T> addNonNullElement(a: List<T>, b: T?): List<T> {
59     if (b == null) {
60         return a
61     }
62     if (a.isEmpty()) {
63         return listOf(b)
64     }
65     return a + b
66 }
67 
68 
69 /**
70  * Exception for a parse error in a file
71  */
72 class ParseException : Exception, UserErrorException {
73     val hasSourceInfo: Boolean
74 
75     constructor(message: String) : super(message) {
76         hasSourceInfo = false
77     }
78 
79     constructor(message: String, file: String, line: Int) :
80             super("$message in file $file line $line") {
81         hasSourceInfo = true
82     }
83 
withSourceInfonull84     fun withSourceInfo(filename: String, lineNo: Int): ParseException {
85         if (hasSourceInfo) {
86             return this // Already has source information.
87         } else {
88             return ParseException(this.message ?: "", filename, lineNo)
89         }
90     }
91 }
92 
93 /**
94  * Escape a string for a CSV field.
95  */
csvEscapenull96 fun csvEscape(value: String): String {
97     return "\"" + value.replace("\"", "\"\"") + "\""
98 }
99