]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
qapi: Smarter camel_to_upper() to reduce need for 'prefix'
authorMarkus Armbruster <armbru@redhat.com>
Wed, 4 Sep 2024 11:18:18 +0000 (13:18 +0200)
committerMarkus Armbruster <armbru@redhat.com>
Tue, 10 Sep 2024 11:22:47 +0000 (13:22 +0200)
camel_to_upper() converts its argument from camel case to upper case
with '_' between words.  Used for generated enumeration constant
prefixes.

When some of the words are spelled all caps, where exactly to insert
'_' is guesswork.  camel_to_upper()'s guesses are bad enough in places
to make people override them with a 'prefix' in the schema.

Rewrite it to guess better:

1. Insert '_' after a non-upper case character followed by an upper
   case character:

       OneTwo -> ONE_TWO
       One2Three -> ONE2_THREE

2. Insert '_' before the last upper case character followed by a
   non-upper case character:

       ACRONYMWord -> ACRONYM_Word

   Except at the beginning (as in OneTwo above), or when there is
   already one:

       AbCd -> AB_CD

This changes the default enumeration constant prefix for a number of
enums.  Generated enumeration constants change only where the default
is not overridden with 'prefix'.

The following enumerations without a 'prefix' change:

    enum                            old camel_to_upper()
                                    new camel_to_upper()
    ------------------------------------------------------------------
    DisplayGLMode                   DISPLAYGL_MODE
                                    DISPLAY_GL_MODE
    EbpfProgramID                   EBPF_PROGRAMID
                                    EBPF_PROGRAM_ID
    HmatLBDataType                  HMATLB_DATA_TYPE
                                    HMAT_LB_DATA_TYPE
    HmatLBMemoryHierarchy           HMATLB_MEMORY_HIERARCHY
                                    HMAT_LB_MEMORY_HIERARCHY
    MultiFDCompression              MULTIFD_COMPRESSION
                                    MULTI_FD_COMPRESSION
    OffAutoPCIBAR                   OFF_AUTOPCIBAR
                                    OFF_AUTO_PCIBAR
    QCryptoBlockFormat              Q_CRYPTO_BLOCK_FORMAT
                                    QCRYPTO_BLOCK_FORMAT
    QCryptoBlockLUKSKeyslotState    Q_CRYPTO_BLOCKLUKS_KEYSLOT_STATE
                                    QCRYPTO_BLOCK_LUKS_KEYSLOT_STATE
    QKeyCode                        Q_KEY_CODE
                                    QKEY_CODE
    XDbgBlockGraphNodeType          X_DBG_BLOCK_GRAPH_NODE_TYPE
                                    XDBG_BLOCK_GRAPH_NODE_TYPE
    TestUnionEnumA                  TEST_UNION_ENUMA
                                    TEST_UNION_ENUM_A

Add a 'prefix' so generated code doesn't change now.  Subsequent
commits will remove most of them again.  Two will remain:
MULTIFD_COMPRESSION, because migration code generally spells "multifd"
that way, and Q_KEY_CODE, because that one is baked into
subprojects/keycodemapdb/tools/keymap-gen.

The following enumerations with a 'prefix' change so that the prefix
is now superfluous:

    enum                            old camel_to_upper()
                                    new camel_to_upper() [equal to prefix]
    ------------------------------------------------------------------
    BlkdebugIOType                  BLKDEBUGIO_TYPE
                                    BLKDEBUG_IO_TYPE
    QCryptoTLSCredsEndpoint         Q_CRYPTOTLS_CREDS_ENDPOINT
                                    QCRYPTO_TLS_CREDS_ENDPOINT
    QCryptoSecretFormat             Q_CRYPTO_SECRET_FORMAT
                                    QCRYPTO_SECRET_FORMAT
    QCryptoCipherMode               Q_CRYPTO_CIPHER_MODE
                                    QCRYPTO_CIPHER_MODE
    QCryptodevBackendType           Q_CRYPTODEV_BACKEND_TYPE
                                    QCRYPTODEV_BACKEND_TYPE
    QType [builtin]                 Q_TYPE
                                    QTYPE

Drop these prefixes.

The following enumerations with a 'prefix' change without making the
'prefix' superfluous:

    enum                            old camel_to_upper()
                                    new camel_to_upper() [equal to prefix]
                                    prefix
    ------------------------------------------------------------------
    CpuS390Entitlement              CPUS390_ENTITLEMENT
                                    CPU_S390_ENTITLEMENT
                                    S390_CPU_ENTITLEMENT
    CpuS390Polarization             CPUS390_POLARIZATION
                                    CPU_S390_POLARIZATION
                                    S390_CPU_POLARIZATION
    CpuS390State                    CPUS390_STATE
                                    CPU_S390_STATE
                                    S390_CPU_STATE
    QAuthZListFormat                Q_AUTHZ_LIST_FORMAT
                                    QAUTH_Z_LIST_FORMAT
                                    QAUTHZ_LIST_FORMAT
    QAuthZListPolicy                Q_AUTHZ_LIST_POLICY
                                    QAUTH_Z_LIST_POLICY
                                    QAUTHZ_LIST_POLICY
    QCryptoAkCipherAlgorithm        Q_CRYPTO_AK_CIPHER_ALGORITHM
                                    QCRYPTO_AK_CIPHER_ALGORITHM
                                    QCRYPTO_AKCIPHER_ALG
    QCryptoAkCipherKeyType          Q_CRYPTO_AK_CIPHER_KEY_TYPE
                                    QCRYPTO_AK_CIPHER_KEY_TYPE
                                    QCRYPTO_AKCIPHER_KEY_TYPE
    QCryptoCipherAlgorithm          Q_CRYPTO_CIPHER_ALGORITHM
                                    QCRYPTO_CIPHER_ALGORITHM
                                    QCRYPTO_CIPHER_ALG
    QCryptoHashAlgorithm            Q_CRYPTO_HASH_ALGORITHM
                                    QCRYPTO_HASH_ALGORITHM
                                    QCRYPTO_HASH_ALG
    QCryptoIVGenAlgorithm           Q_CRYPTOIV_GEN_ALGORITHM
                                    QCRYPTO_IV_GEN_ALGORITHM
                                    QCRYPTO_IVGEN_ALG
    QCryptoRSAPaddingAlgorithm      Q_CRYPTORSA_PADDING_ALGORITHM
                                    QCRYPTO_RSA_PADDING_ALGORITHM
                                    QCRYPTO_RSA_PADDING_ALG
    QCryptodevBackendAlgType        Q_CRYPTODEV_BACKEND_ALG_TYPE
                                    QCRYPTODEV_BACKEND_ALG_TYPE
                                    QCRYPTODEV_BACKEND_ALG
    QCryptodevBackendServiceType    Q_CRYPTODEV_BACKEND_SERVICE_TYPE
                                    QCRYPTODEV_BACKEND_SERVICE_TYPE
                                    QCRYPTODEV_BACKEND_SERVICE

Subsequent commits will tweak things to remove most of these prefixes.
Only QAUTHZ_LIST_FORMAT and QAUTHZ_LIST_POLICY will remain.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20240904111836.3273842-2-armbru@redhat.com>

19 files changed:
qapi/block-core.json
qapi/common.json
qapi/crypto.json
qapi/cryptodev.json
qapi/ebpf.json
qapi/machine.json
qapi/migration.json
qapi/ui.json
scripts/qapi/common.py
scripts/qapi/schema.py
tests/qapi-schema/alternate-array.out
tests/qapi-schema/comments.out
tests/qapi-schema/doc-good.out
tests/qapi-schema/empty.out
tests/qapi-schema/include-repetition.out
tests/qapi-schema/include-simple.out
tests/qapi-schema/indented-expr.out
tests/qapi-schema/qapi-schema-test.json
tests/qapi-schema/qapi-schema-test.out

index aa40d44f1db6b1fa0a18b6b095cacb8d9d19c040..452047102ac7ef717f280ac2d9094118fe003798 100644 (file)
 # Since: 4.0
 ##
 { 'enum': 'XDbgBlockGraphNodeType',
+  'prefix': 'X_DBG_BLOCK_GRAPH_NODE_TYPE', # TODO drop
   'data': [ 'block-backend', 'block-job', 'block-driver' ] }
 
 ##
 #
 # Since: 4.1
 ##
-{ 'enum': 'BlkdebugIOType', 'prefix': 'BLKDEBUG_IO_TYPE',
+{ 'enum': 'BlkdebugIOType',
   'data': [ 'read', 'write', 'write-zeroes', 'discard', 'flush',
             'block-status' ] }
 
index 7558ce5430d5cbccd11c03ba8296ea0618bc64c0..25726d3113c18b75e67577b620c4202515ea5f4e 100644 (file)
@@ -92,6 +92,7 @@
 # Since: 2.12
 ##
 { 'enum': 'OffAutoPCIBAR',
+  'prefix': 'OFF_AUTOPCIBAR',   # TODO drop
   'data': [ 'off', 'auto', 'bar0', 'bar1', 'bar2', 'bar3', 'bar4', 'bar5' ] }
 
 ##
index 97e02dbd59eda6a880f1bda66c90a839bd57dcfe..a192641a033ffe222b3c1fb425f86a4dbd1375d8 100644 (file)
@@ -20,7 +20,6 @@
 # Since: 2.5
 ##
 { 'enum': 'QCryptoTLSCredsEndpoint',
-  'prefix': 'QCRYPTO_TLS_CREDS_ENDPOINT',
   'data': ['client', 'server']}
 
 ##
@@ -36,7 +35,6 @@
 # Since: 2.6
 ##
 { 'enum': 'QCryptoSecretFormat',
-  'prefix': 'QCRYPTO_SECRET_FORMAT',
   'data': ['raw', 'base64']}
 
 ##
 # Since: 2.6
 ##
 { 'enum': 'QCryptoCipherMode',
-  'prefix': 'QCRYPTO_CIPHER_MODE',
   'data': ['ecb', 'cbc', 'xts', 'ctr']}
 
 ##
 # Since: 2.6
 ##
 { 'enum': 'QCryptoBlockFormat',
-#  'prefix': 'QCRYPTO_BLOCK_FORMAT',
+  'prefix': 'Q_CRYPTO_BLOCK_FORMAT', # TODO drop
   'data': ['qcow', 'luks']}
 
 ##
 # Since: 5.1
 ##
 { 'enum': 'QCryptoBlockLUKSKeyslotState',
+  'prefix': 'Q_CRYPTO_BLOCKLUKS_KEYSLOT_STATE', # TODO drop
   'data': [ 'active', 'inactive' ] }
 
 ##
index 68289f49840b767d6952bc0b890b4416c5a1334b..60f8fe8e4ad9c3e2722394faefbed6deb521b2dd 100644 (file)
@@ -48,7 +48,6 @@
 # Since: 8.0
 ##
 { 'enum': 'QCryptodevBackendType',
-  'prefix': 'QCRYPTODEV_BACKEND_TYPE',
   'data': ['builtin', 'vhost-user', 'lkcf']}
 
 ##
index db19ae850fcc2412e59a77921dae8c5b5ba780e6..42df54877788a1e7275d1240f394d0bfe6b4c709 100644 (file)
@@ -42,6 +42,7 @@
 # Since: 9.0
 ##
 { 'enum': 'EbpfProgramID',
+  'prefix': 'EBPF_PROGRAMID',   # TODO drop
   'if': 'CONFIG_EBPF',
   'data': [ { 'name': 'rss' } ] }
 
index d4317435e762eefea8395b07f3d91ad6008dfb53..552d1c20e9ab42124efa4d075c7ed680a18b7fc6 100644 (file)
 # Since: 5.0
 ##
 { 'enum': 'HmatLBMemoryHierarchy',
+  'prefix': 'HMATLB_MEMORY_HIERARCHY', # TODO drop
   'data': [ 'memory', 'first-level', 'second-level', 'third-level' ] }
 
 ##
 # Since: 5.0
 ##
 { 'enum': 'HmatLBDataType',
+  'prefix': 'HMATLB_DATA_TYPE', # TODO drop
   'data': [ 'access-latency', 'read-latency', 'write-latency',
             'access-bandwidth', 'read-bandwidth', 'write-bandwidth' ] }
 
index 7324571e92be4e666df89d6d3658bf77139da5f7..f0ff7b93b401b15fd647efb141cc69b4730e19c5 100644 (file)
 # Since: 5.0
 ##
 { 'enum': 'MultiFDCompression',
+  'prefix': 'MULTIFD_COMPRESSION',
   'data': [ 'none', 'zlib',
             { 'name': 'zstd', 'if': 'CONFIG_ZSTD' },
             { 'name': 'qpl', 'if': 'CONFIG_QPL' },
index 8c8464faac20106c1977f172038d022149e9189c..f61a2b6b655185ffb6884e4ffa1a00e3bae9936e 100644 (file)
 # Since: 1.3
 ##
 { 'enum': 'QKeyCode',
+  'prefix': 'Q_KEY_CODE',
   'data': [ 'unmapped',
             'shift', 'shift_r', 'alt', 'alt_r', 'ctrl',
             'ctrl_r', 'menu', 'esc', '1', '2', '3', '4', '5', '6', '7', '8',
 # Since: 3.0
 ##
 { 'enum'    : 'DisplayGLMode',
+  'prefix'  : 'DISPLAYGL_MODE', # TODO drop
   'data'    : [ 'off', 'on', 'core', 'es' ] }
 
 ##
index 737b059e629142f90fd5229f70416838c1f7c426..d7c8aa3365c6f7638a7e8709f03e0facc7571113 100644 (file)
@@ -40,22 +40,28 @@ def camel_to_upper(value: str) -> str:
         ENUM_Name2 -> ENUM_NAME2
         ENUM24_Name -> ENUM24_NAME
     """
-    c_fun_str = c_name(value, False)
-    if value.isupper():
-        return c_fun_str
-
-    new_name = ''
-    length = len(c_fun_str)
-    for i in range(length):
-        char = c_fun_str[i]
-        # When char is upper case and no '_' appears before, do more checks
-        if char.isupper() and (i > 0) and c_fun_str[i - 1] != '_':
-            if i < length - 1 and c_fun_str[i + 1].islower():
-                new_name += '_'
-            elif c_fun_str[i - 1].isdigit():
-                new_name += '_'
-        new_name += char
-    return new_name.lstrip('_').upper()
+    ret = value[0]
+    upc = value[0].isupper()
+
+    # Copy remainder of ``value`` to ``ret`` with '_' inserted
+    for ch in value[1:]:
+        if ch.isupper() == upc:
+            pass
+        elif upc:
+            # ``ret`` ends in upper case, next char isn't: insert '_'
+            # before the last upper case char unless there is one
+            # already, or it's at the beginning
+            if len(ret) > 2 and ret[-2].isalnum():
+                ret = ret[:-1] + '_' + ret[-1]
+        else:
+            # ``ret`` doesn't end in upper case, next char is: insert
+            # '_' before it
+            if ret[-1].isalnum():
+                ret += '_'
+        ret += ch
+        upc = ch.isupper()
+
+    return c_name(ret.upper()).lstrip('_')
 
 
 def c_enum_const(type_name: str,
@@ -68,9 +74,9 @@ def c_enum_const(type_name: str,
     :param const_name: The name of this constant.
     :param prefix: Optional, prefix that overrides the type_name.
     """
-    if prefix is not None:
-        type_name = prefix
-    return camel_to_upper(type_name) + '_' + c_name(const_name, False).upper()
+    if prefix is None:
+        prefix = camel_to_upper(type_name)
+    return prefix + '_' + c_name(const_name, False).upper()
 
 
 def c_name(name: str, protect: bool = True) -> str:
index d65c35f6ee67e07a56c02badc4b57d2e6a451f5f..e97c978d38d94a7b4b797606e0f00da100a4635d 100644 (file)
@@ -1249,7 +1249,7 @@ class QAPISchema:
             [{'name': n} for n in qtypes], None)
 
         self._def_definition(QAPISchemaEnumType(
-            'QType', None, None, None, None, qtype_values, 'QTYPE'))
+            'QType', None, None, None, None, qtype_values, None))
 
     def _make_features(
         self,
index a657d85738f72e62243352f17ae66d8ff8c7080c..2f30973ac3fa3376ddab671b223c6f9e29da261d 100644 (file)
@@ -1,7 +1,6 @@
 module ./builtin
 object q_empty
 enum QType
-    prefix QTYPE
     member none
     member qnull
     member qnum
index ce4f6a4f0f56f56607479d3eeec83137f20a32e5..937070c2c423d36ad420797d0a9d72654e4fda00 100644 (file)
@@ -1,7 +1,6 @@
 module ./builtin
 object q_empty
 enum QType
-    prefix QTYPE
     member none
     member qnull
     member qnum
index 6d24f1127b908e3326753647302e7f563d901b75..ec277be91e92640fb07902f51635cdfe7e3a7b9b 100644 (file)
@@ -1,7 +1,6 @@
 module ./builtin
 object q_empty
 enum QType
-    prefix QTYPE
     member none
     member qnull
     member qnum
index 3feb3f69d3d68b584c40dc2425b79862bbc43fa2..d1981f858612d0bfc86832eeaf0f75ac0c1c9e16 100644 (file)
@@ -1,7 +1,6 @@
 module ./builtin
 object q_empty
 enum QType
-    prefix QTYPE
     member none
     member qnull
     member qnum
index 16dbd9b8194fa76ea016451aa86094b4743b527e..c564d2786267074df3c6f766d1e4206a808f3913 100644 (file)
@@ -1,7 +1,6 @@
 module ./builtin
 object q_empty
 enum QType
-    prefix QTYPE
     member none
     member qnull
     member qnum
index 48e923bfbc8f31bd2f6114b448c07c4cc3b94cdc..ec8200ab18b1d3f96abd2caa7e7e2015d7216d89 100644 (file)
@@ -1,7 +1,6 @@
 module ./builtin
 object q_empty
 enum QType
-    prefix QTYPE
     member none
     member qnull
     member qnum
index 6a30ded3fa655020b18b00435c60b2d0cd874e9c..a7c22c3eefc36688c0b0248623cdc1dd3b9d9922 100644 (file)
@@ -1,7 +1,6 @@
 module ./builtin
 object q_empty
 enum QType
-    prefix QTYPE
     member none
     member qnull
     member qnum
index 8ca977c49d2935e158daa9cda3db45b094cfa82b..0f5f54e621618d139e4411e0950d440d8e7b8797 100644 (file)
   'data': [ 'value-a', 'value-b' ] }
 
 { 'enum': 'TestUnionEnumA',
+  'prefix': 'TEST_UNION_ENUMA', # TODO drop
   'data': [ 'value-a1', 'value-a2' ] }
 
 { 'struct': 'TestUnionTypeA1',
index e2f0981348b3212a30841092f87af379f7b70c5e..add7346f49d08108b4b14cc8966d35cb8383933c 100644 (file)
@@ -1,7 +1,6 @@
 module ./builtin
 object q_empty
 enum QType
-    prefix QTYPE
     member none
     member qnull
     member qnum
@@ -109,6 +108,7 @@ enum TestUnionEnum
     member value-a
     member value-b
 enum TestUnionEnumA
+    prefix TEST_UNION_ENUMA
     member value-a1
     member value-a2
 object TestUnionTypeA1