CORD-1335: Support singularization in addition to pluralization

Change-Id: Id301def2ed5cd50985b28744e4786275652a944b
diff --git a/xos/genx/tool/lib.py b/xos/genx/tool/lib.py
index 3c68d46..99484e6 100644
--- a/xos/genx/tool/lib.py
+++ b/xos/genx/tool/lib.py
@@ -2,10 +2,25 @@
 import re
 from pattern import en
 
+def unquote(s):
+    if (s.startswith('"') and s.endswith('"')):
+        return s[1:-1]
+
+def xproto_singularize(field):
+    try:
+        # The user has set a singular, as an exception that cannot be handled automatically
+        singular = field['options']['singular']
+        singular = unquote(singular)
+    except KeyError:
+        singular = en.singularize(field['name'])
+
+    return singular
+
 def xproto_pluralize(field):
     try:
         # The user has set a plural, as an exception that cannot be handled automatically
         plural = field['options']['plural']
+        plural = unquote(plural)
     except KeyError:
         plural = en.pluralize(field['name'])
 
diff --git a/xos/genx/tool/tests/target_test.py b/xos/genx/tool/tests/target_test.py
index f39a994..282326b 100644
--- a/xos/genx/tool/tests/target_test.py
+++ b/xos/genx/tool/tests/target_test.py
@@ -28,6 +28,30 @@
         self.generate(target=target, kv='what:what is what')
         self.assertIn("what is what", self.get_output())
 
+    def test_singularize(self):
+        proto = \
+"""
+  message TestSingularize {
+      // The following field has an explicitly specified singular
+      required int many = 1 [singular = "one"];
+      // The following fields have automatically computed singulars
+      required int sheep = 2;
+      required int radii = 2;
+      required int slices = 2;
+      required int networks = 2;
+      required int omf_friendlies = 2;
+  }
+"""
+
+        target = \
+"""
+{% for m in proto.messages.0.fields -%}
+{{ xproto_singularize(m) }},
+{%- endfor %}
+"""
+        self.generate(xproto=proto, target=target)
+        self.assertEqual("one,sheep,radius,slice,network,omf_friendly", self.get_output().lstrip().rstrip().rstrip(','))
+
     def test_pluralize(self):
         proto = \
 """