qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 05/25] qapi: Clean up member name case checking


From: Markus Armbruster
Subject: Re: [PATCH 05/25] qapi: Clean up member name case checking
Date: Tue, 24 Sep 2019 22:20:09 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux)

Eric Blake <address@hidden> writes:

> On 9/24/19 8:28 AM, Markus Armbruster wrote:
>> QAPISchemaMember.check_clash() checks for member names that map to the
>> same c_name().  Takes care of rejecting duplicate names.
>> 
>> It also checks a naming rule: no uppercase in member names.  That's a
>> rather odd place to do it.  Enforcing naming rules is
>> check_name_str()'s job.
>> 
>> qapi-code-gen.txt specifies the name case rule applies to the name as
>> it appears in the schema.  check_clash() checks c_name(name) instead.
>> No difference, as c_name() leaves alone case, but unclean.
>> 
>> Move the name case check into check_name_str(), less the c_name().
>> New argument @permit_upper suppresses it.  Pass permit_upper=True for
>> definitions (which are not members), and when the member's owner is
>> whitelisted with pragma name-case-whitelist.
>> 
>> Bonus: name-case-whitelist now applies to a union's inline base, too.
>> Update qapi/qapi-schema.json pragma to whitelist union CpuInfo instead
>> of CpuInfo's implicit base type's name q_obj_CpuInfo-base.
>> 
>> Signed-off-by: Markus Armbruster <address@hidden>
>> ---
>
>> +++ b/qapi/qapi-schema.json
>> @@ -71,7 +71,7 @@
>>          'QapiErrorClass',           # all members, visible through errors
>>          'UuidInfo',                 # UUID, visible through query-uuid
>>          'X86CPURegister32',         # all members, visible indirectly 
>> through qom-get
>> -        'q_obj_CpuInfo-base'        # CPU, visible through query-cpu
>> +        'CpuInfo'                   # CPU, visible through query-cpu
>
> Yes, much nicer.
>
>>      ] } }
>>  
>>  # Documentation generated with qapi-gen.py is in source order, with
>> diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py
>> index f0e7d5ad34..ed4bff4479 100644
>> --- a/scripts/qapi/common.py
>> +++ b/scripts/qapi/common.py
>> @@ -704,8 +704,8 @@ valid_name = re.compile(r'^(__[a-zA-Z0-9.-]+_)?'
>>                          '[a-zA-Z][a-zA-Z0-9_-]*$')
>>  
>>  
>> -def check_name(info, source, name, allow_optional=False,
>> -               enum_member=False):
>> +def check_name(info, source, name,
>> +               allow_optional=False, enum_member=False, permit_upper=False):
>>      global valid_name
>>      membername = name
>>  
>> @@ -725,11 +725,14 @@ def check_name(info, source, name, 
>> allow_optional=False,
>>      if not valid_name.match(membername) or \
>>         c_name(membername, False).startswith('q_'):
>>          raise QAPISemError(info, "%s uses invalid name '%s'" % (source, 
>> name))
>> +    if not permit_upper and name.lower() != name:
>> +        raise QAPISemError(
>> +            info, "%s uses uppercase in name '%s'" % (source, name))
>>  
>>  
>>  def add_name(name, info, meta):
>>      global all_names
>> -    check_name(info, "'%s'" % meta, name)
>> +    check_name(info, "'%s'" % meta, name, permit_upper=True)
>>      # FIXME should reject names that differ only in '_' vs. '.'
>>      # vs. '-', because they're liable to clash in generated C.
>>      if name in all_names:
>> @@ -797,10 +800,12 @@ def check_type(info, source, value,
>>          raise QAPISemError(info,
>>                             "%s should be an object or type name" % source)
>>  
>> +    permit_upper = allow_dict in name_case_whitelist
>> +
>
> so allow_dict changes from a bool to a string to be looked up...
>
>>      # value is a dictionary, check that each member is okay
>>      for (key, arg) in value.items():
>>          check_name(info, "Member of %s" % source, key,
>> -                   allow_optional=True)
>> +                   allow_optional=True, permit_upper=permit_upper)
>>          if c_name(key, False) == 'u' or c_name(key, 
>> False).startswith('has_'):
>>              raise QAPISemError(info, "Member of %s uses reserved name '%s'"
>>                                 % (source, key))
>> @@ -870,7 +875,7 @@ def check_union(expr, info):
>>      else:
>>          # The object must have a string or dictionary 'base'.
>>          check_type(info, "'base' for union '%s'" % name,
>> -                   base, allow_dict=True,
>> +                   base, allow_dict=name,
>
> ...and this is an example client affected by the change.  That threw me
> for a bit, but seems to work.

I'm not proud of this interface, but I couldn't think of anything
better.

> Reviewed-by: Eric Blake <address@hidden>

Thanks!



reply via email to

[Prev in Thread] Current Thread [Next in Thread]