qapi: Adjust names of implicit types
The original choice of ':obj-' as the prefix for implicit types
made it obvious that we weren't going to clash with any user-defined
names, which cannot contain ':'. But now we want to create structs
for implicit types, to get rid of special cases in the generators,
and our use of ':' in implicit names needs a tweak to produce valid
C code.
We could transliterate ':' to '_', except that C99 mandates that
"identifiers that begin with an underscore are always reserved for
use as identifiers with file scope in both the ordinary and tag name
spaces". So it's time to change our naming convention: we can
instead use the 'q_' prefix that we reserved for ourselves back in
commit 9fb081e0
. Technically, since we aren't planning on exposing
the empty type in generated code, we could keep the name ':empty',
but renaming it to 'q_empty' makes the check for startswith('q_')
cover all implicit types, whether or not code is generated for them.
As long as we don't declare 'empty' or 'obj' ticklish, it shouldn't
clash with c_name() prepending 'q_' to the user's ticklish names.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1458254921-17042-5-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
4040d995e4
commit
7599697c66
@ -575,9 +575,9 @@ names an object type without members.
|
|||||||
Example: the SchemaInfo for command query-qmp-schema
|
Example: the SchemaInfo for command query-qmp-schema
|
||||||
|
|
||||||
{ "name": "query-qmp-schema", "meta-type": "command",
|
{ "name": "query-qmp-schema", "meta-type": "command",
|
||||||
"arg-type": ":empty", "ret-type": "SchemaInfoList" }
|
"arg-type": "q_empty", "ret-type": "SchemaInfoList" }
|
||||||
|
|
||||||
Type ":empty" is an object type without members, and type
|
Type "q_empty" is an automatic object type without members, and type
|
||||||
"SchemaInfoList" is the array of SchemaInfo type.
|
"SchemaInfoList" is the array of SchemaInfo type.
|
||||||
|
|
||||||
The SchemaInfo for an event has meta-type "event", and variant member
|
The SchemaInfo for an event has meta-type "event", and variant member
|
||||||
@ -594,9 +594,9 @@ QAPI schema implicitly defines an object type.
|
|||||||
Example: the SchemaInfo for EVENT_C from section Events
|
Example: the SchemaInfo for EVENT_C from section Events
|
||||||
|
|
||||||
{ "name": "EVENT_C", "meta-type": "event",
|
{ "name": "EVENT_C", "meta-type": "event",
|
||||||
"arg-type": ":obj-EVENT_C-arg" }
|
"arg-type": "q_obj-EVENT_C-arg" }
|
||||||
|
|
||||||
Type ":obj-EVENT_C-arg" is an implicitly defined object type with
|
Type "q_obj-EVENT_C-arg" is an implicitly defined object type with
|
||||||
the two members from the event's definition.
|
the two members from the event's definition.
|
||||||
|
|
||||||
The SchemaInfo for struct and union types has meta-type "object".
|
The SchemaInfo for struct and union types has meta-type "object".
|
||||||
@ -660,11 +660,11 @@ Union types
|
|||||||
{ "name": "type", "type": "BlockdevOptionsKind" } ],
|
{ "name": "type", "type": "BlockdevOptionsKind" } ],
|
||||||
"tag": "type",
|
"tag": "type",
|
||||||
"variants": [
|
"variants": [
|
||||||
{ "case": "file", "type": ":obj-FileOptions-wrapper" },
|
{ "case": "file", "type": "q_obj-FileOptions-wrapper" },
|
||||||
{ "case": "qcow2", "type": ":obj-Qcow2Options-wrapper" } ] }
|
{ "case": "qcow2", "type": "q_obj-Qcow2Options-wrapper" } ] }
|
||||||
|
|
||||||
Enumeration type "BlockdevOptionsKind" and the object types
|
Enumeration type "BlockdevOptionsKind" and the object types
|
||||||
":obj-FileOptions-wrapper", ":obj-Qcow2Options-wrapper" are
|
"q_obj-FileOptions-wrapper", "q_obj-Qcow2Options-wrapper" are
|
||||||
implicitly defined.
|
implicitly defined.
|
||||||
|
|
||||||
The SchemaInfo for an alternate type has meta-type "alternate", and
|
The SchemaInfo for an alternate type has meta-type "alternate", and
|
||||||
|
@ -391,7 +391,8 @@ def check_name(expr_info, source, name, allow_optional=False,
|
|||||||
# code always prefixes it with the enum name
|
# code always prefixes it with the enum name
|
||||||
if enum_member and membername[0].isdigit():
|
if enum_member and membername[0].isdigit():
|
||||||
membername = 'D' + membername
|
membername = 'D' + membername
|
||||||
# Reserve the entire 'q_' namespace for c_name()
|
# Reserve the entire 'q_' namespace for c_name(), and for 'q_empty'
|
||||||
|
# and 'q_obj_*' implicit type names.
|
||||||
if not valid_name.match(membername) or \
|
if not valid_name.match(membername) or \
|
||||||
c_name(membername, False).startswith('q_'):
|
c_name(membername, False).startswith('q_'):
|
||||||
raise QAPIExprError(expr_info,
|
raise QAPIExprError(expr_info,
|
||||||
@ -994,8 +995,9 @@ class QAPISchemaObjectType(QAPISchemaType):
|
|||||||
m.check_clash(info, seen)
|
m.check_clash(info, seen)
|
||||||
|
|
||||||
def is_implicit(self):
|
def is_implicit(self):
|
||||||
# See QAPISchema._make_implicit_object_type()
|
# See QAPISchema._make_implicit_object_type(), as well as
|
||||||
return self.name[0] == ':'
|
# _def_predefineds()
|
||||||
|
return self.name.startswith('q_')
|
||||||
|
|
||||||
def c_name(self):
|
def c_name(self):
|
||||||
assert not self.is_implicit()
|
assert not self.is_implicit()
|
||||||
@ -1044,10 +1046,10 @@ class QAPISchemaMember(object):
|
|||||||
|
|
||||||
def _pretty_owner(self):
|
def _pretty_owner(self):
|
||||||
owner = self.owner
|
owner = self.owner
|
||||||
if owner.startswith(':obj-'):
|
if owner.startswith('q_obj_'):
|
||||||
# See QAPISchema._make_implicit_object_type() - reverse the
|
# See QAPISchema._make_implicit_object_type() - reverse the
|
||||||
# mapping there to create a nice human-readable description
|
# mapping there to create a nice human-readable description
|
||||||
owner = owner[5:]
|
owner = owner[6:]
|
||||||
if owner.endswith('-arg'):
|
if owner.endswith('-arg'):
|
||||||
return '(parameter of %s)' % owner[:-4]
|
return '(parameter of %s)' % owner[:-4]
|
||||||
else:
|
else:
|
||||||
@ -1266,8 +1268,8 @@ class QAPISchema(object):
|
|||||||
('bool', 'boolean', 'bool', 'false'),
|
('bool', 'boolean', 'bool', 'false'),
|
||||||
('any', 'value', 'QObject' + pointer_suffix, 'NULL')]:
|
('any', 'value', 'QObject' + pointer_suffix, 'NULL')]:
|
||||||
self._def_builtin_type(*t)
|
self._def_builtin_type(*t)
|
||||||
self.the_empty_object_type = QAPISchemaObjectType(':empty', None, None,
|
self.the_empty_object_type = QAPISchemaObjectType('q_empty', None,
|
||||||
[], None)
|
None, [], None)
|
||||||
self._def_entity(self.the_empty_object_type)
|
self._def_entity(self.the_empty_object_type)
|
||||||
qtype_values = self._make_enum_members(['none', 'qnull', 'qint',
|
qtype_values = self._make_enum_members(['none', 'qnull', 'qint',
|
||||||
'qstring', 'qdict', 'qlist',
|
'qstring', 'qdict', 'qlist',
|
||||||
@ -1295,7 +1297,7 @@ class QAPISchema(object):
|
|||||||
if not members:
|
if not members:
|
||||||
return None
|
return None
|
||||||
# See also QAPISchemaObjectTypeMember._pretty_owner()
|
# See also QAPISchemaObjectTypeMember._pretty_owner()
|
||||||
name = ':obj-%s-%s' % (name, role)
|
name = 'q_obj_%s-%s' % (name, role)
|
||||||
if not self.lookup_entity(name, QAPISchemaObjectType):
|
if not self.lookup_entity(name, QAPISchemaObjectType):
|
||||||
self._def_entity(QAPISchemaObjectType(name, info, None,
|
self._def_entity(QAPISchemaObjectType(name, info, None,
|
||||||
members, None))
|
members, None))
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
object :empty
|
|
||||||
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
enum Status ['good', 'bad', 'ugly']
|
enum Status ['good', 'bad', 'ugly']
|
||||||
|
object q_empty
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
object :empty
|
|
||||||
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
|
object q_empty
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
object :empty
|
|
||||||
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
event oops None
|
event oops None
|
||||||
|
object q_empty
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
object :empty
|
|
||||||
object :obj-fooA-arg
|
|
||||||
member bar1: str optional=False
|
|
||||||
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
command fooA :obj-fooA-arg -> None
|
command fooA q_obj_fooA-arg -> None
|
||||||
gen=True success_response=True
|
gen=True success_response=True
|
||||||
|
object q_empty
|
||||||
|
object q_obj_fooA-arg
|
||||||
|
member bar1: str optional=False
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
object :empty
|
|
||||||
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
enum Status ['good', 'bad', 'ugly']
|
enum Status ['good', 'bad', 'ugly']
|
||||||
|
object q_empty
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
object :empty
|
|
||||||
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
enum Status ['good', 'bad', 'ugly']
|
enum Status ['good', 'bad', 'ugly']
|
||||||
|
object q_empty
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
object :empty
|
|
||||||
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
enum Status ['good', 'bad', 'ugly']
|
enum Status ['good', 'bad', 'ugly']
|
||||||
|
object q_empty
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
object :empty
|
|
||||||
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
enum QType ['none', 'qnull', 'qint', 'qstring', 'qdict', 'qlist', 'qfloat', 'qbool']
|
||||||
prefix QTYPE
|
prefix QTYPE
|
||||||
command eins None -> None
|
command eins None -> None
|
||||||
gen=True success_response=True
|
gen=True success_response=True
|
||||||
|
object q_empty
|
||||||
command zwei None -> None
|
command zwei None -> None
|
||||||
gen=True success_response=True
|
gen=True success_response=True
|
||||||
|
@ -1,58 +1,3 @@
|
|||||||
object :empty
|
|
||||||
object :obj-EVENT_C-arg
|
|
||||||
member a: int optional=True
|
|
||||||
member b: UserDefOne optional=True
|
|
||||||
member c: str optional=False
|
|
||||||
object :obj-EVENT_D-arg
|
|
||||||
member a: EventStructOne optional=False
|
|
||||||
member b: str optional=False
|
|
||||||
member c: str optional=True
|
|
||||||
member enum3: EnumOne optional=True
|
|
||||||
object :obj-__org.qemu_x-command-arg
|
|
||||||
member a: __org.qemu_x-EnumList optional=False
|
|
||||||
member b: __org.qemu_x-StructList optional=False
|
|
||||||
member c: __org.qemu_x-Union2 optional=False
|
|
||||||
member d: __org.qemu_x-Alt optional=False
|
|
||||||
object :obj-anyList-wrapper
|
|
||||||
member data: anyList optional=False
|
|
||||||
object :obj-boolList-wrapper
|
|
||||||
member data: boolList optional=False
|
|
||||||
object :obj-guest-get-time-arg
|
|
||||||
member a: int optional=False
|
|
||||||
member b: int optional=True
|
|
||||||
object :obj-guest-sync-arg
|
|
||||||
member arg: any optional=False
|
|
||||||
object :obj-int16List-wrapper
|
|
||||||
member data: int16List optional=False
|
|
||||||
object :obj-int32List-wrapper
|
|
||||||
member data: int32List optional=False
|
|
||||||
object :obj-int64List-wrapper
|
|
||||||
member data: int64List optional=False
|
|
||||||
object :obj-int8List-wrapper
|
|
||||||
member data: int8List optional=False
|
|
||||||
object :obj-intList-wrapper
|
|
||||||
member data: intList optional=False
|
|
||||||
object :obj-numberList-wrapper
|
|
||||||
member data: numberList optional=False
|
|
||||||
object :obj-sizeList-wrapper
|
|
||||||
member data: sizeList optional=False
|
|
||||||
object :obj-str-wrapper
|
|
||||||
member data: str optional=False
|
|
||||||
object :obj-strList-wrapper
|
|
||||||
member data: strList optional=False
|
|
||||||
object :obj-uint16List-wrapper
|
|
||||||
member data: uint16List optional=False
|
|
||||||
object :obj-uint32List-wrapper
|
|
||||||
member data: uint32List optional=False
|
|
||||||
object :obj-uint64List-wrapper
|
|
||||||
member data: uint64List optional=False
|
|
||||||
object :obj-uint8List-wrapper
|
|
||||||
member data: uint8List optional=False
|
|
||||||
object :obj-user_def_cmd1-arg
|
|
||||||
member ud1a: UserDefOne optional=False
|
|
||||||
object :obj-user_def_cmd2-arg
|
|
||||||
member ud1a: UserDefOne optional=False
|
|
||||||
member ud1b: UserDefOne optional=True
|
|
||||||
alternate AltIntNum
|
alternate AltIntNum
|
||||||
case i: int
|
case i: int
|
||||||
case n: number
|
case n: number
|
||||||
@ -73,8 +18,8 @@ alternate AltStrNum
|
|||||||
case n: number
|
case n: number
|
||||||
event EVENT_A None
|
event EVENT_A None
|
||||||
event EVENT_B None
|
event EVENT_B None
|
||||||
event EVENT_C :obj-EVENT_C-arg
|
event EVENT_C q_obj_EVENT_C-arg
|
||||||
event EVENT_D :obj-EVENT_D-arg
|
event EVENT_D q_obj_EVENT_D-arg
|
||||||
object Empty1
|
object Empty1
|
||||||
object Empty2
|
object Empty2
|
||||||
base Empty1
|
base Empty1
|
||||||
@ -127,20 +72,20 @@ object UserDefFlatUnion2
|
|||||||
case value2: UserDefB
|
case value2: UserDefB
|
||||||
object UserDefNativeListUnion
|
object UserDefNativeListUnion
|
||||||
member type: UserDefNativeListUnionKind optional=False
|
member type: UserDefNativeListUnionKind optional=False
|
||||||
case integer: :obj-intList-wrapper
|
case integer: q_obj_intList-wrapper
|
||||||
case s8: :obj-int8List-wrapper
|
case s8: q_obj_int8List-wrapper
|
||||||
case s16: :obj-int16List-wrapper
|
case s16: q_obj_int16List-wrapper
|
||||||
case s32: :obj-int32List-wrapper
|
case s32: q_obj_int32List-wrapper
|
||||||
case s64: :obj-int64List-wrapper
|
case s64: q_obj_int64List-wrapper
|
||||||
case u8: :obj-uint8List-wrapper
|
case u8: q_obj_uint8List-wrapper
|
||||||
case u16: :obj-uint16List-wrapper
|
case u16: q_obj_uint16List-wrapper
|
||||||
case u32: :obj-uint32List-wrapper
|
case u32: q_obj_uint32List-wrapper
|
||||||
case u64: :obj-uint64List-wrapper
|
case u64: q_obj_uint64List-wrapper
|
||||||
case number: :obj-numberList-wrapper
|
case number: q_obj_numberList-wrapper
|
||||||
case boolean: :obj-boolList-wrapper
|
case boolean: q_obj_boolList-wrapper
|
||||||
case string: :obj-strList-wrapper
|
case string: q_obj_strList-wrapper
|
||||||
case sizes: :obj-sizeList-wrapper
|
case sizes: q_obj_sizeList-wrapper
|
||||||
case any: :obj-anyList-wrapper
|
case any: q_obj_anyList-wrapper
|
||||||
enum UserDefNativeListUnionKind ['integer', 's8', 's16', 's32', 's64', 'u8', 'u16', 'u32', 'u64', 'number', 'boolean', 'string', 'sizes', 'any']
|
enum UserDefNativeListUnionKind ['integer', 's8', 's16', 's32', 's64', 'u8', 'u16', 'u32', 'u64', 'number', 'boolean', 'string', 'sizes', 'any']
|
||||||
object UserDefOne
|
object UserDefOne
|
||||||
base UserDefZero
|
base UserDefZero
|
||||||
@ -189,23 +134,78 @@ object __org.qemu_x-Struct2
|
|||||||
member array: __org.qemu_x-Union1List optional=False
|
member array: __org.qemu_x-Union1List optional=False
|
||||||
object __org.qemu_x-Union1
|
object __org.qemu_x-Union1
|
||||||
member type: __org.qemu_x-Union1Kind optional=False
|
member type: __org.qemu_x-Union1Kind optional=False
|
||||||
case __org.qemu_x-branch: :obj-str-wrapper
|
case __org.qemu_x-branch: q_obj_str-wrapper
|
||||||
enum __org.qemu_x-Union1Kind ['__org.qemu_x-branch']
|
enum __org.qemu_x-Union1Kind ['__org.qemu_x-branch']
|
||||||
object __org.qemu_x-Union2
|
object __org.qemu_x-Union2
|
||||||
base __org.qemu_x-Base
|
base __org.qemu_x-Base
|
||||||
tag __org.qemu_x-member1
|
tag __org.qemu_x-member1
|
||||||
case __org.qemu_x-value: __org.qemu_x-Struct2
|
case __org.qemu_x-value: __org.qemu_x-Struct2
|
||||||
command __org.qemu_x-command :obj-__org.qemu_x-command-arg -> __org.qemu_x-Union1
|
command __org.qemu_x-command q_obj___org.qemu_x-command-arg -> __org.qemu_x-Union1
|
||||||
gen=True success_response=True
|
gen=True success_response=True
|
||||||
command guest-get-time :obj-guest-get-time-arg -> int
|
command guest-get-time q_obj_guest-get-time-arg -> int
|
||||||
gen=True success_response=True
|
gen=True success_response=True
|
||||||
command guest-sync :obj-guest-sync-arg -> any
|
command guest-sync q_obj_guest-sync-arg -> any
|
||||||
gen=True success_response=True
|
gen=True success_response=True
|
||||||
|
object q_empty
|
||||||
|
object q_obj_EVENT_C-arg
|
||||||
|
member a: int optional=True
|
||||||
|
member b: UserDefOne optional=True
|
||||||
|
member c: str optional=False
|
||||||
|
object q_obj_EVENT_D-arg
|
||||||
|
member a: EventStructOne optional=False
|
||||||
|
member b: str optional=False
|
||||||
|
member c: str optional=True
|
||||||
|
member enum3: EnumOne optional=True
|
||||||
|
object q_obj___org.qemu_x-command-arg
|
||||||
|
member a: __org.qemu_x-EnumList optional=False
|
||||||
|
member b: __org.qemu_x-StructList optional=False
|
||||||
|
member c: __org.qemu_x-Union2 optional=False
|
||||||
|
member d: __org.qemu_x-Alt optional=False
|
||||||
|
object q_obj_anyList-wrapper
|
||||||
|
member data: anyList optional=False
|
||||||
|
object q_obj_boolList-wrapper
|
||||||
|
member data: boolList optional=False
|
||||||
|
object q_obj_guest-get-time-arg
|
||||||
|
member a: int optional=False
|
||||||
|
member b: int optional=True
|
||||||
|
object q_obj_guest-sync-arg
|
||||||
|
member arg: any optional=False
|
||||||
|
object q_obj_int16List-wrapper
|
||||||
|
member data: int16List optional=False
|
||||||
|
object q_obj_int32List-wrapper
|
||||||
|
member data: int32List optional=False
|
||||||
|
object q_obj_int64List-wrapper
|
||||||
|
member data: int64List optional=False
|
||||||
|
object q_obj_int8List-wrapper
|
||||||
|
member data: int8List optional=False
|
||||||
|
object q_obj_intList-wrapper
|
||||||
|
member data: intList optional=False
|
||||||
|
object q_obj_numberList-wrapper
|
||||||
|
member data: numberList optional=False
|
||||||
|
object q_obj_sizeList-wrapper
|
||||||
|
member data: sizeList optional=False
|
||||||
|
object q_obj_str-wrapper
|
||||||
|
member data: str optional=False
|
||||||
|
object q_obj_strList-wrapper
|
||||||
|
member data: strList optional=False
|
||||||
|
object q_obj_uint16List-wrapper
|
||||||
|
member data: uint16List optional=False
|
||||||
|
object q_obj_uint32List-wrapper
|
||||||
|
member data: uint32List optional=False
|
||||||
|
object q_obj_uint64List-wrapper
|
||||||
|
member data: uint64List optional=False
|
||||||
|
object q_obj_uint8List-wrapper
|
||||||
|
member data: uint8List optional=False
|
||||||
|
object q_obj_user_def_cmd1-arg
|
||||||
|
member ud1a: UserDefOne optional=False
|
||||||
|
object q_obj_user_def_cmd2-arg
|
||||||
|
member ud1a: UserDefOne optional=False
|
||||||
|
member ud1b: UserDefOne optional=True
|
||||||
command user_def_cmd None -> None
|
command user_def_cmd None -> None
|
||||||
gen=True success_response=True
|
gen=True success_response=True
|
||||||
command user_def_cmd0 Empty2 -> Empty2
|
command user_def_cmd0 Empty2 -> Empty2
|
||||||
gen=True success_response=True
|
gen=True success_response=True
|
||||||
command user_def_cmd1 :obj-user_def_cmd1-arg -> None
|
command user_def_cmd1 q_obj_user_def_cmd1-arg -> None
|
||||||
gen=True success_response=True
|
gen=True success_response=True
|
||||||
command user_def_cmd2 :obj-user_def_cmd2-arg -> UserDefTwo
|
command user_def_cmd2 q_obj_user_def_cmd2-arg -> UserDefTwo
|
||||||
gen=True success_response=True
|
gen=True success_response=True
|
||||||
|
Loading…
Reference in New Issue
Block a user