# Copyright (C) 2020 Red Hat Inc. # # Authors: # Eduardo Habkost # # This work is licensed under the terms of the GNU GPL, version 2. See # the COPYING file in the top-level directory. from .regexps import * from .qom_macros import * from .qom_type_info import * def test_res() -> None: def fullmatch(regexp, s): return re.fullmatch(regexp, s, re.MULTILINE) assert fullmatch(RE_IDENTIFIER, 'sizeof') assert fullmatch(RE_IDENTIFIER, 'X86CPU') assert fullmatch(RE_FUN_CALL, 'sizeof(X86CPU)') assert fullmatch(RE_IDENTIFIER, 'X86_CPU_TYPE_NAME') assert fullmatch(RE_SIMPLE_VALUE, '"base"') print(RE_FUN_CALL) assert fullmatch(RE_FUN_CALL, 'X86_CPU_TYPE_NAME("base")') print(RE_TI_FIELD_INIT) assert fullmatch(RE_TI_FIELD_INIT, '.name = X86_CPU_TYPE_NAME("base"),\n') assert fullmatch(RE_MACRO_CONCAT, 'TYPE_ASPEED_GPIO "-ast2600"') assert fullmatch(RE_EXPRESSION, 'TYPE_ASPEED_GPIO "-ast2600"') print(RE_MACRO_DEFINE) assert re.search(RE_MACRO_DEFINE, r''' #define OFFSET_CHECK(c) \ do { \ if (!(c)) { \ goto bad_offset; \ } \ } while (0) ''', re.MULTILINE) print(RE_CHECK_MACRO) print(CPP_SPACE) assert not re.match(RE_CHECK_MACRO, r''' #define OFFSET_CHECK(c) \ do { \ if (!(c)) { \ goto bad_offset; \ } \ } while (0)''', re.MULTILINE) print(RE_CHECK_MACRO) assert fullmatch(RE_CHECK_MACRO, r'''#define PCI_DEVICE(obj) \ OBJECT_CHECK(PCIDevice, (obj), TYPE_PCI_DEVICE) ''') assert fullmatch(RE_CHECK_MACRO, r'''#define COLLIE_MACHINE(obj) \ OBJECT_CHECK(CollieMachineState, obj, TYPE_COLLIE_MACHINE) ''') print(RE_TYPEINFO_START) assert re.search(RE_TYPEINFO_START, r''' cc->open = qmp_chardev_open_file; } static const TypeInfo char_file_type_info = { .name = TYPE_CHARDEV_FILE, #ifdef _WIN32 .parent = TYPE_CHARDEV_WIN, ''', re.MULTILINE) assert re.search(RE_TYPEINFO_START, r''' TypeInfo ti = { .name = armsse_variants[i].name, .parent = TYPE_ARMSSE, .class_init = armsse_class_init, .class_data = (void *)&armsse_variants[i], };''', re.MULTILINE) print(RE_ARRAY_ITEM) assert fullmatch(RE_ARRAY_ITEM, '{ TYPE_HOTPLUG_HANDLER },') assert fullmatch(RE_ARRAY_ITEM, '{ TYPE_ACPI_DEVICE_IF },') assert fullmatch(RE_ARRAY_ITEM, '{ }') assert fullmatch(RE_ARRAY_CAST, '(InterfaceInfo[])') assert fullmatch(RE_ARRAY, '''(InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { TYPE_ACPI_DEVICE_IF }, { } }''') print(RE_COMMENT) assert fullmatch(RE_COMMENT, r'''/* multi-line * comment */''') print(RE_TI_FIELDS) assert fullmatch(RE_TI_FIELDS, r'''/* could be TYPE_SYS_BUS_DEVICE (or LPC etc) */ .parent = TYPE_DEVICE, ''') assert fullmatch(RE_TI_FIELDS, r'''.name = TYPE_TPM_CRB, /* could be TYPE_SYS_BUS_DEVICE (or LPC etc) */ .parent = TYPE_DEVICE, .instance_size = sizeof(CRBState), .class_init = tpm_crb_class_init, .interfaces = (InterfaceInfo[]) { { TYPE_TPM_IF }, { } } ''') assert fullmatch(RE_TI_FIELDS + SP + RE_COMMENTS, r'''.name = TYPE_PALM_MISC_GPIO, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(PalmMiscGPIOState), .instance_init = palm_misc_gpio_init, /* * No class init required: device has no internal state so does not * need to set up reset or vmstate, and has no realize method. */''') print(TypeInfoVar.regexp) test_empty = 'static const TypeInfo x86_base_cpu_type_info = {\n'+\ '};\n'; assert fullmatch(TypeInfoVar.regexp, test_empty) test_simple = r''' static const TypeInfo x86_base_cpu_type_info = { .name = X86_CPU_TYPE_NAME("base"), .parent = TYPE_X86_CPU, .class_init = x86_cpu_base_class_init, }; ''' assert re.search(TypeInfoVar.regexp, test_simple, re.MULTILINE) test_interfaces = r''' static const TypeInfo acpi_ged_info = { .name = TYPE_ACPI_GED, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(AcpiGedState), .instance_init = acpi_ged_initfn, .class_init = acpi_ged_class_init, .interfaces = (InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { TYPE_ACPI_DEVICE_IF }, { } } }; ''' assert re.search(TypeInfoVar.regexp, test_interfaces, re.MULTILINE) test_comments = r''' static const TypeInfo palm_misc_gpio_info = { .name = TYPE_PALM_MISC_GPIO, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(PalmMiscGPIOState), .instance_init = palm_misc_gpio_init, /* * No class init required: device has no internal state so does not * need to set up reset or vmstate, and has no realize method. */ }; ''' assert re.search(TypeInfoVar.regexp, test_comments, re.MULTILINE) test_comments = r''' static const TypeInfo tpm_crb_info = { .name = TYPE_TPM_CRB, /* could be TYPE_SYS_BUS_DEVICE (or LPC etc) */ .parent = TYPE_DEVICE, .instance_size = sizeof(CRBState), .class_init = tpm_crb_class_init, .interfaces = (InterfaceInfo[]) { { TYPE_TPM_IF }, { } } }; ''' assert re.search(TypeInfoVar.regexp, test_comments, re.MULTILINE) def test_struct_re(): print('---') print(RE_STRUCT_TYPEDEF) assert re.search(RE_STRUCT_TYPEDEF, r''' typedef struct TCGState { AccelState parent_obj; bool mttcg_enabled; unsigned long tb_size; } TCGState; ''', re.MULTILINE) assert re.search(RE_STRUCT_TYPEDEF, r''' typedef struct { ISADevice parent_obj; QEMUSoundCard card; uint32_t freq; uint32_t port; int ticking[2]; int enabled; int active; int bufpos; #ifdef DEBUG int64_t exp[2]; #endif int16_t *mixbuf; uint64_t dexp[2]; SWVoiceOut *voice; int left, pos, samples; QEMUAudioTimeStamp ats; FM_OPL *opl; PortioList port_list; } AdlibState; ''', re.MULTILINE) false_positive = r''' typedef struct dma_pagetable_entry { int32_t frame; int32_t owner; } A B C D E; struct foo { int x; } some_variable; ''' assert not re.search(RE_STRUCT_TYPEDEF, false_positive, re.MULTILINE) def test_initial_includes(): print(InitialIncludes.regexp) c = ''' #ifndef HW_FLASH_H #define HW_FLASH_H /* NOR flash devices */ #include "qom/object.h" #include "exec/hwaddr.h" /* pflash_cfi01.c */ ''' print(repr(list(m.groupdict() for m in InitialIncludes.finditer(c)))) m = InitialIncludes.domatch(c) assert m print(repr(m.group(0))) assert m.group(0).endswith('#include "exec/hwaddr.h"\n') c = '''#ifndef QEMU_VIRTIO_9P_H #define QEMU_VIRTIO_9P_H #include "standard-headers/linux/virtio_9p.h" #include "hw/virtio/virtio.h" #include "9p.h" ''' print(repr(list(m.groupdict() for m in InitialIncludes.finditer(c)))) m = InitialIncludes.domatch(c) assert m print(repr(m.group(0))) assert m.group(0).endswith('#include "9p.h"\n') c = '''#include "qom/object.h" /* * QEMU ES1370 emulation ... */ /* #define DEBUG_ES1370 */ /* #define VERBOSE_ES1370 */ #define SILENT_ES1370 #include "qemu/osdep.h" #include "hw/audio/soundhw.h" #include "audio/audio.h" #include "hw/pci/pci.h" #include "migration/vmstate.h" #include "qemu/module.h" #include "sysemu/dma.h" /* Missing stuff: SCTRL_P[12](END|ST)INC ''' print(repr(list(m.groupdict() for m in InitialIncludes.finditer(c)))) m = InitialIncludes.domatch(c) assert m print(repr(m.group(0))) assert m.group(0).endswith('#include "sysemu/dma.h"\n')