blob: a445634d88ac90ad45a65790988efee94bbfabc4 [file] [log] [blame]
# Copyright (C) 2020 Red Hat Inc.
#
# Authors:
# Eduardo Habkost <ehabkost@redhat.com>
#
# 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')