1# Copyright (C) 2020 Red Hat Inc. 2# 3# Authors: 4# Eduardo Habkost <ehabkost@redhat.com> 5# 6# This work is licensed under the terms of the GNU GPL, version 2. See 7# the COPYING file in the top-level directory. 8from .regexps import * 9from .qom_macros import * 10from .qom_type_info import * 11 12def test_res() -> None: 13 def fullmatch(regexp, s): 14 return re.fullmatch(regexp, s, re.MULTILINE) 15 16 assert fullmatch(RE_IDENTIFIER, 'sizeof') 17 assert fullmatch(RE_IDENTIFIER, 'X86CPU') 18 assert fullmatch(RE_FUN_CALL, 'sizeof(X86CPU)') 19 assert fullmatch(RE_IDENTIFIER, 'X86_CPU_TYPE_NAME') 20 assert fullmatch(RE_SIMPLE_VALUE, '"base"') 21 print(RE_FUN_CALL) 22 assert fullmatch(RE_FUN_CALL, 'X86_CPU_TYPE_NAME("base")') 23 print(RE_TI_FIELD_INIT) 24 assert fullmatch(RE_TI_FIELD_INIT, '.name = X86_CPU_TYPE_NAME("base"),\n') 25 26 27 assert fullmatch(RE_MACRO_CONCAT, 'TYPE_ASPEED_GPIO "-ast2600"') 28 assert fullmatch(RE_EXPRESSION, 'TYPE_ASPEED_GPIO "-ast2600"') 29 30 print(RE_MACRO_DEFINE) 31 assert re.search(RE_MACRO_DEFINE, r''' 32 #define OFFSET_CHECK(c) \ 33 do { \ 34 if (!(c)) { \ 35 goto bad_offset; \ 36 } \ 37 } while (0) 38 ''', re.MULTILINE) 39 40 print(RE_CHECK_MACRO) 41 print(CPP_SPACE) 42 assert not re.match(RE_CHECK_MACRO, r''' 43 #define OFFSET_CHECK(c) \ 44 do { \ 45 if (!(c)) { \ 46 goto bad_offset; \ 47 } \ 48 } while (0)''', re.MULTILINE) 49 50 print(RE_CHECK_MACRO) 51 assert fullmatch(RE_CHECK_MACRO, r'''#define PCI_DEVICE(obj) \ 52 OBJECT_CHECK(PCIDevice, (obj), TYPE_PCI_DEVICE) 53''') 54 assert fullmatch(RE_CHECK_MACRO, r'''#define COLLIE_MACHINE(obj) \ 55 OBJECT_CHECK(CollieMachineState, obj, TYPE_COLLIE_MACHINE) 56''') 57 58 print(RE_TYPEINFO_START) 59 assert re.search(RE_TYPEINFO_START, r''' 60 cc->open = qmp_chardev_open_file; 61} 62 63static const TypeInfo char_file_type_info = { 64 .name = TYPE_CHARDEV_FILE, 65#ifdef _WIN32 66 .parent = TYPE_CHARDEV_WIN, 67''', re.MULTILINE) 68 assert re.search(RE_TYPEINFO_START, r''' 69 TypeInfo ti = { 70 .name = armsse_variants[i].name, 71 .parent = TYPE_ARMSSE, 72 .class_init = armsse_class_init, 73 .class_data = (void *)&armsse_variants[i], 74 };''', re.MULTILINE) 75 76 print(RE_ARRAY_ITEM) 77 assert fullmatch(RE_ARRAY_ITEM, '{ TYPE_HOTPLUG_HANDLER },') 78 assert fullmatch(RE_ARRAY_ITEM, '{ TYPE_ACPI_DEVICE_IF },') 79 assert fullmatch(RE_ARRAY_ITEM, '{ }') 80 assert fullmatch(RE_ARRAY_CAST, '(InterfaceInfo[])') 81 assert fullmatch(RE_ARRAY, '''(InterfaceInfo[]) { 82 { TYPE_HOTPLUG_HANDLER }, 83 { TYPE_ACPI_DEVICE_IF }, 84 { } 85 }''') 86 print(RE_COMMENT) 87 assert fullmatch(RE_COMMENT, r'''/* multi-line 88 * comment 89 */''') 90 91 print(RE_TI_FIELDS) 92 assert fullmatch(RE_TI_FIELDS, 93 r'''/* could be TYPE_SYS_BUS_DEVICE (or LPC etc) */ 94 .parent = TYPE_DEVICE, 95''') 96 assert fullmatch(RE_TI_FIELDS, r'''.name = TYPE_TPM_CRB, 97 /* could be TYPE_SYS_BUS_DEVICE (or LPC etc) */ 98 .parent = TYPE_DEVICE, 99 .instance_size = sizeof(CRBState), 100 .class_init = tpm_crb_class_init, 101 .interfaces = (InterfaceInfo[]) { 102 { TYPE_TPM_IF }, 103 { } 104 } 105''') 106 assert fullmatch(RE_TI_FIELDS + SP + RE_COMMENTS, 107 r'''.name = TYPE_PALM_MISC_GPIO, 108 .parent = TYPE_SYS_BUS_DEVICE, 109 .instance_size = sizeof(PalmMiscGPIOState), 110 .instance_init = palm_misc_gpio_init, 111 /* 112 * No class init required: device has no internal state so does not 113 * need to set up reset or vmstate, and has no realize method. 114 */''') 115 116 print(TypeInfoVar.regexp) 117 test_empty = 'static const TypeInfo x86_base_cpu_type_info = {\n'+\ 118 '};\n'; 119 assert fullmatch(TypeInfoVar.regexp, test_empty) 120 121 test_simple = r''' 122 static const TypeInfo x86_base_cpu_type_info = { 123 .name = X86_CPU_TYPE_NAME("base"), 124 .parent = TYPE_X86_CPU, 125 .class_init = x86_cpu_base_class_init, 126 }; 127 ''' 128 assert re.search(TypeInfoVar.regexp, test_simple, re.MULTILINE) 129 130 test_interfaces = r''' 131 static const TypeInfo acpi_ged_info = { 132 .name = TYPE_ACPI_GED, 133 .parent = TYPE_SYS_BUS_DEVICE, 134 .instance_size = sizeof(AcpiGedState), 135 .instance_init = acpi_ged_initfn, 136 .class_init = acpi_ged_class_init, 137 .interfaces = (InterfaceInfo[]) { 138 { TYPE_HOTPLUG_HANDLER }, 139 { TYPE_ACPI_DEVICE_IF }, 140 { } 141 } 142 }; 143 ''' 144 assert re.search(TypeInfoVar.regexp, test_interfaces, re.MULTILINE) 145 146 test_comments = r''' 147 static const TypeInfo palm_misc_gpio_info = { 148 .name = TYPE_PALM_MISC_GPIO, 149 .parent = TYPE_SYS_BUS_DEVICE, 150 .instance_size = sizeof(PalmMiscGPIOState), 151 .instance_init = palm_misc_gpio_init, 152 /* 153 * No class init required: device has no internal state so does not 154 * need to set up reset or vmstate, and has no realize method. 155 */ 156 }; 157 ''' 158 assert re.search(TypeInfoVar.regexp, test_comments, re.MULTILINE) 159 160 test_comments = r''' 161 static const TypeInfo tpm_crb_info = { 162 .name = TYPE_TPM_CRB, 163 /* could be TYPE_SYS_BUS_DEVICE (or LPC etc) */ 164 .parent = TYPE_DEVICE, 165 .instance_size = sizeof(CRBState), 166 .class_init = tpm_crb_class_init, 167 .interfaces = (InterfaceInfo[]) { 168 { TYPE_TPM_IF }, 169 { } 170 } 171 }; 172 ''' 173 assert re.search(TypeInfoVar.regexp, test_comments, re.MULTILINE) 174 175def test_struct_re(): 176 print('---') 177 print(RE_STRUCT_TYPEDEF) 178 assert re.search(RE_STRUCT_TYPEDEF, r''' 179typedef struct TCGState { 180 AccelState parent_obj; 181 182 bool mttcg_enabled; 183 unsigned long tb_size; 184} TCGState; 185''', re.MULTILINE) 186 187 assert re.search(RE_STRUCT_TYPEDEF, r''' 188typedef struct { 189 ISADevice parent_obj; 190 191 QEMUSoundCard card; 192 uint32_t freq; 193 uint32_t port; 194 int ticking[2]; 195 int enabled; 196 int active; 197 int bufpos; 198#ifdef DEBUG 199 int64_t exp[2]; 200#endif 201 int16_t *mixbuf; 202 uint64_t dexp[2]; 203 SWVoiceOut *voice; 204 int left, pos, samples; 205 QEMUAudioTimeStamp ats; 206 FM_OPL *opl; 207 PortioList port_list; 208} AdlibState; 209''', re.MULTILINE) 210 211 false_positive = r''' 212typedef struct dma_pagetable_entry { 213 int32_t frame; 214 int32_t owner; 215} A B C D E; 216struct foo { 217 int x; 218} some_variable; 219''' 220 assert not re.search(RE_STRUCT_TYPEDEF, false_positive, re.MULTILINE) 221 222def test_initial_includes(): 223 print(InitialIncludes.regexp) 224 c = ''' 225#ifndef HW_FLASH_H 226#define HW_FLASH_H 227 228/* NOR flash devices */ 229 230#include "qom/object.h" 231#include "exec/hwaddr.h" 232 233/* pflash_cfi01.c */ 234''' 235 print(repr(list(m.groupdict() for m in InitialIncludes.finditer(c)))) 236 m = InitialIncludes.domatch(c) 237 assert m 238 print(repr(m.group(0))) 239 assert m.group(0).endswith('#include "exec/hwaddr.h"\n') 240 241 c = '''#ifndef QEMU_VIRTIO_9P_H 242#define QEMU_VIRTIO_9P_H 243 244#include "standard-headers/linux/virtio_9p.h" 245#include "hw/virtio/virtio.h" 246#include "9p.h" 247 248 249''' 250 print(repr(list(m.groupdict() for m in InitialIncludes.finditer(c)))) 251 m = InitialIncludes.domatch(c) 252 assert m 253 print(repr(m.group(0))) 254 assert m.group(0).endswith('#include "9p.h"\n') 255 256 c = '''#include "qom/object.h" 257/* 258 * QEMU ES1370 emulation 259... 260 */ 261 262/* #define DEBUG_ES1370 */ 263/* #define VERBOSE_ES1370 */ 264#define SILENT_ES1370 265 266#include "qemu/osdep.h" 267#include "hw/audio/soundhw.h" 268#include "audio/audio.h" 269#include "hw/pci/pci.h" 270#include "migration/vmstate.h" 271#include "qemu/module.h" 272#include "sysemu/dma.h" 273 274/* Missing stuff: 275 SCTRL_P[12](END|ST)INC 276''' 277 print(repr(list(m.groupdict() for m in InitialIncludes.finditer(c)))) 278 m = InitialIncludes.domatch(c) 279 assert m 280 print(repr(m.group(0))) 281 assert m.group(0).endswith('#include "sysemu/dma.h"\n') 282 283