aconfig: restrict valid namespace and flag names
The namespace and flag names will be used as identifiers in the
auto-generated code. Place restrictions on what constitutes a valid
name.
Valid identifiers are those that match /[a-z][a-z0-9_]/. aconfig
explicitly does not implement any automatic translation to make names
valid identifiers: this sidesteps potential conflicts such as "foo.bar"
and "foo_bar" mapping to the same name if dots were translated to
underscores.
Bug: b/284252015
Test: atest aconfig.test
Change-Id: I38d005a74311e5829e540063404d1565071e6e96
diff --git a/tools/aconfig/src/codegen.rs b/tools/aconfig/src/codegen.rs
new file mode 100644
index 0000000..b60ec51
--- /dev/null
+++ b/tools/aconfig/src/codegen.rs
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+pub fn is_valid_identifier(s: &str) -> bool {
+ // Identifiers must match [a-z][a-z0-9_]*
+ let mut chars = s.chars();
+ let Some(first) = chars.next() else {
+ return false;
+ };
+ if !first.is_ascii_lowercase() {
+ return false;
+ }
+ chars.all(|ch| ch.is_ascii_lowercase() || ch.is_ascii_digit() || ch == '_')
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_is_valid_identifier() {
+ assert!(is_valid_identifier("foo"));
+ assert!(is_valid_identifier("foo_bar_123"));
+
+ assert!(!is_valid_identifier(""));
+ assert!(!is_valid_identifier("123_foo"));
+ assert!(!is_valid_identifier("foo-bar"));
+ assert!(!is_valid_identifier("foo-b\u{00e5}r"));
+ }
+}