Browse Source

manager: delete QEMU management code

osy 2 years ago
parent
commit
b7cfc156df
55 changed files with 0 additions and 12781 deletions
  1. 0 34
      Managers/UTMJSONStream.h
  2. 0 211
      Managers/UTMJSONStream.m
  3. 0 31
      Managers/UTMJSONStreamDelegate.h
  4. 0 30
      Managers/UTMLoggingDelegate.h
  5. 0 240
      Managers/UTMQcow2.c
  6. 0 31
      Managers/UTMQcow2.h
  7. 0 201
      Managers/UTMQemuGuestAgent.h
  8. 0 367
      Managers/UTMQemuGuestAgent.m
  9. 0 33
      Managers/UTMQemuManager-Protected.h
  10. 0 36
      Managers/UTMQemuManager.h
  11. 0 151
      Managers/UTMQemuManager.m
  12. 0 30
      Managers/UTMQemuMonitor+BlockDevices.h
  13. 0 85
      Managers/UTMQemuMonitor+BlockDevices.m
  14. 0 42
      Managers/UTMQemuMonitor.h
  15. 0 278
      Managers/UTMQemuMonitor.m
  16. 0 38
      Managers/UTMQemuMonitorDelegate.h
  17. 0 29
      Managers/UTMQemuVirtualMachine+SPICE.h
  18. 0 79
      Managers/UTMQemuVirtualMachine+SPICE.m
  19. 0 33
      Managers/UTMQemuVirtualMachine-Protected.h
  20. 0 38
      Managers/UTMQemuVirtualMachine.h
  21. 0 733
      Managers/UTMQemuVirtualMachine.m
  22. 0 602
      UTM.xcodeproj/project.pbxproj
  23. 0 607
      qapi/cf-input-visitor.c
  24. 0 63
      qapi/cf-input-visitor.h
  25. 0 264
      qapi/cf-output-visitor.c
  26. 0 60
      qapi/cf-output-visitor.h
  27. 0 28
      qapi/dealloc-visitor.h
  28. 0 306
      qapi/error.c
  29. 0 534
      qapi/error.h
  30. 0 139
      qapi/qapi-dealloc-visitor.c
  31. 0 87
      qapi/qapi-util.c
  32. 0 431
      qapi/qapi-visit-core.c
  33. 0 79
      qapi/qemu-compat.h
  34. 0 94
      qapi/qerror.h
  35. 0 575
      qapi/queue.h
  36. 0 61
      qapi/util.h
  37. 0 137
      qapi/visitor-impl.h
  38. 0 714
      qapi/visitor.h
  39. 0 11
      scripts/build_dependencies.sh
  40. 0 2
      scripts/pack_dependencies.sh
  41. 0 19
      scripts/qapi-gen.py
  42. 0 0
      scripts/qapi/__init__.py
  43. 0 261
      scripts/qapi/commands.py
  44. 0 251
      scripts/qapi/common.py
  45. 0 50
      scripts/qapi/error.py
  46. 0 275
      scripts/qapi/events.py
  47. 0 694
      scripts/qapi/expr.py
  48. 0 339
      scripts/qapi/gen.py
  49. 0 390
      scripts/qapi/introspect.py
  50. 0 95
      scripts/qapi/main.py
  51. 0 810
      scripts/qapi/parser.py
  52. 0 1189
      scripts/qapi/schema.py
  53. 0 71
      scripts/qapi/source.py
  54. 0 383
      scripts/qapi/types.py
  55. 0 410
      scripts/qapi/visit.py

+ 0 - 34
Managers/UTMJSONStream.h

@@ -1,34 +0,0 @@
-//
-// Copyright © 2022 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import <Foundation/Foundation.h>
-#import "UTMJSONStreamDelegate.h"
-#import <CocoaSpice.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface UTMJSONStream : NSObject<CSPortDelegate>
-
-@property (nonatomic, readonly) CSPort *port;
-@property (nonatomic, weak) id<UTMJSONStreamDelegate> delegate;
-
-- (instancetype)init NS_UNAVAILABLE;
-- (instancetype)initWithPort:(CSPort *)port NS_DESIGNATED_INITIALIZER;
-- (BOOL)sendDictionary:(NSDictionary *)dictionary shouldSynchronize:(BOOL)shouldSynchronize error:(NSError * _Nullable *)error;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 211
Managers/UTMJSONStream.m

@@ -1,211 +0,0 @@
-//
-// Copyright © 2022 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMJSONStream.h"
-#import "UTMLogging.h"
-
-extern NSString *const kUTMErrorDomain;
-const int kMaxBufferSize = 1024;
-
-enum ParserState {
-    PARSER_NOT_IN_STRING,
-    PARSER_IN_STRING,
-    PARSER_IN_STRING_ESCAPE,
-    PARSER_WAITING_FOR_DELIMITER,
-    PARSER_INVALID
-};
-
-@interface UTMJSONStream ()
-
-@property (nonatomic, readwrite) CSPort *port;
-@property (nonatomic, nullable) NSMutableData *data;
-@property (nonatomic, nullable) dispatch_queue_t streamQueue;
-@property (nonatomic) NSUInteger parsedBytes;
-@property (nonatomic) enum ParserState state;
-@property (nonatomic) NSInteger openCurlyCount;
-
-@end
-
-@implementation UTMJSONStream
-
-- (void)setDelegate:(id<UTMJSONStreamDelegate>)delegate {
-    _delegate = delegate;
-    self.port.delegate = self; // consume any cached data
-}
-
-- (instancetype)initWithPort:(CSPort *)port {
-    self = [super init];
-    if (self) {
-        self.streamQueue = dispatch_queue_create("com.utmapp.UTM.JSONStream", NULL);
-        self.port = port;
-        self.data = [NSMutableData data];
-    }
-    return self;
-}
-
-- (void)parseData {
-    __block NSUInteger skipLength = 0;
-    __block NSUInteger endIndex = 0;
-    [self.data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
-        const char *str = (const char *)bytes;
-        if (byteRange.location + byteRange.length < self.parsedBytes) {
-            return;
-        }
-        for (NSUInteger i = self.parsedBytes - byteRange.location; i < byteRange.length; i++) {
-            if (self.state == PARSER_WAITING_FOR_DELIMITER) {
-                skipLength++;
-                if (str[i] == (char)0xFF) {
-                    self.state = PARSER_NOT_IN_STRING;
-                    self.openCurlyCount = 0;
-                }
-                self.parsedBytes++;
-                continue;
-            } else if (self.state == PARSER_IN_STRING_ESCAPE) {
-                self.state = PARSER_IN_STRING;
-            } else {
-                switch (str[i]) {
-                    case '{': {
-                        if (self.state == PARSER_NOT_IN_STRING) {
-                            if (self.openCurlyCount == -1) {
-                                self.openCurlyCount = 0;
-                            }
-                            self.openCurlyCount++;
-                        }
-                        break;
-                    }
-                    case '}': {
-                        if (self.state == PARSER_NOT_IN_STRING) {
-                            self.openCurlyCount--;
-                            if (self.openCurlyCount < 0) {
-                                UTMLog(@"Saw too many close curly!");
-                                self.state = PARSER_INVALID;
-                                NSError *err = [NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: NSLocalizedString(@"Error parsing JSON.", "UTMJSONStream")}];
-                                [self.delegate jsonStream:self seenError:err];
-                            }
-                        }
-                        break;
-                    }
-                    case '\\': {
-                        if (self.state == PARSER_IN_STRING) {
-                            self.state = PARSER_IN_STRING_ESCAPE;
-                        } else {
-                            UTMLog(@"Saw escape in invalid context");
-                            self.state = PARSER_INVALID;
-                            NSError *err = [NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: NSLocalizedString(@"Error parsing JSON.", "UTMJSONStream")}];
-                            [self.delegate jsonStream:self seenError:err];
-                        }
-                        break;
-                    }
-                    case '"': {
-                        if (self.state == PARSER_IN_STRING) {
-                            self.state = PARSER_NOT_IN_STRING;
-                        } else {
-                            self.state = PARSER_IN_STRING;
-                        }
-                        break;
-                    }
-                    default: {
-                        // force reset parser
-                        if (str[i] == (char)0xFF ||
-                            (str[i] >= '\0' && str[i] < ' ' && str[i] != '\t' && str[i] != '\r' && str[i] != '\n')) {
-                            UTMLog(@"Resetting parser...");
-                            self.state = PARSER_NOT_IN_STRING;
-                            self.openCurlyCount = 0;
-                        }
-                    }
-                }
-            }
-            self.parsedBytes++;
-            if (self.openCurlyCount == 0) {
-                endIndex = self.parsedBytes;
-                *stop = YES;
-                break;
-            }
-        }
-    }];
-    if (skipLength > 0) {
-        // discard any data before delimiter
-        [self.data replaceBytesInRange:NSMakeRange(0, skipLength) withBytes:NULL length:0];
-        self.parsedBytes -= skipLength;
-    }
-    if (endIndex > 0) {
-        [self consumeJSONLength:endIndex-skipLength];
-    }
-}
-
-- (void)consumeJSONLength:(NSUInteger)length {
-    NSRange range = NSMakeRange(0, length);
-    NSData *jsonData = [self.data subdataWithRange:range];
-    [self.data replaceBytesInRange:range withBytes:NULL length:0];
-    self.parsedBytes = 0;
-    self.openCurlyCount = -1;
-    NSError *err;
-    id json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&err];
-    if (err) {
-        [self.delegate jsonStream:self seenError:err];
-        return;
-    }
-    NSAssert([json isKindOfClass:[NSDictionary class]], @"JSON data not dictionary");
-    UTMLog(@"Debug JSON recieved <- %@", json);
-    dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
-        [self.delegate jsonStream:self receivedDictionary:(NSDictionary *)json];
-    });
-}
-
-- (void)portDidDisconect:(CSPort *)port {
-    assert(self.port == port);
-    [self.delegate jsonStream:self connected:NO];
-}
-
-- (void)port:(CSPort *)port didError:(NSString *)error {
-    [self.delegate jsonStream:self seenError:[NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: error}]];
-}
-
-- (void)port:(CSPort *)port didRecieveData:(NSData *)data {
-    assert(self.port == port);
-    [self.data appendData:data];
-    dispatch_async(self.streamQueue, ^{
-        while (self.parsedBytes < [self.data length]) {
-            [self parseData];
-        }
-    });
-}
-
-- (BOOL)sendDictionary:(NSDictionary *)dict shouldSynchronize:(BOOL)shouldSynchronize error:(NSError * _Nullable *)error {
-    UTMLog(@"Debug JSON send -> %@", dict);
-    if (!self.port || !self.port.isOpen) {
-        if (error) {
-            *error = [NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: NSLocalizedString(@"Port is not connected.", "UTMJSONStream")}];
-        }
-        return NO;
-    }
-    NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:error];
-    if (!data) {
-        return NO;
-    }
-    if (shouldSynchronize) {
-        dispatch_async(self.streamQueue, ^{
-            [self.port writeData:[NSData dataWithBytes:"\xFF" length:1]];
-            [self.port writeData:data];
-            self.state = PARSER_WAITING_FOR_DELIMITER;
-        });
-    } else {
-        [self.port writeData:data];
-    }
-    return YES;
-}
-
-@end

+ 0 - 31
Managers/UTMJSONStreamDelegate.h

@@ -1,31 +0,0 @@
-//
-// Copyright © 2019 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import <Foundation/Foundation.h>
-
-NS_ASSUME_NONNULL_BEGIN
-
-@class UTMJSONStream;
-
-@protocol UTMJSONStreamDelegate <NSObject>
-
-- (void)jsonStream:(UTMJSONStream *)stream connected:(BOOL)connected;
-- (void)jsonStream:(UTMJSONStream *)stream receivedDictionary:(NSDictionary *)dict;
-- (void)jsonStream:(UTMJSONStream *)stream seenError:(NSError *)error;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 30
Managers/UTMLoggingDelegate.h

@@ -1,30 +0,0 @@
-//
-// Copyright © 2022 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import <Foundation/Foundation.h>
-
-@class UTMLogging;
-
-NS_ASSUME_NONNULL_BEGIN
-
-@protocol UTMLoggingDelegate <NSObject>
-
-- (void)logging:(UTMLogging *)logging didRecieveOutputLine:(NSString *)line;
-- (void)logging:(UTMLogging *)logging didRecieveErrorLine:(NSString *)line;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 240
Managers/UTMQcow2.c

@@ -1,240 +0,0 @@
-//
-// Copyright © 2020 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include "UTMQcow2.h"
-
-#define QEMU_PACKED __attribute__((packed))
-
-#define BYTES_IN_MIB 1048576
-#define DEFAULT_CLUSTER_SIZE 65536
-#define L1E_SIZE (sizeof(uint64_t))
-#define L2E_SIZE_NORMAL   (sizeof(uint64_t))
-#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
-#define QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
-
-typedef struct QCowHeader {
-    uint32_t magic;
-    uint32_t version;
-    uint64_t backing_file_offset;
-    uint32_t backing_file_size;
-    uint32_t cluster_bits;
-    uint64_t size; /* in bytes */
-    uint32_t crypt_method;
-    uint32_t l1_size; /* XXX: save number of clusters instead ? */
-    uint64_t l1_table_offset;
-    uint64_t refcount_table_offset;
-    uint32_t refcount_table_clusters;
-    uint32_t nb_snapshots;
-    uint64_t snapshots_offset;
-
-    /* The following fields are only valid for version >= 3 */
-    uint64_t incompatible_features;
-    uint64_t compatible_features;
-    uint64_t autoclear_features;
-
-    uint32_t refcount_order;
-    uint32_t header_length;
-
-    /* Additional fields */
-    uint8_t compression_type;
-
-    /* header must be a multiple of 8 */
-    uint8_t padding[7];
-} QEMU_PACKED QCowHeader;
-
-typedef struct {
-    uint32_t magic;
-    uint32_t len;
-} QEMU_PACKED QCowExtension;
-
-typedef struct Qcow2Feature {
-    uint8_t type;
-    uint8_t bit;
-    char    name[46];
-} QEMU_PACKED Qcow2Feature;
-
-typedef union {
-    struct {
-        QCowHeader header;
-        QCowExtension featuresHeader;
-        Qcow2Feature features[7];
-    } QEMU_PACKED;
-    char buffer[DEFAULT_CLUSTER_SIZE];
-} QEMU_PACKED QcowDefaultHeader;
-
-enum {
-    QCOW2_FEAT_TYPE_INCOMPATIBLE    = 0,
-    QCOW2_FEAT_TYPE_COMPATIBLE      = 1,
-    QCOW2_FEAT_TYPE_AUTOCLEAR       = 2,
-};
-
-/* Incompatible feature bits */
-enum {
-    QCOW2_INCOMPAT_DIRTY_BITNR      = 0,
-    QCOW2_INCOMPAT_CORRUPT_BITNR    = 1,
-    QCOW2_INCOMPAT_DATA_FILE_BITNR  = 2,
-    QCOW2_INCOMPAT_COMPRESSION_BITNR = 3,
-    QCOW2_INCOMPAT_EXTL2_BITNR      = 4,
-    QCOW2_INCOMPAT_DIRTY            = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
-    QCOW2_INCOMPAT_CORRUPT          = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
-    QCOW2_INCOMPAT_DATA_FILE        = 1 << QCOW2_INCOMPAT_DATA_FILE_BITNR,
-    QCOW2_INCOMPAT_COMPRESSION      = 1 << QCOW2_INCOMPAT_COMPRESSION_BITNR,
-    QCOW2_INCOMPAT_EXTL2            = 1 << QCOW2_INCOMPAT_EXTL2_BITNR,
-
-    QCOW2_INCOMPAT_MASK             = QCOW2_INCOMPAT_DIRTY
-                                    | QCOW2_INCOMPAT_CORRUPT
-                                    | QCOW2_INCOMPAT_DATA_FILE
-                                    | QCOW2_INCOMPAT_COMPRESSION
-                                    | QCOW2_INCOMPAT_EXTL2,
-};
-
-/* Compatible feature bits */
-enum {
-    QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR = 0,
-    QCOW2_COMPAT_LAZY_REFCOUNTS       = 1 << QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
-
-    QCOW2_COMPAT_FEAT_MASK            = QCOW2_COMPAT_LAZY_REFCOUNTS,
-};
-
-/* Autoclear feature bits */
-enum {
-    QCOW2_AUTOCLEAR_BITMAPS_BITNR       = 0,
-    QCOW2_AUTOCLEAR_DATA_FILE_RAW_BITNR = 1,
-    QCOW2_AUTOCLEAR_BITMAPS             = 1 << QCOW2_AUTOCLEAR_BITMAPS_BITNR,
-    QCOW2_AUTOCLEAR_DATA_FILE_RAW       = 1 << QCOW2_AUTOCLEAR_DATA_FILE_RAW_BITNR,
-
-    QCOW2_AUTOCLEAR_MASK                = QCOW2_AUTOCLEAR_BITMAPS
-                                        | QCOW2_AUTOCLEAR_DATA_FILE_RAW,
-};
-
-static inline uint64_t cpu_to_be64(uint64_t x)
-{
-    return __builtin_bswap64(x);
-}
-
-static inline uint32_t cpu_to_be32(uint32_t x)
-{
-    return __builtin_bswap32(x);
-}
-
-static inline int ctz32(uint32_t val)
-{
-    return val ? __builtin_ctz(val) : 32;
-}
-
-static inline int64_t size_to_l1(int64_t size)
-{
-    int cluster_bits = ctz32(DEFAULT_CLUSTER_SIZE);
-    int shift = 2 * cluster_bits - ctz32(L2E_SIZE_NORMAL);
-    return (size + (1ULL << shift) - 1) >> shift;
-}
-
-static bool qcow2_create(CFWriteStreamRef writeStream, size_t size) {
-    uint32_t l1_size = (uint32_t)size_to_l1(size);
-    QcowDefaultHeader header = {
-        .header = {
-            .magic                      = cpu_to_be32(QCOW_MAGIC),
-            .version                    = cpu_to_be32(3),
-            .cluster_bits               = cpu_to_be32(ctz32(DEFAULT_CLUSTER_SIZE)),
-            .size                       = cpu_to_be64(size),
-            .l1_size                    = cpu_to_be32(l1_size),
-            .l1_table_offset            = cpu_to_be64(3 * DEFAULT_CLUSTER_SIZE),
-            .refcount_table_offset      = cpu_to_be64(DEFAULT_CLUSTER_SIZE),
-            .refcount_table_clusters    = cpu_to_be32(1),
-            .refcount_order             = cpu_to_be32(4),
-            .header_length              = cpu_to_be32(sizeof(header.header)),
-        },
-        .featuresHeader = {
-            .magic                      = cpu_to_be32(QCOW2_EXT_MAGIC_FEATURE_TABLE),
-            .len                        = cpu_to_be32(sizeof(header.features)),
-        },
-        .features = {
-            {
-                .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
-                .bit  = QCOW2_INCOMPAT_DIRTY_BITNR,
-                .name = "dirty bit",
-            },
-            {
-                .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
-                .bit  = QCOW2_INCOMPAT_CORRUPT_BITNR,
-                .name = "corrupt bit",
-            },
-            {
-                .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
-                .bit  = QCOW2_INCOMPAT_DATA_FILE_BITNR,
-                .name = "external data file",
-            },
-            {
-                .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
-                .bit  = QCOW2_INCOMPAT_COMPRESSION_BITNR,
-                .name = "compression type",
-            },
-            {
-                .type = QCOW2_FEAT_TYPE_COMPATIBLE,
-                .bit  = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
-                .name = "lazy refcounts",
-            },
-            {
-                .type = QCOW2_FEAT_TYPE_AUTOCLEAR,
-                .bit  = QCOW2_AUTOCLEAR_BITMAPS_BITNR,
-                .name = "bitmaps",
-            },
-            {
-                .type = QCOW2_FEAT_TYPE_AUTOCLEAR,
-                .bit  = QCOW2_AUTOCLEAR_DATA_FILE_RAW_BITNR,
-                .name = "raw external data",
-            },
-        },
-    };
-    
-    if (CFWriteStreamWrite(writeStream, (void *)&header.buffer, sizeof(header.buffer)) < 0) {
-        return false;
-    }
-    
-    size_t total = 3 * DEFAULT_CLUSTER_SIZE + L1E_SIZE * l1_size;
-    for (size_t i = DEFAULT_CLUSTER_SIZE; i < total; i += sizeof(uint64_t)) {
-        uint64_t data = 0;
-        if (i == DEFAULT_CLUSTER_SIZE) {
-            data = cpu_to_be64(0x20000); // initial reftable
-        } else if (i == 2 * DEFAULT_CLUSTER_SIZE) {
-            data = cpu_to_be64(0x1000100010001); // initial refblock
-        }
-        if (CFWriteStreamWrite(writeStream, (void *)&data, sizeof(uint64_t)) < 0) {
-            return false;
-        }
-    }
-    
-    return true;
-}
-
-bool GenerateDefaultQcow2File(CFURLRef path, size_t sizeInMib) {
-    bool success = false;
-    CFWriteStreamRef writeStream = CFWriteStreamCreateWithFile(kCFAllocatorDefault, path);
-    
-    if (!CFWriteStreamOpen(writeStream)) {
-        goto end;
-    }
-    
-    success = qcow2_create(writeStream, sizeInMib * BYTES_IN_MIB);
-
-end:
-    CFWriteStreamClose(writeStream);
-    CFRelease(writeStream);
-    return success;
-}

+ 0 - 31
Managers/UTMQcow2.h

@@ -1,31 +0,0 @@
-//
-// Copyright © 2020 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef UTMQcow2_h
-#define UTMQcow2_h
-
-#include <stdbool.h>
-#include <CoreFoundation/CoreFoundation.h>
-
-CF_IMPLICIT_BRIDGING_ENABLED
-#pragma clang assume_nonnull begin
-
-bool GenerateDefaultQcow2File(CFURLRef path, size_t sizeInMib);
-
-#pragma clang assume_nonnull end
-CF_IMPLICIT_BRIDGING_DISABLED
-
-#endif /* UTMQcow2_h */

+ 0 - 201
Managers/UTMQemuGuestAgent.h

@@ -1,201 +0,0 @@
-//
-// Copyright © 2023 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMQemuManager.h"
-#import "qga-qapi-types.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@class UTMQemuGuestAgentNetworkInterface;
-@class UTMQemuGuestAgentExecStatus;
-
-/// Interface with QEMU Guest Agent
-@interface UTMQemuGuestAgent : UTMQemuManager
-
-/// Attempt synchronization with guest agent
-///
-/// If an error is returned, any number of things could have happened including:
-///   * Guest Agent has not started on the guest side
-///   * Guest Agent has not been installed yet
-///   * Guest Agent is too slow to respond
-/// - Parameter completion: Callback to run on completion
-- (void)synchronizeWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
-
-/// Set guest time
-/// - Parameters:
-///   - time: time in seconds, relative to the Epoch of 1970-01-01 in UTC.
-///   - completion: Callback to run on completion
-- (void)guestSetTime:(NSTimeInterval)time withCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
-
-/// Open a file in the guest and retrieve a file handle for it
-/// - Parameters:
-///   - path: Full path to the file in the guest to open.
-///   - mode: open mode, as per fopen(), "r" is the default.
-///   - completion: Callback to run on completion, returns file handle on success
-- (void)guestFileOpen:(NSString *)path mode:(nullable NSString *)mode withCompletion:(void (^)(NSInteger, NSError * _Nullable))completion;
-
-/// Close an open file in the guest
-/// - Parameters:
-///   - handle: filehandle returned by guest-file-open
-///   - completion: Callback to run on completion
-- (void)guestFileClose:(NSInteger)handle withCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
-
-/// Read from an open file in the guest.
-///
-/// As this command is just for limited, ad-hoc debugging, such as log
-/// file access, the number of bytes to read is limited to 48 MB.
-/// - Parameters:
-///   - handle: filehandle returned by guest-file-open
-///   - count: maximum number of bytes to read (maximum is 48MB)
-///   - completion: Callback to run on completion, returns number of bytes read on success
-- (void)guestFileRead:(NSInteger)handle count:(NSInteger)count withCompletion:(void (^)(NSData *, NSError * _Nullable))completion;
-
-/// Write to an open file in the guest.
-/// - Parameters:
-///   - handle: filehandle returned by guest-file-open
-///   - data: data to be written
-///   - completion: Callback to run on completion, returns number of bytes written
-- (void)guestFileWrite:(NSInteger)handle data:(NSData *)data withCompletion:(void (^)(NSInteger, NSError * _Nullable))completion;
-
-/// Seek to a position in the file, as with fseek()
-/// - Parameters:
-///   - handle: filehandle returned by guest-file-open
-///   - offset: bytes to skip over in the file stream
-///   - whence: numeric code for interpreting offset
-///   - completion: Callback to run on completion, returns current file position
-- (void)guestFileSeek:(NSInteger)handle offset:(NSInteger)offset whence:(QGASeek)whence withCompletion:(void (^)(NSInteger, NSError * _Nullable))completion;
-
-/// Write file changes buffered in userspace to disk/kernel buffers
-/// - Parameters:
-///   - handle: filehandle returned by guest-file-open
-///   - completion: Callback to run on completion
-- (void)guestFileFlush:(NSInteger)handle withCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
-
-/// Get list of guest IP addresses, MAC addresses and netmasks.
-/// - Parameter completion: Callback to run on completion, returns list of network interfaces
-- (void)guestNetworkGetInterfacesWithCompletion:(void (^)(NSArray<UTMQemuGuestAgentNetworkInterface *> *, NSError * _Nullable))completion;
-
-/// Execute a command in the guest
-/// - Parameters:
-///   - path: path or executable name to execute
-///   - argv: argument list to pass to executable
-///   - envp: environment variables to pass to executable
-///   - input: data to be passed to process stdin
-///   - captureOutput: bool flag to enable capture of stdout/stderr of running process
-///   - completion: Callback to run on completion, returns PID on success
-- (void)guestExec:(NSString *)path argv:(nullable NSArray<NSString *> *)argv envp:(nullable NSArray<NSString *> *)envp input:(nullable NSData *)input captureOutput:(BOOL)captureOutput withCompletion:(void (^ _Nullable)(NSInteger, NSError * _Nullable))completion;
-
-/// Check status of process associated with PID retrieved via guest-exec.
-///
-/// Reap the process and associated metadata if it has exited.
-/// - Parameters:
-///   - pid: returned from guest-exec
-///   - completion: Callback to run on completion, returns status on success
-- (void)guestExecStatus:(NSInteger)pid withCompletion:(void (^)(UTMQemuGuestAgentExecStatus *, NSError * _Nullable))completion;
-
-@end
-
-/// Represent a single network address
-@interface UTMQemuGuestAgentNetworkAddress : NSObject
-
-/// IP address
-@property (nonatomic) NSString *ipAddress;
-
-/// If true, `ipAddress` is a IPv6 address
-@property (nonatomic) BOOL isIpV6Address;
-
-/// Network prefix length
-@property (nonatomic) NSInteger ipAddressPrefix;
-
-+ (instancetype)networkAddressFromQapi:(GuestIpAddress *)qapi;
-- (instancetype)init NS_UNAVAILABLE;
-- (instancetype)initFromQapi:(GuestIpAddress *)qapi NS_DESIGNATED_INITIALIZER;
-
-@end
-
-/// Represent a single network interface
-@interface UTMQemuGuestAgentNetworkInterface : NSObject
-
-/// The name of interface for which info are being delivered
-@property (nonatomic) NSString *interfaceName;
-
-/// Hardware address of this interface
-@property (nonatomic, nullable) NSString *hardwareAddress;
-
-/// List of addresses assigned
-@property (nonatomic) NSArray<UTMQemuGuestAgentNetworkAddress *> *ipAddresses;
-
-/// total bytes received
-@property (nonatomic) NSInteger rxBytes;
-
-/// total packets received
-@property (nonatomic) NSInteger rxPackets;
-
-/// bad packets received
-@property (nonatomic) NSInteger rxErrors;
-
-/// receiver dropped packets
-@property (nonatomic) NSInteger rxDropped;
-
-/// total bytes transmitted
-@property (nonatomic) NSInteger txBytes;
-
-/// total packets transmitted
-@property (nonatomic) NSInteger txPackets;
-
-/// packet transmit problems
-@property (nonatomic) NSInteger txErrors;
-
-/// dropped packets transmitted
-@property (nonatomic) NSInteger txDropped;
-
-+ (instancetype)networkInterfaceFromQapi:(GuestNetworkInterface *)qapi;
-- (instancetype)init NS_UNAVAILABLE;
-- (instancetype)initFromQapi:(GuestNetworkInterface *)qapi NS_DESIGNATED_INITIALIZER;
-
-@end
-
-/// Return value of guestExecStatus
-@interface UTMQemuGuestAgentExecStatus : NSObject
-
-/// true if process has already terminated
-@property (nonatomic) BOOL hasExited;
-
-/// process exit code if it was normally terminated
-@property (nonatomic) NSInteger exitCode;
-
-/// signal number (linux) or unhandled exception code (windows) if the process was abnormally terminated.
-@property (nonatomic) NSInteger signal;
-
-/// stdout of the process
-@property (nonatomic, nullable) NSData *outData;
-
-/// stderr of the process
-@property (nonatomic, nullable) NSData *errData;
-
-/// true if stdout was not fully captured due to size limitation
-@property (nonatomic) BOOL isOutDataTruncated;
-
-/// true if stderr was not fully captured due to size limitation
-@property (nonatomic) BOOL isErrDataTruncated;
-
-+ (instancetype)execStatusFromQapi:(GuestExecStatus *)qapi;
-- (instancetype)init NS_UNAVAILABLE;
-- (instancetype)initFromQapi:(GuestExecStatus *)qapi NS_DESIGNATED_INITIALIZER;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 367
Managers/UTMQemuGuestAgent.m

@@ -1,367 +0,0 @@
-//
-// Copyright © 2023 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMQemuGuestAgent.h"
-#import "UTMQemuManager-Protected.h"
-#import "qga-qapi-commands.h"
-
-extern NSString *const kUTMErrorDomain;
-
-@interface UTMQemuGuestAgent ()
-
-@property (nonatomic) BOOL isGuestAgentResponsive;
-@property (nonatomic, readwrite) BOOL shouldSynchronizeParser;
-@property (nonatomic) dispatch_queue_t guestAgentQueue;
-
-@end
-
-@implementation UTMQemuGuestAgent
-
-- (NSInteger)timeoutSeconds {
-    if (self.isGuestAgentResponsive) {
-        return 10;
-    } else {
-        return 1;
-    }
-}
-
-- (instancetype)initWithPort:(CSPort *)port {
-    if (self = [super initWithPort:port]) {
-        dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, QOS_MIN_RELATIVE_PRIORITY);
-        self.guestAgentQueue = dispatch_queue_create("QEMU Guest Agent Server", attr);
-    }
-    return self;
-}
-
-- (void)jsonStream:(UTMJSONStream *)stream seenError:(NSError *)error {
-    self.isGuestAgentResponsive = NO;
-    [super jsonStream:stream seenError:error];
-}
-
-- (__autoreleasing NSError * _Nullable)_convertErrorFromQerrorAndFree:(nullable Error *)qerror {
-    if (qerror) {
-        NSError *error = [self errorForQerror:qerror];
-        error_free(qerror);
-        return error;
-    } else {
-        return nil;
-    }
-}
-
-- (void)synchronizeWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    self.isGuestAgentResponsive = NO;
-    dispatch_async(self.guestAgentQueue, ^{
-        Error *qerr = NULL;
-        int64_t random = g_random_int();
-        int64_t response = 0;
-        self.shouldSynchronizeParser = YES;
-        response = qmp_guest_sync_delimited(random, &qerr, (__bridge void *)self);
-        self.shouldSynchronizeParser = NO;
-        if (qerr) {
-            if (completion) {
-                completion([self _convertErrorFromQerrorAndFree:qerr]);
-            }
-            return;
-        }
-        if (response != random) {
-            if (completion) {
-                completion([NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: NSLocalizedString(@"Mismatched id from guest-sync-delimited.", "UTMQemuGuestAgent")}]);
-            }
-            return;
-        }
-        self.isGuestAgentResponsive = YES;
-        if (completion) {
-            completion(nil);
-        }
-    });
-}
-
-- (void)_withSynchronizeBlock:(NSError * _Nullable (^)(void))block withCompletion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    dispatch_async(self.guestAgentQueue, ^{
-        if (!self.isGuestAgentResponsive) {
-            [self synchronizeWithCompletion:^(NSError *error) {
-                if (error) {
-                    if (completion) {
-                        completion(error);
-                    }
-                } else {
-                    NSError *error = block();
-                    if (completion) {
-                        completion(error);
-                    }
-                }
-            }];
-        } else {
-            NSError *error = block();
-            if (completion) {
-                completion(error);
-            }
-        }
-    });
-}
-
-- (void)guestSetTime:(NSTimeInterval)time withCompletion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    int64_t timeNanoseconds = (int64_t)(time * NSEC_PER_SEC);
-    [self _withSynchronizeBlock:^{
-        Error *qerr = NULL;
-        qmp_guest_set_time(true, timeNanoseconds, &qerr, (__bridge void *)self);
-        return [self _convertErrorFromQerrorAndFree:qerr];
-    } withCompletion:completion];
-}
-
-- (void)guestFileOpen:(NSString *)path mode:(nullable NSString *)mode withCompletion:(void (^)(NSInteger, NSError * _Nullable))completion {
-    __block int64_t handle = 0;
-    [self _withSynchronizeBlock:^{
-        Error *qerr = NULL;
-        handle = qmp_guest_file_open(path.UTF8String, mode != nil, mode.UTF8String, &qerr, (__bridge void *)self);
-        return [self _convertErrorFromQerrorAndFree:qerr];
-    } withCompletion:^(NSError *error){
-        completion(handle, error);
-    }];
-}
-
-- (void)guestFileClose:(NSInteger)handle withCompletion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    [self _withSynchronizeBlock:^{
-        Error *qerr = NULL;
-        qmp_guest_file_close(handle, &qerr, (__bridge void *)self);
-        return [self _convertErrorFromQerrorAndFree:qerr];
-    } withCompletion:completion];
-}
-
-- (void)guestFileRead:(NSInteger)handle count:(NSInteger)count withCompletion:(void (^)(NSData *, NSError * _Nullable))completion {
-    __block NSData *data = [NSData data];
-    [self _withSynchronizeBlock:^{
-        Error *qerr = NULL;
-        GuestFileRead *result = qmp_guest_file_read(handle, true, count, &qerr, (__bridge void *)self);
-        NSError *error = [self _convertErrorFromQerrorAndFree:qerr];
-        if (result) {
-            data = [[NSData alloc] initWithBase64EncodedString:[NSString stringWithCString:result->buf_b64
-                                                                                  encoding:NSASCIIStringEncoding]
-                                                       options:0];
-            qapi_free_GuestFileRead(result);
-        }
-        return error;
-    } withCompletion:^(NSError *error) {
-        completion(data, error);
-    }];
-}
-
-- (void)guestFileWrite:(NSInteger)handle data:(NSData *)data withCompletion:(void (^)(NSInteger, NSError * _Nullable))completion {
-    __block NSInteger written = 0;
-    [self _withSynchronizeBlock:^{
-        Error *qerr = NULL;
-        GuestFileWrite *result = qmp_guest_file_write(handle, [data base64EncodedStringWithOptions:0].UTF8String, true, data.length, &qerr, (__bridge void *)self);
-        NSError *error = [self _convertErrorFromQerrorAndFree:qerr];
-        if (result) {
-            written = result->count;
-            qapi_free_GuestFileWrite(result);
-        }
-        return error;
-    } withCompletion:^(NSError *error) {
-        completion(written, error);
-    }];
-}
-
-- (void)guestFileSeek:(NSInteger)handle offset:(NSInteger)offset whence:(QGASeek)whence withCompletion:(void (^)(NSInteger, NSError * _Nullable))completion {
-    __block NSInteger position = 0;
-    [self _withSynchronizeBlock:^{
-        Error *qerr = NULL;
-        GuestFileWhence _whence = { .type = QTYPE_QSTRING, .u.name = whence };
-        GuestFileSeek *result = qmp_guest_file_seek(handle, offset, &_whence, &qerr, (__bridge void *)self);
-        NSError *error = [self _convertErrorFromQerrorAndFree:qerr];
-        if (result) {
-            position = result->position;
-            qapi_free_GuestFileSeek(result);
-        }
-        return error;
-    } withCompletion:^(NSError *error) {
-        completion(position, error);
-    }];
-}
-
-- (void)guestFileFlush:(NSInteger)handle withCompletion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    [self _withSynchronizeBlock:^{
-        Error *qerr = NULL;
-        qmp_guest_file_flush(handle, &qerr, (__bridge void *)self);
-        return [self _convertErrorFromQerrorAndFree:qerr];
-    } withCompletion:completion];
-}
-
-- (void)guestNetworkGetInterfacesWithCompletion:(void (^)(NSArray<UTMQemuGuestAgentNetworkInterface *> *, NSError * _Nullable))completion {
-    NSMutableArray<UTMQemuGuestAgentNetworkInterface *> *interfaces = [NSMutableArray array];
-    [self _withSynchronizeBlock:^{
-        Error *qerr = NULL;
-        GuestNetworkInterfaceList *result = qmp_guest_network_get_interfaces(&qerr, (__bridge void *)self);
-        NSError *error = [self _convertErrorFromQerrorAndFree:qerr];
-        if (result) {
-            for (GuestNetworkInterfaceList *list = result; list != NULL; list = list->next) {
-                [interfaces addObject:[UTMQemuGuestAgentNetworkInterface networkInterfaceFromQapi:list->value]];
-            }
-            qapi_free_GuestNetworkInterfaceList(result);
-        }
-        return error;
-    } withCompletion:^(NSError *error) {
-        completion(interfaces, error);
-    }];
-}
-
-static strList *arrayToStrList(NSArray<NSString *> * _Nullable arr) {
-    strList *head = NULL;
-    __block strList **next = &head;
-    [arr enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL *stop) {
-        strList *tail = g_malloc0(sizeof(strList));
-        tail->value = g_strdup(obj.UTF8String);
-        *next = tail;
-        next = &tail->next;
-    }];
-    return head;
-}
-
-- (void)guestExec:(NSString *)path argv:(nullable NSArray<NSString *> *)argv envp:(nullable NSArray<NSString *> *)envp input:(nullable NSData *)input captureOutput:(BOOL)captureOutput withCompletion:(void (^)(NSInteger, NSError * _Nullable))completion {
-    strList *_arg = arrayToStrList(argv);
-    strList *_env = arrayToStrList(envp);
-    __block NSInteger pid = -1;
-    [self _withSynchronizeBlock:^{
-        Error *qerr = NULL;
-        GuestExec *result = qmp_guest_exec(path.UTF8String,
-                                           _arg != NULL, _arg,
-                                           _env != NULL, _env,
-                                           input != nil, [input base64EncodedStringWithOptions:0].UTF8String,
-                                           true, captureOutput,
-                                           &qerr, (__bridge void *)self);
-        NSError *error = [self _convertErrorFromQerrorAndFree:qerr];
-        if (result) {
-            pid = result->pid;
-            qapi_free_GuestExec(result);
-        }
-        return error;
-    } withCompletion:^(NSError *error) {
-        if (_arg) {
-            qapi_free_strList(_arg);
-        }
-        if (_env) {
-            qapi_free_strList(_env);
-        }
-        completion(pid, error);
-    }];
-}
-
-- (void)guestExecStatus:(NSInteger)pid withCompletion:(void (^)(UTMQemuGuestAgentExecStatus *, NSError * _Nullable))completion {
-    __block UTMQemuGuestAgentExecStatus *status = nil;
-    [self _withSynchronizeBlock:^{
-        Error *qerr = NULL;
-        GuestExecStatus *result = qmp_guest_exec_status(pid, &qerr, (__bridge void *)self);
-        NSError *error = [self _convertErrorFromQerrorAndFree:qerr];
-        if (result) {
-            status = [UTMQemuGuestAgentExecStatus execStatusFromQapi:result];
-            qapi_free_GuestExecStatus(result);
-        }
-        return error;
-    } withCompletion:^(NSError *error) {
-        completion(status, error);
-    }];
-}
-
-@end
-
-@implementation UTMQemuGuestAgentNetworkAddress
-
-+ (instancetype)networkAddressFromQapi:(GuestIpAddress *)qapi {
-    return [[UTMQemuGuestAgentNetworkAddress alloc] initFromQapi:qapi];
-}
-
-- (instancetype)initFromQapi:(GuestIpAddress *)qapi {
-    if (self = [super init]) {
-        self.ipAddress = [NSString stringWithCString:qapi->ip_address encoding:NSASCIIStringEncoding];
-        self.isIpV6Address = qapi->ip_address_type == GUEST_IP_ADDRESS_TYPE_IPV6;
-        self.ipAddressPrefix = qapi->prefix;
-    }
-    return self;
-}
-
-@end
-
-@implementation UTMQemuGuestAgentNetworkInterface
-
-+ (instancetype)networkInterfaceFromQapi:(GuestNetworkInterface *)qapi {
-    return [[UTMQemuGuestAgentNetworkInterface alloc] initFromQapi:qapi];
-}
-
-- (instancetype)initFromQapi:(GuestNetworkInterface *)qapi {
-    if (self = [super init]) {
-        self.interfaceName = [NSString stringWithCString:qapi->name encoding:NSASCIIStringEncoding];
-        if (qapi->has_hardware_address) {
-            self.hardwareAddress = [NSString stringWithCString:qapi->hardware_address encoding:NSASCIIStringEncoding];
-        }
-        if (qapi->has_ip_addresses) {
-            NSMutableArray<UTMQemuGuestAgentNetworkAddress *> *ipAddresses = [NSMutableArray array];
-            for (GuestIpAddressList *list = qapi->ip_addresses; list != NULL; list = list->next) {
-                [ipAddresses addObject:[UTMQemuGuestAgentNetworkAddress networkAddressFromQapi:list->value]];
-            }
-            self.ipAddresses = ipAddresses;
-        } else {
-            self.ipAddresses = [NSArray array];
-        }
-        if (qapi->has_statistics) {
-            self.rxBytes = qapi->statistics->rx_bytes;
-            self.rxPackets = qapi->statistics->rx_packets;
-            self.rxErrors = qapi->statistics->rx_errs;
-            self.rxDropped = qapi->statistics->rx_dropped;
-            self.txBytes = qapi->statistics->tx_bytes;
-            self.txPackets = qapi->statistics->tx_packets;
-            self.txErrors = qapi->statistics->tx_errs;
-            self.txDropped = qapi->statistics->tx_dropped;
-        }
-    }
-    return self;
-}
-
-@end
-
-@implementation UTMQemuGuestAgentExecStatus
-
-+ (instancetype)execStatusFromQapi:(GuestExecStatus *)qapi {
-    return [[UTMQemuGuestAgentExecStatus alloc] initFromQapi:qapi];
-}
-
-- (instancetype)initFromQapi:(GuestExecStatus *)qapi {
-    if (self = [super init]) {
-        self.hasExited = qapi->exited;
-        if (qapi->has_exitcode) {
-            self.exitCode = qapi->exitcode;
-        }
-        if (qapi->has_signal) {
-            self.signal = qapi->signal;
-        }
-        if (qapi->has_out_data) {
-            self.outData = [[NSData alloc] initWithBase64EncodedString:[NSString stringWithCString:qapi->out_data
-                                                                                          encoding:NSASCIIStringEncoding] options:0];
-        }
-        if (qapi->has_err_data) {
-            self.errData = [[NSData alloc] initWithBase64EncodedString:[NSString stringWithCString:qapi->err_data
-                                                                                          encoding:NSASCIIStringEncoding] options:0];
-        }
-        if (qapi->has_out_truncated) {
-            self.isOutDataTruncated = qapi->out_truncated;
-        }
-        if (qapi->has_err_truncated) {
-            self.isErrDataTruncated = qapi->err_truncated;
-        }
-    }
-    return self;
-}
-
-@end

+ 0 - 33
Managers/UTMQemuManager-Protected.h

@@ -1,33 +0,0 @@
-//
-// Copyright © 2023 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMQemuManager.h"
-#import "error.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface UTMQemuManager (Protected)
-
-@property (nonatomic, readwrite) BOOL isConnected;
-@property (nonatomic, readonly) NSInteger timeoutSeconds;
-@property (nonatomic, readonly) BOOL shouldSynchronizeParser;
-
-- (__autoreleasing NSError *)errorForQerror:(Error *)qerr;
-- (BOOL)didGetUnhandledKey:(NSString *)key value:(id)value;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 36
Managers/UTMQemuManager.h

@@ -1,36 +0,0 @@
-//
-// Copyright © 2022 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import <Foundation/Foundation.h>
-#import "UTMJSONStreamDelegate.h"
-#import "UTMQemuMonitorDelegate.h"
-
-@class UTMJSONStream;
-@class CSPort;
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface UTMQemuManager : NSObject<UTMJSONStreamDelegate>
-
-@property (nonatomic, readonly) UTMJSONStream *jsonStream;
-@property (nonatomic, readonly) BOOL isConnected;
-
-- (instancetype)init NS_UNAVAILABLE;
-- (instancetype)initWithPort:(CSPort *)port NS_DESIGNATED_INITIALIZER;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 151
Managers/UTMQemuManager.m

@@ -1,151 +0,0 @@
-//
-// Copyright © 2022 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMQemuManager-Protected.h"
-#import "UTMJSONStream.h"
-#import "UTMLogging.h"
-#import "qapi-emit-events.h"
-
-extern NSString *const kUTMErrorDomain;
-
-typedef void(^rpcCompletionHandler_t)(NSDictionary *, NSError *);
-
-@interface UTMQemuManager ()
-
-@property (nonatomic, nullable) rpcCompletionHandler_t rpcCallback;
-@property (nonatomic) UTMJSONStream *jsonStream;
-@property (nonatomic) dispatch_semaphore_t cmdLock;
-
-@end
-
-@implementation UTMQemuManager
-
-@synthesize isConnected = _isConnected;
-
-- (void)setIsConnected:(BOOL)isConnected {
-    _isConnected = isConnected;
-}
-
-- (NSInteger)timeoutSeconds {
-    return 10;
-}
-
-- (BOOL)shouldSynchronizeParser {
-    return NO;
-}
-
-void qmp_rpc_call(CFDictionaryRef args, CFDictionaryRef *ret, Error **err, void *ctx) {
-    UTMQemuManager *self = (__bridge UTMQemuManager *)ctx;
-    dispatch_semaphore_t rpc_sema = dispatch_semaphore_create(0);
-    __block NSDictionary *dict;
-    __block NSError *nserr;
-    __weak typeof(self) _self = self;
-    dispatch_semaphore_wait(self.cmdLock, DISPATCH_TIME_FOREVER);
-    self.rpcCallback = ^(NSDictionary *ret_dict, NSError *ret_err){
-        NSCAssert(ret_dict || ret_err, @"Both dict and err are null");
-        nserr = ret_err;
-        dict = ret_dict;
-        _self.rpcCallback = nil;
-        dispatch_semaphore_signal(rpc_sema); // copy to avoid race condition
-    };
-    if (![self.jsonStream sendDictionary:(__bridge NSDictionary *)args shouldSynchronize:self.shouldSynchronizeParser error:&nserr] && self.rpcCallback) {
-        self.rpcCallback(nil, nserr);
-    }
-    if (dispatch_semaphore_wait(rpc_sema, dispatch_time(DISPATCH_TIME_NOW, (int64_t)self.timeoutSeconds*NSEC_PER_SEC)) != 0) {
-        // possible race between this timeout and the callback being triggered
-        self.rpcCallback = ^(NSDictionary *ret_dict, NSError *ret_err){
-            _self.rpcCallback = nil;
-        };
-        nserr = [NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: NSLocalizedString(@"Timed out waiting for RPC.", "UTMQemuManager")}];
-    }
-    if (ret) {
-        *ret = CFBridgingRetain(dict);
-    }
-    dict = nil;
-    if (nserr) {
-        if (err) {
-            error_setg(err, "%s", [nserr.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding]);
-        }
-        UTMLog(@"RPC: %@", nserr);
-    }
-    dispatch_semaphore_signal(self.cmdLock);
-}
-
-- (instancetype)initWithPort:(CSPort *)port {
-    self = [super init];
-    if (self) {
-        self.jsonStream = [[UTMJSONStream alloc] initWithPort:port];
-        self.jsonStream.delegate = self;
-        self.cmdLock = dispatch_semaphore_create(1);
-    }
-    return self;
-}
-
-- (void)dealloc {
-    if (self.rpcCallback) {
-        self.rpcCallback(nil, [NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: NSLocalizedString(@"Manager being deallocated, killing pending RPC.", "UTMQemuManager")}]);
-    }
-}
-
-- (void)jsonStream:(UTMJSONStream *)stream connected:(BOOL)connected {
-    UTMLog(@"QMP %@", connected ? @"connected" : @"disconnected");
-    if (!connected) {
-        self.isConnected = NO;
-    }
-}
-
-- (void)jsonStream:(UTMJSONStream *)stream seenError:(NSError *)error {
-    UTMLog(@"QMP stream error seen: %@", error);
-    if (self.rpcCallback) {
-        self.rpcCallback(nil, error);
-    }
-}
-
-- (void)jsonStream:(UTMJSONStream *)stream receivedDictionary:(NSDictionary *)dict {
-    [dict enumerateKeysAndObjectsUsingBlock:^(id key, id val, BOOL *stop) {
-        if ([key isEqualToString:@"return"]) {
-            if (self.rpcCallback) {
-                self.rpcCallback(dict, nil);
-            } else {
-                UTMLog(@"Got unexpected 'return' response: %@", dict);
-            }
-            *stop = YES;
-        } else if ([key isEqualToString:@"error"]) {
-            if (self.rpcCallback) {
-                self.rpcCallback(nil, [NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: dict[@"error"][@"desc"]}]);
-            } else {
-                UTMLog(@"Got unexpected 'error' response: %@", dict);
-            }
-            *stop = YES;
-        } else if ([key isEqualToString:@"event"]) {
-            const char *event = [dict[@"event"] cStringUsingEncoding:NSASCIIStringEncoding];
-            qapi_event_dispatch(event, (__bridge CFTypeRef)dict, (__bridge void *)self);
-            *stop = YES;
-        } else if ([self didGetUnhandledKey:key value:val]) {
-            *stop = YES;
-        }
-    }];
-}
-
-- (__autoreleasing NSError *)errorForQerror:(Error *)qerr {
-    return [NSError errorWithDomain:kUTMErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithCString:error_get_pretty(qerr) encoding:NSASCIIStringEncoding]}];
-}
-
-- (BOOL)didGetUnhandledKey:(NSString *)key value:(id)value {
-    return NO;
-}
-
-@end

+ 0 - 30
Managers/UTMQemuMonitor+BlockDevices.h

@@ -1,30 +0,0 @@
-//
-// Copyright © 2020 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMQemuMonitor.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface UTMQemuMonitor (BlockDevices)
-
-@property (nonatomic, readonly, nullable) NSDictionary<NSString *, NSString *> *removableDrives;
-
-- (BOOL)ejectDrive:(NSString *)drive force:(BOOL)force error:(NSError * _Nullable *)error;
-- (BOOL)changeMediumForDrive:(NSString *)drive path:(NSString *)path error:(NSError * _Nullable *)error;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 85
Managers/UTMQemuMonitor+BlockDevices.m

@@ -1,85 +0,0 @@
-//
-// Copyright © 2020 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMQemuMonitor+BlockDevices.h"
-#import "UTMQemuManager-Protected.h"
-#import "UTMLogging.h"
-#import "qapi-commands.h"
-#import "error.h"
-
-@implementation UTMQemuMonitor (BlockDevices)
-
-- (NSDictionary<NSString *, NSString *> *)removableDrives {
-    if (!self.isConnected) {
-        return nil;
-    }
-    BlockInfoList *block = NULL;
-    Error *qerr = NULL;
-    block = qmp_query_block(&qerr, (__bridge void *)self);
-    if (qerr) {
-        UTMLog(@"Failed to query drives: %s", error_get_pretty(qerr));
-        error_free(qerr);
-        return nil;
-    }
-    if (!block) {
-        UTMLog(@"Invalid return for query-block");
-        return nil;
-    }
-    id dict = [NSMutableDictionary<NSString *, NSString *> dictionary];
-    for (BlockInfoList *list = block; list->next; list = list->next) {
-        const BlockInfo *info = list->value;
-        if (info->removable) {
-            NSString *drive = [NSString stringWithUTF8String:info->device];
-            NSString *file;
-            if (info->has_inserted) {
-                file = [NSString stringWithUTF8String:info->inserted->file];
-            } else {
-                file = @"";
-            }
-            dict[drive] = file;
-        }
-    }
-    qapi_free_BlockInfoList(block);
-    return dict;
-}
-
-- (BOOL)ejectDrive:(NSString *)drive force:(BOOL)force error:(NSError * _Nullable *)error {
-    Error *qerr = NULL;
-    qmp_eject(true, [drive cStringUsingEncoding:NSUTF8StringEncoding], false, NULL, true, force, &qerr, (__bridge void *)self);
-    if (qerr) {
-        if (error) {
-            *error = [self errorForQerror:qerr];
-        }
-        error_free(qerr);
-        return NO;
-    }
-    return YES;
-}
-
-- (BOOL)changeMediumForDrive:(NSString *)drive path:(NSString *)path error:(NSError * _Nullable __autoreleasing *)error {
-    Error *qerr = NULL;
-    qmp_blockdev_change_medium(true, [drive cStringUsingEncoding:NSUTF8StringEncoding], false, NULL, [path cStringUsingEncoding:NSUTF8StringEncoding], false, NULL, false, false, false, BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &qerr, (__bridge void *)self);
-    if (qerr) {
-        if (error) {
-            *error = [self errorForQerror:qerr];
-        }
-        error_free(qerr);
-        return NO;
-    }
-    return YES;
-}
-
-@end

+ 0 - 42
Managers/UTMQemuMonitor.h

@@ -1,42 +0,0 @@
-//
-// Copyright © 2023 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMQemuManager.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface UTMQemuMonitor : UTMQemuManager
-
-@property (nonatomic, weak) id<UTMQemuMonitorDelegate> delegate;
-
-- (BOOL)qmpEnterCommandModeWithError:(NSError * _Nullable __autoreleasing *)error;
-- (BOOL)continueBootWithError:(NSError * _Nullable __autoreleasing *)error;
-
-- (void)qemuPowerDownWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
-- (void)qemuResetWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
-- (void)qemuStopWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
-- (void)qemuResumeWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
-- (void)qemuQuitWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion;
-- (void)qemuSaveSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion;
-- (void)qemuDeleteSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion;
-- (void)qemuRestoreSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion;
-
-- (void)mouseIndexForAbsolute:(BOOL)absolute withCompletion:(void (^)(int64_t, NSError * _Nullable))completion;
-- (void)mouseSelect:(int64_t)index withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 278
Managers/UTMQemuMonitor.m

@@ -1,278 +0,0 @@
-//
-// Copyright © 2023 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMQemuMonitor.h"
-#import "UTMQemuManager-Protected.h"
-#import "UTMLogging.h"
-#import "qapi-commands.h"
-#import "qapi-emit-events.h"
-#import "qapi-events.h"
-#import "error.h"
-
-static void utm_shutdown_handler(bool guest, ShutdownCause reason, void *ctx) {
-    UTMQemuMonitor *self = (__bridge UTMQemuMonitor *)ctx;
-    [self.delegate qemuWillQuit:self guest:guest reason:reason];
-}
-
-static void utm_powerdown_handler(void *ctx) {
-    
-}
-
-static void utm_reset_handler(bool guest, ShutdownCause reason, void *ctx) {
-    UTMQemuMonitor *self = (__bridge UTMQemuMonitor *)ctx;
-    [self.delegate qemuHasReset:self guest:guest reason:reason];
-}
-
-static void utm_stop_handler(void *ctx) {
-    UTMQemuMonitor *self = (__bridge UTMQemuMonitor *)ctx;
-    [self.delegate qemuHasStopped:self];
-}
-
-static void utm_resume_handler(void *ctx) {
-    UTMQemuMonitor *self = (__bridge UTMQemuMonitor *)ctx;
-    [self.delegate qemuHasResumed:self];
-}
-
-static void utm_suspend_handler(void *ctx) {
-    UTMQemuMonitor *self = (__bridge UTMQemuMonitor *)ctx;
-    [self.delegate qemuHasSuspended:self];
-}
-
-static void utm_suspend_disk_handler(void *ctx) {
-    
-}
-
-static void utm_wakeup_handler(void *ctx) {
-    UTMQemuMonitor *self = (__bridge UTMQemuMonitor *)ctx;
-    [self.delegate qemuHasWakeup:self];
-}
-
-static void utm_watchdog_handler(WatchdogAction action, void *ctx) {
-    
-}
-
-static void utm_guest_panicked_handler(GuestPanicAction action, bool has_info, GuestPanicInformation *info, void *ctx) {
-    UTMQemuMonitor *self = (__bridge UTMQemuMonitor *)ctx;
-    [self.delegate qemuError:self error:NSLocalizedString(@"Guest panic", @"UTMQemuManager")];
-}
-
-static void utm_block_image_corrupted_handler(const char *device, bool has_node_name, const char *node_name, const char *msg, bool has_offset, int64_t offset, bool has_size, int64_t size, bool fatal, void *ctx) {
-    UTMQemuMonitor *self = (__bridge UTMQemuMonitor *)ctx;
-    if (fatal) {
-        [self.delegate qemuError:self error:[NSString stringWithFormat:@"%s, %s: %s", device, node_name, msg]];
-    }
-}
-
-static void utm_block_io_error_handler(const char *device, bool has_node_name, const char *node_name, IoOperationType operation, BlockErrorAction action, bool has_nospace, bool nospace, const char *reason, void *ctx) {
-    UTMQemuMonitor *self = (__bridge UTMQemuMonitor *)ctx;
-    [self.delegate qemuError:self error:[NSString stringWithFormat:@"%s, %s: %s", device, node_name, reason]];
-}
-
-static void utm_spice_connected_handler(SpiceBasicInfo *server, SpiceBasicInfo *client, void *ctx) {
-    
-}
-
-static void utm_spice_initialized_handler(SpiceServerInfo *server, SpiceChannel *client, void *ctx) {
-    
-}
-
-static void utm_spice_disconnected_handler(SpiceBasicInfo *server, SpiceBasicInfo *client, void *ctx) {
-    
-}
-
-static void utm_spice_migrate_completed_handler(void *ctx) {
-    
-}
-
-static void utm_migration_handler(MigrationStatus status, void *ctx) {
-    
-}
-
-static void utm_migration_pass_handler(int64_t pass, void *ctx) {
-    
-}
-
-qapi_enum_handler_registry qapi_enum_handler_registry_data = {
-    .qapi_shutdown_handler = utm_shutdown_handler,
-    .qapi_powerdown_handler = utm_powerdown_handler,
-    .qapi_reset_handler = utm_reset_handler,
-    .qapi_stop_handler = utm_stop_handler,
-    .qapi_resume_handler = utm_resume_handler,
-    .qapi_suspend_handler = utm_suspend_handler,
-    .qapi_suspend_disk_handler = utm_suspend_disk_handler,
-    .qapi_wakeup_handler = utm_wakeup_handler,
-    .qapi_watchdog_handler = utm_watchdog_handler,
-    .qapi_guest_panicked_handler = utm_guest_panicked_handler,
-    .qapi_block_image_corrupted_handler = utm_block_image_corrupted_handler,
-    .qapi_block_io_error_handler = utm_block_io_error_handler,
-    .qapi_spice_connected_handler = utm_spice_connected_handler,
-    .qapi_spice_initialized_handler = utm_spice_initialized_handler,
-    .qapi_spice_disconnected_handler = utm_spice_disconnected_handler,
-    .qapi_spice_migrate_completed_handler = utm_spice_migrate_completed_handler,
-    .qapi_migration_handler = utm_migration_handler,
-    .qapi_migration_pass_handler = utm_migration_pass_handler,
-};
-
-@implementation UTMQemuMonitor
-
-- (BOOL)didGetUnhandledKey:(NSString *)key value:(id)value {
-    if ([key isEqualToString:@"QMP"]) {
-        UTMLog(@"Got QMP handshake: %@", value);
-        [self.delegate qemuQmpDidConnect:self];
-        return YES;
-    }
-    return NO;
-}
-
-- (BOOL)qmpEnterCommandModeWithError:(NSError * _Nullable __autoreleasing *)error {
-    NSDictionary *cmd = @{
-        @"execute": @"qmp_capabilities"
-    };
-    Error *qerr = NULL;
-    qmp_rpc_call((__bridge CFDictionaryRef)cmd, NULL, &qerr, (__bridge void *)self);
-    if (qerr != NULL) {
-        if (error) {
-            *error = [self errorForQerror:qerr];
-            error_free(qerr);
-        }
-        return NO;
-    } else {
-        self.isConnected = YES;
-        return YES;
-    }
-}
-
-- (BOOL)continueBootWithError:(NSError * _Nullable __autoreleasing *)error {
-    Error *qerr = NULL;
-    qmp_cont(&qerr, (__bridge void *)self);
-    if (qerr != NULL) {
-        if (error) {
-            *error = [self errorForQerror:qerr];
-            error_free(qerr);
-        }
-        self.isConnected = NO;
-        return NO;
-    } else {
-        return YES;
-    }
-}
-
-- (void)qmpPowerCommand:(NSString *)command completion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
-        Error *qerr = NULL;
-        NSError *err;
-        NSDictionary *cmd = @{
-            @"execute": command
-        };
-        qmp_rpc_call((__bridge CFDictionaryRef)cmd, NULL, &qerr, (__bridge void *)self);
-        if (qerr) {
-            err = [self errorForQerror:qerr];
-            error_free(qerr);
-        }
-        if (completion) {
-            completion(err);
-        }
-    });
-}
-
-- (void)qmpHmpCommand:(NSString *)cmd completion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion {
-    dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
-        Error *qerr = NULL;
-        NSError *err;
-        NSString *result;
-        char *res;
-        res = qmp_human_monitor_command([cmd cStringUsingEncoding:NSASCIIStringEncoding], false, 0, &qerr, (__bridge void *)self);
-        if (res) {
-            result = [NSString stringWithCString:res encoding:NSASCIIStringEncoding];
-            g_free(res);
-        }
-        if (qerr) {
-            err = [self errorForQerror:qerr];
-            error_free(qerr);
-        }
-        if (completion) {
-            completion(result, err);
-        }
-    });
-}
-
-- (void)qemuPowerDownWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    [self qmpPowerCommand:@"system_powerdown" completion:completion];
-}
-
-- (void)qemuResetWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    [self qmpPowerCommand:@"system_reset" completion:completion];
-}
-
-- (void)qemuStopWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    [self qmpPowerCommand:@"stop" completion:completion];
-}
-
-- (void)qemuResumeWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    [self qmpPowerCommand:@"cont" completion:completion];
-}
-
-- (void)qemuQuitWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    [self qmpPowerCommand:@"quit" completion:completion];
-}
-
-- (void)qemuSaveSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion {
-    NSString *cmd = [NSString stringWithFormat:@"savevm %@", snapshot];
-    [self qmpHmpCommand:cmd completion:completion];
-}
-
-- (void)qemuDeleteSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion {
-    NSString *cmd = [NSString stringWithFormat:@"delvm %@", snapshot];
-    [self qmpHmpCommand:cmd completion:completion];
-}
-
-- (void)qemuRestoreSnapshot:(NSString *)snapshot withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion {
-    NSString *cmd = [NSString stringWithFormat:@"loadvm %@", snapshot];
-    [self qmpHmpCommand:cmd completion:completion];
-}
-
-- (void)mouseIndexForAbsolute:(BOOL)absolute withCompletion:(void (^)(int64_t, NSError * _Nullable))completion {
-    dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
-        MouseInfoList *info = NULL;
-        Error *qerr = NULL;
-        int64_t index = -1;
-        NSError *err;
-        info = qmp_query_mice(&qerr, (__bridge void *)self);
-        if (qerr) {
-            err = [self errorForQerror:qerr];
-            error_free(qerr);
-        }
-        if (info) {
-            for (MouseInfoList *list = info; list; list = list->next) {
-                if (list->value->absolute == absolute) {
-                    index = list->value->index;
-                    break;
-                }
-            }
-            qapi_free_MouseInfoList(info);
-        }
-        if (completion) {
-            completion(index, err);
-        }
-    });
-}
-
-- (void)mouseSelect:(int64_t)index withCompletion:(void (^)(NSString * _Nullable, NSError * _Nullable))completion {
-    NSString *cmd = [NSString stringWithFormat:@"mouse_set %lld", index];
-    [self qmpHmpCommand:cmd completion:completion];
-}
-
-@end

+ 0 - 38
Managers/UTMQemuMonitorDelegate.h

@@ -1,38 +0,0 @@
-//
-// Copyright © 2019 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import <Foundation/Foundation.h>
-
-typedef enum ShutdownCause ShutdownCause;
-
-NS_ASSUME_NONNULL_BEGIN
-
-@class UTMQemuMonitor;
-
-@protocol UTMQemuMonitorDelegate <NSObject>
-
-- (void)qemuHasStopped:(UTMQemuMonitor *)monitor;
-- (void)qemuHasReset:(UTMQemuMonitor *)monitor guest:(BOOL)guest reason:(ShutdownCause)reason;
-- (void)qemuHasResumed:(UTMQemuMonitor *)monitor;
-- (void)qemuHasSuspended:(UTMQemuMonitor *)monitor;
-- (void)qemuHasWakeup:(UTMQemuMonitor *)monitor;
-- (void)qemuWillQuit:(UTMQemuMonitor *)monitor guest:(BOOL)guest reason:(ShutdownCause)reason;
-- (void)qemuError:(UTMQemuMonitor *)monitor error:(NSString *)error;
-- (void)qemuQmpDidConnect:(UTMQemuMonitor *)monitor;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 29
Managers/UTMQemuVirtualMachine+SPICE.h

@@ -1,29 +0,0 @@
-//
-// Copyright © 2020 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMQemuVirtualMachine.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface UTMQemuVirtualMachine (SPICE)
-
-@property (nonatomic, readonly) BOOL hasUsbRedirection;
-
-- (void)requestInputTablet:(BOOL)tablet;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 79
Managers/UTMQemuVirtualMachine+SPICE.m

@@ -1,79 +0,0 @@
-//
-// Copyright © 2020 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMQemuVirtualMachine+SPICE.h"
-#import "UTMLogging.h"
-#import "UTMQemuMonitor.h"
-#import "UTMSpiceIO.h"
-#import "UTMJailbreak.h"
-#import "UTM-Swift.h"
-#if defined(WITH_QEMU_TCI)
-@import CocoaSpiceNoUsb;
-#else
-@import CocoaSpice;
-#endif
-
-@interface UTMQemuVirtualMachine ()
-
-@property (nonatomic, readonly, nullable) UTMQemuMonitor *qemu;
-@property (nonatomic, readonly, nullable) UTMSpiceIO *ioService;
-@property (nonatomic) BOOL changeCursorRequestInProgress;
-
-@end
-
-@implementation UTMQemuVirtualMachine (SPICE)
-
-#pragma mark - Input device switching
-
-- (void)requestInputTablet:(BOOL)tablet {
-    UTMQemuMonitor *qemu;
-    @synchronized (self) {
-        qemu = self.qemu;
-        if (self.changeCursorRequestInProgress || !qemu) {
-            return;
-        }
-        self.changeCursorRequestInProgress = YES;
-    }
-    [qemu mouseIndexForAbsolute:tablet withCompletion:^(int64_t index, NSError *err) {
-        if (err) {
-            UTMLog(@"error finding index: %@", err);
-            self.changeCursorRequestInProgress = NO;
-        } else {
-            UTMLog(@"found index:%lld absolute:%d", index, tablet);
-            [self.qemu mouseSelect:index withCompletion:^(NSString *res, NSError *err) {
-                if (err) {
-                    UTMLog(@"input select returned error: %@", err);
-                } else {
-                    UTMSpiceIO *spiceIO = self.ioService;
-                    if (spiceIO) {
-                        [spiceIO.primaryInput requestMouseMode:!tablet];
-                    } else {
-                        UTMLog(@"failed to get SPICE manager: %@", err);
-                    }
-                }
-                self.changeCursorRequestInProgress = NO;
-            }];
-        }
-    }];
-}
-
-#pragma mark - USB redirection
-
-- (BOOL)hasUsbRedirection {
-    return jb_has_usb_entitlement();
-}
-
-@end

+ 0 - 33
Managers/UTMQemuVirtualMachine-Protected.h

@@ -1,33 +0,0 @@
-//
-// Copyright © 2022 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMQemuVirtualMachine.h"
-
-@class UTMQemu;
-@class UTMQemuMonitor;
-@class UTMSpiceIO;
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface UTMQemuVirtualMachine (Protected)
-
-@property (nonatomic, readonly, nullable) UTMQemuMonitor *qemu;
-@property (nonatomic, readonly, nullable) UTMQemu *system;
-@property (nonatomic, readonly, nullable) UTMSpiceIO *ioService;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 38
Managers/UTMQemuVirtualMachine.h

@@ -1,38 +0,0 @@
-//
-// Copyright © 2021 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import "UTMVirtualMachine.h"
-#import "UTMSpiceIODelegate.h"
-
-@class UTMQemuGuestAgent;
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface UTMQemuVirtualMachine : UTMVirtualMachine
-
-@property (nonatomic, weak, nullable) id<UTMSpiceIODelegate> ioDelegate;
-
-/// If non-null, provides access to the QEMU guest agent interface
-@property (nonatomic, readonly, nullable) UTMQemuGuestAgent *guestAgent;
-
-/// Set to true to request guest tools install.
-///
-/// This property is observable and must only be accessed on the main thread.
-@property (nonatomic) BOOL isGuestToolsInstallRequested;
-
-@end
-
-NS_ASSUME_NONNULL_END

+ 0 - 733
Managers/UTMQemuVirtualMachine.m

@@ -1,733 +0,0 @@
-//
-// Copyright © 2021 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#import <TargetConditionals.h>
-#import "UTMVirtualMachine-Protected.h"
-#import "UTMVirtualMachine-Private.h"
-#import "UTMLoggingDelegate.h"
-#import "UTMQemuMonitorDelegate.h"
-#import "UTMQemuVirtualMachine.h"
-#import "UTMQemuVirtualMachine+SPICE.h"
-#import "UTMQemuMonitor.h"
-#import "UTMQemuGuestAgent.h"
-#import "UTMQemuSystem.h"
-#import "UTMSpiceIO.h"
-#import "UTMLogging.h"
-#import "UTM-Swift.h"
-#import "qapi-events.h"
-
-const int64_t kStopTimeout = (int64_t)30*NSEC_PER_SEC;
-
-extern NSString *const kUTMBundleConfigFilename;
-NSString *const kSuspendSnapshotName = @"suspend";
-
-static void *SpiceIoServiceGuestAgentContext = &SpiceIoServiceGuestAgentContext;
-
-@interface UTMQemuVirtualMachine () <UTMLoggingDelegate, UTMQemuMonitorDelegate>
-
-@property (nonatomic, readwrite, nullable) UTMQemuMonitor *qemu;
-@property (nonatomic, readwrite, nullable) UTMQemuGuestAgent *guestAgent;
-@property (nonatomic, readwrite, nullable) UTMQemuSystem *system;
-@property (nonatomic, readwrite, nullable) UTMSpiceIO *ioService;
-@property (nonatomic, weak) id<UTMSpiceIODelegate> ioServiceDelegate;
-@property (nonatomic) dispatch_queue_t vmOperations;
-@property (nonatomic, nullable) dispatch_semaphore_t qemuWillQuitEvent;
-@property (nonatomic, nullable) dispatch_semaphore_t qemuDidExitEvent;
-@property (nonatomic, nullable) dispatch_semaphore_t qemuDidConnectEvent;
-@property (nonatomic) BOOL changeCursorRequestInProgress;
-@property (nonatomic, nullable) NSString *lastErrorLine;
-@property (nonatomic, readonly) UTMQEMURendererBackend rendererBackend;
-
-@end
-
-@implementation UTMQemuVirtualMachine
-
-- (id<UTMSpiceIODelegate>)ioDelegate {
-    return self.ioService ? self.ioService.delegate : self.ioServiceDelegate;
-}
-
-- (void)setIoDelegate:(id<UTMSpiceIODelegate>)ioDelegate {
-    if (self.ioService) {
-        self.ioService.delegate = ioDelegate;
-    } else {
-        // we haven't started the VM yet, save a copy
-        self.ioServiceDelegate = ioDelegate;
-    }
-}
-
-- (void)setIsGuestToolsInstallRequested:(BOOL)isGuestToolsInstallRequested {
-    [self propertyWillChange];
-    _isGuestToolsInstallRequested = isGuestToolsInstallRequested;
-}
-
-- (UTMQEMURendererBackend)rendererBackend {
-    NSInteger value = [NSUserDefaults.standardUserDefaults integerForKey:@"QEMURendererBackend"];
-    if (value >= 0 && value < kQEMURendererBackendMax) {
-        return (UTMQEMURendererBackend)value;
-    } else {
-        return kQEMURendererBackendDefault;
-    }
-}
-
-- (instancetype)initWithConfiguration:(UTMConfigurationWrapper *)configuration packageURL:(NSURL *)packageURL {
-    self = [super initWithConfiguration:configuration packageURL:packageURL];
-    if (self) {
-        self.qemuWillQuitEvent = dispatch_semaphore_create(0);
-        self.qemuDidExitEvent = dispatch_semaphore_create(0);
-        self.qemuDidConnectEvent = dispatch_semaphore_create(0);
-        dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, 0);
-        self.vmOperations = dispatch_queue_create("com.utmapp.UTM.VMOperations", attr);
-    }
-    return self;
-}
-
-#pragma mark - Shortcut access
-
-- (void)accessShortcutWithCompletion:(void (^ _Nullable)(NSError * _Nullable))completion {
-    NSAssert(self.path != nil, @"VM must be existing in the filesystem!");
-    if (!completion) {
-        // default handler
-        completion = ^(NSError *error){};
-    }
-    if (!self.isShortcut) {
-        completion(nil); // not needed
-        return;
-    }
-    UTMQemu *service = self.system;
-    if (!service) {
-        service = [UTMQemu new]; // VM has not started yet, we create a temporary process
-    }
-    NSData *bookmark = self.registryEntry.packageRemoteBookmark;
-    NSString *bookmarkPath = self.registryEntry.packageRemotePath;
-    BOOL existing = bookmark != nil;
-    if (!existing) {
-        // create temporary bookmark
-        NSError *err;
-        bookmark = [self.path bookmarkDataWithOptions:0
-                       includingResourceValuesForKeys:nil
-                                        relativeToURL:nil
-                                                error:&err];
-        if (!bookmark) {
-            completion(err);
-            return;
-        }
-    }
-    if (bookmarkPath) {
-        [service stopAccessingPath:bookmarkPath]; // in case old path is still accessed
-    }
-    [service accessDataWithBookmark:bookmark securityScoped:existing completion:^(BOOL success, NSData *newBookmark, NSString *newPath) {
-        (void)service; // required to capture service so it is not released by ARC
-        if (success) {
-            dispatch_async(dispatch_get_main_queue(), ^{
-                self.registryEntry.packageRemoteBookmark = newBookmark;
-                self.registryEntry.packageRemotePath = newPath;
-                completion(nil);
-            });
-        } else if (existing) { // the remote bookmark is invalid but the local one still might be valid
-            dispatch_async(dispatch_get_main_queue(), ^{
-                self.registryEntry.packageRemoteBookmark = nil;
-                self.registryEntry.packageRemotePath = nil;
-                [self accessShortcutWithCompletion:completion];
-            });
-        } else {
-            completion([self errorWithMessage:NSLocalizedString(@"Failed to access data from shortcut.", @"UTMQemuVirtualMachine")]);
-        }
-    }];
-}
-
-#pragma mark - VM actions
-
-- (void)_vmStartWithCompletion:(void (^)(NSError * _Nullable))completion {
-    // check if we can actually start this VM
-    if (!self.isSupported) {
-        completion([self errorWithMessage:NSLocalizedString(@"This build of UTM does not support emulating the architecture of this VM.", @"UTMQemuVirtualMachine")]);
-        return;
-    }
-    // start logging
-    if (self.config.qemuHasDebugLog) {
-        [self.logging logToFile:self.config.qemuDebugLogURL];
-    }
-    
-    self.config.qemuIsDisposable = self.isRunningAsSnapshot;
-    
-    NSArray<NSString *> *arguments = self.config.qemuArguments;
-    NSArray<NSURL *> *resources = self.config.qemuResources;
-    NSDictionary<NSURL *, NSData *> *remoteBookmarks = self.remoteBookmarks;
-    self.system = [[UTMQemuSystem alloc] initWithArguments:arguments architecture:self.config.qemuArchitecture];
-    self.system.resources = resources;
-    self.system.remoteBookmarks = remoteBookmarks;
-    self.system.logging = self.logging;
-    self.system.logging.delegate = self;
-
-    if (!self.system) {
-        completion([self errorGeneric]);
-        return;
-    }
-    
-    if (self.isShortcut) {
-        __block NSError *accessErr = nil;
-        dispatch_semaphore_t accessCompleteEvent = dispatch_semaphore_create(0);
-        [self accessShortcutWithCompletion:^(NSError *err){
-            accessErr = err;
-            dispatch_semaphore_signal(accessCompleteEvent);
-        }];
-        dispatch_semaphore_wait(accessCompleteEvent, DISPATCH_TIME_FOREVER);
-        if (accessErr) {
-            completion(accessErr);
-            return;
-        }
-    }
-    
-    self.ioService = [[UTMSpiceIO alloc] initWithConfiguration:self.config];
-    self.ioService.delegate = self.ioServiceDelegate;
-    self.ioServiceDelegate = nil;
-    [self.ioService addObserver:self
-                     forKeyPath:@"qemuGuestAgent"
-                        options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial
-                        context:SpiceIoServiceGuestAgentContext];
-    
-    NSError *spiceError;
-    if (![self.ioService startWithError:&spiceError]) {
-        completion(spiceError);
-        return;
-    }
-    // create EFI variables for legacy config
-    // this is ugly code and should be removed when legacy config support is removed
-    dispatch_semaphore_t ensureEfiVarsEvent = dispatch_semaphore_create(0);
-    __block NSError *ensureEfiVarsError = nil;
-    [self.config qemuEnsureEfiVarsAvailableWithCompletion:^(NSError * _Nullable error) {
-        ensureEfiVarsError = error;
-        dispatch_semaphore_signal(ensureEfiVarsEvent);
-    }];
-    if (ensureEfiVarsError) {
-        completion(ensureEfiVarsError);
-        return;
-    }
-    // start QEMU (this can be in parallel with SPICE connect below)
-    __weak typeof(self) weakSelf = self;
-    __block NSError *qemuStartError = nil;
-    dispatch_semaphore_t spiceConnectOrErrorEvent = dispatch_semaphore_create(0);
-    self.system.rendererBackend = self.rendererBackend;
-    [self.system startWithCompletion:^(BOOL success, NSString *msg){
-        typeof(self) _self = weakSelf;
-        if (!_self) {
-            return; // outlived class
-        }
-        if (!success) {
-            if (!msg) {
-                msg = [NSString localizedStringWithFormat:NSLocalizedString(@"QEMU exited from an error: %@", @"UTMQemuVirtualMachine"), self.lastErrorLine];
-            }
-            qemuStartError = [_self errorWithMessage:msg];
-            dispatch_semaphore_signal(spiceConnectOrErrorEvent);
-            if (_self.qemu.isConnected) { // we are NOT in vmStart, so pass error to delegate
-                dispatch_async(dispatch_get_main_queue(), ^{
-                    [_self.delegate virtualMachine:_self didErrorWithMessage:msg];
-                });
-            }
-        }
-        dispatch_semaphore_signal(_self.qemuDidExitEvent);
-        [_self vmStopForce:YES completion:^(NSError *error){}];
-    }];
-    __block BOOL spiceConnectFailed = NO; // failure could have no error message
-    __block NSError *spiceConnectError = nil;
-    NSError *err;
-    // start SPICE client
-    [self.ioService connectWithCompletion:^(UTMQemuMonitor *monitor, NSError *error) {
-        if (monitor) { // success
-            self.qemu = monitor;
-            self.qemu.delegate = self;
-        } else { // give up
-            UTMLog(@"Failed to connect to SPICE: %@", error);
-            spiceConnectFailed = YES;
-            spiceConnectError = error;
-        }
-        dispatch_semaphore_signal(spiceConnectOrErrorEvent);
-    }];
-    if (dispatch_semaphore_wait(spiceConnectOrErrorEvent, self.config.qemuShouldWaitForeverForConnect ? DISPATCH_TIME_FOREVER : dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        UTMLog(@"Timed out waiting for SPICE connect event");
-        [self _vmStopForce:YES completion:^(NSError *err) {}];
-        completion([self errorGeneric]);
-        return;
-    }
-    if (qemuStartError) {
-        completion(qemuStartError);
-        return;
-    }
-    if (spiceConnectFailed) {
-        [self _vmStopForce:YES completion:^(NSError *err) {}];
-        completion(spiceConnectError);
-        return;
-    }
-    assert(self.ioService.isConnected);
-    // wait for QMP to connect
-    if (dispatch_semaphore_wait(self.qemuDidConnectEvent, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        UTMLog(@"Timed out waiting for QMP connect event");
-        [self _vmStopForce:YES completion:^(NSError *err) {}];
-        completion([self errorGeneric]);
-        return;
-    }
-    assert(self.qemu);
-    // enter command mode
-    if (![self.qemu qmpEnterCommandModeWithError:&err]) {
-        UTMLog(@"Failed to enter command mode: %@", err);
-        [self _vmStopForce:YES completion:^(NSError *err) {}];
-        completion(err);
-        return;
-    }
-    assert(self.qemu.isConnected);
-    // load saved state if requested
-    if (!self.isRunningAsSnapshot && self.registryEntry.hasSaveState) {
-        __block NSError *restoreError = nil;
-        dispatch_semaphore_t restoreSnapshotEvent = dispatch_semaphore_create(0);
-        [self.qemu qemuRestoreSnapshot:kSuspendSnapshotName withCompletion:^(NSString *result, NSError *error) {
-            if (error) {
-                restoreError = error;
-            } else if ([result localizedCaseInsensitiveContainsString:@"Error"]) {
-                restoreError = [self errorWithMessage:result]; // error message
-            }
-            dispatch_semaphore_signal(restoreSnapshotEvent);
-        }];
-        if (dispatch_semaphore_wait(restoreSnapshotEvent, DISPATCH_TIME_FOREVER) != 0) {
-            completion([self errorGeneric]);
-            return;
-        }
-        if (restoreError) {
-            [self _vmStopForce:YES completion:^(NSError *err) {}];
-            completion(restoreError);
-            return;
-        }
-    }
-    // set up SPICE sharing and removable drives
-    NSString *errMsg;
-    __block NSError *restoreExternalDrivesAndSharesError = nil;
-    dispatch_semaphore_t restoreExternalDrivesAndSharesEvent = dispatch_semaphore_create(0);
-    [self restoreExternalDrivesAndSharesWithCompletion:^(NSError *err) {
-        restoreExternalDrivesAndSharesError = err;
-        dispatch_semaphore_signal(restoreExternalDrivesAndSharesEvent);
-    }];
-    if (dispatch_semaphore_wait(restoreExternalDrivesAndSharesEvent, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        UTMLog(@"Timed out waiting for external drives and shares to be restored.");
-        [self _vmStopForce:YES completion:^(NSError *err) {}];
-        completion([self errorGeneric]);
-        return;
-    }
-    if (restoreExternalDrivesAndSharesError) {
-        errMsg = [NSString localizedStringWithFormat:NSLocalizedString(@"Error trying to restore external drives and shares: %@", @"UTMVirtualMachine"), restoreExternalDrivesAndSharesError.localizedDescription];
-        [self _vmStopForce:YES completion:^(NSError *err) {}];
-        completion([self errorWithMessage:errMsg]);
-        return;
-    }
-    // continue VM boot
-    if (![self.qemu continueBootWithError:&err]) {
-        UTMLog(@"Failed to boot: %@", err);
-        [self _vmStopForce:YES completion:^(NSError *err) {}];
-        completion(err);
-        return;
-    }
-    if (self.registryEntry.hasSaveState) {
-        [self _vmDeleteStateWithCompletion:^(NSError *error){
-            // ignore error
-            completion(nil);
-        }];
-    } else {
-        completion(nil); // everything successful
-    }
-}
-
-- (void)vmStartWithCompletion:(void (^)(NSError * _Nullable))completion {
-    dispatch_async(self.vmOperations, ^{
-        if (self.state != kVMStopped) {
-            completion([self errorGeneric]);
-            return;
-        }
-        [self changeState:kVMStarting];
-        [self _vmStartWithCompletion:^(NSError *err){
-            if (err) { // delete suspend state on error
-                dispatch_async(dispatch_get_main_queue(), ^{
-                    self.registryEntry.hasSaveState = NO;
-                });
-                [self changeState:kVMStopped];
-            } else {
-                [self changeState:kVMStarted];
-            }
-            completion(err);
-        }];
-    });
-}
-
-- (void)_vmStopForce:(BOOL)force completion:(void (^)(NSError * _Nullable))completion {
-    [self.qemu qemuQuitWithCompletion:nil];
-    if (force || dispatch_semaphore_wait(self.qemuWillQuitEvent, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        UTMLog(@"Stop operation timeout or force quit");
-    }
-    self.qemu.delegate = nil;
-    self.qemu = nil;
-    [self.ioService removeObserver:self forKeyPath:@"qemuGuestAgent" context:SpiceIoServiceGuestAgentContext];
-    self.ioService = nil;
-    
-    if (force || dispatch_semaphore_wait(self.qemuDidExitEvent, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        UTMLog(@"Exit operation timeout or force quit");
-    }
-    [self.system stopQemu];
-    self.system = nil;
-    // stop logging
-    [self.logging endLog];
-    // clear ptty devices
-    [self.config qemuClearPttyPaths];
-    completion(nil);
-}
-
-- (void)vmStopForce:(BOOL)force completion:(void (^)(NSError * _Nullable))completion {
-    if (force) {
-        [self.ioService disconnect]; // prevent deadlock force stopping during startup
-    }
-    dispatch_async(self.vmOperations, ^{
-        if (self.state == kVMStopped) {
-            completion(nil);
-            return;
-        }
-        if (!force && self.state != kVMStarted) {
-            completion([self errorGeneric]);
-            return;
-        }
-        if (!force) {
-            [self changeState:kVMStopping];
-        }
-        [self _vmStopForce:force completion:^(NSError *err){
-            [self changeState:kVMStopped];
-            completion(err);
-        }];
-    });
-}
-
-- (void)_vmResetWithCompletion:(void (^)(NSError * _Nullable))completion {
-    if (self.registryEntry.hasSaveState) {
-        [self _vmDeleteStateWithCompletion:^(NSError *error) {}];
-    }
-    __block NSError *resetError = nil;
-    dispatch_semaphore_t resetTriggeredEvent = dispatch_semaphore_create(0);
-    [self.qemu qemuResetWithCompletion:^(NSError *err) {
-        UTMLog(@"reset callback: err? %@", err);
-        if (err) {
-            UTMLog(@"error: %@", err);
-            resetError = err;
-        }
-        dispatch_semaphore_signal(resetTriggeredEvent);
-    }];
-    if (dispatch_semaphore_wait(resetTriggeredEvent, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        UTMLog(@"Reset operation timeout");
-        resetError = [self errorGeneric];;
-    }
-    completion(resetError);
-}
-
-- (void)vmResetWithCompletion:(void (^)(NSError * _Nullable))completion {
-    dispatch_async(self.vmOperations, ^{
-        if (self.state != kVMStarted && self.state != kVMPaused) {
-            completion([self errorGeneric]);
-            return;
-        }
-        [self changeState:kVMStopping];
-        [self _vmResetWithCompletion:^(NSError *err){
-            if (!err) {
-                [self changeState:kVMStarted];
-            } else {
-                [self changeState:kVMStopped];
-            }
-            completion(err);
-        }];
-    });
-}
-
-- (void)_vmPauseWithCompletion:(void (^)(NSError * _Nullable))completion {
-    dispatch_sync(dispatch_get_main_queue(), ^{
-        [self updateScreenshot];
-    });
-    [self saveScreenshot];
-    __block NSError *suspendError = nil;
-    dispatch_semaphore_t suspendTriggeredEvent = dispatch_semaphore_create(0);
-    [self.qemu qemuStopWithCompletion:^(NSError * err) {
-        UTMLog(@"stop callback: err? %@", err);
-        if (err) {
-            UTMLog(@"error: %@", err);
-            suspendError = err;
-        }
-        dispatch_semaphore_signal(suspendTriggeredEvent);
-    }];
-    if (dispatch_semaphore_wait(suspendTriggeredEvent, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        UTMLog(@"Stop operation timeout");
-        suspendError = [self errorGeneric];
-    }
-    completion(suspendError);
-}
-
-- (void)vmPauseSave:(BOOL)save completion:(void (^)(NSError * _Nullable))completion {
-    dispatch_async(self.vmOperations, ^{
-        if (self.state != kVMStarted) {
-            completion([self errorGeneric]);
-            return;
-        }
-        [self changeState:kVMPausing];
-        [self _vmPauseWithCompletion:^(NSError *err){
-            if (!err) {
-                if (save) {
-                    [self _vmSaveStateWithCompletion:^(NSError *err) {
-                        [self changeState:kVMPaused];
-                        completion(err);
-                    }];
-                } else {
-                    [self changeState:kVMPaused];
-                    completion(err);
-                }
-            } else {
-                [self changeState:kVMStopped];
-                completion(err);
-            }
-        }];
-    });
-}
-
-- (void)_vmSaveStateWithCompletion:(void (^)(NSError * _Nullable))completion {
-    __block NSError *saveError = nil;
-    dispatch_semaphore_t saveTriggeredEvent = dispatch_semaphore_create(0);
-    [self.qemu qemuSaveSnapshot:kSuspendSnapshotName withCompletion:^(NSString *result, NSError *err) {
-        UTMLog(@"save callback: %@", result);
-        if (err) {
-            UTMLog(@"error: %@", err);
-            saveError = err;
-        } else if ([result localizedCaseInsensitiveContainsString:@"Error"]) {
-            UTMLog(@"save result: %@", result);
-            saveError = [self errorWithMessage:result]; // error message
-        }
-        if (saveError) {
-            // replace error with detailed message
-            NSString *newMsg = [NSString localizedStringWithFormat:NSLocalizedString(@"Failed to save VM snapshot. Usually this means at least one device does not support snapshots. %@", @"UTMQemuVirtualMachine"), saveError.localizedDescription];
-            saveError = [self errorWithMessage:newMsg];
-        }
-        dispatch_semaphore_signal(saveTriggeredEvent);
-    }];
-    if (dispatch_semaphore_wait(saveTriggeredEvent, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        UTMLog(@"Save operation timeout");
-        saveError = [self errorGeneric];
-    } else if (!saveError) {
-        UTMLog(@"Save completed");
-        dispatch_async(dispatch_get_main_queue(), ^{
-            self.registryEntry.hasSaveState = YES;
-        });
-        [self saveScreenshot];
-    }
-    completion(saveError);
-}
-
-- (void)vmSaveStateWithCompletion:(void (^)(NSError * _Nullable))completion {
-    dispatch_async(self.vmOperations, ^{
-        if (self.state != kVMPaused && self.state != kVMStarted) {
-            completion([self errorGeneric]);
-            return;
-        }
-        [self _vmSaveStateWithCompletion:completion];
-    });
-}
-
-- (void)_vmDeleteStateWithCompletion:(void (^)(NSError * _Nullable))completion {
-    __block NSError *deleteError = nil;
-    if (self.qemu) { // if QEMU is running
-        dispatch_semaphore_t deleteTriggeredEvent = dispatch_semaphore_create(0);
-        [self.qemu qemuDeleteSnapshot:kSuspendSnapshotName withCompletion:^(NSString *result, NSError *err) {
-            UTMLog(@"delete save callback: %@", result);
-            if (err) {
-                UTMLog(@"error: %@", err);
-                deleteError = err;
-            } else if ([result localizedCaseInsensitiveContainsString:@"Error"]) {
-                UTMLog(@"save result: %@", result);
-                deleteError = [self errorWithMessage:result]; // error message
-            }
-            dispatch_semaphore_signal(deleteTriggeredEvent);
-        }];
-        if (dispatch_semaphore_wait(deleteTriggeredEvent, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-            UTMLog(@"Delete save operation timeout");
-            deleteError = [self errorGeneric];
-        } else {
-            UTMLog(@"Delete save completed");
-        }
-    } // otherwise we mark as deleted
-    dispatch_async(dispatch_get_main_queue(), ^{
-        self.registryEntry.hasSaveState = NO;
-    });
-    completion(deleteError);
-}
-
-- (void)vmDeleteStateWithCompletion:(void (^)(NSError * _Nullable))completion {
-    dispatch_async(self.vmOperations, ^{
-        [self _vmDeleteStateWithCompletion:completion];
-    });
-}
-
-- (void)_vmResumeWithCompletion:(void (^)(NSError * _Nullable))completion {
-    __block NSError *resumeError = nil;
-    dispatch_semaphore_t resumeTriggeredEvent = dispatch_semaphore_create(0);
-    [self.qemu qemuResumeWithCompletion:^(NSError *err) {
-        UTMLog(@"resume callback: err? %@", err);
-        if (err) {
-            UTMLog(@"error: %@", err);
-            resumeError = err;
-        }
-        dispatch_semaphore_signal(resumeTriggeredEvent);
-    }];
-    if (dispatch_semaphore_wait(resumeTriggeredEvent, dispatch_time(DISPATCH_TIME_NOW, kStopTimeout)) != 0) {
-        UTMLog(@"Resume operation timeout");
-        resumeError = [self errorGeneric];
-    }
-    if (self.registryEntry.hasSaveState) {
-        [self _vmDeleteStateWithCompletion:^(NSError *error){
-            completion(nil);
-        }];
-    } else {
-        completion(nil);
-    }
-}
-
-- (void)vmResumeWithCompletion:(void (^)(NSError * _Nullable))completion {
-    dispatch_async(self.vmOperations, ^{
-        if (self.state != kVMPaused) {
-            completion([self errorGeneric]);
-            return;
-        }
-        [self changeState:kVMResuming];
-        [self _vmResumeWithCompletion:^(NSError *err){
-            if (!err) {
-                [self changeState:kVMStarted];
-            } else {
-                [self changeState:kVMStopped];
-            }
-            completion(err);
-        }];
-    });
-}
-
-- (void)vmGuestPowerDownWithCompletion:(void (^)(NSError * _Nullable))completion {
-    dispatch_async(self.vmOperations, ^{
-        [self.qemu qemuPowerDownWithCompletion:^(NSError *err) {
-            completion(err);
-        }];
-    });
-}
-
-#pragma mark - QEMU Guest agent
-
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
-    if (context == SpiceIoServiceGuestAgentContext) {
-        UTMQemuGuestAgent *guestAgent = ((UTMSpiceIO *)object).qemuGuestAgent;
-        if (guestAgent == nil && self.guestAgent != nil) {
-            [self _didDisconnectGuestAgent:self.guestAgent];
-        }
-        if (guestAgent != nil) {
-            [self _didConnectGuestAgent:guestAgent];
-        }
-        self.guestAgent = guestAgent;
-    } else {
-        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
-    }
-}
-
-- (void)_didConnectGuestAgent:(UTMQemuGuestAgent *)guestAgent {
-    UTMLog(@"QEMU guest agent has connected.");
-    [guestAgent guestSetTime:NSDate.now.timeIntervalSince1970 withCompletion:nil];
-}
-
-- (void)_didDisconnectGuestAgent:(UTMQemuGuestAgent *)guestAgent {
-    UTMLog(@"QEMU guest agent has disconnected.");
-}
-
-#pragma mark - Qemu manager delegate
-
-- (void)qemuHasWakeup:(UTMQemuMonitor *)monitor {
-    UTMLog(@"qemuHasWakeup");
-}
-
-- (void)qemuHasResumed:(UTMQemuMonitor *)monitor {
-    UTMLog(@"qemuHasResumed");
-    [self.guestAgent guestSetTime:NSDate.now.timeIntervalSince1970 withCompletion:nil];
-}
-
-- (void)qemuHasStopped:(UTMQemuMonitor *)monitor {
-    UTMLog(@"qemuHasStopped");
-}
-
-- (void)qemuHasReset:(UTMQemuMonitor *)monitor guest:(BOOL)guest reason:(ShutdownCause)reason {
-    UTMLog(@"qemuHasReset, reason = %s", ShutdownCause_str(reason));
-}
-
-- (void)qemuHasSuspended:(UTMQemuMonitor *)monitor {
-    UTMLog(@"qemuHasSuspended");
-}
-
-- (void)qemuWillQuit:(UTMQemuMonitor *)monitor guest:(BOOL)guest reason:(ShutdownCause)reason {
-    UTMLog(@"qemuWillQuit, reason = %s", ShutdownCause_str(reason));
-    dispatch_semaphore_signal(self.qemuWillQuitEvent);
-    [self vmStopWithCompletion:^(NSError *error) {}]; // trigger quit
-}
-
-- (void)qemuError:(UTMQemuMonitor *)monitor error:(NSString *)error {
-    UTMLog(@"qemuError: %@", error);
-    dispatch_async(dispatch_get_main_queue(), ^{
-        [self.delegate virtualMachine:self didErrorWithMessage:error];
-    });
-    [self vmStopForce:YES completion:^(NSError *error) {}];
-}
-
-// this is called right before we execute qmp_cont so we can setup additional option
-- (void)qemuQmpDidConnect:(UTMQemuMonitor *)monitor {
-    UTMLog(@"qemuQmpDidConnect");
-    dispatch_semaphore_signal(self.qemuDidConnectEvent);
-}
-
-#pragma mark - Logging delegate
-
-- (void)logging:(UTMLogging *)logging didRecieveErrorLine:(NSString *)line {
-    self.lastErrorLine = line;
-}
-
-- (void)logging:(UTMLogging *)logging didRecieveOutputLine:(NSString *)line {
-    if ([line hasPrefix:@"char device"]) {
-        [self parseCharDeviceLine:line];
-    }
-}
-
-- (void)parseCharDeviceLine:(NSString *)line {
-    const char *cline = line.UTF8String;
-    char devpath[PATH_MAX] = {0};
-    int term = -1;
-    if (sscanf(cline, "char device redirected to %s (label term%d)", devpath, &term) < 2) {
-        UTMLog(@"Cannot parse char device line: '%@'", line);
-        return;
-    } else {
-        UTMLog(@"Detected PTTY at '%s' for device %d", devpath, term);
-    }
-    [self.config qemuSetPttyDevicePath:[NSString stringWithUTF8String:devpath] for:term];
-}
-
-#pragma mark - Screenshot
-
-- (void)updateScreenshot {
-    [self.ioService screenshotWithCompletion:^(CSScreenshot * _Nullable screenshot) {
-        dispatch_async(dispatch_get_main_queue(), ^{
-            self.screenshot = screenshot;
-        });
-    }];
-}
-
-@end

+ 0 - 602
UTM.xcodeproj/project.pbxproj

@@ -1235,20 +1235,6 @@
 /* Begin PBXFileReference section */
 		2C33B3A82566C9B100A954A6 /* VMContextMenuModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMContextMenuModifier.swift; sourceTree = "<group>"; };
 		2C6D9E02256EE454003298E6 /* VMDisplayQemuTerminalWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMDisplayQemuTerminalWindowController.swift; sourceTree = "<group>"; };
-		2C6D9E122571AFE5003298E6 /* UTMQcow2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTMQcow2.h; sourceTree = "<group>"; };
-		2C6D9E132571AFE5003298E6 /* UTMQcow2.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = UTMQcow2.c; sourceTree = "<group>"; };
-		2CE8EAEC2572E0C2000E2EBB /* qapi-events-block-export.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-block-export.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-block-export.c"; sourceTree = SOURCE_ROOT; };
-		2CE8EAED2572E0C2000E2EBB /* qapi-events-block-export.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-block-export.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-block-export.h"; sourceTree = SOURCE_ROOT; };
-		2CE8EAF12572E0D0000E2EBB /* qapi-events-acpi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-acpi.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-acpi.h"; sourceTree = SOURCE_ROOT; };
-		2CE8EAF22572E0D0000E2EBB /* qapi-events-acpi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-acpi.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-acpi.c"; sourceTree = SOURCE_ROOT; };
-		2CE8EAF72572E130000E2EBB /* qapi-types-acpi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-acpi.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-acpi.c"; sourceTree = SOURCE_ROOT; };
-		2CE8EAF82572E130000E2EBB /* qapi-types-acpi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-acpi.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-acpi.h"; sourceTree = SOURCE_ROOT; };
-		2CE8EAFC2572E14C000E2EBB /* qapi-types-block-export.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-block-export.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-block-export.c"; sourceTree = SOURCE_ROOT; };
-		2CE8EAFD2572E14C000E2EBB /* qapi-types-block-export.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-block-export.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-block-export.h"; sourceTree = SOURCE_ROOT; };
-		2CE8EB022572E166000E2EBB /* qapi-visit-acpi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-acpi.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-acpi.h"; sourceTree = SOURCE_ROOT; };
-		2CE8EB032572E166000E2EBB /* qapi-visit-acpi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-acpi.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-acpi.c"; sourceTree = SOURCE_ROOT; };
-		2CE8EB072572E173000E2EBB /* qapi-visit-block-export.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-block-export.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-block-export.h"; sourceTree = SOURCE_ROOT; };
-		2CE8EB082572E173000E2EBB /* qapi-visit-block-export.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-block-export.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-block-export.c"; sourceTree = SOURCE_ROOT; };
 		4B224B9C279D4D8100B63CFF /* InListButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InListButtonStyle.swift; sourceTree = "<group>"; };
 		521F3EFA2414F73800130500 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
 		5286EC8E2437488E007E6CBC /* VMDisplayMetalViewController+Gamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "VMDisplayMetalViewController+Gamepad.h"; sourceTree = "<group>"; };
@@ -1304,7 +1290,6 @@
 		841E58D02893AF5400137A20 /* UTMApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMApp.swift; sourceTree = "<group>"; };
 		841E997428AA1191003C6CB6 /* UTMRegistry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMRegistry.swift; sourceTree = "<group>"; };
 		841E997828AA119B003C6CB6 /* UTMRegistryEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMRegistryEntry.swift; sourceTree = "<group>"; };
-		841E999628AC80CA003C6CB6 /* UTMQemuVirtualMachine-Protected.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UTMQemuVirtualMachine-Protected.h"; sourceTree = "<group>"; };
 		841E999728AC817D003C6CB6 /* UTMQemuVirtualMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMQemuVirtualMachine.swift; sourceTree = "<group>"; };
 		84258C41288F806400C66366 /* VMToolbarUSBMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMToolbarUSBMenuView.swift; sourceTree = "<group>"; };
 		842B9F8C28CC58B700031EE7 /* UTMPatches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMPatches.swift; sourceTree = "<group>"; };
@@ -1332,10 +1317,6 @@
 		845F1708289CA15C00944904 /* VMDisplayAppleTerminalWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMDisplayAppleTerminalWindowController.swift; sourceTree = "<group>"; };
 		845F170A289CB07200944904 /* VMDisplayAppleDisplayWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMDisplayAppleDisplayWindowController.swift; sourceTree = "<group>"; };
 		845F170C289CB3DE00944904 /* VMDisplayTerminal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMDisplayTerminal.swift; sourceTree = "<group>"; };
-		8469CAC8277D301300BA5601 /* qapi-types-compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-compat.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-compat.h"; sourceTree = SOURCE_ROOT; };
-		8469CAC9277D301300BA5601 /* qapi-types-compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-compat.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-compat.c"; sourceTree = SOURCE_ROOT; };
-		8469CACD277D345700BA5601 /* qapi-visit-compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-compat.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-compat.c"; sourceTree = SOURCE_ROOT; };
-		8469CACE277D345700BA5601 /* qapi-visit-compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-compat.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-compat.h"; sourceTree = SOURCE_ROOT; };
 		8471770527CC974F00D3A50B /* DefaultTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTextField.swift; sourceTree = "<group>"; };
 		8471772727CD3CAB00D3A50B /* DetailedSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailedSection.swift; sourceTree = "<group>"; };
 		84818C0B2898A07A009EDB67 /* AVFAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFAudio.framework; path = System/Library/Frameworks/AVFAudio.framework; sourceTree = SDKROOT; };
@@ -1381,7 +1362,6 @@
 		84A381A9268CB30C0048EE4D /* VMDrivesSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMDrivesSettingsView.swift; sourceTree = "<group>"; };
 		84B36D2427B704C200C22685 /* UTMDownloadVMTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMDownloadVMTask.swift; sourceTree = "<group>"; };
 		84B36D2827B790BE00C22685 /* DestructiveButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DestructiveButton.swift; sourceTree = "<group>"; };
-		84BB99382899AB1800DF28B2 /* UTMLoggingDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTMLoggingDelegate.h; sourceTree = "<group>"; };
 		84BB99392899E8D500DF28B2 /* VMHeadlessSessionState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMHeadlessSessionState.swift; sourceTree = "<group>"; };
 		84C4D9012880CA8A00EC3B2B /* VMSettingsAddDeviceMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMSettingsAddDeviceMenuView.swift; sourceTree = "<group>"; };
 		84C505AB28C588EC007CE8FF /* SizeTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SizeTextField.swift; sourceTree = "<group>"; };
@@ -1408,8 +1388,6 @@
 		84F746B8276FF40900A20C87 /* VMDisplayAppleWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMDisplayAppleWindowController.swift; sourceTree = "<group>"; };
 		84F746BA276FF70700A20C87 /* VMDisplayQemuDisplayController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMDisplayQemuDisplayController.swift; sourceTree = "<group>"; };
 		84F909FE289488F90008DBE2 /* MenuLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuLabel.swift; sourceTree = "<group>"; };
-		84FCABB8268CE05E0036196C /* UTMQemuVirtualMachine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTMQemuVirtualMachine.h; sourceTree = "<group>"; };
-		84FCABB9268CE05E0036196C /* UTMQemuVirtualMachine.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UTMQemuVirtualMachine.m; sourceTree = "<group>"; };
 		84FCABBD268CE4080036196C /* UTMVirtualMachine-Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UTMVirtualMachine-Private.h"; sourceTree = "<group>"; };
 		85EC516327CC8C98004A51DE /* VMConfigAdvancedNetworkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMConfigAdvancedNetworkView.swift; sourceTree = "<group>"; };
 		9786BB59294056960032B858 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = "<group>"; };
@@ -1445,251 +1423,6 @@
 		CE19392526DCB093005CEC17 /* RAMSlider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RAMSlider.swift; sourceTree = "<group>"; };
 		CE20FAE62448D2BE0059AE11 /* VMScroll.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VMScroll.h; sourceTree = "<group>"; };
 		CE20FAE72448D2BE0059AE11 /* VMScroll.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VMScroll.m; sourceTree = "<group>"; };
-		CE23C07B23FCEBFF001177D6 /* qapi-visit-error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-error.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-error.h"; sourceTree = SOURCE_ROOT; };
-		CE23C07C23FCEBFF001177D6 /* qapi-events-machine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-machine.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-machine.h"; sourceTree = SOURCE_ROOT; };
-		CE23C07D23FCEBFF001177D6 /* qapi-commands-block-core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-block-core.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-block-core.h"; sourceTree = SOURCE_ROOT; };
-		CE23C07E23FCEBFF001177D6 /* qapi-commands-run-state.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-run-state.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-run-state.c"; sourceTree = SOURCE_ROOT; };
-		CE23C07F23FCEBFF001177D6 /* qapi-visit-tpm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-tpm.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-tpm.c"; sourceTree = SOURCE_ROOT; };
-		CE23C08023FCEBFF001177D6 /* qapi-events-block.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-block.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-block.h"; sourceTree = SOURCE_ROOT; };
-		CE23C08123FCEBFF001177D6 /* qapi-commands-rocker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-rocker.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-rocker.c"; sourceTree = SOURCE_ROOT; };
-		CE23C08223FCEBFF001177D6 /* qapi-commands-ui.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-ui.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-ui.c"; sourceTree = SOURCE_ROOT; };
-		CE23C08323FCEBFF001177D6 /* qapi-commands-migration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-migration.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-migration.h"; sourceTree = SOURCE_ROOT; };
-		CE23C08423FCEBFF001177D6 /* qapi-events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events.h"; sourceTree = SOURCE_ROOT; };
-		CE23C08523FCEBFF001177D6 /* qapi-types-run-state.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-run-state.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-run-state.c"; sourceTree = SOURCE_ROOT; };
-		CE23C08623FCEBFF001177D6 /* qapi-commands-char.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-char.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-char.c"; sourceTree = SOURCE_ROOT; };
-		CE23C08723FCEBFF001177D6 /* qapi-types-block.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-block.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-block.c"; sourceTree = SOURCE_ROOT; };
-		CE23C08823FCEBFF001177D6 /* qapi-visit-qdev.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-qdev.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-qdev.h"; sourceTree = SOURCE_ROOT; };
-		CE23C08923FCEBFF001177D6 /* qapi-events-trace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-trace.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-trace.c"; sourceTree = SOURCE_ROOT; };
-		CE23C08A23FCEC00001177D6 /* qapi-visit-net.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-net.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-net.c"; sourceTree = SOURCE_ROOT; };
-		CE23C08B23FCEC00001177D6 /* qapi-events-rdma.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-rdma.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-rdma.h"; sourceTree = SOURCE_ROOT; };
-		CE23C08C23FCEC00001177D6 /* qapi-events-rocker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-rocker.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-rocker.h"; sourceTree = SOURCE_ROOT; };
-		CE23C08D23FCEC00001177D6 /* qapi-events-error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-error.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-error.h"; sourceTree = SOURCE_ROOT; };
-		CE23C08E23FCEC00001177D6 /* qapi-commands-tpm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-tpm.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-tpm.h"; sourceTree = SOURCE_ROOT; };
-		CE23C08F23FCEC00001177D6 /* qapi-commands-net.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-net.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-net.c"; sourceTree = SOURCE_ROOT; };
-		CE23C09023FCEC00001177D6 /* qapi-visit-trace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-trace.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-trace.h"; sourceTree = SOURCE_ROOT; };
-		CE23C09123FCEC00001177D6 /* qapi-events-net.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-net.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-net.h"; sourceTree = SOURCE_ROOT; };
-		CE23C09223FCEC00001177D6 /* qapi-emit-events.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-emit-events.c"; path = "$(SYSROOT_DIR)/qapi/qapi-emit-events.c"; sourceTree = SOURCE_ROOT; };
-		CE23C09323FCEC00001177D6 /* qapi-types-qdev.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-qdev.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-qdev.h"; sourceTree = SOURCE_ROOT; };
-		CE23C09423FCEC00001177D6 /* qapi-commands-misc-target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-misc-target.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-misc-target.h"; sourceTree = SOURCE_ROOT; };
-		CE23C09523FCEC00001177D6 /* qapi-visit-job.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-job.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-job.c"; sourceTree = SOURCE_ROOT; };
-		CE23C09623FCEC00001177D6 /* qapi-builtin-visit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-builtin-visit.c"; path = "$(SYSROOT_DIR)/qapi/qapi-builtin-visit.c"; sourceTree = SOURCE_ROOT; };
-		CE23C09723FCEC00001177D6 /* qapi-visit-sockets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-sockets.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-sockets.h"; sourceTree = SOURCE_ROOT; };
-		CE23C09823FCEC00001177D6 /* qapi-commands-common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-common.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-common.h"; sourceTree = SOURCE_ROOT; };
-		CE23C09923FCEC00001177D6 /* qapi-types-block-core.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-block-core.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-block-core.c"; sourceTree = SOURCE_ROOT; };
-		CE23C09A23FCEC00001177D6 /* qapi-commands-run-state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-run-state.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-run-state.h"; sourceTree = SOURCE_ROOT; };
-		CE23C09B23FCEC00001177D6 /* qapi-commands-migration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-migration.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-migration.c"; sourceTree = SOURCE_ROOT; };
-		CE23C09C23FCEC00001177D6 /* qapi-events-migration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-migration.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-migration.h"; sourceTree = SOURCE_ROOT; };
-		CE23C09D23FCEC00001177D6 /* qapi-commands-audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-audio.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-audio.c"; sourceTree = SOURCE_ROOT; };
-		CE23C09E23FCEC00001177D6 /* qapi-events-qdev.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-qdev.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-qdev.c"; sourceTree = SOURCE_ROOT; };
-		CE23C09F23FCEC01001177D6 /* qapi-visit-migration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-migration.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-migration.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0A023FCEC01001177D6 /* qapi-visit-rocker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-rocker.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-rocker.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0A123FCEC01001177D6 /* qapi-events-run-state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-run-state.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-run-state.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0A223FCEC01001177D6 /* qapi-commands-dump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-dump.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-dump.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0A323FCEC01001177D6 /* qapi-visit-ui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-ui.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-ui.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0A423FCEC01001177D6 /* qapi-commands-authz.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-authz.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-authz.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0A523FCEC01001177D6 /* qapi-events-ui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-ui.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-ui.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0A623FCEC01001177D6 /* qapi-visit-transaction.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-transaction.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-transaction.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0A723FCEC01001177D6 /* qapi-visit-block.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-block.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-block.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0A823FCEC01001177D6 /* qapi-events-qom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-qom.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-qom.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0A923FCEC01001177D6 /* qapi-types-misc-target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-misc-target.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-misc-target.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0AA23FCEC01001177D6 /* qapi-commands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0AB23FCEC01001177D6 /* qapi-types-audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-audio.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-audio.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0AC23FCEC01001177D6 /* qapi-events-transaction.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-transaction.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-transaction.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0AD23FCEC01001177D6 /* qapi-events-introspect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-introspect.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-introspect.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0AE23FCEC01001177D6 /* qapi-commands-crypto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-crypto.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-crypto.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0AF23FCEC01001177D6 /* qapi-events-sockets.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-sockets.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-sockets.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0B023FCEC01001177D6 /* qapi-visit-rdma.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-rdma.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-rdma.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0B123FCEC01001177D6 /* qapi-visit-block-core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-block-core.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-block-core.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0B223FCEC01001177D6 /* qapi-events-tpm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-tpm.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-tpm.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0B323FCEC01001177D6 /* qapi-visit-dump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-dump.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-dump.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0B423FCEC01001177D6 /* qapi-events-introspect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-introspect.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-introspect.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0B523FCEC02001177D6 /* qapi-types-net.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-net.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-net.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0B623FCEC02001177D6 /* qapi-types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0B723FCEC02001177D6 /* qapi-visit-ui.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-ui.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-ui.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0B823FCEC02001177D6 /* qapi-visit-authz.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-authz.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-authz.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0B923FCEC02001177D6 /* qapi-events-machine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-machine.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-machine.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0BA23FCEC02001177D6 /* qapi-commands-audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-audio.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-audio.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0BB23FCEC02001177D6 /* qapi-commands-crypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-crypto.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-crypto.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0BC23FCEC02001177D6 /* qapi-events-trace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-trace.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-trace.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0BD23FCEC02001177D6 /* qapi-commands-sockets.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-sockets.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-sockets.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0BE23FCEC02001177D6 /* qapi-visit-audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-audio.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-audio.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0BF23FCEC02001177D6 /* qapi-commands-tpm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-tpm.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-tpm.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0C023FCEC02001177D6 /* qapi-commands-block.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-block.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-block.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0C123FCEC02001177D6 /* qapi-events-crypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-crypto.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-crypto.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0C223FCEC02001177D6 /* qapi-visit-crypto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-crypto.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-crypto.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0C323FCEC02001177D6 /* qapi-visit-qom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-qom.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-qom.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0C423FCEC02001177D6 /* qapi-types-run-state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-run-state.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-run-state.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0C523FCEC02001177D6 /* qapi-events-char.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-char.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-char.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0C623FCEC02001177D6 /* qapi-types-common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-common.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-common.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0C723FCEC02001177D6 /* qapi-events-misc-target.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-misc-target.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-misc-target.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0C823FCEC02001177D6 /* qapi-builtin-types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-builtin-types.h"; path = "$(SYSROOT_DIR)/qapi/qapi-builtin-types.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0C923FCEC02001177D6 /* qapi-types-machine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-machine.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-machine.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0CA23FCEC02001177D6 /* qapi-commands-misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-misc.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-misc.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0CB23FCEC02001177D6 /* qapi-types-migration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-migration.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-migration.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0CC23FCEC03001177D6 /* qapi-events-authz.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-authz.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-authz.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0CD23FCEC03001177D6 /* qapi-visit-crypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-crypto.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-crypto.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0CE23FCEC03001177D6 /* qapi-visit-migration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-migration.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-migration.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0CF23FCEC03001177D6 /* qapi-visit-audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-audio.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-audio.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0D023FCEC03001177D6 /* qapi-commands-trace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-trace.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-trace.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0D123FCEC03001177D6 /* qapi-commands-transaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-transaction.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-transaction.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0D223FCEC03001177D6 /* qapi-commands.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0D323FCEC03001177D6 /* qapi-events-dump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-dump.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-dump.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0D423FCEC03001177D6 /* qapi-events-authz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-authz.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-authz.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0D523FCEC03001177D6 /* qapi-builtin-types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-builtin-types.c"; path = "$(SYSROOT_DIR)/qapi/qapi-builtin-types.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0D623FCEC03001177D6 /* qapi-events-sockets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-sockets.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-sockets.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0D723FCEC03001177D6 /* qapi-events-common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-common.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-common.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0D823FCEC03001177D6 /* qapi-commands-sockets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-sockets.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-sockets.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0D923FCEC03001177D6 /* qapi-events-block-core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-block-core.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-block-core.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0DA23FCEC03001177D6 /* qapi-types-authz.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-authz.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-authz.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0DB23FCEC03001177D6 /* qapi-commands-machine-target.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-machine-target.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-machine-target.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0DC23FCEC03001177D6 /* qapi-types-tpm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-tpm.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-tpm.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0DD23FCEC03001177D6 /* qapi-commands-dump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-dump.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-dump.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0DE23FCEC04001177D6 /* qapi-types-block-core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-block-core.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-block-core.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0DF23FCEC04001177D6 /* qapi-commands-block-core.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-block-core.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-block-core.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0E023FCEC04001177D6 /* qapi-visit-block-core.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-block-core.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-block-core.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0E123FCEC04001177D6 /* qapi-commands-rdma.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-rdma.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-rdma.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0E223FCEC04001177D6 /* qapi-visit-introspect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-introspect.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-introspect.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0E323FCEC04001177D6 /* qapi-types-crypto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-crypto.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-crypto.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0E423FCEC04001177D6 /* qapi-visit-qom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-qom.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-qom.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0E523FCEC04001177D6 /* qapi-visit-trace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-trace.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-trace.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0E623FCEC04001177D6 /* qapi-commands-char.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-char.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-char.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0E723FCEC04001177D6 /* qapi-commands-block.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-block.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-block.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0E823FCEC04001177D6 /* qapi-visit-machine-target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-machine-target.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-machine-target.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0E923FCEC04001177D6 /* qapi-visit-char.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-char.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-char.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0EA23FCEC04001177D6 /* qapi-visit-introspect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-introspect.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-introspect.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0EB23FCEC04001177D6 /* qapi-visit-job.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-job.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-job.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0EC23FCEC04001177D6 /* qapi-visit-machine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-machine.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-machine.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0ED23FCEC04001177D6 /* qapi-visit-misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-misc.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-misc.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0EE23FCEC04001177D6 /* qapi-events-migration.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-migration.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-migration.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0EF23FCEC04001177D6 /* qapi-events-block-core.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-block-core.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-block-core.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0F023FCEC04001177D6 /* qapi-events-error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-error.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-error.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0F123FCEC04001177D6 /* qapi-visit-authz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-authz.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-authz.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0F223FCEC04001177D6 /* qapi-types-net.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-net.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-net.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0F323FCEC05001177D6 /* qapi-commands-error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-error.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-error.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0F423FCEC05001177D6 /* qapi-types-char.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-char.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-char.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0F523FCEC05001177D6 /* qapi-visit-run-state.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-run-state.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-run-state.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0F623FCEC05001177D6 /* qapi-types-common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-common.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-common.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0F723FCEC05001177D6 /* qapi-visit-rocker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-rocker.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-rocker.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0F823FCEC05001177D6 /* qapi-events-common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-common.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-common.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0F923FCEC05001177D6 /* qapi-types-introspect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-introspect.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-introspect.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0FA23FCEC05001177D6 /* qapi-builtin-visit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-builtin-visit.h"; path = "$(SYSROOT_DIR)/qapi/qapi-builtin-visit.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0FB23FCEC05001177D6 /* qapi-commands-rdma.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-rdma.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-rdma.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0FC23FCEC05001177D6 /* qapi-commands-error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-error.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-error.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0FD23FCEC05001177D6 /* qapi-events-run-state.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-run-state.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-run-state.c"; sourceTree = SOURCE_ROOT; };
-		CE23C0FE23FCEC05001177D6 /* qapi-types-dump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-dump.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-dump.h"; sourceTree = SOURCE_ROOT; };
-		CE23C0FF23FCEC05001177D6 /* qapi-commands-machine-target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-machine-target.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-machine-target.h"; sourceTree = SOURCE_ROOT; };
-		CE23C10023FCEC05001177D6 /* qapi-types-ui.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-ui.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-ui.c"; sourceTree = SOURCE_ROOT; };
-		CE23C10123FCEC05001177D6 /* qapi-events-net.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-net.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-net.c"; sourceTree = SOURCE_ROOT; };
-		CE23C10223FCEC05001177D6 /* qapi-visit-common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-common.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-common.c"; sourceTree = SOURCE_ROOT; };
-		CE23C10323FCEC05001177D6 /* qapi-commands-ui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-ui.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-ui.h"; sourceTree = SOURCE_ROOT; };
-		CE23C10423FCEC05001177D6 /* qapi-visit-misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-misc.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-misc.c"; sourceTree = SOURCE_ROOT; };
-		CE23C10523FCEC05001177D6 /* qapi-commands-introspect.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-introspect.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-introspect.c"; sourceTree = SOURCE_ROOT; };
-		CE23C10623FCEC05001177D6 /* qapi-visit-sockets.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-sockets.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-sockets.c"; sourceTree = SOURCE_ROOT; };
-		CE23C10723FCEC06001177D6 /* qapi-visit-net.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-net.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-net.h"; sourceTree = SOURCE_ROOT; };
-		CE23C10823FCEC06001177D6 /* qapi-commands-common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-common.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-common.c"; sourceTree = SOURCE_ROOT; };
-		CE23C10923FCEC06001177D6 /* qapi-visit-qdev.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-qdev.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-qdev.c"; sourceTree = SOURCE_ROOT; };
-		CE23C10A23FCEC06001177D6 /* qapi-types-qom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-qom.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-qom.h"; sourceTree = SOURCE_ROOT; };
-		CE23C10B23FCEC06001177D6 /* qapi-commands-transaction.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-transaction.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-transaction.c"; sourceTree = SOURCE_ROOT; };
-		CE23C10C23FCEC06001177D6 /* qapi-visit-transaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-transaction.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-transaction.h"; sourceTree = SOURCE_ROOT; };
-		CE23C10D23FCEC06001177D6 /* qapi-visit-machine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-machine.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-machine.c"; sourceTree = SOURCE_ROOT; };
-		CE23C10E23FCEC06001177D6 /* qapi-types-sockets.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-sockets.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-sockets.c"; sourceTree = SOURCE_ROOT; };
-		CE23C10F23FCEC06001177D6 /* qapi-commands-rocker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-rocker.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-rocker.h"; sourceTree = SOURCE_ROOT; };
-		CE23C11023FCEC06001177D6 /* qapi-commands-trace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-trace.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-trace.c"; sourceTree = SOURCE_ROOT; };
-		CE23C11123FCEC06001177D6 /* qapi-visit-machine-target.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-machine-target.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-machine-target.c"; sourceTree = SOURCE_ROOT; };
-		CE23C11223FCEC06001177D6 /* qapi-types-error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-error.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-error.c"; sourceTree = SOURCE_ROOT; };
-		CE23C11323FCEC06001177D6 /* qapi-events-misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-misc.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-misc.h"; sourceTree = SOURCE_ROOT; };
-		CE23C11423FCEC06001177D6 /* qapi-types-audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-audio.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-audio.c"; sourceTree = SOURCE_ROOT; };
-		CE23C11523FCEC06001177D6 /* qapi-types-trace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-trace.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-trace.c"; sourceTree = SOURCE_ROOT; };
-		CE23C11623FCEC06001177D6 /* qapi-events-block.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-block.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-block.c"; sourceTree = SOURCE_ROOT; };
-		CE23C11723FCEC06001177D6 /* qapi-types-introspect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-introspect.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-introspect.h"; sourceTree = SOURCE_ROOT; };
-		CE23C11823FCEC06001177D6 /* qapi-types-misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-misc.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-misc.h"; sourceTree = SOURCE_ROOT; };
-		CE23C11923FCEC06001177D6 /* qapi-visit-tpm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-tpm.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-tpm.h"; sourceTree = SOURCE_ROOT; };
-		CE23C11A23FCEC07001177D6 /* qapi-types-ui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-ui.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-ui.h"; sourceTree = SOURCE_ROOT; };
-		CE23C11B23FCEC07001177D6 /* qapi-events-misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-misc.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-misc.c"; sourceTree = SOURCE_ROOT; };
-		CE23C11C23FCEC07001177D6 /* qapi-events-dump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-dump.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-dump.h"; sourceTree = SOURCE_ROOT; };
-		CE23C11D23FCEC07001177D6 /* qapi-events-crypto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-crypto.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-crypto.c"; sourceTree = SOURCE_ROOT; };
-		CE23C11E23FCEC07001177D6 /* qapi-types-machine-target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-machine-target.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-machine-target.h"; sourceTree = SOURCE_ROOT; };
-		CE23C11F23FCEC07001177D6 /* qapi-commands-qdev.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-qdev.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-qdev.c"; sourceTree = SOURCE_ROOT; };
-		CE23C12023FCEC07001177D6 /* qapi-types-char.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-char.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-char.c"; sourceTree = SOURCE_ROOT; };
-		CE23C12123FCEC07001177D6 /* qapi-types-dump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-dump.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-dump.c"; sourceTree = SOURCE_ROOT; };
-		CE23C12223FCEC07001177D6 /* qapi-visit-char.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-char.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-char.h"; sourceTree = SOURCE_ROOT; };
-		CE23C12323FCEC07001177D6 /* qapi-commands-job.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-job.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-job.h"; sourceTree = SOURCE_ROOT; };
-		CE23C12423FCEC07001177D6 /* qapi-types-job.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-job.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-job.h"; sourceTree = SOURCE_ROOT; };
-		CE23C12523FCEC07001177D6 /* qapi-events-job.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-job.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-job.h"; sourceTree = SOURCE_ROOT; };
-		CE23C12623FCEC07001177D6 /* qapi-events-ui.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-ui.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-ui.c"; sourceTree = SOURCE_ROOT; };
-		CE23C12723FCEC07001177D6 /* qapi-events-char.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-char.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-char.c"; sourceTree = SOURCE_ROOT; };
-		CE23C12823FCEC07001177D6 /* qapi-types-misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-misc.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-misc.c"; sourceTree = SOURCE_ROOT; };
-		CE23C12923FCEC07001177D6 /* qapi-events-rdma.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-rdma.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-rdma.c"; sourceTree = SOURCE_ROOT; };
-		CE23C12A23FCEC07001177D6 /* qapi-commands-qdev.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-qdev.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-qdev.h"; sourceTree = SOURCE_ROOT; };
-		CE23C12B23FCEC07001177D6 /* qapi-types-crypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-crypto.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-crypto.h"; sourceTree = SOURCE_ROOT; };
-		CE23C12C23FCEC07001177D6 /* qapi-visit-dump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-dump.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-dump.h"; sourceTree = SOURCE_ROOT; };
-		CE23C12D23FCEC07001177D6 /* qapi-events-audio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-audio.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-audio.h"; sourceTree = SOURCE_ROOT; };
-		CE23C12E23FCEC08001177D6 /* qapi-types-block.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-block.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-block.h"; sourceTree = SOURCE_ROOT; };
-		CE23C12F23FCEC08001177D6 /* qapi-types-rocker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-rocker.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-rocker.h"; sourceTree = SOURCE_ROOT; };
-		CE23C13023FCEC08001177D6 /* qapi-types-rdma.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-rdma.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-rdma.c"; sourceTree = SOURCE_ROOT; };
-		CE23C13123FCEC08001177D6 /* qapi-types-job.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-job.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-job.c"; sourceTree = SOURCE_ROOT; };
-		CE23C13223FCEC08001177D6 /* qapi-commands-machine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-machine.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-machine.c"; sourceTree = SOURCE_ROOT; };
-		CE23C13323FCEC08001177D6 /* qapi-commands-qom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-qom.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-qom.h"; sourceTree = SOURCE_ROOT; };
-		CE23C13423FCEC08001177D6 /* qapi-types-transaction.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-transaction.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-transaction.c"; sourceTree = SOURCE_ROOT; };
-		CE23C13523FCEC08001177D6 /* qapi-visit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit.c"; sourceTree = SOURCE_ROOT; };
-		CE23C13623FCEC08001177D6 /* qapi-visit-rdma.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-rdma.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-rdma.c"; sourceTree = SOURCE_ROOT; };
-		CE23C13723FCEC08001177D6 /* qapi-visit-block.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-block.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-block.h"; sourceTree = SOURCE_ROOT; };
-		CE23C13823FCEC08001177D6 /* qapi-types-qom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-qom.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-qom.c"; sourceTree = SOURCE_ROOT; };
-		CE23C13923FCEC08001177D6 /* qapi-events-tpm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-tpm.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-tpm.c"; sourceTree = SOURCE_ROOT; };
-		CE23C13A23FCEC08001177D6 /* qapi-types-sockets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-sockets.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-sockets.h"; sourceTree = SOURCE_ROOT; };
-		CE23C13B23FCEC08001177D6 /* qapi-events-machine-target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-machine-target.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-machine-target.h"; sourceTree = SOURCE_ROOT; };
-		CE23C13C23FCEC08001177D6 /* qapi-commands-misc-target.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-misc-target.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-misc-target.c"; sourceTree = SOURCE_ROOT; };
-		CE23C13D23FCEC08001177D6 /* qapi-events-machine-target.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-machine-target.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-machine-target.c"; sourceTree = SOURCE_ROOT; };
-		CE23C13E23FCEC08001177D6 /* qapi-events-audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-audio.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-audio.c"; sourceTree = SOURCE_ROOT; };
-		CE23C13F23FCEC08001177D6 /* qapi-commands-introspect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-introspect.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-introspect.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14023FCEC09001177D6 /* qapi-events.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events.c"; sourceTree = SOURCE_ROOT; };
-		CE23C14123FCEC09001177D6 /* qapi-events-misc-target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-misc-target.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-misc-target.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14223FCEC09001177D6 /* qapi-visit-misc-target.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-misc-target.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-misc-target.c"; sourceTree = SOURCE_ROOT; };
-		CE23C14323FCEC09001177D6 /* qapi-visit-run-state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-run-state.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-run-state.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14423FCEC09001177D6 /* qapi-events-qom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-qom.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-qom.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14523FCEC09001177D6 /* qapi-events-job.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-job.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-job.c"; sourceTree = SOURCE_ROOT; };
-		CE23C14623FCEC09001177D6 /* qapi-events-qdev.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-qdev.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-qdev.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14723FCEC09001177D6 /* qapi-types-migration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-migration.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-migration.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14823FCEC09001177D6 /* qapi-events-transaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-events-transaction.h"; path = "$(SYSROOT_DIR)/qapi/qapi-events-transaction.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14923FCEC09001177D6 /* qapi-types-authz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-authz.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-authz.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14A23FCEC09001177D6 /* qapi-types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14B23FCEC09001177D6 /* qapi-visit-misc-target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-misc-target.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-misc-target.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14C23FCEC09001177D6 /* qapi-visit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14D23FCEC09001177D6 /* qapi-types-rocker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-rocker.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-rocker.c"; sourceTree = SOURCE_ROOT; };
-		CE23C14E23FCEC09001177D6 /* qapi-commands-net.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-net.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-net.h"; sourceTree = SOURCE_ROOT; };
-		CE23C14F23FCEC09001177D6 /* qapi-types-rdma.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-rdma.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-rdma.h"; sourceTree = SOURCE_ROOT; };
-		CE23C15023FCEC09001177D6 /* qapi-visit-common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-visit-common.h"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-common.h"; sourceTree = SOURCE_ROOT; };
-		CE23C15123FCEC09001177D6 /* qapi-commands-misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-misc.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-misc.c"; sourceTree = SOURCE_ROOT; };
-		CE23C15223FCEC09001177D6 /* qapi-types-machine-target.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-machine-target.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-machine-target.c"; sourceTree = SOURCE_ROOT; };
-		CE23C15323FCEC09001177D6 /* qapi-commands-machine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-machine.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-machine.h"; sourceTree = SOURCE_ROOT; };
-		CE23C15423FCEC0A001177D6 /* qapi-types-trace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-trace.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-trace.h"; sourceTree = SOURCE_ROOT; };
-		CE23C15523FCEC0A001177D6 /* qapi-commands-qom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-qom.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-qom.c"; sourceTree = SOURCE_ROOT; };
-		CE23C15623FCEC0A001177D6 /* qapi-emit-events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-emit-events.h"; path = "$(SYSROOT_DIR)/qapi/qapi-emit-events.h"; sourceTree = SOURCE_ROOT; };
-		CE23C15723FCEC0A001177D6 /* qapi-commands-job.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-commands-job.c"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-job.c"; sourceTree = SOURCE_ROOT; };
-		CE23C15823FCEC0A001177D6 /* qapi-types-machine.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-machine.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-machine.c"; sourceTree = SOURCE_ROOT; };
-		CE23C15923FCEC0A001177D6 /* qapi-events-rocker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-events-rocker.c"; path = "$(SYSROOT_DIR)/qapi/qapi-events-rocker.c"; sourceTree = SOURCE_ROOT; };
-		CE23C15A23FCEC0A001177D6 /* qapi-types-error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-error.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-error.h"; sourceTree = SOURCE_ROOT; };
-		CE23C15B23FCEC0A001177D6 /* qapi-types-qdev.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-qdev.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-qdev.c"; sourceTree = SOURCE_ROOT; };
-		CE23C15C23FCEC0A001177D6 /* qapi-commands-authz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-commands-authz.h"; path = "$(SYSROOT_DIR)/qapi/qapi-commands-authz.h"; sourceTree = SOURCE_ROOT; };
-		CE23C15D23FCEC0A001177D6 /* qapi-visit-error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-visit-error.c"; path = "$(SYSROOT_DIR)/qapi/qapi-visit-error.c"; sourceTree = SOURCE_ROOT; };
-		CE23C15E23FCEC0A001177D6 /* qapi-types-tpm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-tpm.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-tpm.h"; sourceTree = SOURCE_ROOT; };
-		CE23C15F23FCEC0A001177D6 /* qapi-types-transaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qapi-types-transaction.h"; path = "$(SYSROOT_DIR)/qapi/qapi-types-transaction.h"; sourceTree = SOURCE_ROOT; };
-		CE23C16023FCEC0A001177D6 /* qapi-types-misc-target.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qapi-types-misc-target.c"; path = "$(SYSROOT_DIR)/qapi/qapi-types-misc-target.c"; sourceTree = SOURCE_ROOT; };
-		CE25121E29BD42FE000790AB /* qga-qapi-types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qga-qapi-types.c"; path = "$(SYSROOT_DIR)/qga/qga-qapi-types.c"; sourceTree = SOURCE_ROOT; };
-		CE25121F29BD42FE000790AB /* qga-qapi-types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qga-qapi-types.h"; path = "$(SYSROOT_DIR)/qga/qga-qapi-types.h"; sourceTree = SOURCE_ROOT; };
-		CE25122029BD42FE000790AB /* qga-qapi-visit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qga-qapi-visit.h"; path = "$(SYSROOT_DIR)/qga/qga-qapi-visit.h"; sourceTree = SOURCE_ROOT; };
-		CE25122129BD42FE000790AB /* qga-qapi-events.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qga-qapi-events.c"; path = "$(SYSROOT_DIR)/qga/qga-qapi-events.c"; sourceTree = SOURCE_ROOT; };
-		CE25122229BD42FE000790AB /* qga-qapi-events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qga-qapi-events.h"; path = "$(SYSROOT_DIR)/qga/qga-qapi-events.h"; sourceTree = SOURCE_ROOT; };
-		CE25122329BD42FE000790AB /* qga-qapi-emit-events.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qga-qapi-emit-events.c"; path = "$(SYSROOT_DIR)/qga/qga-qapi-emit-events.c"; sourceTree = SOURCE_ROOT; };
-		CE25122429BD42FE000790AB /* qga-qapi-visit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qga-qapi-visit.c"; path = "$(SYSROOT_DIR)/qga/qga-qapi-visit.c"; sourceTree = SOURCE_ROOT; };
-		CE25122529BD42FF000790AB /* qga-qapi-emit-events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qga-qapi-emit-events.h"; path = "$(SYSROOT_DIR)/qga/qga-qapi-emit-events.h"; sourceTree = SOURCE_ROOT; };
-		CE25122629BD42FF000790AB /* qga-qapi-commands.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "qga-qapi-commands.c"; path = "$(SYSROOT_DIR)/qga/qga-qapi-commands.c"; sourceTree = SOURCE_ROOT; };
-		CE25122729BD42FF000790AB /* qga-qapi-commands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "qga-qapi-commands.h"; path = "$(SYSROOT_DIR)/qga/qga-qapi-commands.h"; sourceTree = SOURCE_ROOT; };
-		CE25123729BD46B4000790AB /* UTMQemuMonitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTMQemuMonitor.h; sourceTree = "<group>"; };
-		CE25123829BD46B4000790AB /* UTMQemuMonitor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UTMQemuMonitor.m; sourceTree = "<group>"; };
-		CE25123C29BD47D0000790AB /* UTMQemuManager-Protected.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UTMQemuManager-Protected.h"; sourceTree = "<group>"; };
-		CE25124129BD4F10000790AB /* UTMQemuGuestAgent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTMQemuGuestAgent.h; sourceTree = "<group>"; };
-		CE25124229BD4F10000790AB /* UTMQemuGuestAgent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UTMQemuGuestAgent.m; sourceTree = "<group>"; };
 		CE25124629BFDB87000790AB /* UTMScriptingGuestProcessImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMScriptingGuestProcessImpl.swift; sourceTree = "<group>"; };
 		CE25124829BFDBA6000790AB /* UTMScriptingGuestFileImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMScriptingGuestFileImpl.swift; sourceTree = "<group>"; };
 		CE25124A29BFE273000790AB /* UTMScriptable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMScriptable.swift; sourceTree = "<group>"; };
@@ -1791,21 +1524,6 @@
 		CE2D955624AD4F980059923A /* Swift-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Swift-Bridging-Header.h"; sourceTree = "<group>"; };
 		CE31C243225E553500A965DD /* UTMLegacyQemuConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTMLegacyQemuConfiguration.h; sourceTree = "<group>"; };
 		CE31C244225E555600A965DD /* UTMLegacyQemuConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UTMLegacyQemuConfiguration.m; sourceTree = "<group>"; };
-		CE3559992273AEA10059CB2D /* cf-output-visitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cf-output-visitor.h"; sourceTree = "<group>"; };
-		CE35599A2273AEA20059CB2D /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = error.h; sourceTree = "<group>"; };
-		CE35599B2273AEA20059CB2D /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
-		CE35599C2273AEA20059CB2D /* cf-input-visitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cf-input-visitor.h"; sourceTree = "<group>"; };
-		CE35599D2273AEA20059CB2D /* dealloc-visitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "dealloc-visitor.h"; sourceTree = "<group>"; };
-		CE35599E2273AEA20059CB2D /* visitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = visitor.h; sourceTree = "<group>"; };
-		CE35599F2273AEA20059CB2D /* visitor-impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "visitor-impl.h"; sourceTree = "<group>"; };
-		CE3559A12273AEE80059CB2D /* queue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = queue.h; sourceTree = "<group>"; };
-		CE3559A32273B49D0059CB2D /* qerror.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = qerror.h; sourceTree = "<group>"; };
-		CE36B1542275061B004A1435 /* error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = error.c; sourceTree = "<group>"; };
-		CE36B26822763F28004A1435 /* UTMJSONStream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTMJSONStream.h; sourceTree = "<group>"; };
-		CE36B26922763F28004A1435 /* UTMJSONStream.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UTMJSONStream.m; sourceTree = "<group>"; };
-		CE36B27E227665B7004A1435 /* UTMJSONStreamDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTMJSONStreamDelegate.h; sourceTree = "<group>"; };
-		CE36B27F227668D1004A1435 /* UTMQemuManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTMQemuManager.h; sourceTree = "<group>"; };
-		CE36B280227668D1004A1435 /* UTMQemuManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UTMQemuManager.m; sourceTree = "<group>"; };
 		CE3ADD65240EFBCA002D6A5F /* VMDisplayMetalViewController+Keyboard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "VMDisplayMetalViewController+Keyboard.h"; sourceTree = "<group>"; };
 		CE3ADD66240EFBCA002D6A5F /* VMDisplayMetalViewController+Keyboard.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "VMDisplayMetalViewController+Keyboard.m"; sourceTree = "<group>"; };
 		CE3ADD682411C661002D6A5F /* VMCursor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VMCursor.h; sourceTree = "<group>"; };
@@ -1848,7 +1566,6 @@
 		CE7D972B24B2B17D0080CB69 /* BusyOverlay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BusyOverlay.swift; sourceTree = "<group>"; };
 		CE8813D224CD230300532628 /* ActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityView.swift; sourceTree = "<group>"; };
 		CE8813D424CD265700532628 /* VMShareFileModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMShareFileModifier.swift; sourceTree = "<group>"; };
-		CE8E6620227E5DF2003B9903 /* UTMQemuMonitorDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UTMQemuMonitorDelegate.h; sourceTree = "<group>"; };
 		CE928C2926ABE6690099F293 /* UTMAppleVirtualMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMAppleVirtualMachine.swift; sourceTree = "<group>"; };
 		CE928C3026ACCDEA0099F293 /* VMAppleRemovableDrivesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMAppleRemovableDrivesView.swift; sourceTree = "<group>"; };
 		CE9375A024BBDDD10074066F /* VMConfigDriveDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMConfigDriveDetailsView.swift; sourceTree = "<group>"; };
@@ -1911,12 +1628,6 @@
 		CEC794B9294924E300121A9F /* UTMScriptingSerialPortImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMScriptingSerialPortImpl.swift; sourceTree = "<group>"; };
 		CEC794BB2949663C00121A9F /* UTMScripting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UTMScripting.swift; sourceTree = "<group>"; };
 		CEC9968328AA516000E7A025 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ja; path = ja.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
-		CECC764C2273A7D50059B955 /* cf-input-visitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "cf-input-visitor.c"; sourceTree = "<group>"; };
-		CECC764D2273A7D50059B955 /* qapi-dealloc-visitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "qapi-dealloc-visitor.c"; sourceTree = "<group>"; };
-		CECC764E2273A7D50059B955 /* qapi-util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "qapi-util.c"; sourceTree = "<group>"; };
-		CECC764F2273A7D50059B955 /* qapi-visit-core.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "qapi-visit-core.c"; sourceTree = "<group>"; };
-		CECC76502273A7D50059B955 /* cf-output-visitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "cf-output-visitor.c"; sourceTree = "<group>"; };
-		CECC76562273A88F0059B955 /* qemu-compat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "qemu-compat.h"; sourceTree = "<group>"; };
 		CED234EC254796E500ED0A57 /* NumberTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NumberTextField.swift; sourceTree = "<group>"; };
 		CED814E824C79F070042F0F1 /* VMConfigDriveCreateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMConfigDriveCreateView.swift; sourceTree = "<group>"; };
 		CED814EB24C7C2850042F0F1 /* VMConfigInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VMConfigInfoView.swift; sourceTree = "<group>"; };
@@ -1951,10 +1662,6 @@
 		CEF6F5EA26DDD60500BC434D /* macOS-unsigned.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "macOS-unsigned.entitlements"; sourceTree = "<group>"; };
 		CEF6F5EB26DDD63100BC434D /* QEMUHelper-unsigned.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "QEMUHelper-unsigned.entitlements"; sourceTree = "<group>"; };
 		CEF6F5EC26DDD65700BC434D /* QEMULauncher-unsigned.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "QEMULauncher-unsigned.entitlements"; sourceTree = "<group>"; };
-		CEF83EB824F9ABEA00557D15 /* UTMQemuMonitor+BlockDevices.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UTMQemuMonitor+BlockDevices.h"; sourceTree = "<group>"; };
-		CEF83EB924F9ABEA00557D15 /* UTMQemuMonitor+BlockDevices.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UTMQemuMonitor+BlockDevices.m"; sourceTree = "<group>"; };
-		CEF83EC624FB1B9300557D15 /* UTMQemuVirtualMachine+SPICE.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UTMQemuVirtualMachine+SPICE.m"; sourceTree = "<group>"; };
-		CEF83EC924FB1BB200557D15 /* UTMQemuVirtualMachine+SPICE.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UTMQemuVirtualMachine+SPICE.h"; sourceTree = "<group>"; };
 		CEF84ADA2887D7D300578F41 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
 		CEFE98DE29485237007CB7A8 /* UTM.sdef */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = UTM.sdef; sourceTree = "<group>"; };
 		CEFE98E029485776007CB7A8 /* UTMScriptingVirtualMachineImpl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMScriptingVirtualMachineImpl.swift; sourceTree = "<group>"; };
@@ -2533,269 +2240,6 @@
 			path = Configuration;
 			sourceTree = "<group>";
 		};
-		CE36B2672275312A004A1435 /* Generated */ = {
-			isa = PBXGroup;
-			children = (
-				CE23C0D523FCEC03001177D6 /* qapi-builtin-types.c */,
-				CE23C0C823FCEC02001177D6 /* qapi-builtin-types.h */,
-				CE23C09623FCEC00001177D6 /* qapi-builtin-visit.c */,
-				CE23C0FA23FCEC05001177D6 /* qapi-builtin-visit.h */,
-				CE23C09D23FCEC00001177D6 /* qapi-commands-audio.c */,
-				CE23C0BA23FCEC02001177D6 /* qapi-commands-audio.h */,
-				CE23C0A423FCEC01001177D6 /* qapi-commands-authz.c */,
-				CE23C15C23FCEC0A001177D6 /* qapi-commands-authz.h */,
-				CE23C0DF23FCEC04001177D6 /* qapi-commands-block-core.c */,
-				CE23C07D23FCEBFF001177D6 /* qapi-commands-block-core.h */,
-				CE23C0E723FCEC04001177D6 /* qapi-commands-block.c */,
-				CE23C0C023FCEC02001177D6 /* qapi-commands-block.h */,
-				CE23C08623FCEBFF001177D6 /* qapi-commands-char.c */,
-				CE23C0E623FCEC04001177D6 /* qapi-commands-char.h */,
-				CE23C10823FCEC06001177D6 /* qapi-commands-common.c */,
-				CE23C09823FCEC00001177D6 /* qapi-commands-common.h */,
-				CE23C0AE23FCEC01001177D6 /* qapi-commands-crypto.c */,
-				CE23C0BB23FCEC02001177D6 /* qapi-commands-crypto.h */,
-				CE23C0DD23FCEC03001177D6 /* qapi-commands-dump.c */,
-				CE23C0A223FCEC01001177D6 /* qapi-commands-dump.h */,
-				CE23C0FC23FCEC05001177D6 /* qapi-commands-error.c */,
-				CE23C0F323FCEC05001177D6 /* qapi-commands-error.h */,
-				CE23C10523FCEC05001177D6 /* qapi-commands-introspect.c */,
-				CE23C13F23FCEC08001177D6 /* qapi-commands-introspect.h */,
-				CE23C15723FCEC0A001177D6 /* qapi-commands-job.c */,
-				CE23C12323FCEC07001177D6 /* qapi-commands-job.h */,
-				CE23C0DB23FCEC03001177D6 /* qapi-commands-machine-target.c */,
-				CE23C0FF23FCEC05001177D6 /* qapi-commands-machine-target.h */,
-				CE23C13223FCEC08001177D6 /* qapi-commands-machine.c */,
-				CE23C15323FCEC09001177D6 /* qapi-commands-machine.h */,
-				CE23C09B23FCEC00001177D6 /* qapi-commands-migration.c */,
-				CE23C08323FCEBFF001177D6 /* qapi-commands-migration.h */,
-				CE23C13C23FCEC08001177D6 /* qapi-commands-misc-target.c */,
-				CE23C09423FCEC00001177D6 /* qapi-commands-misc-target.h */,
-				CE23C15123FCEC09001177D6 /* qapi-commands-misc.c */,
-				CE23C0CA23FCEC02001177D6 /* qapi-commands-misc.h */,
-				CE23C08F23FCEC00001177D6 /* qapi-commands-net.c */,
-				CE23C14E23FCEC09001177D6 /* qapi-commands-net.h */,
-				CE23C11F23FCEC07001177D6 /* qapi-commands-qdev.c */,
-				CE23C12A23FCEC07001177D6 /* qapi-commands-qdev.h */,
-				CE23C15523FCEC0A001177D6 /* qapi-commands-qom.c */,
-				CE23C13323FCEC08001177D6 /* qapi-commands-qom.h */,
-				CE23C0FB23FCEC05001177D6 /* qapi-commands-rdma.c */,
-				CE23C0E123FCEC04001177D6 /* qapi-commands-rdma.h */,
-				CE23C08123FCEBFF001177D6 /* qapi-commands-rocker.c */,
-				CE23C10F23FCEC06001177D6 /* qapi-commands-rocker.h */,
-				CE23C07E23FCEBFF001177D6 /* qapi-commands-run-state.c */,
-				CE23C09A23FCEC00001177D6 /* qapi-commands-run-state.h */,
-				CE23C0BD23FCEC02001177D6 /* qapi-commands-sockets.c */,
-				CE23C0D823FCEC03001177D6 /* qapi-commands-sockets.h */,
-				CE23C0BF23FCEC02001177D6 /* qapi-commands-tpm.c */,
-				CE23C08E23FCEC00001177D6 /* qapi-commands-tpm.h */,
-				CE23C11023FCEC06001177D6 /* qapi-commands-trace.c */,
-				CE23C0D023FCEC03001177D6 /* qapi-commands-trace.h */,
-				CE23C10B23FCEC06001177D6 /* qapi-commands-transaction.c */,
-				CE23C0D123FCEC03001177D6 /* qapi-commands-transaction.h */,
-				CE23C08223FCEBFF001177D6 /* qapi-commands-ui.c */,
-				CE23C10323FCEC05001177D6 /* qapi-commands-ui.h */,
-				CE23C0D223FCEC03001177D6 /* qapi-commands.c */,
-				CE23C0AA23FCEC01001177D6 /* qapi-commands.h */,
-				CE23C09223FCEC00001177D6 /* qapi-emit-events.c */,
-				CE23C15623FCEC0A001177D6 /* qapi-emit-events.h */,
-				2CE8EAF22572E0D0000E2EBB /* qapi-events-acpi.c */,
-				2CE8EAF12572E0D0000E2EBB /* qapi-events-acpi.h */,
-				CE23C13E23FCEC08001177D6 /* qapi-events-audio.c */,
-				CE23C12D23FCEC07001177D6 /* qapi-events-audio.h */,
-				CE23C0CC23FCEC03001177D6 /* qapi-events-authz.c */,
-				CE23C0D423FCEC03001177D6 /* qapi-events-authz.h */,
-				CE23C0EF23FCEC04001177D6 /* qapi-events-block-core.c */,
-				CE23C0D923FCEC03001177D6 /* qapi-events-block-core.h */,
-				2CE8EAEC2572E0C2000E2EBB /* qapi-events-block-export.c */,
-				2CE8EAED2572E0C2000E2EBB /* qapi-events-block-export.h */,
-				CE23C11623FCEC06001177D6 /* qapi-events-block.c */,
-				CE23C08023FCEBFF001177D6 /* qapi-events-block.h */,
-				CE23C12723FCEC07001177D6 /* qapi-events-char.c */,
-				CE23C0C523FCEC02001177D6 /* qapi-events-char.h */,
-				CE23C0D723FCEC03001177D6 /* qapi-events-common.c */,
-				CE23C0F823FCEC05001177D6 /* qapi-events-common.h */,
-				CE23C11D23FCEC07001177D6 /* qapi-events-crypto.c */,
-				CE23C0C123FCEC02001177D6 /* qapi-events-crypto.h */,
-				CE23C0D323FCEC03001177D6 /* qapi-events-dump.c */,
-				CE23C11C23FCEC07001177D6 /* qapi-events-dump.h */,
-				CE23C0F023FCEC04001177D6 /* qapi-events-error.c */,
-				CE23C08D23FCEC00001177D6 /* qapi-events-error.h */,
-				CE23C0B423FCEC01001177D6 /* qapi-events-introspect.c */,
-				CE23C0AD23FCEC01001177D6 /* qapi-events-introspect.h */,
-				CE23C14523FCEC09001177D6 /* qapi-events-job.c */,
-				CE23C12523FCEC07001177D6 /* qapi-events-job.h */,
-				CE23C13D23FCEC08001177D6 /* qapi-events-machine-target.c */,
-				CE23C13B23FCEC08001177D6 /* qapi-events-machine-target.h */,
-				CE23C0B923FCEC02001177D6 /* qapi-events-machine.c */,
-				CE23C07C23FCEBFF001177D6 /* qapi-events-machine.h */,
-				CE23C0EE23FCEC04001177D6 /* qapi-events-migration.c */,
-				CE23C09C23FCEC00001177D6 /* qapi-events-migration.h */,
-				CE23C0C723FCEC02001177D6 /* qapi-events-misc-target.c */,
-				CE23C14123FCEC09001177D6 /* qapi-events-misc-target.h */,
-				CE23C11B23FCEC07001177D6 /* qapi-events-misc.c */,
-				CE23C11323FCEC06001177D6 /* qapi-events-misc.h */,
-				CE23C10123FCEC05001177D6 /* qapi-events-net.c */,
-				CE23C09123FCEC00001177D6 /* qapi-events-net.h */,
-				CE23C09E23FCEC00001177D6 /* qapi-events-qdev.c */,
-				CE23C14623FCEC09001177D6 /* qapi-events-qdev.h */,
-				CE23C0A823FCEC01001177D6 /* qapi-events-qom.c */,
-				CE23C14423FCEC09001177D6 /* qapi-events-qom.h */,
-				CE23C12923FCEC07001177D6 /* qapi-events-rdma.c */,
-				CE23C08B23FCEC00001177D6 /* qapi-events-rdma.h */,
-				CE23C15923FCEC0A001177D6 /* qapi-events-rocker.c */,
-				CE23C08C23FCEC00001177D6 /* qapi-events-rocker.h */,
-				CE23C0FD23FCEC05001177D6 /* qapi-events-run-state.c */,
-				CE23C0A123FCEC01001177D6 /* qapi-events-run-state.h */,
-				CE23C0AF23FCEC01001177D6 /* qapi-events-sockets.c */,
-				CE23C0D623FCEC03001177D6 /* qapi-events-sockets.h */,
-				CE23C13923FCEC08001177D6 /* qapi-events-tpm.c */,
-				CE23C0B223FCEC01001177D6 /* qapi-events-tpm.h */,
-				CE23C08923FCEBFF001177D6 /* qapi-events-trace.c */,
-				CE23C0BC23FCEC02001177D6 /* qapi-events-trace.h */,
-				CE23C0AC23FCEC01001177D6 /* qapi-events-transaction.c */,
-				CE23C14823FCEC09001177D6 /* qapi-events-transaction.h */,
-				CE23C12623FCEC07001177D6 /* qapi-events-ui.c */,
-				CE23C0A523FCEC01001177D6 /* qapi-events-ui.h */,
-				CE23C14023FCEC09001177D6 /* qapi-events.c */,
-				CE23C08423FCEBFF001177D6 /* qapi-events.h */,
-				2CE8EAF72572E130000E2EBB /* qapi-types-acpi.c */,
-				2CE8EAF82572E130000E2EBB /* qapi-types-acpi.h */,
-				CE23C11423FCEC06001177D6 /* qapi-types-audio.c */,
-				CE23C0AB23FCEC01001177D6 /* qapi-types-audio.h */,
-				CE23C0DA23FCEC03001177D6 /* qapi-types-authz.c */,
-				CE23C14923FCEC09001177D6 /* qapi-types-authz.h */,
-				CE23C09923FCEC00001177D6 /* qapi-types-block-core.c */,
-				CE23C0DE23FCEC04001177D6 /* qapi-types-block-core.h */,
-				2CE8EAFC2572E14C000E2EBB /* qapi-types-block-export.c */,
-				2CE8EAFD2572E14C000E2EBB /* qapi-types-block-export.h */,
-				CE23C08723FCEBFF001177D6 /* qapi-types-block.c */,
-				CE23C12E23FCEC08001177D6 /* qapi-types-block.h */,
-				CE23C12023FCEC07001177D6 /* qapi-types-char.c */,
-				CE23C0F423FCEC05001177D6 /* qapi-types-char.h */,
-				CE23C0C623FCEC02001177D6 /* qapi-types-common.c */,
-				CE23C0F623FCEC05001177D6 /* qapi-types-common.h */,
-				8469CAC9277D301300BA5601 /* qapi-types-compat.c */,
-				8469CAC8277D301300BA5601 /* qapi-types-compat.h */,
-				CE23C0E323FCEC04001177D6 /* qapi-types-crypto.c */,
-				CE23C12B23FCEC07001177D6 /* qapi-types-crypto.h */,
-				CE23C12123FCEC07001177D6 /* qapi-types-dump.c */,
-				CE23C0FE23FCEC05001177D6 /* qapi-types-dump.h */,
-				CE23C11223FCEC06001177D6 /* qapi-types-error.c */,
-				CE23C15A23FCEC0A001177D6 /* qapi-types-error.h */,
-				CE23C0F923FCEC05001177D6 /* qapi-types-introspect.c */,
-				CE23C11723FCEC06001177D6 /* qapi-types-introspect.h */,
-				CE23C13123FCEC08001177D6 /* qapi-types-job.c */,
-				CE23C12423FCEC07001177D6 /* qapi-types-job.h */,
-				CE23C15223FCEC09001177D6 /* qapi-types-machine-target.c */,
-				CE23C11E23FCEC07001177D6 /* qapi-types-machine-target.h */,
-				CE23C15823FCEC0A001177D6 /* qapi-types-machine.c */,
-				CE23C0C923FCEC02001177D6 /* qapi-types-machine.h */,
-				CE23C0CB23FCEC02001177D6 /* qapi-types-migration.c */,
-				CE23C14723FCEC09001177D6 /* qapi-types-migration.h */,
-				CE23C16023FCEC0A001177D6 /* qapi-types-misc-target.c */,
-				CE23C0A923FCEC01001177D6 /* qapi-types-misc-target.h */,
-				CE23C12823FCEC07001177D6 /* qapi-types-misc.c */,
-				CE23C11823FCEC06001177D6 /* qapi-types-misc.h */,
-				CE23C0B523FCEC02001177D6 /* qapi-types-net.c */,
-				CE23C0F223FCEC04001177D6 /* qapi-types-net.h */,
-				CE23C15B23FCEC0A001177D6 /* qapi-types-qdev.c */,
-				CE23C09323FCEC00001177D6 /* qapi-types-qdev.h */,
-				CE23C13823FCEC08001177D6 /* qapi-types-qom.c */,
-				CE23C10A23FCEC06001177D6 /* qapi-types-qom.h */,
-				CE23C13023FCEC08001177D6 /* qapi-types-rdma.c */,
-				CE23C14F23FCEC09001177D6 /* qapi-types-rdma.h */,
-				CE23C14D23FCEC09001177D6 /* qapi-types-rocker.c */,
-				CE23C12F23FCEC08001177D6 /* qapi-types-rocker.h */,
-				CE23C08523FCEBFF001177D6 /* qapi-types-run-state.c */,
-				CE23C0C423FCEC02001177D6 /* qapi-types-run-state.h */,
-				CE23C10E23FCEC06001177D6 /* qapi-types-sockets.c */,
-				CE23C13A23FCEC08001177D6 /* qapi-types-sockets.h */,
-				CE23C0DC23FCEC03001177D6 /* qapi-types-tpm.c */,
-				CE23C15E23FCEC0A001177D6 /* qapi-types-tpm.h */,
-				CE23C11523FCEC06001177D6 /* qapi-types-trace.c */,
-				CE23C15423FCEC0A001177D6 /* qapi-types-trace.h */,
-				CE23C13423FCEC08001177D6 /* qapi-types-transaction.c */,
-				CE23C15F23FCEC0A001177D6 /* qapi-types-transaction.h */,
-				CE23C10023FCEC05001177D6 /* qapi-types-ui.c */,
-				CE23C11A23FCEC07001177D6 /* qapi-types-ui.h */,
-				CE23C0B623FCEC02001177D6 /* qapi-types.c */,
-				CE23C14A23FCEC09001177D6 /* qapi-types.h */,
-				2CE8EB032572E166000E2EBB /* qapi-visit-acpi.c */,
-				2CE8EB022572E166000E2EBB /* qapi-visit-acpi.h */,
-				CE23C0BE23FCEC02001177D6 /* qapi-visit-audio.c */,
-				CE23C0CF23FCEC03001177D6 /* qapi-visit-audio.h */,
-				CE23C0B823FCEC02001177D6 /* qapi-visit-authz.c */,
-				CE23C0F123FCEC04001177D6 /* qapi-visit-authz.h */,
-				CE23C0E023FCEC04001177D6 /* qapi-visit-block-core.c */,
-				CE23C0B123FCEC01001177D6 /* qapi-visit-block-core.h */,
-				2CE8EB082572E173000E2EBB /* qapi-visit-block-export.c */,
-				2CE8EB072572E173000E2EBB /* qapi-visit-block-export.h */,
-				CE23C0A723FCEC01001177D6 /* qapi-visit-block.c */,
-				CE23C13723FCEC08001177D6 /* qapi-visit-block.h */,
-				CE23C0E923FCEC04001177D6 /* qapi-visit-char.c */,
-				CE23C12223FCEC07001177D6 /* qapi-visit-char.h */,
-				CE23C10223FCEC05001177D6 /* qapi-visit-common.c */,
-				CE23C15023FCEC09001177D6 /* qapi-visit-common.h */,
-				8469CACD277D345700BA5601 /* qapi-visit-compat.c */,
-				8469CACE277D345700BA5601 /* qapi-visit-compat.h */,
-				CE23C0C223FCEC02001177D6 /* qapi-visit-crypto.c */,
-				CE23C0CD23FCEC03001177D6 /* qapi-visit-crypto.h */,
-				CE23C0B323FCEC01001177D6 /* qapi-visit-dump.c */,
-				CE23C12C23FCEC07001177D6 /* qapi-visit-dump.h */,
-				CE23C15D23FCEC0A001177D6 /* qapi-visit-error.c */,
-				CE23C07B23FCEBFF001177D6 /* qapi-visit-error.h */,
-				CE23C0E223FCEC04001177D6 /* qapi-visit-introspect.c */,
-				CE23C0EA23FCEC04001177D6 /* qapi-visit-introspect.h */,
-				CE23C09523FCEC00001177D6 /* qapi-visit-job.c */,
-				CE23C0EB23FCEC04001177D6 /* qapi-visit-job.h */,
-				CE23C11123FCEC06001177D6 /* qapi-visit-machine-target.c */,
-				CE23C0E823FCEC04001177D6 /* qapi-visit-machine-target.h */,
-				CE23C10D23FCEC06001177D6 /* qapi-visit-machine.c */,
-				CE23C0EC23FCEC04001177D6 /* qapi-visit-machine.h */,
-				CE23C0CE23FCEC03001177D6 /* qapi-visit-migration.c */,
-				CE23C09F23FCEC01001177D6 /* qapi-visit-migration.h */,
-				CE23C14223FCEC09001177D6 /* qapi-visit-misc-target.c */,
-				CE23C14B23FCEC09001177D6 /* qapi-visit-misc-target.h */,
-				CE23C10423FCEC05001177D6 /* qapi-visit-misc.c */,
-				CE23C0ED23FCEC04001177D6 /* qapi-visit-misc.h */,
-				CE23C08A23FCEC00001177D6 /* qapi-visit-net.c */,
-				CE23C10723FCEC06001177D6 /* qapi-visit-net.h */,
-				CE23C10923FCEC06001177D6 /* qapi-visit-qdev.c */,
-				CE23C08823FCEBFF001177D6 /* qapi-visit-qdev.h */,
-				CE23C0E423FCEC04001177D6 /* qapi-visit-qom.c */,
-				CE23C0C323FCEC02001177D6 /* qapi-visit-qom.h */,
-				CE23C13623FCEC08001177D6 /* qapi-visit-rdma.c */,
-				CE23C0B023FCEC01001177D6 /* qapi-visit-rdma.h */,
-				CE23C0F723FCEC05001177D6 /* qapi-visit-rocker.c */,
-				CE23C0A023FCEC01001177D6 /* qapi-visit-rocker.h */,
-				CE23C0F523FCEC05001177D6 /* qapi-visit-run-state.c */,
-				CE23C14323FCEC09001177D6 /* qapi-visit-run-state.h */,
-				CE23C10623FCEC05001177D6 /* qapi-visit-sockets.c */,
-				CE23C09723FCEC00001177D6 /* qapi-visit-sockets.h */,
-				CE23C07F23FCEBFF001177D6 /* qapi-visit-tpm.c */,
-				CE23C11923FCEC06001177D6 /* qapi-visit-tpm.h */,
-				CE23C0E523FCEC04001177D6 /* qapi-visit-trace.c */,
-				CE23C09023FCEC00001177D6 /* qapi-visit-trace.h */,
-				CE23C0A623FCEC01001177D6 /* qapi-visit-transaction.c */,
-				CE23C10C23FCEC06001177D6 /* qapi-visit-transaction.h */,
-				CE23C0B723FCEC02001177D6 /* qapi-visit-ui.c */,
-				CE23C0A323FCEC01001177D6 /* qapi-visit-ui.h */,
-				CE23C13523FCEC08001177D6 /* qapi-visit.c */,
-				CE23C14C23FCEC09001177D6 /* qapi-visit.h */,
-				CE25122629BD42FF000790AB /* qga-qapi-commands.c */,
-				CE25122729BD42FF000790AB /* qga-qapi-commands.h */,
-				CE25122329BD42FE000790AB /* qga-qapi-emit-events.c */,
-				CE25122529BD42FF000790AB /* qga-qapi-emit-events.h */,
-				CE25122129BD42FE000790AB /* qga-qapi-events.c */,
-				CE25122229BD42FE000790AB /* qga-qapi-events.h */,
-				CE25121E29BD42FE000790AB /* qga-qapi-types.c */,
-				CE25121F29BD42FE000790AB /* qga-qapi-types.h */,
-				CE25122429BD42FE000790AB /* qga-qapi-visit.c */,
-				CE25122029BD42FE000790AB /* qga-qapi-visit.h */,
-			);
-			name = Generated;
-			sourceTree = "<group>";
-		};
 		CE550BC0225947990063E575 = {
 			isa = PBXGroup;
 			children = (
@@ -2804,7 +2248,6 @@
 				CE31C242225E543A00A965DD /* Configuration */,
 				CE5F1659226138AB00F3D56B /* Managers */,
 				CE2D953624AD4F980059923A /* Platform */,
-				CECC76492273A7AE0059B955 /* qapi */,
 				CEBDA1DB24D8BDDA0010B5EC /* QEMUHelper */,
 				CE9D18F72265410E00355E14 /* qemu */,
 				CE6B240925F1F3CE0020D43E /* QEMULauncher */,
@@ -2835,37 +2278,16 @@
 		CE5F1659226138AB00F3D56B /* Managers */ = {
 			isa = PBXGroup;
 			children = (
-				CE36B26822763F28004A1435 /* UTMJSONStream.h */,
-				CE36B26922763F28004A1435 /* UTMJSONStream.m */,
-				CE36B27E227665B7004A1435 /* UTMJSONStreamDelegate.h */,
 				CE6EDCE0241DA0E900A719DC /* UTMLogging.h */,
 				CE6EDCE1241DA0E900A719DC /* UTMLogging.m */,
-				84BB99382899AB1800DF28B2 /* UTMLoggingDelegate.h */,
 				CEDF83F8258AE24E0030E4AC /* UTMPasteboard.swift */,
-				2C6D9E122571AFE5003298E6 /* UTMQcow2.h */,
-				2C6D9E132571AFE5003298E6 /* UTMQcow2.c */,
 				CE9D197A226542FE00355E14 /* UTMQemu.h */,
 				CE9D197B226542FE00355E14 /* UTMQemu.m */,
 				8453DCB3278CE5410037A0DA /* UTMQemuImage.swift */,
-				CE36B27F227668D1004A1435 /* UTMQemuManager.h */,
-				CE36B280227668D1004A1435 /* UTMQemuManager.m */,
-				CE25123C29BD47D0000790AB /* UTMQemuManager-Protected.h */,
-				CE25123729BD46B4000790AB /* UTMQemuMonitor.h */,
-				CE25123829BD46B4000790AB /* UTMQemuMonitor.m */,
-				CEF83EB824F9ABEA00557D15 /* UTMQemuMonitor+BlockDevices.h */,
-				CEF83EB924F9ABEA00557D15 /* UTMQemuMonitor+BlockDevices.m */,
-				CE8E6620227E5DF2003B9903 /* UTMQemuMonitorDelegate.h */,
 				84A0A8822A47D52E0038F329 /* UTMQemuPort.swift */,
-				CE25124129BD4F10000790AB /* UTMQemuGuestAgent.h */,
-				CE25124229BD4F10000790AB /* UTMQemuGuestAgent.m */,
 				CE03D05424D90BE000F76B84 /* UTMQemuSystem.h */,
 				CE03D05024D90B4E00F76B84 /* UTMQemuSystem.m */,
 				841E999728AC817D003C6CB6 /* UTMQemuVirtualMachine.swift */,
-				84FCABB8268CE05E0036196C /* UTMQemuVirtualMachine.h */,
-				84FCABB9268CE05E0036196C /* UTMQemuVirtualMachine.m */,
-				841E999628AC80CA003C6CB6 /* UTMQemuVirtualMachine-Protected.h */,
-				CEF83EC924FB1BB200557D15 /* UTMQemuVirtualMachine+SPICE.h */,
-				CEF83EC624FB1B9300557D15 /* UTMQemuVirtualMachine+SPICE.m */,
 				CE2B89352262B2F600C6D9D8 /* UTMVirtualMachineDelegate.h */,
 				CE020BB524B14F8400B44AB6 /* UTMVirtualMachine.swift */,
 				CE2B89332262A21E00C6D9D8 /* UTMVirtualMachine.h */,
@@ -3030,30 +2452,6 @@
 			path = QEMUHelper;
 			sourceTree = "<group>";
 		};
-		CECC76492273A7AE0059B955 /* qapi */ = {
-			isa = PBXGroup;
-			children = (
-				CE36B2672275312A004A1435 /* Generated */,
-				CE35599C2273AEA20059CB2D /* cf-input-visitor.h */,
-				CE3559992273AEA10059CB2D /* cf-output-visitor.h */,
-				CE35599D2273AEA20059CB2D /* dealloc-visitor.h */,
-				CE35599A2273AEA20059CB2D /* error.h */,
-				CECC76562273A88F0059B955 /* qemu-compat.h */,
-				CE3559A32273B49D0059CB2D /* qerror.h */,
-				CE3559A12273AEE80059CB2D /* queue.h */,
-				CE35599B2273AEA20059CB2D /* util.h */,
-				CE35599F2273AEA20059CB2D /* visitor-impl.h */,
-				CE35599E2273AEA20059CB2D /* visitor.h */,
-				CECC764C2273A7D50059B955 /* cf-input-visitor.c */,
-				CECC76502273A7D50059B955 /* cf-output-visitor.c */,
-				CE36B1542275061B004A1435 /* error.c */,
-				CECC764D2273A7D50059B955 /* qapi-dealloc-visitor.c */,
-				CECC764E2273A7D50059B955 /* qapi-util.c */,
-				CECC764F2273A7D50059B955 /* qapi-visit-core.c */,
-			);
-			path = qapi;
-			sourceTree = "<group>";
-		};
 		CEFE98DD2948518D007CB7A8 /* Scripting */ = {
 			isa = PBXGroup;
 			children = (

+ 0 - 607
qapi/cf-input-visitor.c

@@ -1,607 +0,0 @@
-/*
- * Input Visitor
- *
- * Copyright (C) 2012-2017 Red Hat, Inc.
- * Copyright IBM, Corp. 2011
- * Copyright (C) 2019 osy
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *  osy             <dev@getutm.app>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qemu-compat.h"
-#include "error.h"
-#include "visitor-impl.h"
-#include "queue.h"
-#include "qerror.h"
-#include "cf-input-visitor.h"
-#include <math.h>
-
-typedef struct StackObject {
-    const char *name;            /* Name of @obj in its parent, if any */
-    CFTypeRef obj;               /* CFDictionary or CFArray being visited */
-    void *qapi; /* sanity check that caller uses same pointer */
-
-    GHashTable *h;              /* If @obj is CFDictionary: unvisited keys */
-    CFIndex index;              /* If @obj is CFArray: current index */
-    CFIndex count;              /* If @obj is CFArray: total count */
-
-    QSLIST_ENTRY(StackObject) node; /* parent */
-} StackObject;
-
-struct CFObjectInputVisitor {
-    Visitor visitor;
-
-    /* Root of visit at visitor creation. */
-    CFDictionaryRef root;
-    bool keyval;                /* Assume @root made with keyval_parse() */
-
-    /* Stack of objects being visited (all entries will be either
-     * QDict or QList). */
-    QSLIST_HEAD(, StackObject) stack;
-
-    GString *errname;           /* Accumulator for full_name() */
-};
-
-static CFObjectInputVisitor *to_qiv(Visitor *v)
-{
-    return container_of(v, CFObjectInputVisitor, visitor);
-}
-
-/*
- * Find the full name of something @qiv is currently visiting.
- * @qiv is visiting something named @name in the stack of containers
- * @qiv->stack.
- * If @n is zero, return its full name.
- * If @n is positive, return the full name of the @n-th container
- * counting from the top.  The stack of containers must have at least
- * @n elements.
- * The returned string is valid until the next full_name_nth(@v) or
- * destruction of @v.
- */
-static const char *full_name_nth(CFObjectInputVisitor *qiv, const char *name,
-                                 int n)
-{
-    StackObject *so;
-    char buf[32];
-
-    if (qiv->errname) {
-        g_string_truncate(qiv->errname, 0);
-    } else {
-        qiv->errname = g_string_new("");
-    }
-
-    QSLIST_FOREACH(so , &qiv->stack, node) {
-        if (n) {
-            n--;
-        } else if (CFGetTypeID(so->obj) == CFDictionaryGetTypeID()) {
-            g_string_prepend(qiv->errname, name ?: "<anonymous>");
-            g_string_prepend_c(qiv->errname, '.');
-        } else {
-            snprintf(buf, sizeof(buf),
-                     qiv->keyval ? ".%u" : "[%u]",
-                     (unsigned)so->index);
-            g_string_prepend(qiv->errname, buf);
-        }
-        name = so->name;
-    }
-    assert(!n);
-
-    if (name) {
-        g_string_prepend(qiv->errname, name);
-    } else if (qiv->errname->str[0] == '.') {
-        g_string_erase(qiv->errname, 0, 1);
-    } else if (!qiv->errname->str[0]) {
-        return "<anonymous>";
-    }
-
-    return qiv->errname->str;
-}
-
-static const char *full_name(CFObjectInputVisitor *qiv, const char *name)
-{
-    return full_name_nth(qiv, name, 0);
-}
-
-static CFTypeRef cf_input_try_get_object(CFObjectInputVisitor *qiv,
-                                             const char *name,
-                                             bool consume)
-{
-    StackObject *tos;
-    CFTypeRef cfobj;
-    CFTypeRef ret;
-
-    if (QSLIST_EMPTY(&qiv->stack)) {
-        /* Starting at root, name is ignored. */
-        assert(qiv->root);
-        return qiv->root;
-    }
-
-    /* We are in a container; find the next element. */
-    tos = QSLIST_FIRST(&qiv->stack);
-    cfobj = tos->obj;
-    assert(cfobj);
-
-    if (CFGetTypeID(cfobj) == CFDictionaryGetTypeID()) {
-        assert(name);
-        CFStringRef cfname = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, name, kCFStringEncodingUTF8, kCFAllocatorNull);
-        ret = (CFTypeRef)CFDictionaryGetValue((CFDictionaryRef)cfobj, cfname);
-        if (tos->h && consume && ret) {
-            bool removed = g_hash_table_remove(tos->h, cfname);
-            assert(removed);
-        }
-        CFRelease(cfname);
-    } else {
-        assert(CFGetTypeID(cfobj) == CFArrayGetTypeID());
-        assert(!name);
-        if (tos->index < tos->count) {
-            ret = (CFTypeRef)CFArrayGetValueAtIndex((CFArrayRef)cfobj, tos->index);
-            if (consume) {
-                tos->index++;
-            }
-        } else {
-            ret = NULL;
-        }
-    }
-
-    return ret;
-}
-
-static CFTypeRef cf_input_get_object(CFObjectInputVisitor *qiv,
-                                         const char *name,
-                                         bool consume, Error **errp)
-{
-    CFTypeRef obj = cf_input_try_get_object(qiv, name, consume);
-
-    if (!obj) {
-        error_setg(errp, QERR_MISSING_PARAMETER, full_name(qiv, name));
-    }
-    return obj;
-}
-
-static void cfdictionary_add_key(const void *key, const void *val, void *context)
-{
-    GHashTable *h = context;
-    g_hash_table_insert(h, (gpointer) CFRetain((CFTypeRef)key), NULL);
-}
-
-static guint cfstring_hash(gconstpointer key)
-{
-    return (guint)CFHash((CFTypeRef)key);
-}
-
-static gboolean cfstring_equal(gconstpointer a, gconstpointer b)
-{
-    return CFStringCompare((CFStringRef)a, (CFStringRef)b, 0) == kCFCompareEqualTo;
-}
-
-static void cfstring_destroy(gpointer data)
-{
-    CFRelease((CFTypeRef)data);
-}
-
-static void cf_input_push(CFObjectInputVisitor *qiv,
-                                            const char *name,
-                                            CFTypeRef obj, void *qapi)
-{
-    GHashTable *h;
-    StackObject *tos = g_new0(StackObject, 1);
-
-    assert(obj);
-    tos->name = name;
-    tos->obj = obj;
-    tos->qapi = qapi;
-
-    if (CFGetTypeID(obj) == CFDictionaryGetTypeID()) {
-        h = g_hash_table_new_full(cfstring_hash, cfstring_equal, cfstring_destroy, NULL);
-        CFDictionaryApplyFunction((CFDictionaryRef)obj, cfdictionary_add_key, h);
-        tos->h = h;
-    } else {
-        assert(CFGetTypeID(obj) == CFArrayGetTypeID());
-        tos->count = CFArrayGetCount((CFArrayRef)obj);
-        tos->index = 0;
-    }
-
-    QSLIST_INSERT_HEAD(&qiv->stack, tos, node);
-}
-
-
-static bool cf_input_check_struct(Visitor *v, Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    StackObject *tos = QSLIST_FIRST(&qiv->stack);
-    GHashTableIter iter;
-    const char *key;
-
-    assert(tos);
-
-    g_hash_table_iter_init(&iter, tos->h);
-    if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) {
-        error_setg(errp, "Parameter '%s' is unexpected",
-                   full_name(qiv, key));
-        return false;
-    }
-    
-    return true;
-}
-
-static void cf_input_stack_object_free(StackObject *tos)
-{
-    if (tos->h) {
-        g_hash_table_unref(tos->h);
-    }
-
-    g_free(tos);
-}
-
-static void cf_input_pop(Visitor *v, void **obj)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    StackObject *tos = QSLIST_FIRST(&qiv->stack);
-
-    assert(tos && tos->qapi == obj);
-    QSLIST_REMOVE_HEAD(&qiv->stack, node);
-    cf_input_stack_object_free(tos);
-}
-
-static bool cf_input_start_struct(Visitor *v, const char *name, void **obj,
-                                       size_t size, Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    CFTypeRef cfobj = cf_input_get_object(qiv, name, true, errp);
-
-    if (obj) {
-        *obj = NULL;
-    }
-    if (!cfobj) {
-        return false;
-    }
-    if (CFGetTypeID(cfobj) != CFDictionaryGetTypeID()) {
-        error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
-                   full_name(qiv, name), "object");
-        return false;
-    }
-
-    cf_input_push(qiv, name, cfobj, obj);
-
-    if (obj) {
-        *obj = g_malloc0(size);
-    }
-    
-    return true;
-}
-
-static void cf_input_end_struct(Visitor *v, void **obj)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    StackObject *tos = QSLIST_FIRST(&qiv->stack);
-
-    assert(CFGetTypeID(tos->obj) == CFDictionaryGetTypeID() && tos->h);
-    cf_input_pop(v, obj);
-}
-
-
-static bool cf_input_start_list(Visitor *v, const char *name,
-                                     GenericList **list, size_t size,
-                                     Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    CFTypeRef cfobj = cf_input_get_object(qiv, name, true, errp);
-
-    if (list) {
-        *list = NULL;
-    }
-    if (!cfobj) {
-        return false;
-    }
-    if (CFGetTypeID(cfobj) != CFArrayGetTypeID()) {
-        error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
-                   full_name(qiv, name), "array");
-        return false;
-    }
-
-    cf_input_push(qiv, name, cfobj, list);
-    if (list) {
-        *list = g_malloc0(size);
-    }
-    
-    return true;
-}
-
-static GenericList *cf_input_next_list(Visitor *v, GenericList *tail,
-                                            size_t size)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    StackObject *tos = QSLIST_FIRST(&qiv->stack);
-
-    assert(tos && CFGetTypeID(tos->obj) == CFArrayGetTypeID());
-
-    if (tos->index == tos->count) {
-        return NULL;
-    }
-    tail->next = g_malloc0(size);
-    return tail->next;
-}
-
-static bool cf_input_check_list(Visitor *v, Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    StackObject *tos = QSLIST_FIRST(&qiv->stack);
-
-    assert(tos && CFGetTypeID(tos->obj) == CFArrayGetTypeID());
-
-    if (tos->index != tos->count) {
-        error_setg(errp, "Only %u list elements expected in %s",
-                   (unsigned)tos->index + 1, full_name_nth(qiv, NULL, 1));
-        return false;
-    }
-    
-    return true;
-}
-
-static void cf_input_end_list(Visitor *v, void **obj)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    StackObject *tos = QSLIST_FIRST(&qiv->stack);
-
-    assert(CFGetTypeID(tos->obj) == CFArrayGetTypeID() && !tos->h);
-    cf_input_pop(v, obj);
-}
-
-static bool cf_input_start_alternate(Visitor *v, const char *name,
-                                          GenericAlternate **obj, size_t size,
-                                          Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    CFTypeRef cfobj = cf_input_get_object(qiv, name, false, errp);
-
-    if (!cfobj) {
-        *obj = NULL;
-        return false;
-    }
-    *obj = g_malloc0(size);
-    (*obj)->type = CFGetTypeID(cfobj);
-    
-    return true;
-}
-
-static bool cf_input_type_int64(Visitor *v, const char *name, int64_t *obj,
-                                     Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    CFTypeRef cfobj = cf_input_get_object(qiv, name, true, errp);
-    CFNumberRef cfnum;
-
-    if (!cfobj) {
-        return false;
-    }
-    cfnum = (CFNumberRef)cfobj;
-    if (CFGetTypeID(cfobj) != CFNumberGetTypeID() || 
-        !CFNumberGetValue(cfnum, kCFNumberSInt64Type, obj)) {
-        error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
-                   full_name(qiv, name), "integer");
-        return false;
-    }
-    
-    return true;
-}
-
-static bool cf_input_type_uint64(Visitor *v, const char *name,
-                                      uint64_t *obj, Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    CFTypeRef cfobj = cf_input_get_object(qiv, name, true, errp);
-    CFNumberRef cfnum;
-    int64_t val;
-
-    if (!cfobj) {
-        return false;
-    }
-    cfnum = (CFNumberRef)cfobj;
-    if (CFGetTypeID(cfobj) != CFNumberGetTypeID()) {
-        goto err;
-    }
-
-    if (!CFNumberGetValue(cfnum, kCFNumberSInt64Type, &val)) {
-        return false;
-    }
-    
-    *obj = val;
-    // FIXME: CFNumber doesn't work with uint64_t!
-
-    return true;
-err:
-    error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-               full_name(qiv, name), "uint64");
-    return false;
-}
-
-static bool cf_input_type_bool(Visitor *v, const char *name, bool *obj,
-                                    Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    CFTypeRef cfobj = cf_input_get_object(qiv, name, true, errp);
-    CFBooleanRef cfbool;
-
-    if (!cfobj) {
-        return false;
-    }
-    cfbool = (CFBooleanRef)cfobj;
-    if (CFGetTypeID(cfobj) != CFBooleanGetTypeID()) {
-        error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
-                   full_name(qiv, name), "boolean");
-        return false;
-    }
-
-    *obj = CFBooleanGetValue(cfbool);
-    
-    return true;
-}
-
-static bool cf_input_type_str(Visitor *v, const char *name, char **obj,
-                                   Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    CFTypeRef cfobj = cf_input_get_object(qiv, name, true, errp);
-    CFStringRef cfstr;
-    const char *str;
-
-    *obj = NULL;
-    if (!cfobj) {
-        return false;
-    }
-    cfstr = (CFStringRef)cfobj;
-    if (CFGetTypeID(cfobj) != CFStringGetTypeID()) {
-        error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
-                   full_name(qiv, name), "string");
-        return false;
-    }
-        
-    str = CFStringGetCStringPtr(cfstr, CFStringGetFastestEncoding(cfstr));
-    if (str == NULL) {
-        CFIndex length = CFStringGetLength(cfstr);
-        CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
-        char *buffer = (char *)g_malloc(maxSize);
-        if (!CFStringGetCString(cfstr, buffer, maxSize, kCFStringEncodingUTF8)) {
-            error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
-                       full_name(qiv, name), "string");
-            g_free(buffer);
-            return false;
-        } else {
-            *obj = buffer;
-        }
-    } else {
-        *obj = g_strdup(str);
-    }
-    return true;
-}
-
-static bool cf_input_type_number(Visitor *v, const char *name, double *obj,
-                                      Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    CFTypeRef cfobj = cf_input_get_object(qiv, name, true, errp);
-    CFNumberRef cfnum;
-
-    if (!cfobj) {
-        return false;
-    }
-    cfnum = (CFNumberRef)cfobj;
-    if (CFGetTypeID(cfobj) != CFNumberGetTypeID() || !CFNumberIsFloatType(cfnum)) {
-        error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
-                   full_name(qiv, name), "number");
-        return false;
-    }
-
-    CFNumberGetValue(cfnum, kCFNumberDoubleType, obj);
-    return true;
-}
-
-static bool cf_input_type_any(Visitor *v, const char *name, CFTypeRef *obj,
-                                   Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    CFTypeRef cfobj = cf_input_get_object(qiv, name, true, errp);
-
-    *obj = NULL;
-    if (!cfobj) {
-        return false;
-    }
-
-    *obj = CFRetain(cfobj);
-    return true;
-}
-
-static bool cf_input_type_null(Visitor *v, const char *name,
-                                    CFNullRef *obj, Error **errp)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    CFTypeRef cfobj = cf_input_get_object(qiv, name, true, errp);
-
-    *obj = NULL;
-    if (!cfobj) {
-        return false;
-    }
-
-    if (CFGetTypeID(cfobj) != CFNullGetTypeID()) {
-        error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
-                   full_name(qiv, name), "null");
-        return false;
-    }
-    *obj = kCFNull;
-    return true;
-}
-
-static void cf_input_optional(Visitor *v, const char *name, bool *present)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-    CFTypeRef cfobj = cf_input_try_get_object(qiv, name, false);
-
-    if (!cfobj) {
-        *present = false;
-        return;
-    }
-
-    *present = true;
-}
-
-static void cf_input_free(Visitor *v)
-{
-    CFObjectInputVisitor *qiv = to_qiv(v);
-
-    while (!QSLIST_EMPTY(&qiv->stack)) {
-        StackObject *tos = QSLIST_FIRST(&qiv->stack);
-
-        QSLIST_REMOVE_HEAD(&qiv->stack, node);
-        cf_input_stack_object_free(tos);
-    }
-
-    CFRelease(qiv->root);
-    if (qiv->errname) {
-        g_string_free(qiv->errname, true);
-    }
-    g_free(qiv);
-}
-
-static CFObjectInputVisitor *cf_input_visitor_base_new(CFTypeRef obj)
-{
-    CFObjectInputVisitor *v = g_malloc0(sizeof(*v));
-
-    assert(obj);
-
-    v->visitor.type = VISITOR_INPUT;
-    v->visitor.start_struct = cf_input_start_struct;
-    v->visitor.check_struct = cf_input_check_struct;
-    v->visitor.end_struct = cf_input_end_struct;
-    v->visitor.start_list = cf_input_start_list;
-    v->visitor.next_list = cf_input_next_list;
-    v->visitor.check_list = cf_input_check_list;
-    v->visitor.end_list = cf_input_end_list;
-    v->visitor.start_alternate = cf_input_start_alternate;
-    v->visitor.optional = cf_input_optional;
-    v->visitor.free = cf_input_free;
-
-    v->root = CFRetain(obj);
-
-    return v;
-}
-
-Visitor *cf_input_visitor_new(CFTypeRef obj)
-{
-    CFObjectInputVisitor *v = cf_input_visitor_base_new(obj);
-
-    v->visitor.type_int64 = cf_input_type_int64;
-    v->visitor.type_uint64 = cf_input_type_uint64;
-    v->visitor.type_bool = cf_input_type_bool;
-    v->visitor.type_str = cf_input_type_str;
-    v->visitor.type_number = cf_input_type_number;
-    v->visitor.type_any = cf_input_type_any;
-    v->visitor.type_null = cf_input_type_null;
-
-    return &v->visitor;
-}

+ 0 - 63
qapi/cf-input-visitor.h

@@ -1,63 +0,0 @@
-/*
- * Input Visitor
- *
- * Copyright (C) 2017 Red Hat, Inc.
- * Copyright IBM, Corp. 2011
- * Copyright (C) 2019 osy
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *  osy             <dev@getutm.app>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef CF_INPUT_VISITOR_H
-#define CF_INPUT_VISITOR_H
-
-#include "visitor.h"
-
-typedef struct CFObjectInputVisitor CFObjectInputVisitor;
-
-/*
- * Create a CoreFoundation input visitor for @obj
- *
- * A CFType input visitor visit builds a QAPI object from a CFType.
- * This simultaneously walks the QAPI object being built and the
- * CFType.  The latter walk starts at @obj.
- *
- * visit_type_FOO() creates an instance of QAPI type FOO.  The visited
- * CFType must match FOO.  CFDictionary matches struct/union types, 
- * CFArray matches list types, CFString matches type 'str' and enumeration
- * types, CFNumber matches integer and float types, CFBoolean matches type
- * 'bool'.  Type 'any' is matched by CFType.  A QAPI alternate type
- * is matched when one of its member types is.
- *
- * visit_start_struct() ... visit_end_struct() visits a CFDictionary and
- * creates a QAPI struct/union.  Visits in between visit the
- * dictionary members.  visit_optional() is true when the CFDictionary has
- * this member.  visit_check_struct() fails if unvisited members
- * remain.
- *
- * visit_start_list() ... visit_end_list() visits a CFArray and creates
- * a QAPI list.  Visits in between visit list members, one after the
- * other.  visit_next_list() returns NULL when all CFArray members have
- * been visited.  visit_check_list() fails if unvisited members
- * remain.
- *
- * visit_start_alternate() ... visit_end_alternate() visits a CFType
- * and creates a QAPI alternate.  The visit in between visits the same
- * CFType and initializes the alternate member that is in use.
- *
- * Error messages refer to parts of @obj in JavaScript/Python syntax.
- * For example, 'a.b[2]' refers to the second member of the CFArray
- * member 'b' of the CFDictionary member 'a' of CFDictionary @obj.
- *
- * The caller is responsible for freeing the visitor with
- * visit_free().
- */
-Visitor *cf_input_visitor_new(CFTypeRef obj);
-
-#endif

+ 0 - 264
qapi/cf-output-visitor.c

@@ -1,264 +0,0 @@
-/*
- * Core Definitions for QAPI/QMP Command Registry
- *
- * Copyright (C) 2012-2016 Red Hat, Inc.
- * Copyright IBM, Corp. 2011
- * Copyright (C) 2019 osy
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *  osy             <dev@getutm.app>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qemu-compat.h"
-#include "visitor-impl.h"
-#include "queue.h"
-#include "cf-output-visitor.h"
-
-typedef struct QStackEntry {
-    CFTypeRef value;
-    void *qapi; /* sanity check that caller uses same pointer */
-    QSLIST_ENTRY(QStackEntry) node;
-} QStackEntry;
-
-struct CFObjectOutputVisitor {
-    Visitor visitor;
-    QSLIST_HEAD(, QStackEntry) stack; /* Stack of unfinished containers */
-    CFTypeRef root; /* Root of the output visit */
-    CFTypeRef *result; /* User's storage location for result */
-};
-
-#define cf_output_add(qov, name, value) \
-    cf_output_add_obj(qov, name, (CFTypeRef)(value))
-#define cf_output_push(qov, value, qapi) \
-    cf_output_push_obj(qov, (CFTypeRef)(value), qapi)
-
-static CFObjectOutputVisitor *to_qov(Visitor *v)
-{
-    return container_of(v, CFObjectOutputVisitor, visitor);
-}
-
-/* Push @value onto the stack of current CFType being built */
-static void cf_output_push_obj(CFObjectOutputVisitor *qov, CFTypeRef value,
-                                    void *qapi)
-{
-    QStackEntry *e = g_malloc0(sizeof(*e));
-
-    assert(qov->root);
-    assert(value);
-    e->value = value;
-    e->qapi = qapi;
-    QSLIST_INSERT_HEAD(&qov->stack, e, node);
-}
-
-/* Pop a value off the stack of CFType being built, and return it. */
-static CFTypeRef cf_output_pop(CFObjectOutputVisitor *qov, void *qapi)
-{
-    QStackEntry *e = QSLIST_FIRST(&qov->stack);
-    CFTypeRef value;
-
-    assert(e);
-    assert(e->qapi == qapi);
-    QSLIST_REMOVE_HEAD(&qov->stack, node);
-    value = e->value;
-    assert(value);
-    g_free(e);
-    return value;
-}
-
-/* Add @value to the current CFType being built.
- * If the stack is visiting a dictionary or list, @value is now owned
- * by that container. Otherwise, @value is now the root.  */
-static void cf_output_add_obj(CFObjectOutputVisitor *qov, const char *name,
-                                   CFTypeRef value)
-{
-    QStackEntry *e = QSLIST_FIRST(&qov->stack);
-    CFTypeRef cur = e ? e->value : NULL;
-    CFStringRef cfname;
-
-    if (!cur) {
-        /* Don't allow reuse of visitor on more than one root */
-        assert(!qov->root);
-        qov->root = value;
-    } else {
-        if (CFGetTypeID(cur) == CFDictionaryGetTypeID()) {
-            assert(name);
-            cfname = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingUTF8);
-            CFDictionaryAddValue((CFMutableDictionaryRef)cur, cfname, value);
-            CFRelease(cfname);
-            CFRelease(value); // now retained by dictionary
-        } else {
-            assert(CFGetTypeID(cur) == CFArrayGetTypeID());
-            assert(!name);
-            CFArrayAppendValue((CFMutableArrayRef)cur, value);
-            CFRelease(value); // now retained by array
-        }
-    }
-}
-
-static bool cf_output_start_struct(Visitor *v, const char *name,
-                                        void **obj, size_t unused, Error **errp)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-
-    cf_output_add(qov, name, dict);
-    cf_output_push(qov, dict, obj);
-    return true;
-}
-
-static void cf_output_end_struct(Visitor *v, void **obj)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-    CFTypeRef value = cf_output_pop(qov, obj);
-    assert(CFGetTypeID(value) == CFDictionaryGetTypeID());
-}
-
-static bool cf_output_start_list(Visitor *v, const char *name,
-                                      GenericList **listp, size_t size,
-                                      Error **errp)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-    CFMutableArrayRef list = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-
-    cf_output_add(qov, name, list);
-    cf_output_push(qov, list, listp);
-    return true;
-}
-
-static GenericList *cf_output_next_list(Visitor *v, GenericList *tail,
-                                             size_t size)
-{
-    return tail->next;
-}
-
-static void cf_output_end_list(Visitor *v, void **obj)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-    CFTypeRef value = cf_output_pop(qov, obj);
-    assert(CFGetTypeID(value) == CFArrayGetTypeID());
-}
-
-static bool cf_output_type_int64(Visitor *v, const char *name,
-                                      int64_t *obj, Error **errp)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-    cf_output_add(qov, name, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, obj));
-    return true;
-}
-
-static bool cf_output_type_uint64(Visitor *v, const char *name,
-                                       uint64_t *obj, Error **errp)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-    // FIXME: CFNumber does not support uint64_t
-    cf_output_add(qov, name, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, obj));
-    return true;
-}
-
-static bool cf_output_type_bool(Visitor *v, const char *name, bool *obj,
-                                     Error **errp)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-    cf_output_add(qov, name, *obj ? kCFBooleanTrue : kCFBooleanFalse);
-    return true;
-}
-
-static bool cf_output_type_str(Visitor *v, const char *name, char **obj,
-                                    Error **errp)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-    if (*obj) {
-        cf_output_add(qov, name, CFStringCreateWithCString(kCFAllocatorDefault, *obj, kCFStringEncodingUTF8));
-    } else {
-        cf_output_add(qov, name, CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8));
-    }
-    return true;
-}
-
-static bool cf_output_type_number(Visitor *v, const char *name,
-                                       double *obj, Error **errp)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-    cf_output_add(qov, name, CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, obj));
-    return true;
-}
-
-static bool cf_output_type_any(Visitor *v, const char *name,
-                                    CFTypeRef *obj, Error **errp)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-
-    cf_output_add_obj(qov, name, CFRetain(*obj));
-    return true;
-}
-
-static bool cf_output_type_null(Visitor *v, const char *name,
-                                     CFNullRef *obj, Error **errp)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-    cf_output_add(qov, name, kCFNull);
-    return true;
-}
-
-/* Finish building, and return the root object.
- * The root object is never null. The caller becomes the object's
- * owner, and should use CFRelease() when done with it.  */
-static void cf_output_complete(Visitor *v, void *opaque)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-
-    /* A visit must have occurred, with each start paired with end.  */
-    assert(qov->root && QSLIST_EMPTY(&qov->stack));
-    assert(opaque == qov->result);
-
-    *qov->result = CFRetain(qov->root);
-    qov->result = NULL;
-}
-
-static void cf_output_free(Visitor *v)
-{
-    CFObjectOutputVisitor *qov = to_qov(v);
-    QStackEntry *e;
-
-    while (!QSLIST_EMPTY(&qov->stack)) {
-        e = QSLIST_FIRST(&qov->stack);
-        QSLIST_REMOVE_HEAD(&qov->stack, node);
-        g_free(e);
-    }
-
-    CFRelease(qov->root);
-    g_free(qov);
-}
-
-Visitor *cf_output_visitor_new(CFTypeRef *result)
-{
-    CFObjectOutputVisitor *v;
-
-    v = g_malloc0(sizeof(*v));
-
-    v->visitor.type = VISITOR_OUTPUT;
-    v->visitor.start_struct = cf_output_start_struct;
-    v->visitor.end_struct = cf_output_end_struct;
-    v->visitor.start_list = cf_output_start_list;
-    v->visitor.next_list = cf_output_next_list;
-    v->visitor.end_list = cf_output_end_list;
-    v->visitor.type_int64 = cf_output_type_int64;
-    v->visitor.type_uint64 = cf_output_type_uint64;
-    v->visitor.type_bool = cf_output_type_bool;
-    v->visitor.type_str = cf_output_type_str;
-    v->visitor.type_number = cf_output_type_number;
-    v->visitor.type_any = cf_output_type_any;
-    v->visitor.type_null = cf_output_type_null;
-    v->visitor.complete = cf_output_complete;
-    v->visitor.free = cf_output_free;
-
-    *result = NULL;
-    v->result = result;
-
-    return &v->visitor;
-}

+ 0 - 60
qapi/cf-output-visitor.h

@@ -1,60 +0,0 @@
-/*
- * Output Visitor
- *
- * Copyright IBM, Corp. 2011
- * Copyright (C) 2019 osy
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *  osy             <dev@getutm.app>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef CF_OUTPUT_VISITOR_H
-#define CF_OUTPUT_VISITOR_H
-
-#include "visitor.h"
-
-typedef struct CFObjectOutputVisitor CFObjectOutputVisitor;
-
-/**
- * Create a CoreFoundation output visitor for @obj
- *
- * A CFType output visitor visit builds a CFType from QAPI Object.
- * This simultaneously walks the QAPI object and the CFType being
- * built.  The latter walk starts at @obj.
- *
- * visit_type_FOO() creates a CFType for QAPI type FOO.  It creates a
- * CFMutableDictionary for struct/union types, a CFMutableArray for 
- * list types, CFString for type 'str' and enumeration types, 
- * CFNumber for integer and float types, CFBoolean for type 'bool'. 
- * For type 'any', it increments the CFType's reference count. 
- * For QAPI alternate types, it creates the CFType for the member 
- * that is in use.
- *
- * visit_start_struct() ... visit_end_struct() visits a QAPI
- * struct/union and creates a CFMutableDictionary.  Visits in between 
- * visit the members.  visit_optional() is true when the struct/union 
- * has this member.  visit_check_struct() does nothing.
- *
- * visit_start_list() ... visit_end_list() visits a QAPI list and
- * creates a CFMutableArray.  Visits in between visit list members, 
- * one after the other.  visit_next_list() returns NULL when all 
- * QAPI list members have been visited.  visit_check_list() does 
- * nothing.
- *
- * visit_start_alternate() ... visit_end_alternate() visits a QAPI
- * alternate.  The visit in between creates the CFType for the
- * alternate member that is in use.
- *
- * Errors are not expected to happen.
- *
- * The caller is responsible for freeing the visitor with
- * visit_free().
- */
-Visitor *cf_output_visitor_new(CFTypeRef *result);
-
-#endif

+ 0 - 28
qapi/dealloc-visitor.h

@@ -1,28 +0,0 @@
-/*
- * Dealloc Visitor
- *
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- *  Michael Roth   <mdroth@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QAPI_DEALLOC_VISITOR_H
-#define QAPI_DEALLOC_VISITOR_H
-
-#include "visitor.h"
-
-typedef struct QapiDeallocVisitor QapiDeallocVisitor;
-
-/*
- * The dealloc visitor is primarily used only by generated
- * qapi_free_FOO() functions, and is the only visitor designed to work
- * correctly in the face of a partially-constructed QAPI tree.
- */
-Visitor *qapi_dealloc_visitor_new(void);
-
-#endif

+ 0 - 306
qapi/error.c

@@ -1,306 +0,0 @@
-/*
- * QEMU Error Objects
- *
- * Copyright IBM, Corp. 2011
- * Copyright (C) 2011-2015 Red Hat, Inc.
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *  Markus Armbruster <armbru@redhat.com>,
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.  See
- * the COPYING.LIB file in the top-level directory.
- */
-
-#include "qemu-compat.h"
-#include "error.h"
-
-#define error_printf(...) fprintf(stderr, __VA_ARGS__)
-
-struct Error
-{
-    char *msg;
-    ErrorClass err_class;
-    const char *src, *func;
-    int line;
-    GString *hint;
-};
-
-Error *error_abort;
-Error *error_fatal;
-
-static void error_handle_fatal(Error **errp, Error *err)
-{
-    if (errp == &error_abort) {
-        fprintf(stderr, "Unexpected error in %s() at %s:%d:\n",
-                err->func, err->src, err->line);
-        error_report("%s", error_get_pretty(err));
-        if (err->hint) {
-            error_printf("%s", err->hint->str);
-        }
-        abort();
-    }
-    if (errp == &error_fatal) {
-        error_report_err(err);
-        exit(1);
-    }
-}
-
-static void error_setv(Error **errp,
-                       const char *src, int line, const char *func,
-                       ErrorClass err_class, const char *fmt, va_list ap,
-                       const char *suffix)
-{
-    Error *err;
-    int saved_errno = errno;
-
-    if (errp == NULL) {
-        return;
-    }
-    assert(*errp == NULL);
-
-    err = g_malloc0(sizeof(*err));
-    err->msg = g_strdup_vprintf(fmt, ap);
-    if (suffix) {
-        char *msg = err->msg;
-        err->msg = g_strdup_printf("%s: %s", msg, suffix);
-        g_free(msg);
-    }
-    err->err_class = err_class;
-    err->src = src;
-    err->line = line;
-    err->func = func;
-
-    error_handle_fatal(errp, err);
-    *errp = err;
-
-    errno = saved_errno;
-}
-
-void error_set_internal(Error **errp,
-                        const char *src, int line, const char *func,
-                        ErrorClass err_class, const char *fmt, ...)
-{
-    va_list ap;
-
-    va_start(ap, fmt);
-    error_setv(errp, src, line, func, err_class, fmt, ap, NULL);
-    va_end(ap);
-}
-
-void error_setg_internal(Error **errp,
-                         const char *src, int line, const char *func,
-                         const char *fmt, ...)
-{
-    va_list ap;
-
-    va_start(ap, fmt);
-    error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap, NULL);
-    va_end(ap);
-}
-
-void error_setg_errno_internal(Error **errp,
-                               const char *src, int line, const char *func,
-                               int os_errno, const char *fmt, ...)
-{
-    va_list ap;
-    int saved_errno = errno;
-
-    va_start(ap, fmt);
-    error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR, fmt, ap,
-               os_errno != 0 ? strerror(os_errno) : NULL);
-    va_end(ap);
-
-    errno = saved_errno;
-}
-
-void error_setg_file_open_internal(Error **errp,
-                                   const char *src, int line, const char *func,
-                                   int os_errno, const char *filename)
-{
-    error_setg_errno_internal(errp, src, line, func, os_errno,
-                              "Could not open '%s'", filename);
-}
-
-void error_vprepend(Error *const *errp, const char *fmt, va_list ap)
-{
-    GString *newmsg;
-
-    if (!errp) {
-        return;
-    }
-
-    newmsg = g_string_new(NULL);
-    g_string_vprintf(newmsg, fmt, ap);
-    g_string_append(newmsg, (*errp)->msg);
-    g_free((*errp)->msg);
-    (*errp)->msg = g_string_free(newmsg, 0);
-}
-
-void error_prepend(Error *const *errp, const char *fmt, ...)
-{
-    va_list ap;
-
-    va_start(ap, fmt);
-    error_vprepend(errp, fmt, ap);
-    va_end(ap);
-}
-
-void error_append_hint(Error *const *errp, const char *fmt, ...)
-{
-    va_list ap;
-    int saved_errno = errno;
-    Error *err;
-
-    if (!errp) {
-        return;
-    }
-    err = *errp;
-    assert(err && errp != &error_abort && errp != &error_fatal);
-
-    if (!err->hint) {
-        err->hint = g_string_new(NULL);
-    }
-    va_start(ap, fmt);
-    g_string_append_vprintf(err->hint, fmt, ap);
-    va_end(ap);
-
-    errno = saved_errno;
-}
-
-#ifdef _WIN32
-
-void error_setg_win32_internal(Error **errp,
-                               const char *src, int line, const char *func,
-                               int win32_err, const char *fmt, ...)
-{
-    va_list ap;
-    char *suffix = NULL;
-
-    if (errp == NULL) {
-        return;
-    }
-
-    if (win32_err != 0) {
-        suffix = g_win32_error_message(win32_err);
-    }
-
-    va_start(ap, fmt);
-    error_setv(errp, src, line, func, ERROR_CLASS_GENERIC_ERROR,
-               fmt, ap, suffix);
-    va_end(ap);
-
-    g_free(suffix);
-}
-
-#endif
-
-Error *error_copy(const Error *err)
-{
-    Error *err_new;
-
-    err_new = g_malloc0(sizeof(*err));
-    err_new->msg = g_strdup(err->msg);
-    err_new->err_class = err->err_class;
-    err_new->src = err->src;
-    err_new->line = err->line;
-    err_new->func = err->func;
-    if (err->hint) {
-        err_new->hint = g_string_new(err->hint->str);
-    }
-
-    return err_new;
-}
-
-ErrorClass error_get_class(const Error *err)
-{
-    return err->err_class;
-}
-
-const char *error_get_pretty(const Error *err)
-{
-    return err->msg;
-}
-
-void error_report_err(Error *err)
-{
-    error_report("%s", error_get_pretty(err));
-    if (err->hint) {
-        error_printf("%s", err->hint->str);
-    }
-    error_free(err);
-}
-
-void warn_report_err(Error *err)
-{
-    warn_report("%s", error_get_pretty(err));
-    if (err->hint) {
-        error_printf("%s", err->hint->str);
-    }
-    error_free(err);
-}
-
-void error_reportf_err(Error *err, const char *fmt, ...)
-{
-    va_list ap;
-
-    va_start(ap, fmt);
-    error_vprepend(&err, fmt, ap);
-    va_end(ap);
-    error_report_err(err);
-}
-
-
-void warn_reportf_err(Error *err, const char *fmt, ...)
-{
-    va_list ap;
-
-    va_start(ap, fmt);
-    error_vprepend(&err, fmt, ap);
-    va_end(ap);
-    warn_report_err(err);
-}
-
-void error_free(Error *err)
-{
-    if (err) {
-        g_free(err->msg);
-        if (err->hint) {
-            g_string_free(err->hint, true);
-        }
-        g_free(err);
-    }
-}
-
-void error_free_or_abort(Error **errp)
-{
-    assert(errp && *errp);
-    error_free(*errp);
-    *errp = NULL;
-}
-
-void error_propagate(Error **dst_errp, Error *local_err)
-{
-    if (!local_err) {
-        return;
-    }
-    error_handle_fatal(dst_errp, local_err);
-    if (dst_errp && !*dst_errp) {
-        *dst_errp = local_err;
-    } else {
-        error_free(local_err);
-    }
-}
-
-void error_propagate_prepend(Error **dst_errp, Error *err,
-                             const char *fmt, ...)
-{
-    va_list ap;
-
-    if (dst_errp && !*dst_errp) {
-        va_start(ap, fmt);
-        error_vprepend(&err, fmt, ap);
-        va_end(ap);
-    } /* else error is being ignored, don't bother with prepending */
-    error_propagate(dst_errp, err);
-}

+ 0 - 534
qapi/error.h

@@ -1,534 +0,0 @@
-/*
- * QEMU Error Objects
- *
- * Copyright IBM, Corp. 2011
- * Copyright (C) 2011-2015 Red Hat, Inc.
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *  Markus Armbruster <armbru@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.  See
- * the COPYING.LIB file in the top-level directory.
- */
-
-/*
- * Error reporting system loosely patterned after Glib's GError.
- *
- * = Rules =
- *
- * - Functions that use Error to report errors have an Error **errp
- *   parameter.  It should be the last parameter, except for functions
- *   taking variable arguments.
- *
- * - You may pass NULL to not receive the error, &error_abort to abort
- *   on error, &error_fatal to exit(1) on error, or a pointer to a
- *   variable containing NULL to receive the error.
- *
- * - Separation of concerns: the function is responsible for detecting
- *   errors and failing cleanly; handling the error is its caller's
- *   job.  Since the value of @errp is about handling the error, the
- *   function should not examine it.
- *
- * - The function may pass @errp to functions it calls to pass on
- *   their errors to its caller.  If it dereferences @errp to check
- *   for errors, it must use ERRP_GUARD().
- *
- * - On success, the function should not touch *errp.  On failure, it
- *   should set a new error, e.g. with error_setg(errp, ...), or
- *   propagate an existing one, e.g. with error_propagate(errp, ...).
- *
- * - Whenever practical, also return a value that indicates success /
- *   failure.  This can make the error checking more concise, and can
- *   avoid useless error object creation and destruction.  Note that
- *   we still have many functions returning void.  We recommend
- *   • bool-valued functions return true on success / false on failure,
- *   • pointer-valued functions return non-null / null pointer, and
- *   • integer-valued functions return non-negative / negative.
- *
- * = Creating errors =
- *
- * Create an error:
- *     error_setg(errp, "situation normal, all fouled up");
- * where @errp points to the location to receive the error.
- *
- * Create an error and add additional explanation:
- *     error_setg(errp, "invalid quark");
- *     error_append_hint(errp, "Valid quarks are up, down, strange, "
- *                       "charm, top, bottom.\n");
- * This may require use of ERRP_GUARD(); more on that below.
- *
- * Do *not* contract this to
- *     error_setg(errp, "invalid quark\n" // WRONG!
- *                "Valid quarks are up, down, strange, charm, top, bottom.");
- *
- * = Reporting and destroying errors =
- *
- * Report an error to the current monitor if we have one, else stderr:
- *     error_report_err(err);
- * This frees the error object.
- *
- * Likewise, but with additional text prepended:
- *     error_reportf_err(err, "Could not frobnicate '%s': ", name);
- *
- * Report an error somewhere else:
- *     const char *msg = error_get_pretty(err);
- *     do with msg what needs to be done...
- *     error_free(err);
- * Note that this loses hints added with error_append_hint().
- *
- * Call a function ignoring errors:
- *     foo(arg, NULL);
- * This is more concise than
- *     Error *err = NULL;
- *     foo(arg, &err);
- *     error_free(err); // don't do this
- *
- * Call a function aborting on errors:
- *     foo(arg, &error_abort);
- * This is more concise and fails more nicely than
- *     Error *err = NULL;
- *     foo(arg, &err);
- *     assert(!err); // don't do this
- *
- * Call a function treating errors as fatal:
- *     foo(arg, &error_fatal);
- * This is more concise than
- *     Error *err = NULL;
- *     foo(arg, &err);
- *     if (err) { // don't do this
- *         error_report_err(err);
- *         exit(1);
- *     }
- *
- * Handle an error without reporting it (just for completeness):
- *     error_free(err);
- *
- * Assert that an expected error occurred, but clean it up without
- * reporting it (primarily useful in testsuites):
- *     error_free_or_abort(&err);
- *
- * = Passing errors around =
- *
- * Errors get passed to the caller through the conventional @errp
- * parameter.
- *
- * Create a new error and pass it to the caller:
- *     error_setg(errp, "situation normal, all fouled up");
- *
- * Call a function, receive an error from it, and pass it to the caller
- * - when the function returns a value that indicates failure, say
- *   false:
- *     if (!foo(arg, errp)) {
- *         handle the error...
- *     }
- * - when it does not, say because it is a void function:
- *     ERRP_GUARD();
- *     foo(arg, errp);
- *     if (*errp) {
- *         handle the error...
- *     }
- * More on ERRP_GUARD() below.
- *
- * Code predating ERRP_GUARD() still exists, and looks like this:
- *     Error *err = NULL;
- *     foo(arg, &err);
- *     if (err) {
- *         handle the error...
- *         error_propagate(errp, err); // deprecated
- *     }
- * Avoid in new code.  Do *not* "optimize" it to
- *     foo(arg, errp);
- *     if (*errp) { // WRONG!
- *         handle the error...
- *     }
- * because errp may be NULL without the ERRP_GUARD() guard.
- *
- * But when all you do with the error is pass it on, please use
- *     foo(arg, errp);
- * for readability.
- *
- * Receive an error, and handle it locally
- * - when the function returns a value that indicates failure, say
- *   false:
- *     Error *err = NULL;
- *     if (!foo(arg, &err)) {
- *         handle the error...
- *     }
- * - when it does not, say because it is a void function:
- *     Error *err = NULL;
- *     foo(arg, &err);
- *     if (err) {
- *         handle the error...
- *     }
- *
- * Pass an existing error to the caller:
- *     error_propagate(errp, err);
- * This is rarely needed.  When @err is a local variable, use of
- * ERRP_GUARD() commonly results in more readable code.
- *
- * Pass an existing error to the caller with the message modified:
- *     error_propagate_prepend(errp, err,
- *                             "Could not frobnicate '%s': ", name);
- * This is more concise than
- *     error_propagate(errp, err); // don't do this
- *     error_prepend(errp, "Could not frobnicate '%s': ", name);
- * and works even when @errp is &error_fatal.
- *
- * Receive and accumulate multiple errors (first one wins):
- *     Error *err = NULL, *local_err = NULL;
- *     foo(arg, &err);
- *     bar(arg, &local_err);
- *     error_propagate(&err, local_err);
- *     if (err) {
- *         handle the error...
- *     }
- *
- * Do *not* "optimize" this to
- *     Error *err = NULL;
- *     foo(arg, &err);
- *     bar(arg, &err); // WRONG!
- *     if (err) {
- *         handle the error...
- *     }
- * because this may pass a non-null err to bar().
- *
- * Likewise, do *not*
- *     Error *err = NULL;
- *     if (cond1) {
- *         error_setg(&err, ...);
- *     }
- *     if (cond2) {
- *         error_setg(&err, ...); // WRONG!
- *     }
- * because this may pass a non-null err to error_setg().
- *
- * = Why, when and how to use ERRP_GUARD() =
- *
- * Without ERRP_GUARD(), use of the @errp parameter is restricted:
- * - It must not be dereferenced, because it may be null.
- * - It should not be passed to error_prepend() or
- *   error_append_hint(), because that doesn't work with &error_fatal.
- * ERRP_GUARD() lifts these restrictions.
- *
- * To use ERRP_GUARD(), add it right at the beginning of the function.
- * @errp can then be used without worrying about the argument being
- * NULL or &error_fatal.
- *
- * Using it when it's not needed is safe, but please avoid cluttering
- * the source with useless code.
- *
- * = Converting to ERRP_GUARD() =
- *
- * To convert a function to use ERRP_GUARD():
- *
- * 0. If the Error ** parameter is not named @errp, rename it to
- *    @errp.
- *
- * 1. Add an ERRP_GUARD() invocation, by convention right at the
- *    beginning of the function.  This makes @errp safe to use.
- *
- * 2. Replace &err by errp, and err by *errp.  Delete local variable
- *    @err.
- *
- * 3. Delete error_propagate(errp, *errp), replace
- *    error_propagate_prepend(errp, *errp, ...) by error_prepend(errp, ...)
- *
- * 4. Ensure @errp is valid at return: when you destroy *errp, set
- *    errp = NULL.
- *
- * Example:
- *
- *     bool fn(..., Error **errp)
- *     {
- *         Error *err = NULL;
- *
- *         foo(arg, &err);
- *         if (err) {
- *             handle the error...
- *             error_propagate(errp, err);
- *             return false;
- *         }
- *         ...
- *     }
- *
- * becomes
- *
- *     bool fn(..., Error **errp)
- *     {
- *         ERRP_GUARD();
- *
- *         foo(arg, errp);
- *         if (*errp) {
- *             handle the error...
- *             return false;
- *         }
- *         ...
- *     }
- *
- * For mass-conversion, use scripts/coccinelle/errp-guard.cocci.
- */
-
-#ifndef ERROR_H
-#define ERROR_H
-
-#include "qapi-types-error.h"
-
-/*
- * Overall category of an error.
- * Based on the qapi type QapiErrorClass, but reproduced here for nicer
- * enum names.
- */
-typedef enum ErrorClass {
-    ERROR_CLASS_GENERIC_ERROR = QAPI_ERROR_CLASS_GENERICERROR,
-    ERROR_CLASS_COMMAND_NOT_FOUND = QAPI_ERROR_CLASS_COMMANDNOTFOUND,
-    ERROR_CLASS_DEVICE_NOT_ACTIVE = QAPI_ERROR_CLASS_DEVICENOTACTIVE,
-    ERROR_CLASS_DEVICE_NOT_FOUND = QAPI_ERROR_CLASS_DEVICENOTFOUND,
-    ERROR_CLASS_KVM_MISSING_CAP = QAPI_ERROR_CLASS_KVMMISSINGCAP,
-} ErrorClass;
-
-/*
- * Get @err's human-readable error message.
- */
-const char *error_get_pretty(const Error *err);
-
-/*
- * Get @err's error class.
- * Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is
- * strongly discouraged.
- */
-ErrorClass error_get_class(const Error *err);
-
-/*
- * Create a new error object and assign it to *@errp.
- * If @errp is NULL, the error is ignored.  Don't bother creating one
- * then.
- * If @errp is &error_abort, print a suitable message and abort().
- * If @errp is &error_fatal, print a suitable message and exit(1).
- * If @errp is anything else, *@errp must be NULL.
- * The new error's class is ERROR_CLASS_GENERIC_ERROR, and its
- * human-readable error message is made from printf-style @fmt, ...
- * The resulting message should be a single phrase, with no newline or
- * trailing punctuation.
- * Please don't error_setg(&error_fatal, ...), use error_report() and
- * exit(), because that's more obvious.
- * Likewise, don't error_setg(&error_abort, ...), use assert().
- */
-#define error_setg(errp, fmt, ...)                              \
-    error_setg_internal((errp), __FILE__, __LINE__, __func__,   \
-                        (fmt), ## __VA_ARGS__)
-void error_setg_internal(Error **errp,
-                         const char *src, int line, const char *func,
-                         const char *fmt, ...)
-    GCC_FMT_ATTR(5, 6);
-
-/*
- * Just like error_setg(), with @os_error info added to the message.
- * If @os_error is non-zero, ": " + strerror(os_error) is appended to
- * the human-readable error message.
- *
- * The value of errno (which usually can get clobbered by almost any
- * function call) will be preserved.
- */
-#define error_setg_errno(errp, os_error, fmt, ...)                      \
-    error_setg_errno_internal((errp), __FILE__, __LINE__, __func__,     \
-                              (os_error), (fmt), ## __VA_ARGS__)
-void error_setg_errno_internal(Error **errp,
-                               const char *fname, int line, const char *func,
-                               int os_error, const char *fmt, ...)
-    GCC_FMT_ATTR(6, 7);
-
-#ifdef _WIN32
-/*
- * Just like error_setg(), with @win32_error info added to the message.
- * If @win32_error is non-zero, ": " + g_win32_error_message(win32_err)
- * is appended to the human-readable error message.
- */
-#define error_setg_win32(errp, win32_err, fmt, ...)                     \
-    error_setg_win32_internal((errp), __FILE__, __LINE__, __func__,     \
-                              (win32_err), (fmt), ## __VA_ARGS__)
-void error_setg_win32_internal(Error **errp,
-                               const char *src, int line, const char *func,
-                               int win32_err, const char *fmt, ...)
-    GCC_FMT_ATTR(6, 7);
-#endif
-
-/*
- * Propagate error object (if any) from @local_err to @dst_errp.
- * If @local_err is NULL, do nothing (because there's nothing to
- * propagate).
- * Else, if @dst_errp is NULL, errors are being ignored.  Free the
- * error object.
- * Else, if @dst_errp is &error_abort, print a suitable message and
- * abort().
- * Else, if @dst_errp is &error_fatal, print a suitable message and
- * exit(1).
- * Else, if @dst_errp already contains an error, ignore this one: free
- * the error object.
- * Else, move the error object from @local_err to *@dst_errp.
- * On return, @local_err is invalid.
- * Please use ERRP_GUARD() instead when possible.
- * Please don't error_propagate(&error_fatal, ...), use
- * error_report_err() and exit(), because that's more obvious.
- */
-void error_propagate(Error **dst_errp, Error *local_err);
-
-
-/*
- * Propagate error object (if any) with some text prepended.
- * Behaves like
- *     error_prepend(&local_err, fmt, ...);
- *     error_propagate(dst_errp, local_err);
- * Please use ERRP_GUARD() and error_prepend() instead when possible.
- */
-void error_propagate_prepend(Error **dst_errp, Error *local_err,
-                             const char *fmt, ...)
-    GCC_FMT_ATTR(3, 4);
-
-/*
- * Prepend some text to @errp's human-readable error message.
- * The text is made by formatting @fmt, @ap like vprintf().
- */
-void error_vprepend(Error *const *errp, const char *fmt, va_list ap)
-    GCC_FMT_ATTR(2, 0);
-
-/*
- * Prepend some text to @errp's human-readable error message.
- * The text is made by formatting @fmt, ... like printf().
- */
-void error_prepend(Error *const *errp, const char *fmt, ...)
-    GCC_FMT_ATTR(2, 3);
-
-/*
- * Append a printf-style human-readable explanation to an existing error.
- * If the error is later reported to a human user with
- * error_report_err() or warn_report_err(), the hints will be shown,
- * too.  If it's reported via QMP, the hints will be ignored.
- * Intended use is adding helpful hints on the human user interface,
- * e.g. a list of valid values.  It's not for clarifying a confusing
- * error message.
- * @errp may be NULL, but not &error_fatal or &error_abort.
- * Trivially the case if you call it only after error_setg() or
- * error_propagate().
- * May be called multiple times.  The resulting hint should end with a
- * newline.
- */
-void error_append_hint(Error *const *errp, const char *fmt, ...)
-    GCC_FMT_ATTR(2, 3);
-
-/*
- * Convenience function to report open() failure.
- */
-#define error_setg_file_open(errp, os_errno, filename)                  \
-    error_setg_file_open_internal((errp), __FILE__, __LINE__, __func__, \
-                                  (os_errno), (filename))
-void error_setg_file_open_internal(Error **errp,
-                                   const char *src, int line, const char *func,
-                                   int os_errno, const char *filename);
-
-/*
- * Return an exact copy of @err.
- */
-Error *error_copy(const Error *err);
-
-/*
- * Free @err.
- * @err may be NULL.
- */
-void error_free(Error *err);
-
-/*
- * Convenience function to assert that *@errp is set, then silently free it.
- */
-void error_free_or_abort(Error **errp);
-
-/*
- * Convenience function to warn_report() and free @err.
- * The report includes hints added with error_append_hint().
- */
-void warn_report_err(Error *err);
-
-/*
- * Convenience function to error_report() and free @err.
- * The report includes hints added with error_append_hint().
- */
-void error_report_err(Error *err);
-
-/*
- * Convenience function to error_prepend(), warn_report() and free @err.
- */
-void warn_reportf_err(Error *err, const char *fmt, ...)
-    GCC_FMT_ATTR(2, 3);
-
-/*
- * Convenience function to error_prepend(), error_report() and free @err.
- */
-void error_reportf_err(Error *err, const char *fmt, ...)
-    GCC_FMT_ATTR(2, 3);
-
-/*
- * Just like error_setg(), except you get to specify the error class.
- * Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is
- * strongly discouraged.
- */
-#define error_set(errp, err_class, fmt, ...)                    \
-    error_set_internal((errp), __FILE__, __LINE__, __func__,    \
-                       (err_class), (fmt), ## __VA_ARGS__)
-void error_set_internal(Error **errp,
-                        const char *src, int line, const char *func,
-                        ErrorClass err_class, const char *fmt, ...)
-    GCC_FMT_ATTR(6, 7);
-
-/*
- * Make @errp parameter easier to use regardless of argument value
- *
- * This macro is for use right at the beginning of a function that
- * takes an Error **errp parameter to pass errors to its caller.  The
- * parameter must be named @errp.
- *
- * It must be used when the function dereferences @errp or passes
- * @errp to error_prepend(), error_vprepend(), or error_append_hint().
- * It is safe to use even when it's not needed, but please avoid
- * cluttering the source with useless code.
- *
- * If @errp is NULL or &error_fatal, rewrite it to point to a local
- * Error variable, which will be automatically propagated to the
- * original @errp on function exit.
- *
- * Note: &error_abort is not rewritten, because that would move the
- * abort from the place where the error is created to the place where
- * it's propagated.
- */
-#define ERRP_GUARD()                                            \
-    g_auto(ErrorPropagator) _auto_errp_prop = {.errp = errp};   \
-    do {                                                        \
-        if (!errp || errp == &error_fatal) {                    \
-            errp = &_auto_errp_prop.local_err;                  \
-        }                                                       \
-    } while (0)
-
-typedef struct ErrorPropagator {
-    Error *local_err;
-    Error **errp;
-} ErrorPropagator;
-
-static inline void error_propagator_cleanup(ErrorPropagator *prop)
-{
-    error_propagate(prop->errp, prop->local_err);
-}
-
-G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(ErrorPropagator, error_propagator_cleanup);
-
-/*
- * Special error destination to abort on error.
- * See error_setg() and error_propagate() for details.
- */
-extern Error *error_abort;
-
-/*
- * Special error destination to exit(1) on error.
- * See error_setg() and error_propagate() for details.
- */
-extern Error *error_fatal;
-
-#endif

+ 0 - 139
qapi/qapi-dealloc-visitor.c

@@ -1,139 +0,0 @@
-/*
- * Dealloc Visitor
- *
- * Copyright (C) 2012-2016 Red Hat, Inc.
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- *  Michael Roth   <mdroth@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "dealloc-visitor.h"
-#include "queue.h"
-#include "visitor-impl.h"
-
-struct QapiDeallocVisitor
-{
-    Visitor visitor;
-};
-
-static bool qapi_dealloc_start_struct(Visitor *v, const char *name, void **obj,
-                                      size_t unused, Error **errp)
-{
-    return true;
-}
-
-static void qapi_dealloc_end_struct(Visitor *v, void **obj)
-{
-    if (obj) {
-        g_free(*obj);
-    }
-}
-
-static void qapi_dealloc_end_alternate(Visitor *v, void **obj)
-{
-    if (obj) {
-        g_free(*obj);
-    }
-}
-
-static bool qapi_dealloc_start_list(Visitor *v, const char *name,
-                                    GenericList **list, size_t size,
-                                    Error **errp)
-{
-    return true;
-}
-
-static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList *tail,
-                                           size_t size)
-{
-    GenericList *next = tail->next;
-    g_free(tail);
-    return next;
-}
-
-static void qapi_dealloc_end_list(Visitor *v, void **obj)
-{
-}
-
-static bool qapi_dealloc_type_str(Visitor *v, const char *name, char **obj,
-                                  Error **errp)
-{
-    if (obj) {
-        g_free(*obj);
-    }
-    return true;
-}
-
-static bool qapi_dealloc_type_int64(Visitor *v, const char *name, int64_t *obj,
-                                    Error **errp)
-{
-    return true;
-}
-
-static bool qapi_dealloc_type_uint64(Visitor *v, const char *name,
-                                     uint64_t *obj, Error **errp)
-{
-    return true;
-}
-
-static bool qapi_dealloc_type_bool(Visitor *v, const char *name, bool *obj,
-                                   Error **errp)
-{
-    return true;
-}
-
-static bool qapi_dealloc_type_number(Visitor *v, const char *name, double *obj,
-                                     Error **errp)
-{
-    return true;
-}
-
-static bool qapi_dealloc_type_anything(Visitor *v, const char *name,
-                                       CFTypeRef *obj, Error **errp)
-{
-    if (obj) {
-        CFRelease(*obj);
-    }
-    return true;
-}
-
-static bool qapi_dealloc_type_null(Visitor *v, const char *name,
-                                   CFNullRef *obj, Error **errp)
-{
-    return true;
-}
-
-static void qapi_dealloc_free(Visitor *v)
-{
-    g_free(container_of(v, QapiDeallocVisitor, visitor));
-}
-
-Visitor *qapi_dealloc_visitor_new(void)
-{
-    QapiDeallocVisitor *v;
-
-    v = g_malloc0(sizeof(*v));
-
-    v->visitor.type = VISITOR_DEALLOC;
-    v->visitor.start_struct = qapi_dealloc_start_struct;
-    v->visitor.end_struct = qapi_dealloc_end_struct;
-    v->visitor.end_alternate = qapi_dealloc_end_alternate;
-    v->visitor.start_list = qapi_dealloc_start_list;
-    v->visitor.next_list = qapi_dealloc_next_list;
-    v->visitor.end_list = qapi_dealloc_end_list;
-    v->visitor.type_int64 = qapi_dealloc_type_int64;
-    v->visitor.type_uint64 = qapi_dealloc_type_uint64;
-    v->visitor.type_bool = qapi_dealloc_type_bool;
-    v->visitor.type_str = qapi_dealloc_type_str;
-    v->visitor.type_number = qapi_dealloc_type_number;
-    v->visitor.type_any = qapi_dealloc_type_anything;
-    v->visitor.type_null = qapi_dealloc_type_null;
-    v->visitor.free = qapi_dealloc_free;
-
-    return &v->visitor;
-}

+ 0 - 87
qapi/qapi-util.c

@@ -1,87 +0,0 @@
-/*
- * QAPI util functions
- *
- * Authors:
- *  Hu Tao       <hutao@cn.fujitsu.com>
- *  Peter Lieven <pl@kamp.de>
- * 
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qemu-compat.h"
-#include "error.h"
-
-const char *qapi_enum_lookup(const QEnumLookup *lookup, int val)
-{
-    assert(val >= 0 && val < lookup->size);
-
-    return lookup->array[val];
-}
-
-int qapi_enum_parse(const QEnumLookup *lookup, const char *buf,
-                    int def, Error **errp)
-{
-    int i;
-
-    if (!buf) {
-        return def;
-    }
-
-    for (i = 0; i < lookup->size; i++) {
-        if (!strcmp(buf, lookup->array[i])) {
-            return i;
-        }
-    }
-
-    error_setg(errp, "invalid parameter value: %s", buf);
-    return def;
-}
-
-/*
- * Parse a valid QAPI name from @str.
- * A valid name consists of letters, digits, hyphen and underscore.
- * It may be prefixed by __RFQDN_ (downstream extension), where RFQDN
- * may contain only letters, digits, hyphen and period.
- * The special exception for enumeration names is not implemented.
- * See docs/devel/qapi-code-gen.txt for more on QAPI naming rules.
- * Keep this consistent with scripts/qapi.py!
- * If @complete, the parse fails unless it consumes @str completely.
- * Return its length on success, -1 on failure.
- */
-int parse_qapi_name(const char *str, bool complete)
-{
-    const char *p = str;
-
-    if (*p == '_') {            /* Downstream __RFQDN_ */
-        p++;
-        if (*p != '_') {
-            return -1;
-        }
-        while (*++p) {
-            if (!isalnum(*p) && *p != '-' && *p != '.') {
-                break;
-            }
-        }
-
-        if (*p != '_') {
-            return -1;
-        }
-        p++;
-    }
-
-    if (!isalpha(*p)) {
-        return -1;
-    }
-    while (*++p) {
-        if (!isalnum(*p) && *p != '-' && *p != '_') {
-            break;
-        }
-    }
-
-    if (complete && *p) {
-        return -1;
-    }
-    return (int)(p - str);
-}

+ 0 - 431
qapi/qapi-visit-core.c

@@ -1,431 +0,0 @@
-/*
- * Core Definitions for QAPI Visitor Classes
- *
- * Copyright (C) 2012-2016 Red Hat, Inc.
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#include "qemu-compat.h"
-#include "qerror.h"
-#include "error.h"
-#include "visitor.h"
-#include "visitor-impl.h"
-
-void visit_complete(Visitor *v, void *opaque)
-{
-    assert(v->type != VISITOR_OUTPUT || v->complete);
-    trace_visit_complete(v, opaque);
-    if (v->complete) {
-        v->complete(v, opaque);
-    }
-}
-
-void visit_free(Visitor *v)
-{
-    trace_visit_free(v);
-    if (v) {
-        v->free(v);
-    }
-}
-
-bool visit_start_struct(Visitor *v, const char *name, void **obj,
-                        size_t size, Error **errp)
-{
-    bool ok;
-
-    trace_visit_start_struct(v, name, obj, size);
-    if (obj) {
-        assert(size);
-        assert(!(v->type & VISITOR_OUTPUT) || *obj);
-    }
-    ok = v->start_struct(v, name, obj, size, errp);
-    if (obj && (v->type & VISITOR_INPUT)) {
-        assert(ok != !*obj);
-    }
-    return ok;
-}
-
-bool visit_check_struct(Visitor *v, Error **errp)
-{
-    trace_visit_check_struct(v);
-    return v->check_struct ? v->check_struct(v, errp) : true;
-}
-
-void visit_end_struct(Visitor *v, void **obj)
-{
-    trace_visit_end_struct(v, obj);
-    v->end_struct(v, obj);
-}
-
-bool visit_start_list(Visitor *v, const char *name, GenericList **list,
-                      size_t size, Error **errp)
-{
-    bool ok;
-
-    assert(!list || size >= sizeof(GenericList));
-    trace_visit_start_list(v, name, list, size);
-    ok = v->start_list(v, name, list, size, errp);
-    if (list && (v->type & VISITOR_INPUT)) {
-        assert(ok || !*list);
-    }
-    return ok;
-}
-
-GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size)
-{
-    assert(tail && size >= sizeof(GenericList));
-    trace_visit_next_list(v, tail, size);
-    return v->next_list(v, tail, size);
-}
-
-bool visit_check_list(Visitor *v, Error **errp)
-{
-    trace_visit_check_list(v);
-    return v->check_list ? v->check_list(v, errp) : true;
-}
-
-void visit_end_list(Visitor *v, void **obj)
-{
-    trace_visit_end_list(v, obj);
-    v->end_list(v, obj);
-}
-
-bool visit_start_alternate(Visitor *v, const char *name,
-                           GenericAlternate **obj, size_t size,
-                           Error **errp)
-{
-    bool ok;
-
-    assert(obj && size >= sizeof(GenericAlternate));
-    assert(!(v->type & VISITOR_OUTPUT) || *obj);
-    trace_visit_start_alternate(v, name, obj, size);
-    if (!v->start_alternate) {
-        assert(!(v->type & VISITOR_INPUT));
-        return true;
-    }
-    ok = v->start_alternate(v, name, obj, size, errp);
-    if (v->type & VISITOR_INPUT) {
-        assert(ok != !*obj);
-    }
-    return ok;
-}
-
-void visit_end_alternate(Visitor *v, void **obj)
-{
-    trace_visit_end_alternate(v, obj);
-    if (v->end_alternate) {
-        v->end_alternate(v, obj);
-    }
-}
-
-bool visit_optional(Visitor *v, const char *name, bool *present)
-{
-    trace_visit_optional(v, name, present);
-    if (v->optional) {
-        v->optional(v, name, present);
-    }
-    return *present;
-}
-
-bool visit_policy_reject(Visitor *v, const char *name,
-                         unsigned special_features, Error **errp)
-{
-    trace_visit_policy_reject(v, name);
-    if (v->policy_reject) {
-        return v->policy_reject(v, name, special_features, errp);
-    }
-    return false;
-}
-
-bool visit_policy_skip(Visitor *v, const char *name,
-                       unsigned special_features)
-{
-    trace_visit_policy_skip(v, name);
-    if (v->policy_skip) {
-        return v->policy_skip(v, name, special_features);
-    }
-    return false;
-}
-
-void visit_set_policy(Visitor *v, CompatPolicy *policy)
-{
-    v->compat_policy = *policy;
-}
-
-bool visit_is_input(Visitor *v)
-{
-    return v->type == VISITOR_INPUT;
-}
-
-bool visit_is_dealloc(Visitor *v)
-{
-    return v->type == VISITOR_DEALLOC;
-}
-
-bool visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp)
-{
-    assert(obj);
-    trace_visit_type_int(v, name, obj);
-    return v->type_int64(v, name, obj, errp);
-}
-
-static bool visit_type_uintN(Visitor *v, uint64_t *obj, const char *name,
-                             uint64_t max, const char *type, Error **errp)
-{
-    uint64_t value = *obj;
-
-    assert(v->type == VISITOR_INPUT || value <= max);
-
-    if (!v->type_uint64(v, name, &value, errp)) {
-        return false;
-    }
-    if (value > max) {
-        assert(v->type == VISITOR_INPUT);
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                   name ? name : "null", type);
-        return false;
-    }
-    *obj = value;
-    return true;
-}
-
-bool visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
-                      Error **errp)
-{
-    uint64_t value;
-    bool ok;
-
-    trace_visit_type_uint8(v, name, obj);
-    value = *obj;
-    ok = visit_type_uintN(v, &value, name, UINT8_MAX, "uint8_t", errp);
-    *obj = value;
-    return ok;
-}
-
-bool visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
-                       Error **errp)
-{
-    uint64_t value;
-    bool ok;
-
-    trace_visit_type_uint16(v, name, obj);
-    value = *obj;
-    ok = visit_type_uintN(v, &value, name, UINT16_MAX, "uint16_t", errp);
-    *obj = value;
-    return ok;
-}
-
-bool visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
-                       Error **errp)
-{
-    uint64_t value;
-    bool ok;
-
-    trace_visit_type_uint32(v, name, obj);
-    value = *obj;
-    ok = visit_type_uintN(v, &value, name, UINT32_MAX, "uint32_t", errp);
-    *obj = (uint32_t)value;
-    return ok;
-}
-
-bool visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
-                       Error **errp)
-{
-    assert(obj);
-    trace_visit_type_uint64(v, name, obj);
-    return v->type_uint64(v, name, obj, errp);
-}
-
-static bool visit_type_intN(Visitor *v, int64_t *obj, const char *name,
-                            int64_t min, int64_t max, const char *type,
-                            Error **errp)
-{
-    int64_t value = *obj;
-
-    assert(v->type == VISITOR_INPUT || (value >= min && value <= max));
-
-    if (!v->type_int64(v, name, &value, errp)) {
-        return false;
-    }
-    if (value < min || value > max) {
-        assert(v->type == VISITOR_INPUT);
-        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                   name ? name : "null", type);
-        return false;
-    }
-    *obj = value;
-    return true;
-}
-
-bool visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp)
-{
-    int64_t value;
-    bool ok;
-
-    trace_visit_type_int8(v, name, obj);
-    value = *obj;
-    ok = visit_type_intN(v, &value, name, INT8_MIN, INT8_MAX, "int8_t", errp);
-    *obj = value;
-    return ok;
-}
-
-bool visit_type_int16(Visitor *v, const char *name, int16_t *obj,
-                      Error **errp)
-{
-    int64_t value;
-    bool ok;
-
-    trace_visit_type_int16(v, name, obj);
-    value = *obj;
-    ok = visit_type_intN(v, &value, name, INT16_MIN, INT16_MAX, "int16_t",
-                         errp);
-    *obj = value;
-    return ok;
-}
-
-bool visit_type_int32(Visitor *v, const char *name, int32_t *obj,
-                      Error **errp)
-{
-    int64_t value;
-    bool ok;
-
-    trace_visit_type_int32(v, name, obj);
-    value = *obj;
-    ok = visit_type_intN(v, &value, name, INT32_MIN, INT32_MAX, "int32_t",
-                        errp);
-    *obj = (int32_t)value;
-    return ok;
-}
-
-bool visit_type_int64(Visitor *v, const char *name, int64_t *obj,
-                      Error **errp)
-{
-    assert(obj);
-    trace_visit_type_int64(v, name, obj);
-    return v->type_int64(v, name, obj, errp);
-}
-
-bool visit_type_size(Visitor *v, const char *name, uint64_t *obj,
-                     Error **errp)
-{
-    assert(obj);
-    trace_visit_type_size(v, name, obj);
-    if (v->type_size) {
-        return v->type_size(v, name, obj, errp);
-    }
-    return v->type_uint64(v, name, obj, errp);
-}
-
-bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
-{
-    assert(obj);
-    trace_visit_type_bool(v, name, obj);
-    return v->type_bool(v, name, obj, errp);
-}
-
-bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp)
-{
-    bool ok;
-
-    assert(obj);
-    /* TODO: Fix callers to not pass NULL when they mean "", so that we
-     * can enable:
-    assert(!(v->type & VISITOR_OUTPUT) || *obj);
-     */
-    trace_visit_type_str(v, name, obj);
-    ok = v->type_str(v, name, obj, errp);
-    if (v->type & VISITOR_INPUT) {
-        assert(ok != !*obj);
-    }
-    return ok;
-}
-
-bool visit_type_number(Visitor *v, const char *name, double *obj,
-                       Error **errp)
-{
-    assert(obj);
-    trace_visit_type_number(v, name, obj);
-    return v->type_number(v, name, obj, errp);
-}
-
-bool visit_type_any(Visitor *v, const char *name, CFTypeRef *obj, Error **errp)
-{
-    bool ok;
-
-    assert(obj);
-    assert(v->type != VISITOR_OUTPUT || *obj);
-    trace_visit_type_any(v, name, obj);
-    ok = v->type_any(v, name, obj, errp);
-    if (v->type == VISITOR_INPUT) {
-        assert(ok != !*obj);
-    }
-    return ok;
-}
-
-bool visit_type_null(Visitor *v, const char *name, CFNullRef *obj,
-                     Error **errp)
-{
-    trace_visit_type_null(v, name, obj);
-    return v->type_null(v, name, obj, errp);
-}
-
-static bool output_type_enum(Visitor *v, const char *name, int *obj,
-                             const QEnumLookup *lookup, Error **errp)
-{
-    int value = *obj;
-    char *enum_str;
-
-    enum_str = (char *)qapi_enum_lookup(lookup, value);
-    return visit_type_str(v, name, &enum_str, errp);
-}
-
-static bool input_type_enum(Visitor *v, const char *name, int *obj,
-                            const QEnumLookup *lookup, Error **errp)
-{
-    int64_t value;
-    char *enum_str;
-
-    if (!visit_type_str(v, name, &enum_str, errp)) {
-        return false;
-    }
-
-    value = qapi_enum_parse(lookup, enum_str, -1, NULL);
-    if (value < 0) {
-        error_setg(errp, QERR_INVALID_PARAMETER, enum_str);
-        g_free(enum_str);
-        return false;
-    }
-
-    g_free(enum_str);
-    *obj = (int)value;
-    return true;
-}
-
-bool visit_type_enum(Visitor *v, const char *name, int *obj,
-                     const QEnumLookup *lookup, Error **errp)
-{
-    assert(obj && lookup);
-    trace_visit_type_enum(v, name, obj);
-    switch (v->type) {
-    case VISITOR_INPUT:
-        return input_type_enum(v, name, obj, lookup, errp);
-    case VISITOR_OUTPUT:
-        return output_type_enum(v, name, obj, lookup, errp);
-    case VISITOR_CLONE:
-        /* nothing further to do, scalar value was already copied by
-         * g_memdup() during visit_start_*() */
-        return true;
-    case VISITOR_DEALLOC:
-        /* nothing to deallocate for a scalar */
-        return true;
-    default:
-        abort();
-    }
-}

+ 0 - 79
qapi/qemu-compat.h

@@ -1,79 +0,0 @@
-//
-// Copyright © 2019 osy. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef qemu_compat_h
-#define qemu_compat_h
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <glib.h>
-
-typedef struct Error Error;
-typedef struct Visitor Visitor;
-
-#ifndef container_of
-#define container_of(ptr, type, member) ({                      \
-        const typeof(((type *) 0)->member) *__mptr = (ptr);     \
-        (type *) ((char *) __mptr - offsetof(type, member));})
-#endif
-
-#define error_report(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
-#define warn_report(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
-#define error_printf_unless_qmp(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
-
-#define trace_visit_complete(...)
-#define trace_visit_free(...)
-#define trace_visit_start_struct(...)
-#define trace_visit_check_struct(...)
-#define trace_visit_end_struct(...)
-#define trace_visit_start_list(...)
-#define trace_visit_next_list(...)
-#define trace_visit_check_list(...)
-#define trace_visit_end_list(...)
-#define trace_visit_start_alternate(...)
-#define trace_visit_end_alternate(...)
-#define trace_visit_optional(...)
-#define trace_visit_type_int(...)
-#define trace_visit_type_uint8(...)
-#define trace_visit_type_uint16(...)
-#define trace_visit_type_uint32(...)
-#define trace_visit_type_uint64(...)
-#define trace_visit_type_int8(...)
-#define trace_visit_type_int16(...)
-#define trace_visit_type_int32(...)
-#define trace_visit_type_int64(...)
-#define trace_visit_type_size(...)
-#define trace_visit_type_bool(...)
-#define trace_visit_type_str(...)
-#define trace_visit_type_number(...)
-#define trace_visit_type_any(...)
-#define trace_visit_type_null(...)
-#define trace_visit_type_enum(...)
-#define trace_visit_policy_reject(...)
-#define trace_visit_policy_skip(...)
-
-void qmp_rpc_call(CFDictionaryRef args, CFDictionaryRef *ret, Error **err, void *ctx);
-
-// TODO: make this match with qemu build
-#define CONFIG_SPICE 1
-#define CONFIG_VNC 1
-#define TARGET_I386 1
-
-#define GCC_FMT_ATTR(n, m)
-
-#endif /* qemu_compat_h */

+ 0 - 94
qapi/qerror.h

@@ -1,94 +0,0 @@
-/*
- * QError Module
- *
- * Copyright (C) 2009 Red Hat Inc.
- *
- * Authors:
- *  Luiz Capitulino <lcapitulino@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-#ifndef QERROR_H
-#define QERROR_H
-
-/*
- * These macros will go away, please don't use in new code, and do not
- * add new ones!
- */
-#define QERR_BASE_NOT_FOUND \
-    "Base '%s' not found"
-
-#define QERR_BUS_NO_HOTPLUG \
-    "Bus '%s' does not support hotplugging"
-
-#define QERR_DEVICE_HAS_NO_MEDIUM \
-    "Device '%s' has no medium"
-
-#define QERR_DEVICE_INIT_FAILED \
-    "Device '%s' could not be initialized"
-
-#define QERR_DEVICE_IN_USE \
-    "Device '%s' is in use"
-
-#define QERR_DEVICE_NO_HOTPLUG \
-    "Device '%s' does not support hotplugging"
-
-#define QERR_FD_NOT_FOUND \
-    "File descriptor named '%s' not found"
-
-#define QERR_FD_NOT_SUPPLIED \
-    "No file descriptor supplied via SCM_RIGHTS"
-
-#define QERR_FEATURE_DISABLED \
-    "The feature '%s' is not enabled"
-
-#define QERR_INVALID_BLOCK_FORMAT \
-    "Invalid block format '%s'"
-
-#define QERR_INVALID_PARAMETER \
-    "Invalid parameter '%s'"
-
-#define QERR_INVALID_PARAMETER_TYPE \
-    "Invalid parameter type for '%s', expected: %s"
-
-#define QERR_INVALID_PARAMETER_VALUE \
-    "Parameter '%s' expects %s"
-
-#define QERR_INVALID_PASSWORD \
-    "Password incorrect"
-
-#define QERR_IO_ERROR \
-    "An IO error has occurred"
-
-#define QERR_MIGRATION_ACTIVE \
-    "There's a migration process in progress"
-
-#define QERR_MISSING_PARAMETER \
-    "Parameter '%s' is missing"
-
-#define QERR_PERMISSION_DENIED \
-    "Insufficient permission to perform this operation"
-
-#define QERR_PROPERTY_VALUE_BAD \
-    "Property '%s.%s' doesn't take value '%s'"
-
-#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
-    "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", maximum: %" PRId64 ")"
-
-#define QERR_QGA_COMMAND_FAILED \
-    "Guest agent command failed, error was '%s'"
-
-#define QERR_REPLAY_NOT_SUPPORTED \
-    "Record/replay feature is not supported for '%s'"
-
-#define QERR_SET_PASSWD_FAILED \
-    "Could not set password"
-
-#define QERR_UNDEFINED_ERROR \
-    "An undefined error has occurred"
-
-#define QERR_UNSUPPORTED \
-    "this feature or command is not currently supported"
-
-#endif /* QERROR_H */

+ 0 - 575
qapi/queue.h

@@ -1,575 +0,0 @@
-/*      $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
-
-/*
- * QEMU version: Copy from netbsd, removed debug code, removed some of
- * the implementations.  Left in singly-linked lists, lists, simple
- * queues, and tail queues.
- */
-
-/*
- * Copyright (c) 1991, 1993
- *      The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *      @(#)queue.h     8.5 (Berkeley) 8/20/94
- */
-
-#ifndef QEMU_SYS_QUEUE_H
-#define QEMU_SYS_QUEUE_H
-
-/*
- * This file defines four types of data structures: singly-linked lists,
- * lists, simple queues, and tail queues.
- *
- * A singly-linked list is headed by a single forward pointer. The
- * elements are singly linked for minimum space and pointer manipulation
- * overhead at the expense of O(n) removal for arbitrary elements. New
- * elements can be added to the list after an existing element or at the
- * head of the list.  Elements being removed from the head of the list
- * should use the explicit macro for this purpose for optimum
- * efficiency. A singly-linked list may only be traversed in the forward
- * direction.  Singly-linked lists are ideal for applications with large
- * datasets and few or no removals or for implementing a LIFO queue.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A simple queue is headed by a pair of pointers, one the head of the
- * list and the other to the tail of the list. The elements are singly
- * linked to save space, so elements can only be removed from the
- * head of the list. New elements can be added to the list after
- * an existing element, at the head of the list, or at the end of the
- * list. A simple queue may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-/*
- * List definitions.
- */
-#define QLIST_HEAD(name, type)                                          \
-struct name {                                                           \
-        struct type *lh_first;  /* first element */                     \
-}
-
-#define QLIST_HEAD_INITIALIZER(head)                                    \
-        { NULL }
-
-#define QLIST_ENTRY(type)                                               \
-struct {                                                                \
-        struct type *le_next;   /* next element */                      \
-        struct type **le_prev;  /* address of previous next element */  \
-}
-
-/*
- * List functions.
- */
-#define QLIST_INIT(head) do {                                           \
-        (head)->lh_first = NULL;                                        \
-} while (/*CONSTCOND*/0)
-
-#define QLIST_SWAP(dstlist, srclist, field) do {                        \
-        void *tmplist;                                                  \
-        tmplist = (srclist)->lh_first;                                  \
-        (srclist)->lh_first = (dstlist)->lh_first;                      \
-        if ((srclist)->lh_first != NULL) {                              \
-            (srclist)->lh_first->field.le_prev = &(srclist)->lh_first;  \
-        }                                                               \
-        (dstlist)->lh_first = tmplist;                                  \
-        if ((dstlist)->lh_first != NULL) {                              \
-            (dstlist)->lh_first->field.le_prev = &(dstlist)->lh_first;  \
-        }                                                               \
-} while (/*CONSTCOND*/0)
-
-#define QLIST_INSERT_AFTER(listelm, elm, field) do {                    \
-        if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
-                (listelm)->field.le_next->field.le_prev =               \
-                    &(elm)->field.le_next;                              \
-        (listelm)->field.le_next = (elm);                               \
-        (elm)->field.le_prev = &(listelm)->field.le_next;               \
-} while (/*CONSTCOND*/0)
-
-#define QLIST_INSERT_BEFORE(listelm, elm, field) do {                   \
-        (elm)->field.le_prev = (listelm)->field.le_prev;                \
-        (elm)->field.le_next = (listelm);                               \
-        *(listelm)->field.le_prev = (elm);                              \
-        (listelm)->field.le_prev = &(elm)->field.le_next;               \
-} while (/*CONSTCOND*/0)
-
-#define QLIST_INSERT_HEAD(head, elm, field) do {                        \
-        if (((elm)->field.le_next = (head)->lh_first) != NULL)          \
-                (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
-        (head)->lh_first = (elm);                                       \
-        (elm)->field.le_prev = &(head)->lh_first;                       \
-} while (/*CONSTCOND*/0)
-
-#define QLIST_REMOVE(elm, field) do {                                   \
-        if ((elm)->field.le_next != NULL)                               \
-                (elm)->field.le_next->field.le_prev =                   \
-                    (elm)->field.le_prev;                               \
-        *(elm)->field.le_prev = (elm)->field.le_next;                   \
-        (elm)->field.le_next = NULL;                                    \
-        (elm)->field.le_prev = NULL;                                    \
-} while (/*CONSTCOND*/0)
-
-/*
- * Like QLIST_REMOVE() but safe to call when elm is not in a list
- */
-#define QLIST_SAFE_REMOVE(elm, field) do {                              \
-        if ((elm)->field.le_prev != NULL) {                             \
-                if ((elm)->field.le_next != NULL)                       \
-                        (elm)->field.le_next->field.le_prev =           \
-                            (elm)->field.le_prev;                       \
-                *(elm)->field.le_prev = (elm)->field.le_next;           \
-                (elm)->field.le_next = NULL;                            \
-                (elm)->field.le_prev = NULL;                            \
-        }                                                               \
-} while (/*CONSTCOND*/0)
-
-/* Is elm in a list? */
-#define QLIST_IS_INSERTED(elm, field) ((elm)->field.le_prev != NULL)
-
-#define QLIST_FOREACH(var, head, field)                                 \
-        for ((var) = ((head)->lh_first);                                \
-                (var);                                                  \
-                (var) = ((var)->field.le_next))
-
-#define QLIST_FOREACH_SAFE(var, head, field, next_var)                  \
-        for ((var) = ((head)->lh_first);                                \
-                (var) && ((next_var) = ((var)->field.le_next), 1);      \
-                (var) = (next_var))
-
-/*
- * List access methods.
- */
-#define QLIST_EMPTY(head)                ((head)->lh_first == NULL)
-#define QLIST_FIRST(head)                ((head)->lh_first)
-#define QLIST_NEXT(elm, field)           ((elm)->field.le_next)
-
-
-/*
- * Singly-linked List definitions.
- */
-#define QSLIST_HEAD(name, type)                                          \
-struct name {                                                           \
-        struct type *slh_first; /* first element */                     \
-}
-
-#define QSLIST_HEAD_INITIALIZER(head)                                    \
-        { NULL }
-
-#define QSLIST_ENTRY(type)                                               \
-struct {                                                                \
-        struct type *sle_next;  /* next element */                      \
-}
-
-/*
- * Singly-linked List functions.
- */
-#define QSLIST_INIT(head) do {                                           \
-        (head)->slh_first = NULL;                                       \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_INSERT_AFTER(slistelm, elm, field) do {                   \
-        (elm)->field.sle_next = (slistelm)->field.sle_next;             \
-        (slistelm)->field.sle_next = (elm);                             \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_INSERT_HEAD(head, elm, field) do {                        \
-        (elm)->field.sle_next = (head)->slh_first;                       \
-        (head)->slh_first = (elm);                                       \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_INSERT_HEAD_ATOMIC(head, elm, field) do {                     \
-        typeof(elm) save_sle_next;                                           \
-        do {                                                                 \
-            save_sle_next = (elm)->field.sle_next = (head)->slh_first;       \
-        } while (atomic_cmpxchg(&(head)->slh_first, save_sle_next, (elm)) != \
-                 save_sle_next);                                             \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_MOVE_ATOMIC(dest, src) do {                               \
-        (dest)->slh_first = atomic_xchg(&(src)->slh_first, NULL);        \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_REMOVE_HEAD(head, field) do {                             \
-        typeof((head)->slh_first) elm = (head)->slh_first;               \
-        (head)->slh_first = elm->field.sle_next;                         \
-        elm->field.sle_next = NULL;                                      \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_REMOVE_AFTER(slistelm, field) do {                       \
-        typeof(slistelm) next = (slistelm)->field.sle_next;             \
-        (slistelm)->field.sle_next = next->field.sle_next;              \
-        next->field.sle_next = NULL;                                    \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_REMOVE(head, elm, type, field) do {                      \
-    if ((head)->slh_first == (elm)) {                                   \
-        QSLIST_REMOVE_HEAD((head), field);                              \
-    } else {                                                            \
-        struct type *curelm = (head)->slh_first;                        \
-        while (curelm->field.sle_next != (elm))                         \
-            curelm = curelm->field.sle_next;                            \
-        curelm->field.sle_next = curelm->field.sle_next->field.sle_next; \
-        (elm)->field.sle_next = NULL;                                   \
-    }                                                                   \
-} while (/*CONSTCOND*/0)
-
-#define QSLIST_FOREACH(var, head, field)                                 \
-        for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
-
-#define QSLIST_FOREACH_SAFE(var, head, field, tvar)                      \
-        for ((var) = QSLIST_FIRST((head));                               \
-            (var) && ((tvar) = QSLIST_NEXT((var), field), 1);            \
-            (var) = (tvar))
-
-/*
- * Singly-linked List access methods.
- */
-#define QSLIST_EMPTY(head)       ((head)->slh_first == NULL)
-#define QSLIST_FIRST(head)       ((head)->slh_first)
-#define QSLIST_NEXT(elm, field)  ((elm)->field.sle_next)
-
-
-/*
- * Simple queue definitions.
- */
-#define QSIMPLEQ_HEAD(name, type)                                       \
-struct name {                                                           \
-    struct type *sqh_first;    /* first element */                      \
-    struct type **sqh_last;    /* addr of last next element */          \
-}
-
-#define QSIMPLEQ_HEAD_INITIALIZER(head)                                 \
-    { NULL, &(head).sqh_first }
-
-#define QSIMPLEQ_ENTRY(type)                                            \
-struct {                                                                \
-    struct type *sqe_next;    /* next element */                        \
-}
-
-/*
- * Simple queue functions.
- */
-#define QSIMPLEQ_INIT(head) do {                                        \
-    (head)->sqh_first = NULL;                                           \
-    (head)->sqh_last = &(head)->sqh_first;                              \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_INSERT_HEAD(head, elm, field) do {                     \
-    if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)            \
-        (head)->sqh_last = &(elm)->field.sqe_next;                      \
-    (head)->sqh_first = (elm);                                          \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_INSERT_TAIL(head, elm, field) do {                     \
-    (elm)->field.sqe_next = NULL;                                       \
-    *(head)->sqh_last = (elm);                                          \
-    (head)->sqh_last = &(elm)->field.sqe_next;                          \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {           \
-    if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)    \
-        (head)->sqh_last = &(elm)->field.sqe_next;                      \
-    (listelm)->field.sqe_next = (elm);                                  \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_REMOVE_HEAD(head, field) do {                          \
-    typeof((head)->sqh_first) elm = (head)->sqh_first;                  \
-    if (((head)->sqh_first = elm->field.sqe_next) == NULL)              \
-        (head)->sqh_last = &(head)->sqh_first;                          \
-    elm->field.sqe_next = NULL;                                         \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do {            \
-    QSIMPLEQ_INIT(removed);                                             \
-    if (((removed)->sqh_first = (head)->sqh_first) != NULL) {           \
-        if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) {      \
-            (head)->sqh_last = &(head)->sqh_first;                      \
-        }                                                               \
-        (removed)->sqh_last = &(elm)->field.sqe_next;                   \
-        (elm)->field.sqe_next = NULL;                                   \
-    }                                                                   \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_REMOVE(head, elm, type, field) do {                    \
-    if ((head)->sqh_first == (elm)) {                                   \
-        QSIMPLEQ_REMOVE_HEAD((head), field);                            \
-    } else {                                                            \
-        struct type *curelm = (head)->sqh_first;                        \
-        while (curelm->field.sqe_next != (elm))                         \
-            curelm = curelm->field.sqe_next;                            \
-        if ((curelm->field.sqe_next =                                   \
-            curelm->field.sqe_next->field.sqe_next) == NULL)            \
-                (head)->sqh_last = &(curelm)->field.sqe_next;           \
-        (elm)->field.sqe_next = NULL;                                   \
-    }                                                                   \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_FOREACH(var, head, field)                              \
-    for ((var) = ((head)->sqh_first);                                   \
-        (var);                                                          \
-        (var) = ((var)->field.sqe_next))
-
-#define QSIMPLEQ_FOREACH_SAFE(var, head, field, next)                   \
-    for ((var) = ((head)->sqh_first);                                   \
-        (var) && ((next = ((var)->field.sqe_next)), 1);                 \
-        (var) = (next))
-
-#define QSIMPLEQ_CONCAT(head1, head2) do {                              \
-    if (!QSIMPLEQ_EMPTY((head2))) {                                     \
-        *(head1)->sqh_last = (head2)->sqh_first;                        \
-        (head1)->sqh_last = (head2)->sqh_last;                          \
-        QSIMPLEQ_INIT((head2));                                         \
-    }                                                                   \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_PREPEND(head1, head2) do {                             \
-    if (!QSIMPLEQ_EMPTY((head2))) {                                     \
-        *(head2)->sqh_last = (head1)->sqh_first;                        \
-        (head1)->sqh_first = (head2)->sqh_first;                          \
-        QSIMPLEQ_INIT((head2));                                         \
-    }                                                                   \
-} while (/*CONSTCOND*/0)
-
-#define QSIMPLEQ_LAST(head, type, field)                                \
-    (QSIMPLEQ_EMPTY((head)) ?                                           \
-        NULL :                                                          \
-            ((struct type *)(void *)                                    \
-        ((char *)((head)->sqh_last) - offsetof(struct type, field))))
-
-/*
- * Simple queue access methods.
- */
-#define QSIMPLEQ_EMPTY_ATOMIC(head) (atomic_read(&((head)->sqh_first)) == NULL)
-#define QSIMPLEQ_EMPTY(head)        ((head)->sqh_first == NULL)
-#define QSIMPLEQ_FIRST(head)        ((head)->sqh_first)
-#define QSIMPLEQ_NEXT(elm, field)   ((elm)->field.sqe_next)
-
-typedef struct QTailQLink {
-    void *tql_next;
-    struct QTailQLink *tql_prev;
-} QTailQLink;
-
-/*
- * Tail queue definitions.  The union acts as a poor man template, as if
- * it were QTailQLink<type>.
- */
-#define QTAILQ_HEAD(name, type)                                         \
-union name {                                                            \
-        struct type *tqh_first;       /* first element */               \
-        QTailQLink tqh_circ;          /* link for circular backwards list */ \
-}
-
-#define QTAILQ_HEAD_INITIALIZER(head)                                   \
-        { .tqh_circ = { NULL, &(head).tqh_circ } }
-
-#define QTAILQ_ENTRY(type)                                              \
-union {                                                                 \
-        struct type *tqe_next;        /* next element */                \
-        QTailQLink tqe_circ;          /* link for circular backwards list */ \
-}
-
-/*
- * Tail queue functions.
- */
-#define QTAILQ_INIT(head) do {                                          \
-        (head)->tqh_first = NULL;                                       \
-        (head)->tqh_circ.tql_prev = &(head)->tqh_circ;                  \
-} while (/*CONSTCOND*/0)
-
-#define QTAILQ_INSERT_HEAD(head, elm, field) do {                       \
-        if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
-            (head)->tqh_first->field.tqe_circ.tql_prev =                \
-                &(elm)->field.tqe_circ;                                 \
-        else                                                            \
-            (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;         \
-        (head)->tqh_first = (elm);                                      \
-        (elm)->field.tqe_circ.tql_prev = &(head)->tqh_circ;             \
-} while (/*CONSTCOND*/0)
-
-#define QTAILQ_INSERT_TAIL(head, elm, field) do {                       \
-        (elm)->field.tqe_next = NULL;                                   \
-        (elm)->field.tqe_circ.tql_prev = (head)->tqh_circ.tql_prev;     \
-        (head)->tqh_circ.tql_prev->tql_next = (elm);                    \
-        (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;             \
-} while (/*CONSTCOND*/0)
-
-#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do {             \
-        if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
-            (elm)->field.tqe_next->field.tqe_circ.tql_prev =            \
-                &(elm)->field.tqe_circ;                                 \
-        else                                                            \
-            (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;         \
-        (listelm)->field.tqe_next = (elm);                              \
-        (elm)->field.tqe_circ.tql_prev = &(listelm)->field.tqe_circ;    \
-} while (/*CONSTCOND*/0)
-
-#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do {                       \
-        (elm)->field.tqe_circ.tql_prev = (listelm)->field.tqe_circ.tql_prev; \
-        (elm)->field.tqe_next = (listelm);                                   \
-        (listelm)->field.tqe_circ.tql_prev->tql_next = (elm);                \
-        (listelm)->field.tqe_circ.tql_prev = &(elm)->field.tqe_circ;         \
-} while (/*CONSTCOND*/0)
-
-#define QTAILQ_REMOVE(head, elm, field) do {                            \
-        if (((elm)->field.tqe_next) != NULL)                            \
-            (elm)->field.tqe_next->field.tqe_circ.tql_prev =            \
-                (elm)->field.tqe_circ.tql_prev;                         \
-        else                                                            \
-            (head)->tqh_circ.tql_prev = (elm)->field.tqe_circ.tql_prev; \
-        (elm)->field.tqe_circ.tql_prev->tql_next = (elm)->field.tqe_next; \
-        (elm)->field.tqe_circ.tql_prev = NULL;                          \
-        (elm)->field.tqe_circ.tql_next = NULL;                          \
-        (elm)->field.tqe_next = NULL;                                   \
-} while (/*CONSTCOND*/0)
-
-/* remove @left, @right and all elements in between from @head */
-#define QTAILQ_REMOVE_SEVERAL(head, left, right, field) do {            \
-        if (((right)->field.tqe_next) != NULL)                          \
-            (right)->field.tqe_next->field.tqe_circ.tql_prev =          \
-                (left)->field.tqe_circ.tql_prev;                        \
-        else                                                            \
-            (head)->tqh_circ.tql_prev = (left)->field.tqe_circ.tql_prev; \
-        (left)->field.tqe_circ.tql_prev->tql_next = (right)->field.tqe_next; \
-    } while (/*CONSTCOND*/0)
-
-#define QTAILQ_FOREACH(var, head, field)                                \
-        for ((var) = ((head)->tqh_first);                               \
-                (var);                                                  \
-                (var) = ((var)->field.tqe_next))
-
-#define QTAILQ_FOREACH_SAFE(var, head, field, next_var)                 \
-        for ((var) = ((head)->tqh_first);                               \
-                (var) && ((next_var) = ((var)->field.tqe_next), 1);     \
-                (var) = (next_var))
-
-#define QTAILQ_FOREACH_REVERSE(var, head, field)                        \
-        for ((var) = QTAILQ_LAST(head);                                 \
-                (var);                                                  \
-                (var) = QTAILQ_PREV(var, field))
-
-#define QTAILQ_FOREACH_REVERSE_SAFE(var, head, field, prev_var)         \
-        for ((var) = QTAILQ_LAST(head);                                 \
-             (var) && ((prev_var) = QTAILQ_PREV(var, field), 1);        \
-             (var) = (prev_var))
-
-/*
- * Tail queue access methods.
- */
-#define QTAILQ_EMPTY(head)               ((head)->tqh_first == NULL)
-#define QTAILQ_FIRST(head)               ((head)->tqh_first)
-#define QTAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
-#define QTAILQ_IN_USE(elm, field)        ((elm)->field.tqe_circ.tql_prev != NULL)
-
-#define QTAILQ_LINK_PREV(link)                                          \
-        ((link).tql_prev->tql_prev->tql_next)
-#define QTAILQ_LAST(head)                                               \
-        ((typeof((head)->tqh_first)) QTAILQ_LINK_PREV((head)->tqh_circ))
-#define QTAILQ_PREV(elm, field)                                         \
-        ((typeof((elm)->field.tqe_next)) QTAILQ_LINK_PREV((elm)->field.tqe_circ))
-
-#define field_at_offset(base, offset, type)                                    \
-        ((type *) (((char *) (base)) + (offset)))
-
-/*
- * Raw access of elements of a tail queue head.  Offsets are all zero
- * because it's a union.
- */
-#define QTAILQ_RAW_FIRST(head)                                                 \
-        field_at_offset(head, 0, void *)
-#define QTAILQ_RAW_TQH_CIRC(head)                                              \
-        field_at_offset(head, 0, QTailQLink)
-
-/*
- * Raw access of elements of a tail entry
- */
-#define QTAILQ_RAW_NEXT(elm, entry)                                            \
-        field_at_offset(elm, entry, void *)
-#define QTAILQ_RAW_TQE_CIRC(elm, entry)                                        \
-        field_at_offset(elm, entry, QTailQLink)
-/*
- * Tail queue traversal using pointer arithmetic.
- */
-#define QTAILQ_RAW_FOREACH(elm, head, entry)                                   \
-        for ((elm) = *QTAILQ_RAW_FIRST(head);                                  \
-             (elm);                                                            \
-             (elm) = *QTAILQ_RAW_NEXT(elm, entry))
-/*
- * Tail queue insertion using pointer arithmetic.
- */
-#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do {                           \
-        *QTAILQ_RAW_NEXT(elm, entry) = NULL;                                    \
-        QTAILQ_RAW_TQE_CIRC(elm, entry)->tql_prev = QTAILQ_RAW_TQH_CIRC(head)->tql_prev; \
-        QTAILQ_RAW_TQH_CIRC(head)->tql_prev->tql_next = (elm);                  \
-        QTAILQ_RAW_TQH_CIRC(head)->tql_prev = QTAILQ_RAW_TQE_CIRC(elm, entry);  \
-} while (/*CONSTCOND*/0)
-
-#define QLIST_RAW_FIRST(head)                                                  \
-        field_at_offset(head, 0, void *)
-
-#define QLIST_RAW_NEXT(elm, entry)                                             \
-        field_at_offset(elm, entry, void *)
-
-#define QLIST_RAW_PREVIOUS(elm, entry)                                         \
-        field_at_offset(elm, entry + sizeof(void *), void *)
-
-#define QLIST_RAW_FOREACH(elm, head, entry)                                    \
-        for ((elm) = *QLIST_RAW_FIRST(head);                                   \
-             (elm);                                                            \
-             (elm) = *QLIST_RAW_NEXT(elm, entry))
-
-#define QLIST_RAW_INSERT_AFTER(head, prev, elem, entry) do {                   \
-        *QLIST_RAW_NEXT(prev, entry) = elem;                                   \
-        *QLIST_RAW_PREVIOUS(elem, entry) = QLIST_RAW_NEXT(prev, entry);        \
-        *QLIST_RAW_NEXT(elem, entry) = NULL;                                   \
-} while (0)
-
-#define QLIST_RAW_INSERT_HEAD(head, elm, entry) do {                           \
-        void *first = *QLIST_RAW_FIRST(head);                                  \
-        *QLIST_RAW_FIRST(head) = elm;                                          \
-        *QLIST_RAW_PREVIOUS(elm, entry) = QLIST_RAW_FIRST(head);               \
-        if (first) {                                                           \
-            *QLIST_RAW_NEXT(elm, entry) = first;                               \
-            *QLIST_RAW_PREVIOUS(first, entry) = QLIST_RAW_NEXT(elm, entry);    \
-        } else {                                                               \
-            *QLIST_RAW_NEXT(elm, entry) = NULL;                                \
-        }                                                                      \
-} while (0)
-
-#endif /* QEMU_SYS_QUEUE_H */

+ 0 - 61
qapi/util.h

@@ -1,61 +0,0 @@
-/*
- * QAPI util functions
- *
- * Copyright Fujitsu, Inc. 2014
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QAPI_UTIL_H
-#define QAPI_UTIL_H
-
-#include "qemu-compat.h"
-
-typedef enum {
-    QAPI_DEPRECATED,
-    QAPI_UNSTABLE,
-} QapiSpecialFeature;
-
-typedef struct QEnumLookup {
-    const char *const *array;
-    const unsigned char *const special_features;
-    const int size;
-} QEnumLookup;
-
-const char *qapi_enum_lookup(const QEnumLookup *lookup, int val);
-int qapi_enum_parse(const QEnumLookup *lookup, const char *buf,
-                    int def, Error **errp);
-bool qapi_bool_parse(const char *name, const char *value, bool *obj,
-                     Error **errp);
-
-int parse_qapi_name(const char *name, bool complete);
-
-/*
- * For any GenericList @list, insert @element at the front.
- *
- * Note that this macro evaluates @element exactly once, so it is safe
- * to have side-effects with that argument.
- */
-#define QAPI_LIST_PREPEND(list, element) do { \
-    typeof(list) _tmp = g_malloc(sizeof(*(list))); \
-    _tmp->value = (element); \
-    _tmp->next = (list); \
-    (list) = _tmp; \
-} while (0)
-
-/*
- * For any pointer to a GenericList @tail (usually the 'next' member of a
- * list element), insert @element at the back and update the tail.
- *
- * Note that this macro evaluates @element exactly once, so it is safe
- * to have side-effects with that argument.
- */
-#define QAPI_LIST_APPEND(tail, element) do { \
-    *(tail) = g_malloc0(sizeof(**(tail))); \
-    (*(tail))->value = (element); \
-    (tail) = &(*(tail))->next; \
-} while (0)
-
-#endif

+ 0 - 137
qapi/visitor-impl.h

@@ -1,137 +0,0 @@
-/*
- * Core Definitions for QAPI Visitor implementations
- *
- * Copyright (C) 2012-2016 Red Hat, Inc.
- *
- * Author: Paolo Bonizni <pbonzini@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-#ifndef QAPI_VISITOR_IMPL_H
-#define QAPI_VISITOR_IMPL_H
-
-#include "visitor.h"
-
-/*
- * This file describes the callback interface for implementing a QAPI
- * visitor.  For the client interface, see visitor.h.  When
- * implementing the callbacks, it is easiest to declare a struct with
- * 'Visitor visitor;' as the first member.  A callback's contract
- * matches the corresponding public functions' contract unless stated
- * otherwise.  In the comments below, some callbacks are marked "must
- * be set for $TYPE visits to work"; if a visitor implementation omits
- * that callback, it should also document that it is only useful for a
- * subset of QAPI.
- */
-
-/*
- * There are four classes of visitors; setting the class determines
- * how QAPI enums are visited, as well as what additional restrictions
- * can be asserted.  The values are intentionally chosen so as to
- * permit some assertions based on whether a given bit is set (that
- * is, some assertions apply to input and clone visitors, some
- * assertions apply to output and clone visitors).
- */
-typedef enum VisitorType {
-    VISITOR_INPUT = 1,
-    VISITOR_OUTPUT = 2,
-    VISITOR_CLONE = 3,
-    VISITOR_DEALLOC = 4,
-} VisitorType;
-
-struct Visitor
-{
-    /*
-     * Only input visitors may fail!
-     */
-
-    /* Must be set to visit structs */
-    bool (*start_struct)(Visitor *v, const char *name, void **obj,
-                         size_t size, Error **errp);
-
-    /* Optional; intended for input visitors */
-    bool (*check_struct)(Visitor *v, Error **errp);
-
-    /* Must be set to visit structs */
-    void (*end_struct)(Visitor *v, void **obj);
-
-    /* Must be set; implementations may require @list to be non-null,
-     * but must document it. */
-    bool (*start_list)(Visitor *v, const char *name, GenericList **list,
-                       size_t size, Error **errp);
-
-    /* Must be set */
-    GenericList *(*next_list)(Visitor *v, GenericList *tail, size_t size);
-
-    /* Optional; intended for input visitors */
-    bool (*check_list)(Visitor *v, Error **errp);
-
-    /* Must be set */
-    void (*end_list)(Visitor *v, void **list);
-
-    /* Must be set by input and clone visitors to visit alternates */
-    bool (*start_alternate)(Visitor *v, const char *name,
-                            GenericAlternate **obj, size_t size,
-                            Error **errp);
-
-    /* Optional */
-    void (*end_alternate)(Visitor *v, void **obj);
-
-    /* Must be set */
-    bool (*type_int64)(Visitor *v, const char *name, int64_t *obj,
-                       Error **errp);
-
-    /* Must be set */
-    bool (*type_uint64)(Visitor *v, const char *name, uint64_t *obj,
-                        Error **errp);
-
-    /* Optional; fallback is type_uint64() */
-    bool (*type_size)(Visitor *v, const char *name, uint64_t *obj,
-                      Error **errp);
-
-    /* Must be set */
-    bool (*type_bool)(Visitor *v, const char *name, bool *obj, Error **errp);
-
-    /* Must be set */
-    bool (*type_str)(Visitor *v, const char *name, char **obj, Error **errp);
-
-    /* Must be set to visit numbers */
-    bool (*type_number)(Visitor *v, const char *name, double *obj,
-                        Error **errp);
-
-    /* Must be set to visit arbitrary QTypes */
-    bool (*type_any)(Visitor *v, const char *name, CFTypeRef *obj,
-                     Error **errp);
-
-    /* Must be set to visit explicit null values.  */
-    bool (*type_null)(Visitor *v, const char *name, CFNullRef *obj,
-                      Error **errp);
-
-    /* Must be set for input visitors to visit structs, optional otherwise.
-       The core takes care of the return type in the public interface. */
-    void (*optional)(Visitor *v, const char *name, bool *present);
-
-    /* Optional */
-    bool (*policy_reject)(Visitor *v, const char *name,
-                          unsigned special_features, Error **errp);
-
-    /* Optional */
-    bool (*policy_skip)(Visitor *v, const char *name,
-                        unsigned special_features);
-
-    /* Must be set */
-    VisitorType type;
-    
-    /* Optional */
-    struct CompatPolicy compat_policy;
-
-    /* Must be set for output visitors, optional otherwise. */
-    void (*complete)(Visitor *v, void *opaque);
-
-    /* Must be set */
-    void (*free)(Visitor *v);
-};
-
-#endif

+ 0 - 714
qapi/visitor.h

@@ -1,714 +0,0 @@
-/*
- * Core Definitions for QAPI Visitor Classes
- *
- * Copyright (C) 2012-2016 Red Hat, Inc.
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- *  Anthony Liguori   <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- *
- */
-
-#ifndef QAPI_VISITOR_H
-#define QAPI_VISITOR_H
-
-#include "qemu-compat.h"
-#include "qapi-builtin-types.h"
-#include "qapi-types-compat.h"
-
-/*
- * The QAPI schema defines both a set of C data types, and a QMP wire
- * format.  QAPI objects can contain references to other QAPI objects,
- * resulting in a directed acyclic graph.  QAPI also generates visitor
- * functions to walk these graphs.  This file represents the interface
- * for doing work at each node of a QAPI graph; it can also be used
- * for a virtual walk, where there is no actual QAPI C struct.
- *
- * There are four kinds of visitors: input visitors (QObject, string,
- * and QemuOpts) parse an external representation and build the
- * corresponding QAPI object, output visitors (QObject and string)
- * take a QAPI object and generate an external representation, the
- * dealloc visitor takes a QAPI object (possibly partially
- * constructed) and recursively frees it, and the clone visitor
- * performs a deep clone of a QAPI object.
- *
- * While the dealloc and QObject input/output visitors are general,
- * the string, QemuOpts, and clone visitors have some implementation
- * limitations; see the documentation for each visitor for more
- * details on what it supports.  Also, see visitor-impl.h for the
- * callback contracts implemented by each visitor, and
- * docs/devel/qapi-code-gen.txt for more about the QAPI code
- * generator.
- *
- * All of the visitors are created via:
- *
- * Visitor *subtype_visitor_new(parameters...);
- *
- * A visitor should be used for exactly one top-level visit_type_FOO()
- * or virtual walk; if that is successful, the caller can optionally
- * call visit_complete() (useful only for output visits, but safe to
- * call on all visits).  Then, regardless of success or failure, the
- * user should call visit_free() to clean up resources.  It is okay to
- * free the visitor without completing the visit, if some other error
- * is detected in the meantime.
- *
- * The clone and dealloc visitor should not be used directly outside
- * of QAPI code.  Use the qapi_free_FOO() and QAPI_CLONE() instead,
- * described below.
- *
- * All QAPI types have a corresponding function with a signature
- * roughly compatible with this:
- *
- * bool visit_type_FOO(Visitor *v, const char *name, T obj, Error **errp);
- *
- * where T is FOO for scalar types, and FOO * otherwise.  The scalar
- * visitors are declared here; the remaining visitors are generated in
- * qapi-visit-MODULE.h.
- *
- * The @name parameter of visit_type_FOO() describes the relation
- * between this QAPI value and its parent container.  When visiting
- * the root of a tree, @name is ignored; when visiting a member of an
- * object, @name is the key associated with the value; when visiting a
- * member of a list, @name is NULL; and when visiting the member of an
- * alternate, @name should equal the name used for visiting the
- * alternate.
- *
- * The visit_type_FOO() functions take a non-null @obj argument; they
- * allocate *@obj during input visits, leave it unchanged during
- * output and clone visits, and free it (recursively) during a dealloc
- * visit.
- *
- * Each function also takes the customary @errp argument (see
- * qapi/error.h for details), for reporting any errors (such as if a
- * member @name is not present, or is present but not the specified
- * type).  Only input visitors can fail.
- *
- * If an error is detected during visit_type_FOO() with an input
- * visitor, then *@obj will be set to NULL for pointer types, and left
- * unchanged for scalar types.
- *
- * Using an output or clone visitor with an incomplete object has
- * undefined behavior (other than a special case for visit_type_str()
- * treating NULL like ""), while the dealloc visitor safely handles
- * incomplete objects.  Since input visitors never produce an
- * incomplete object, such an object is possible only by manual
- * construction.
- *
- * visit_type_FOO() returns true on success, false on error.
- *
- * For the QAPI object types (structs, unions, and alternates), there
- * is an additional generated function in qapi-visit-MODULE.h
- * compatible with:
- *
- * bool visit_type_FOO_members(Visitor *v, FOO *obj, Error **errp);
- *
- * for visiting the members of a type without also allocating the QAPI
- * struct.  It also returns true on success, false on error.
- *
- * Additionally, QAPI pointer types (structs, unions, alternates, and
- * lists) have a generated function in qapi-types-MODULE.h compatible
- * with:
- *
- * void qapi_free_FOO(FOO *obj);
- *
- * Does nothing when @obj is NULL.
- *
- * Such objects may also be used with macro
- *
- * Type *QAPI_CLONE(Type, src);
- *
- * in order to perform a deep clone of @src.
- *
- * For QAPI types can that inherit from a base type, a function is
- * generated for going from the derived type to the base type:
- *
- * BASE *qapi_CHILD_base(CHILD *obj);
- *
- * Typical input visitor usage involves:
- *
- * <example>
- *  Foo *f;
- *  Error *err = NULL;
- *  Visitor *v;
- *
- *  v = FOO_visitor_new(...);
- *  if (!visit_type_Foo(v, NULL, &f, &err)) {
- *      ...handle error...
- *  } else {
- *      ...use f...
- *  }
- *  visit_free(v);
- *  qapi_free_Foo(f);
- * </example>
- *
- * For a list, it is:
- * <example>
- *  FooList *l;
- *  Error *err = NULL;
- *  Visitor *v;
- *
- *  v = FOO_visitor_new(...);
- *  if (!visit_type_FooList(v, NULL, &l, &err)) {
- *      ...handle error...
- *  } else {
- *      for ( ; l; l = l->next) {
- *          ...use l->value...
- *      }
- *  }
- *  visit_free(v);
- *  qapi_free_FooList(l);
- * </example>
- *
- * Typical output visitor usage:
- *
- * <example>
- *  Foo *f = ...obtain populated object...
- *  Visitor *v;
- *  Type *result;
- *
- *  v = FOO_visitor_new(..., &result);
- *  visit_type_Foo(v, NULL, &f, &error_abort);
- *  visit_complete(v, &result);
- *  visit_free(v);
- *  ...use result...
- * </example>
- *
- * It is also possible to use the visitors to do a virtual walk, where
- * no actual QAPI object is present.  In this situation, decisions
- * about what needs to be walked are made by the calling code, and
- * structured visits are split between pairs of start and end methods
- * (where the end method must be called if the start function
- * succeeded, even if an intermediate visit encounters an error).
- * Thus, a virtual walk corresponding to '{ "list": [1, 2] }' looks
- * like:
- *
- * <example>
- *  Visitor *v;
- *  Error *err = NULL;
- *  bool ok = false;
- *  int value;
- *
- *  v = FOO_visitor_new(...);
- *  if (!visit_start_struct(v, NULL, NULL, 0, &err)) {
- *      goto out;
- *  }
- *  if (!visit_start_list(v, "list", NULL, 0, &err)) {
- *      goto outobj;
- *  }
- *  value = 1;
- *  if (!visit_type_int(v, NULL, &value, &err)) {
- *      goto outlist;
- *  }
- *  value = 2;
- *  if (!visit_type_int(v, NULL, &value, &err)) {
- *      goto outlist;
- *  }
- *  ok = true;
- * outlist:
- *  if (ok) {
- *      ok = visit_check_list(v, &err);
- *  }
- *  visit_end_list(v, NULL);
- *  if (ok) {
- *      ok = visit_check_struct(v, &err);
- *  }
- * outobj:
- *  visit_end_struct(v, NULL);
- * out:
- *  visit_free(v);
- * </example>
- *
- * This file provides helpers for use by the generated
- * visit_type_FOO(): visit_optional() for the 'has_member' field
- * associated with optional 'member' in the C struct,
- * visit_next_list() for advancing through a FooList linked list, and
- * visit_is_input() for cleaning up on failure.
- */
-
-/*** Useful types ***/
-
-/* This struct is layout-compatible with all other *List structs
- * created by the QAPI generator.  It is used as a typical
- * singly-linked list. */
-typedef struct GenericList {
-    struct GenericList *next;
-    char padding[];
-} GenericList;
-
-/* This struct is layout-compatible with all Alternate types
- * created by the QAPI generator. */
-typedef struct GenericAlternate {
-    CFTypeID type;
-    char padding[];
-} GenericAlternate;
-
-/*** Visitor cleanup ***/
-
-/*
- * Complete the visit, collecting any output.
- *
- * May only be called only once after a successful top-level
- * visit_type_FOO() or visit_end_ITEM(), and marks the end of the
- * visit.  The @opaque pointer should match the output parameter
- * passed to the subtype_visitor_new() used to create an output
- * visitor, or NULL for any other visitor.  Needed for output
- * visitors, but may also be called with other visitors.
- */
-void visit_complete(Visitor *v, void *opaque);
-
-/*
- * Free @v and any resources it has tied up.
- *
- * May be called whether or not the visit has been successfully
- * completed, but should not be called until a top-level
- * visit_type_FOO() or visit_start_ITEM() has been performed on the
- * visitor.  Safe if @v is NULL.
- */
-void visit_free(Visitor *v);
-
-
-/*** Visiting structures ***/
-
-/*
- * Start visiting an object @obj (struct or union).
- *
- * @name expresses the relationship of this object to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL for a real walk, in which case @size
- * determines how much memory an input or clone visitor will allocate
- * into *@obj.  @obj may also be NULL for a virtual walk, in which
- * case @size is ignored.
- *
- * On failure, set *@obj to NULL and store an error through @errp.
- * Can happen only when @v is an input visitor.
- *
- * Return true on success, false on failure.
- *
- * After visit_start_struct() succeeds, the caller may visit its
- * members one after the other, passing the member's name and address
- * within the struct.  Finally, visit_end_struct() needs to be called
- * with the same @obj to clean up, even if intermediate visits fail.
- * See the examples above.
- *
- * FIXME Should this be named visit_start_object, since it is also
- * used for QAPI unions, and maps to JSON objects?
- */
-bool visit_start_struct(Visitor *v, const char *name, void **obj,
-                        size_t size, Error **errp);
-
-/*
- * Prepare for completing an object visit.
- *
- * On failure, store an error through @errp.  Can happen only when @v
- * is an input visitor.
- *
- * Return true on success, false on failure.
- *
- * Should be called prior to visit_end_struct() if all other
- * intermediate visit steps were successful, to allow the visitor one
- * last chance to report errors.  May be skipped on a cleanup path,
- * where there is no need to check for further errors.
- */
-bool visit_check_struct(Visitor *v, Error **errp);
-
-/*
- * Complete an object visit started earlier.
- *
- * @obj must match what was passed to the paired visit_start_struct().
- *
- * Must be called after any successful use of visit_start_struct(),
- * even if intermediate processing was skipped due to errors, to allow
- * the backend to release any resources.  Destroying the visitor early
- * with visit_free() behaves as if this was implicitly called.
- */
-void visit_end_struct(Visitor *v, void **obj);
-
-
-/*** Visiting lists ***/
-
-/*
- * Start visiting a list.
- *
- * @name expresses the relationship of this list to its parent
- * container; see the general description of @name above.
- *
- * @list must be non-NULL for a real walk, in which case @size
- * determines how much memory an input or clone visitor will allocate
- * into *@list (at least sizeof(GenericList)).  Some visitors also
- * allow @list to be NULL for a virtual walk, in which case @size is
- * ignored.
- *
- * On failure, set *@list to NULL and store an error through @errp.
- * Can happen only when @v is an input visitor.
- *
- * Return true on success, false on failure.
- *
- * After visit_start_list() succeeds, the caller may visit its members
- * one after the other.  A real visit (where @list is non-NULL) uses
- * visit_next_list() for traversing the linked list, while a virtual
- * visit (where @list is NULL) uses other means.  For each list
- * element, call the appropriate visit_type_FOO() with name set to
- * NULL and obj set to the address of the value member of the list
- * element.  Finally, visit_end_list() needs to be called with the
- * same @list to clean up, even if intermediate visits fail.  See the
- * examples above.
- */
-bool visit_start_list(Visitor *v, const char *name, GenericList **list,
-                      size_t size, Error **errp);
-
-/*
- * Iterate over a GenericList during a non-virtual list visit.
- *
- * @size represents the size of a linked list node (at least
- * sizeof(GenericList)).
- *
- * @tail must not be NULL; on the first call, @tail is the value of
- * *list after visit_start_list(), and on subsequent calls @tail must
- * be the previously returned value.  Should be called in a loop until
- * a NULL return; for each non-NULL return, the caller then calls the
- * appropriate visit_type_*() for the element type of the list, with
- * that function's name parameter set to NULL and obj set to the
- * address of @tail->value.
- */
-GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size);
-
-/*
- * Prepare for completing a list visit.
- *
- * On failure, store an error through @errp.  Can happen only when @v
- * is an input visitor.
- *
- * Return true on success, false on failure.
- *
- * Should be called prior to visit_end_list() if all other
- * intermediate visit steps were successful, to allow the visitor one
- * last chance to report errors.  May be skipped on a cleanup path,
- * where there is no need to check for further errors.
- */
-bool visit_check_list(Visitor *v, Error **errp);
-
-/*
- * Complete a list visit started earlier.
- *
- * @list must match what was passed to the paired visit_start_list().
- *
- * Must be called after any successful use of visit_start_list(), even
- * if intermediate processing was skipped due to errors, to allow the
- * backend to release any resources.  Destroying the visitor early
- * with visit_free() behaves as if this was implicitly called.
- */
-void visit_end_list(Visitor *v, void **list);
-
-
-/*** Visiting alternates ***/
-
-/*
- * Start the visit of an alternate @obj.
- *
- * @name expresses the relationship of this alternate to its parent
- * container; see the general description of @name above.
- *
- * @obj must not be NULL. Input and clone visitors use @size to
- * determine how much memory to allocate into *@obj, then determine
- * the qtype of the next thing to be visited, and store it in
- * (*@obj)->type.  Other visitors leave @obj unchanged.
- *
- * On failure, set *@obj to NULL and store an error through @errp.
- * Can happen only when @v is an input visitor.
- *
- * Return true on success, false on failure.
- *
- * If successful, this must be paired with visit_end_alternate() with
- * the same @obj to clean up, even if visiting the contents of the
- * alternate fails.
- */
-bool visit_start_alternate(Visitor *v, const char *name,
-                           GenericAlternate **obj, size_t size,
-                           Error **errp);
-
-/*
- * Finish visiting an alternate type.
- *
- * @obj must match what was passed to the paired visit_start_alternate().
- *
- * Must be called after any successful use of visit_start_alternate(),
- * even if intermediate processing was skipped due to errors, to allow
- * the backend to release any resources.  Destroying the visitor early
- * with visit_free() behaves as if this was implicitly called.
- *
- */
-void visit_end_alternate(Visitor *v, void **obj);
-
-
-/*** Other helpers ***/
-
-/*
- * Does optional struct member @name need visiting?
- *
- * @name must not be NULL.  This function is only useful between
- * visit_start_struct() and visit_end_struct(), since only objects
- * have optional keys.
- *
- * @present points to the address of the optional member's has_ flag.
- *
- * Input visitors set *@present according to input; other visitors
- * leave it unchanged.  In either case, return *@present for
- * convenience.
- */
-bool visit_optional(Visitor *v, const char *name, bool *present);
-
-/*
- * Should we reject member @name due to policy?
- *
- * @special_features is the member's special features encoded as a
- * bitset of QapiSpecialFeature.
- *
- * @name must not be NULL.  This function is only useful between
- * visit_start_struct() and visit_end_struct(), since only objects
- * have deprecated members.
- */
-bool visit_policy_reject(Visitor *v, const char *name,
-                         unsigned special_features, Error **errp);
-
-/*
- *
- * Should we skip member @name due to policy?
- *
- * @special_features is the member's special features encoded as a
- * bitset of QapiSpecialFeature.
- *
- * @name must not be NULL.  This function is only useful between
- * visit_start_struct() and visit_end_struct(), since only objects
- * have deprecated members.
- */
-bool visit_policy_skip(Visitor *v, const char *name,
-                       unsigned special_features);
-
-/*
- * Set policy for handling deprecated management interfaces.
- *
- * Intended use: call visit_set_policy(v, &compat_policy) when
- * visiting management interface input or output.
- */
-void visit_set_policy(Visitor *v, CompatPolicy *policy);
-
-/*
- * Visit an enum value.
- *
- * @name expresses the relationship of this enum to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input visitors parse input and set *@obj to
- * the enumeration value, leaving @obj unchanged on error; other
- * visitors use *@obj but leave it unchanged.
- *
- * Currently, all input visitors parse text input, and all output
- * visitors produce text output.  The mapping between enumeration
- * values and strings is done by the visitor core, using @lookup.
- *
- * On failure, store an error through @errp.  Can happen only when @v
- * is an input visitor.
- *
- * Return true on success, false on failure.
- *
- * May call visit_type_str() under the hood, and the enum visit may
- * fail even if the corresponding string visit succeeded; this implies
- * that an input visitor's visit_type_str() must have no unwelcome
- * side effects.
- */
-bool visit_type_enum(Visitor *v, const char *name, int *obj,
-                     const QEnumLookup *lookup, Error **errp);
-
-/*
- * Check if visitor is an input visitor.
- */
-bool visit_is_input(Visitor *v);
-
-/*
- * Check if visitor is a dealloc visitor.
- */
-bool visit_is_dealloc(Visitor *v);
-
-/*** Visiting built-in types ***/
-
-/*
- * Visit an integer value.
- *
- * @name expresses the relationship of this integer to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input visitors set *@obj to the value;
- * other visitors will leave *@obj unchanged.
- *
- * On failure, store an error through @errp.  Can happen only when @v
- * is an input visitor.
- *
- * Return true on success, false on failure.
- */
-bool visit_type_int(Visitor *v, const char *name, int64_t *obj, Error **errp);
-
-/*
- * Visit a uint8_t value.
- * Like visit_type_int(), except clamps the value to uint8_t range.
- */
-bool visit_type_uint8(Visitor *v, const char *name, uint8_t *obj,
-                      Error **errp);
-
-/*
- * Visit a uint16_t value.
- * Like visit_type_int(), except clamps the value to uint16_t range.
- */
-bool visit_type_uint16(Visitor *v, const char *name, uint16_t *obj,
-                       Error **errp);
-
-/*
- * Visit a uint32_t value.
- * Like visit_type_int(), except clamps the value to uint32_t range.
- */
-bool visit_type_uint32(Visitor *v, const char *name, uint32_t *obj,
-                       Error **errp);
-
-/*
- * Visit a uint64_t value.
- * Like visit_type_int(), except clamps the value to uint64_t range,
- * that is, ensures it is unsigned.
- */
-bool visit_type_uint64(Visitor *v, const char *name, uint64_t *obj,
-                       Error **errp);
-
-/*
- * Visit an int8_t value.
- * Like visit_type_int(), except clamps the value to int8_t range.
- */
-bool visit_type_int8(Visitor *v, const char *name, int8_t *obj, Error **errp);
-
-/*
- * Visit an int16_t value.
- * Like visit_type_int(), except clamps the value to int16_t range.
- */
-bool visit_type_int16(Visitor *v, const char *name, int16_t *obj,
-                      Error **errp);
-
-/*
- * Visit an int32_t value.
- * Like visit_type_int(), except clamps the value to int32_t range.
- */
-bool visit_type_int32(Visitor *v, const char *name, int32_t *obj,
-                      Error **errp);
-
-/*
- * Visit an int64_t value.
- * Identical to visit_type_int().
- */
-bool visit_type_int64(Visitor *v, const char *name, int64_t *obj,
-                      Error **errp);
-
-/*
- * Visit a uint64_t value.
- * Like visit_type_uint64(), except that some visitors may choose to
- * recognize additional syntax, such as suffixes for easily scaling
- * values.
- */
-bool visit_type_size(Visitor *v, const char *name, uint64_t *obj,
-                     Error **errp);
-
-/*
- * Visit a boolean value.
- *
- * @name expresses the relationship of this boolean to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input visitors set *@obj to the value;
- * other visitors will leave *@obj unchanged.
- *
- * On failure, store an error through @errp.  Can happen only when @v
- * is an input visitor.
- *
- * Return true on success, false on failure.
- */
-bool visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp);
-
-/*
- * Visit a string value.
- *
- * @name expresses the relationship of this string to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input and clone visitors set *@obj to the
- * value (always using "" rather than NULL for an empty string).
- * Other visitors leave *@obj unchanged, and commonly treat NULL like
- * "".
- *
- * It is safe to cast away const when preparing a (const char *) value
- * into @obj for use by an output visitor.
- *
- * On failure, set *@obj to NULL and store an error through @errp.
- * Can happen only when @v is an input visitor.
- *
- * Return true on success, false on failure.
- *
- * FIXME: Callers that try to output NULL *obj should not be allowed.
- */
-bool visit_type_str(Visitor *v, const char *name, char **obj, Error **errp);
-
-/*
- * Visit a number (i.e. double) value.
- *
- * @name expresses the relationship of this number to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input visitors set *@obj to the value;
- * other visitors will leave *@obj unchanged.  Visitors should
- * document if infinity or NaN are not permitted.
- *
- * On failure, store an error through @errp.  Can happen only when @v
- * is an input visitor.
- *
- * Return true on success, false on failure.
- */
-bool visit_type_number(Visitor *v, const char *name, double *obj,
-                       Error **errp);
-
-/*
- * Visit an arbitrary value.
- *
- * @name expresses the relationship of this value to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input visitors set *@obj to the value;
- * other visitors will leave *@obj unchanged.  *@obj must be non-NULL
- * for output visitors.
- *
- * On failure, set *@obj to NULL and store an error through @errp.
- * Can happen only when @v is an input visitor.
- *
- * Return true on success, false on failure.
- *
- * Note that some kinds of input can't express arbitrary QObject.
- * E.g. the visitor returned by qobject_input_visitor_new_keyval()
- * can't create numbers or booleans, only strings.
- */
-bool visit_type_any(Visitor *v, const char *name, CFTypeRef *obj, Error **errp);
-
-/*
- * Visit a JSON null value.
- *
- * @name expresses the relationship of the null value to its parent
- * container; see the general description of @name above.
- *
- * @obj must be non-NULL.  Input visitors set *@obj to the value;
- * other visitors ignore *@obj.
- *
- * On failure, set *@obj to NULL and store an error through @errp.
- * Can happen only when @v is an input visitor.
- *
- * Return true on success, false on failure.
- */
-bool visit_type_null(Visitor *v, const char *name, CFNullRef *obj,
-                     Error **errp);
-
-#endif

+ 0 - 11
scripts/build_dependencies.sh

@@ -585,16 +585,6 @@ remove_shared_gst_plugins () {
     find "$SYSROOT_DIR/lib/gstreamer-1.0" -name '*.dylib' -exec rm \{\} \;
 }
 
-generate_qapi () {
-    DIR="$1"
-    GA_APIS="$DIR/qga/qapi-schema.json"
-    APIS="$DIR/qapi/qapi-schema.json"
-
-    echo "${GREEN}Generating qapi sources from ${APIS}...${NC}"
-    python3 "$BASEDIR/qapi-gen.py" -b -o "$SYSROOT_DIR/qapi" "$APIS"
-    python3 "$BASEDIR/qapi-gen.py" -p 'qga-' -o "$SYSROOT_DIR/qga" "$GA_APIS"
-}
-
 # parse args
 ARCH=
 REBUILD=
@@ -813,6 +803,5 @@ if [ "$PLATFORM" == "ios_simulator" ]; then
     generate_fake_hypervisor
 fi
 remove_shared_gst_plugins # another hack...
-generate_qapi $QEMU_DIR
 echo "${GREEN}All done!${NC}"
 touch "$BUILD_DIR/BUILD_SUCCESS"

+ 0 - 2
scripts/pack_dependencies.sh

@@ -79,6 +79,4 @@ pack_dir "$BASEDIR" "Frameworks" # for all the Info.plist
 pack_all_objs "$BASEDIR" "*/Frameworks/*.framework/*"
 pack_dir "$BASEDIR" "include"
 pack_dir "$BASEDIR" "lib/glib-2.0/include"
-pack_dir "$BASEDIR" "qapi"
-pack_dir "$BASEDIR" "qga"
 pack_dir "$BASEDIR" "share/qemu"

+ 0 - 19
scripts/qapi-gen.py

@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-# This work is licensed under the terms of the GNU GPL, version 2 or later.
-# See the COPYING file in the top-level directory.
-
-"""
-QAPI code generation execution shim.
-
-This standalone script exists primarily to facilitate the running of the QAPI
-code generator without needing to install the python module to the current
-execution environment.
-"""
-
-import sys
-
-from qapi import main
-
-if __name__ == '__main__':
-    sys.exit(main.main())

+ 0 - 0
scripts/qapi/__init__.py


+ 0 - 261
scripts/qapi/commands.py

@@ -1,261 +0,0 @@
-"""
-QAPI command marshaller generator
-
-Copyright IBM, Corp. 2011
-Copyright (C) 2014-2018 Red Hat, Inc.
-Copyright (c) 2019 osy
-
-Authors:
- Anthony Liguori <aliguori@us.ibm.com>
- Michael Roth <mdroth@linux.vnet.ibm.com>
- Markus Armbruster <armbru@redhat.com>
- osy <dev@getutm.app>
-
-This work is licensed under the terms of the GNU GPL, version 2.
-See the COPYING file in the top-level directory.
-"""
-
-from typing import (
-    Dict,
-    List,
-    Optional,
-    Set,
-)
-
-from .common import c_name, mcgen
-from .gen import (
-    QAPIGenC,
-    QAPIGenCCode,
-    QAPISchemaModularCVisitor,
-    build_params,
-    ifcontext,
-)
-from .schema import (
-    QAPISchema,
-    QAPISchemaFeature,
-    QAPISchemaObjectType,
-    QAPISchemaType,
-)
-from .source import QAPISourceInfo
-
-
-def gen_command_decl(name: str,
-                     arg_type: Optional[QAPISchemaObjectType],
-                     boxed: bool,
-                     ret_type: Optional[QAPISchemaType],
-                     proto: bool = True) -> str:
-    return mcgen('''
-%(c_type)s qmp_%(c_name)s(%(params)s)%(proto)s
-''',
-                 proto=';' if proto else '', 
-                 c_type=(ret_type and ret_type.c_type()) or 'void',
-                 c_name=c_name(name),
-                 params=build_params(arg_type, boxed, 'Error **errp, void *ctx'))
-
-
-def gen_marshal_rpc(ret_type: QAPISchemaType) -> str:
-    return mcgen('''
-
-static %(c_type)s qmp_marshal_rpc_%(c_name)s(CFDictionaryRef args, Error **errp, void *ctx)
-{
-    Error *err = NULL;
-    Visitor *v;
-    CFDictionaryRef cfret;
-    %(c_type)s ret = {0};
-
-    qmp_rpc_call(args, &cfret, &err, ctx);
-    if (err) {
-        error_propagate(errp, err);
-        return ret;
-    }
-    v = cf_input_visitor_new(cfret);
-    visit_start_struct(v, "command", NULL, 0, &err);
-    if (err) {
-        error_propagate(errp, err);
-        return ret;
-    }
-    visit_type_%(c_name)s(v, "return", &ret, &err);
-    error_propagate(errp, err);
-    visit_end_struct(v, NULL);
-    visit_free(v);
-    CFRelease(cfret);
-    return ret;
-}
-''',
-                 c_type=ret_type.c_type(), c_name=ret_type.c_name())
-
-
-def gen_rpc_call(name: str,
-                 arg_type: Optional[QAPISchemaObjectType],
-                 boxed: bool,
-                 ret_type: Optional[QAPISchemaType]) -> str:
-    have_args = boxed or (arg_type and not arg_type.is_empty())
-
-    ret = mcgen('''
-
-%(proto)s
-{
-    const char *cmdname = "%(name)s";
-    CFDictionaryRef cfargs;
-    Error *err = NULL;
-    Visitor *v = NULL;
-''',
-                name=name, proto=gen_command_decl(name, arg_type, boxed, ret_type, proto=False))
-
-    if ret_type:
-        ret += mcgen('''
-    %(c_type)s ret = {0};
-''',
-                     c_type=ret_type.c_type())
-
-    if have_args:
-        if boxed:
-            visit_type = ('visit_type_%s(v, "arguments", &argp, &err);'
-                             % arg_type.c_name())
-            ret += mcgen('''
-    %(c_name)s *argp = arg;
-''',
-                     c_name=arg_type.c_name())
-        else:
-            visit_type = ('visit_type_%s(v, "arguments", &argp, &err);'
-                             % arg_type.c_name())
-            ret += mcgen('''
-    %(c_name)s _arg = {
-''',
-                     c_name=arg_type.c_name())
-            if arg_type:
-                assert not arg_type.variants
-                for memb in arg_type.members:
-                    if memb.optional:
-                        ret += mcgen('''
-        .has_%(c_name)s = has_%(c_name)s,
-''',
-                                     c_name=c_name(memb.name))
-                    ret += mcgen('''
-        .%(c_name)s = %(cast)s%(c_name)s,
-''',
-                                     cast='(char *)' if memb.type.name == 'str' else '', c_name=c_name(memb.name))
-            ret += mcgen('''
-    };
-    %(c_name)s *argp = &_arg;
-''',
-                                     c_name=arg_type.c_name())
-    else:
-        visit_type = ''
-        ret += mcgen('''
-
-''')
-
-    ret += mcgen('''
-    v = cf_output_visitor_new((CFTypeRef *)&cfargs);
-    visit_start_struct(v, "command", NULL, 0, &err);
-    if (err) {
-        goto out;
-    }
-    visit_type_str(v, "execute", (char **)&cmdname, &err);
-    if (err) {
-        goto out;
-    }
-    %(visit_type)s
-    if (err) {
-        goto out;
-    }
-    visit_end_struct(v, NULL);
-    visit_complete(v, &cfargs);
-''',
-                 visit_type=visit_type)
-
-    if ret_type:
-        ret += mcgen('''
-    ret = qmp_marshal_rpc_%(c_type)s(cfargs, &err, ctx);
-''',
-                    c_type=ret_type.c_name())
-    else:
-        ret += mcgen('''
-    qmp_rpc_call(cfargs, NULL, &err, ctx);
-''')
-
-    ret += mcgen('''
-    CFRelease(cfargs);
-
-out:
-    error_propagate(errp, err);
-    visit_free(v);
-''')
-
-    if ret_type:
-        ret += mcgen('''
-    return ret;
-''')
-
-    ret += mcgen('''
-}
-''')
-    return ret
-
-
-class QAPISchemaGenCommandVisitor(QAPISchemaModularCVisitor):
-    def __init__(self, prefix: str):
-        super().__init__(
-            prefix, 'qapi-commands',
-            ' * Schema-defined QAPI/QMP commands', None, __doc__)
-        self._visited_ret_types: Dict[QAPIGenC, Set[QAPISchemaType]] = {}
-
-    def _begin_user_module(self, name: str) -> None:
-        self._visited_ret_types[self._genc] = set()
-        commands = self._module_basename('qapi-commands', name)
-        types = self._module_basename('qapi-types', name)
-        visit = self._module_basename('qapi-visit', name)
-        self._genc.add(mcgen('''
-#include "qemu-compat.h"
-#include "cf-output-visitor.h"
-#include "cf-input-visitor.h"
-#include "dealloc-visitor.h"
-#include "error.h"
-#include "%(visit)s.h"
-#include "%(commands)s.h"
-
-''',
-                             commands=commands, visit=visit))
-        self._genh.add(mcgen('''
-#include "%(types)s.h"
-
-''',
-                             types=types))
-
-    def visit_command(self,
-                      name: str,
-                      info: QAPISourceInfo,
-                      ifcond: List[str],
-                      features: List[QAPISchemaFeature],
-                      arg_type: Optional[QAPISchemaObjectType],
-                      ret_type: Optional[QAPISchemaType],
-                      gen: bool,
-                      success_response: bool,
-                      boxed: bool,
-                      allow_oob: bool,
-                      allow_preconfig: bool,
-                      coroutine: bool) -> None:
-        if not gen:
-            return
-        # FIXME: If T is a user-defined type, the user is responsible
-        # for making this work, i.e. to make T's condition the
-        # conjunction of the T-returning commands' conditions.  If T
-        # is a built-in type, this isn't possible: the
-        # qmp_marshal_output_T() will be generated unconditionally.
-        if ret_type and ret_type not in self._visited_ret_types[self._genc]:
-            self._visited_ret_types[self._genc].add(ret_type)
-            with ifcontext(ret_type.ifcond,
-                           self._genh, self._genc):
-                self._genc.add(gen_marshal_rpc(ret_type))
-        with ifcontext(ifcond, self._genh, self._genc):
-            self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
-            self._genc.add(gen_rpc_call(name, arg_type, boxed, ret_type))
-
-
-def gen_commands(schema: QAPISchema,
-                 output_dir: str,
-                 prefix: str) -> None:
-    vis = QAPISchemaGenCommandVisitor(prefix)
-    schema.visit(vis)
-    vis.write(output_dir)

+ 0 - 251
scripts/qapi/common.py

@@ -1,251 +0,0 @@
-#
-# QAPI helper library
-#
-# Copyright IBM, Corp. 2011
-# Copyright (c) 2013-2018 Red Hat Inc.
-#
-# Authors:
-#  Anthony Liguori <aliguori@us.ibm.com>
-#  Markus Armbruster <armbru@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2.
-# See the COPYING file in the top-level directory.
-
-import re
-from typing import (
-    Any,
-    Dict,
-    Match,
-    Optional,
-    Sequence,
-    Union,
-)
-
-
-#: Magic string that gets removed along with all space to its right.
-EATSPACE = '\033EATSPACE.'
-POINTER_SUFFIX = ' *' + EATSPACE
-
-
-def camel_to_upper(value: str) -> str:
-    """
-    Converts CamelCase to CAMEL_CASE.
-
-    Examples::
-
-        ENUMName -> ENUM_NAME
-        EnumName1 -> ENUM_NAME1
-        ENUM_NAME -> ENUM_NAME
-        ENUM_NAME1 -> ENUM_NAME1
-        ENUM_Name2 -> ENUM_NAME2
-        ENUM24_Name -> ENUM24_NAME
-    """
-    c_fun_str = c_name(value, False)
-    if value.isupper():
-        return c_fun_str
-
-    new_name = ''
-    length = len(c_fun_str)
-    for i in range(length):
-        char = c_fun_str[i]
-        # When char is upper case and no '_' appears before, do more checks
-        if char.isupper() and (i > 0) and c_fun_str[i - 1] != '_':
-            if i < length - 1 and c_fun_str[i + 1].islower():
-                new_name += '_'
-            elif c_fun_str[i - 1].isdigit():
-                new_name += '_'
-        new_name += char
-    return new_name.lstrip('_').upper()
-
-
-def c_enum_const(type_name: str,
-                 const_name: str,
-                 prefix: Optional[str] = None) -> str:
-    """
-    Generate a C enumeration constant name.
-
-    :param type_name: The name of the enumeration.
-    :param const_name: The name of this constant.
-    :param prefix: Optional, prefix that overrides the type_name.
-    """
-    if prefix is not None:
-        type_name = prefix
-    return camel_to_upper(type_name) + '_' + c_name(const_name, False).upper()
-
-
-def c_name(name: str, protect: bool = True) -> str:
-    """
-    Map ``name`` to a valid C identifier.
-
-    Used for converting 'name' from a 'name':'type' qapi definition
-    into a generated struct member, as well as converting type names
-    into substrings of a generated C function name.
-
-    '__a.b_c' -> '__a_b_c', 'x-foo' -> 'x_foo'
-    protect=True: 'int' -> 'q_int'; protect=False: 'int' -> 'int'
-
-    :param name: The name to map.
-    :param protect: If true, avoid returning certain ticklish identifiers
-                    (like C keywords) by prepending ``q_``.
-    """
-    # ANSI X3J11/88-090, 3.1.1
-    c89_words = set(['auto', 'break', 'case', 'char', 'const', 'continue',
-                     'default', 'do', 'double', 'else', 'enum', 'extern',
-                     'float', 'for', 'goto', 'if', 'int', 'long', 'register',
-                     'return', 'short', 'signed', 'sizeof', 'static',
-                     'struct', 'switch', 'typedef', 'union', 'unsigned',
-                     'void', 'volatile', 'while'])
-    # ISO/IEC 9899:1999, 6.4.1
-    c99_words = set(['inline', 'restrict', '_Bool', '_Complex', '_Imaginary'])
-    # ISO/IEC 9899:2011, 6.4.1
-    c11_words = set(['_Alignas', '_Alignof', '_Atomic', '_Generic',
-                     '_Noreturn', '_Static_assert', '_Thread_local'])
-    # GCC http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/C-Extensions.html
-    # excluding _.*
-    gcc_words = set(['asm', 'typeof'])
-    # C++ ISO/IEC 14882:2003 2.11
-    cpp_words = set(['bool', 'catch', 'class', 'const_cast', 'delete',
-                     'dynamic_cast', 'explicit', 'false', 'friend', 'mutable',
-                     'namespace', 'new', 'operator', 'private', 'protected',
-                     'public', 'reinterpret_cast', 'static_cast', 'template',
-                     'this', 'throw', 'true', 'try', 'typeid', 'typename',
-                     'using', 'virtual', 'wchar_t',
-                     # alternative representations
-                     'and', 'and_eq', 'bitand', 'bitor', 'compl', 'not',
-                     'not_eq', 'or', 'or_eq', 'xor', 'xor_eq'])
-    # namespace pollution:
-    polluted_words = set(['unix', 'errno', 'mips', 'sparc', 'i386'])
-    name = re.sub(r'[^A-Za-z0-9_]', '_', name)
-    if protect and (name in (c89_words | c99_words | c11_words | gcc_words
-                             | cpp_words | polluted_words)
-                    or name[0].isdigit()):
-        return 'q_' + name
-    return name
-
-
-class Indentation:
-    """
-    Indentation level management.
-
-    :param initial: Initial number of spaces, default 0.
-    """
-    def __init__(self, initial: int = 0) -> None:
-        self._level = initial
-
-    def __repr__(self) -> str:
-        return "{}({:d})".format(type(self).__name__, self._level)
-
-    def __str__(self) -> str:
-        """Return the current indentation as a string of spaces."""
-        return ' ' * self._level
-
-    def increase(self, amount: int = 4) -> None:
-        """Increase the indentation level by ``amount``, default 4."""
-        self._level += amount
-
-    def decrease(self, amount: int = 4) -> None:
-        """Decrease the indentation level by ``amount``, default 4."""
-        assert amount <= self._level
-        self._level -= amount
-
-
-#: Global, current indent level for code generation.
-indent = Indentation()
-
-
-def cgen(code: str, **kwds: object) -> str:
-    """
-    Generate ``code`` with ``kwds`` interpolated.
-
-    Obey `indent`, and strip `EATSPACE`.
-    """
-    raw = code % kwds
-    pfx = str(indent)
-    if pfx:
-        raw = re.sub(r'^(?!(#|$))', pfx, raw, flags=re.MULTILINE)
-    return re.sub(re.escape(EATSPACE) + r' *', '', raw)
-
-
-def mcgen(code: str, **kwds: object) -> str:
-    if code[0] == '\n':
-        code = code[1:]
-    return cgen(code, **kwds)
-
-
-def c_fname(filename: str) -> str:
-    return re.sub(r'[^A-Za-z0-9_]', '_', filename)
-
-
-def guardstart(name: str) -> str:
-    return mcgen('''
-#ifndef %(name)s
-#define %(name)s
-
-''',
-                 name=c_fname(name).upper())
-
-
-def guardend(name: str) -> str:
-    return mcgen('''
-
-#endif /* %(name)s */
-''',
-                 name=c_fname(name).upper())
-
-
-def gen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]],
-               cond_fmt: str, not_fmt: str,
-               all_operator: str, any_operator: str) -> str:
-
-    def do_gen(ifcond: Union[str, Dict[str, Any]],
-               need_parens: bool) -> str:
-        if isinstance(ifcond, str):
-            return cond_fmt % ifcond
-        assert isinstance(ifcond, dict) and len(ifcond) == 1
-        if 'not' in ifcond:
-            return not_fmt % do_gen(ifcond['not'], True)
-        if 'all' in ifcond:
-            gen = gen_infix(all_operator, ifcond['all'])
-        else:
-            gen = gen_infix(any_operator, ifcond['any'])
-        if need_parens:
-            gen = '(' + gen + ')'
-        return gen
-
-    def gen_infix(operator: str, operands: Sequence[Any]) -> str:
-        return operator.join([do_gen(o, True) for o in operands])
-
-    if not ifcond:
-        return ''
-    return do_gen(ifcond, False)
-
-
-def cgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str:
-    return gen_ifcond(ifcond, 'defined(%s)', '!%s', ' && ', ' || ')
-
-
-def docgen_ifcond(ifcond: Optional[Union[str, Dict[str, Any]]]) -> str:
-    # TODO Doc generated for conditions needs polish
-    return gen_ifcond(ifcond, '%s', 'not %s', ' and ', ' or ')
-
-
-def gen_if(cond: str) -> str:
-    if not cond:
-        return ''
-    return mcgen('''
-#if %(cond)s
-''', cond=cond)
-
-
-def gen_endif(cond: str) -> str:
-    if not cond:
-        return ''
-    return mcgen('''
-#endif /* %(cond)s */
-''', cond=cond)
-
-
-def must_match(pattern: str, string: str) -> Match[str]:
-    match = re.match(pattern, string)
-    assert match is not None
-    return match

+ 0 - 50
scripts/qapi/error.py

@@ -1,50 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017-2019 Red Hat Inc.
-#
-# Authors:
-#  Markus Armbruster <armbru@redhat.com>
-#  Marc-André Lureau <marcandre.lureau@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2.
-# See the COPYING file in the top-level directory.
-
-"""
-QAPI error classes
-
-Common error classes used throughout the package.  Additional errors may
-be defined in other modules.  At present, `QAPIParseError` is defined in
-parser.py.
-"""
-
-from typing import Optional
-
-from .source import QAPISourceInfo
-
-
-class QAPIError(Exception):
-    """Base class for all exceptions from the QAPI package."""
-
-
-class QAPISourceError(QAPIError):
-    """Error class for all exceptions identifying a source location."""
-    def __init__(self,
-                 info: Optional[QAPISourceInfo],
-                 msg: str,
-                 col: Optional[int] = None):
-        super().__init__()
-        self.info = info
-        self.msg = msg
-        self.col = col
-
-    def __str__(self) -> str:
-        assert self.info is not None
-        loc = str(self.info)
-        if self.col is not None:
-            assert self.info.line is not None
-            loc += ':%s' % self.col
-        return loc + ': ' + self.msg
-
-
-class QAPISemError(QAPISourceError):
-    """Error class for semantic QAPI errors."""

+ 0 - 275
scripts/qapi/events.py

@@ -1,275 +0,0 @@
-"""
-QAPI event generator
-
-Copyright (c) 2014 Wenchao Xia
-Copyright (c) 2015-2018 Red Hat Inc.
-Copyright (c) 2019 osy
-
-Authors:
- Wenchao Xia <wenchaoqemu@gmail.com>
- Markus Armbruster <armbru@redhat.com>
- osy <dev@getutm.app>
-
-This work is licensed under the terms of the GNU GPL, version 2.
-See the COPYING file in the top-level directory.
-"""
-
-from typing import List
-
-from .common import c_enum_const, c_name, mcgen
-from .gen import QAPISchemaModularCVisitor, build_params, ifcontext
-from .schema import (
-    QAPISchema,
-    QAPISchemaEnumMember,
-    QAPISchemaFeature,
-    QAPISchemaObjectType,
-)
-from .source import QAPISourceInfo
-from .types import gen_enum, gen_enum_lookup
-
-
-def build_handler_name(name: str) -> str:
-    return 'qapi_%s_handler' % name.lower()
-
-
-def build_event_handler_proto(name: str,
-                              arg_type: QAPISchemaObjectType,
-                              boxed: bool) -> str:
-    return 'typedef void (*%(handler)s)(%(param)s)' % {
-        'handler': build_handler_name(name),
-        'param': build_params(arg_type, boxed, extra='void *ctx')}
-
-
-def gen_event_dispatch_decl(name: str,
-                            arg_type: QAPISchemaObjectType,
-                            boxed: bool) -> str:
-    return mcgen('''
-
-%(proto)s;
-void qapi_event_dispatch_%(name)s(%(handler_type)s handler, CFDictionaryRef data, void *ctx);
-''',
-                 proto=build_event_handler_proto(name, arg_type, boxed),
-                 name=name,
-                 handler_type=build_handler_name(name))
-
-
-# Calling the handler
-def gen_call_handler(typ: QAPISchemaObjectType) -> str:
-    if typ:
-        assert not typ.variants
-        ret = ''
-        sep = ''
-        for memb in typ.members:
-            ret += sep
-            sep = ', '
-            if memb.optional:
-                ret += 'arg->has_' + c_name(memb.name) + sep
-            ret += 'arg->' + c_name(memb.name)
-        ret += sep + 'ctx'
-        return ret
-    else:
-        return 'ctx'
-
-
-def gen_event_dispatch(name: str,
-                       arg_type: QAPISchemaObjectType,
-                       boxed: bool,
-                       event_enum_name: str,
-                       event_dispatch: str) -> str:
-    # FIXME: Our declaration of local variables (and of 'errp' in the
-    # parameter list) can collide with exploded members of the event's
-    # data type passed in as parameters.  If this collision ever hits in
-    # practice, we can rename our local variables with a leading _ prefix,
-    # or split the code into a wrapper function that creates a boxed
-    # 'param' object then calls another to do the real work.
-    have_args = boxed or (arg_type and not arg_type.is_empty())
-    ret = mcgen('''
-
-void qapi_event_dispatch_%(name)s(%(handler_type)s handler, CFDictionaryRef data, void *ctx)
-{
-''',
-                name=name, handler_type=build_handler_name(name))
-
-    if have_args:
-        ret += mcgen('''
-    %(c_name)s *arg;
-    Visitor *v;
-''',
-                    c_name=arg_type.c_name())
-
-    if have_args:
-        ret += mcgen('''
-    v = cf_input_visitor_new(data);
-''')
-        ret += mcgen('''
-    visit_start_struct(v, "event", NULL, 0, &error_abort);
-    visit_type_%(c_name)s(v, "data", &arg, &error_abort);
-    visit_end_struct(v, NULL);
-''',
-                         name=name, c_name=arg_type.c_name())
-
-    ret += mcgen('''
-    handler(%(param)s);
-
-''',
-                 param='arg' if boxed else gen_call_handler(arg_type))
-
-    if have_args:
-        ret += mcgen('''
-    visit_free(v);
-    v = qapi_dealloc_visitor_new();
-    visit_type_%(c_name)s(v, "unused", &arg, NULL);
-    visit_free(v);
-''',
-                c_name=arg_type.c_name())
-    ret += mcgen('''
-}
-''')
-    return ret
-
-
-def gen_dispatcher_proto(name: str) -> str:
-    return mcgen('''
-
-void %(name)s(const char *event, CFDictionaryRef data, void *ctx);
-''',
-                name=name)
-
-
-def gen_dispatcher(name: str,
-                   event_enum_name: str,
-                   events) -> str:
-    ret = mcgen('''
-
-void %(name)s(const char *event, CFDictionaryRef data, void *ctx)
-{
-    %(event_enum)s num;
-
-    num = (%(event_enum)s)qapi_enum_parse(&%(event_enum)s_lookup, event, 0, &error_abort);
-    switch (num) {
-        default:
-            assert(0);
-            break;
-''',
-                event_enum=event_enum_name, name=name)
-
-    for event in events:
-        ret += event[0].gen_if()
-        ret += mcgen('''
-        case %(enum_name)s:
-            if (qapi_enum_handler_registry_data.%(handler_name)s) {
-                %(event_name)s(qapi_enum_handler_registry_data.%(handler_name)s, data, ctx);
-            }
-            break;
-''',
-                enum_name=event[1], event_name=event[2], handler_name=event[3])
-        ret += event[0].gen_endif()
-
-    ret += mcgen('''
-    }
-}
-''')
-    return ret
-
-
-def gen_registry(events) -> str:
-    ret = mcgen('''
-
-typedef struct {
-''')
-
-    for event in events:
-        ret += event[0].gen_if()
-        ret += mcgen('''
-    %(handler_name)s %(handler_name)s;
-''',
-                handler_name=event[3])
-        ret += event[0].gen_endif()
-
-    ret += mcgen('''
-} qapi_enum_handler_registry;
-
-extern qapi_enum_handler_registry qapi_enum_handler_registry_data;
-''')
-    return ret
-
-
-class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
-
-    def __init__(self, prefix: str):
-        super().__init__(
-            prefix, 'qapi-events',
-            ' * Schema-defined QAPI/QMP events', None, __doc__)
-        self._event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)
-        self._event_registry = []
-        self._event_enum_members: List[QAPISchemaEnumMember] = []
-        self._event_dispatch_name = c_name(prefix + 'qapi_event_dispatch')
-
-    def _begin_user_module(self, name: str) -> None:
-        events = self._module_basename('qapi-events', name)
-        types = self._module_basename('qapi-types', name)
-        visit = self._module_basename('qapi-visit', name)
-        self._genc.add(mcgen('''
-#include "qemu-compat.h"
-#include "%(prefix)sqapi-emit-events.h"
-#include "%(events)s.h"
-#include "%(visit)s.h"
-#include "error.h"
-#include "cf-input-visitor.h"
-#include "dealloc-visitor.h"
-
-''',
-                             events=events, visit=visit,
-                             prefix=self._prefix))
-        self._genh.add(mcgen('''
-#include "util.h"
-#include "%(types)s.h"
-''',
-                             types=types))
-
-    def visit_end(self) -> None:
-        self._add_module('./emit', ' * QAPI Events emission')
-        self._genc.preamble_add(mcgen('''
-#include "qemu-compat.h"
-#include "%(prefix)sqapi-emit-events.h"
-#include "error.h"
-''',
-                                      prefix=self._prefix))
-        self._genh.preamble_add(mcgen('''
-#include "qapi-events.h"
-#include "util.h"
-'''))
-        self._genh.add(gen_enum(self._event_enum_name,
-                                self._event_enum_members))
-        self._genc.add(gen_enum_lookup(self._event_enum_name,
-                                       self._event_enum_members))
-        self._genh.add(gen_registry(self._event_registry))
-        self._genh.add(gen_dispatcher_proto(self._event_dispatch_name))
-        self._genc.add(gen_dispatcher(self._event_dispatch_name,
-                                      self._event_enum_name,
-                                      self._event_registry))
-
-    def visit_event(self,
-                    name: str,
-                    info: QAPISourceInfo,
-                    ifcond: List[str],
-                    features: List[QAPISchemaFeature],
-                    arg_type: QAPISchemaObjectType,
-                    boxed: bool) -> None:
-        with ifcontext(ifcond, self._genh, self._genc):
-            self._genh.add(gen_event_dispatch_decl(name, arg_type, boxed))
-            self._genc.add(gen_event_dispatch(name, arg_type, boxed,
-                                          self._event_enum_name,
-                                          self._event_dispatch_name))
-            self._event_registry.append((ifcond, c_enum_const(self._event_enum_name, name), 'qapi_event_dispatch_%s' % name, build_handler_name(name)))
-        # Note: we generate the enum member regardless of @ifcond, to
-        # keep the enumeration usable in target-independent code.
-        self._event_enum_members.append(QAPISchemaEnumMember(name, None))
-
-
-def gen_events(schema: QAPISchema,
-               output_dir: str,
-               prefix: str) -> None:
-    vis = QAPISchemaGenEventVisitor(prefix)
-    schema.visit(vis)
-    vis.write(output_dir)

+ 0 - 694
scripts/qapi/expr.py

@@ -1,694 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright IBM, Corp. 2011
-# Copyright (c) 2013-2021 Red Hat Inc.
-#
-# Authors:
-#  Anthony Liguori <aliguori@us.ibm.com>
-#  Markus Armbruster <armbru@redhat.com>
-#  Eric Blake <eblake@redhat.com>
-#  Marc-André Lureau <marcandre.lureau@redhat.com>
-#  John Snow <jsnow@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2.
-# See the COPYING file in the top-level directory.
-
-"""
-Normalize and validate (context-free) QAPI schema expression structures.
-
-`QAPISchemaParser` parses a QAPI schema into abstract syntax trees
-consisting of dict, list, str, bool, and int nodes.  This module ensures
-that these nested structures have the correct type(s) and key(s) where
-appropriate for the QAPI context-free grammar.
-
-The QAPI schema expression language allows for certain syntactic sugar;
-this module also handles the normalization process of these nested
-structures.
-
-See `check_exprs` for the main entry point.
-
-See `schema.QAPISchema` for processing into native Python data
-structures and contextual semantic validation.
-"""
-
-import re
-from typing import (
-    Collection,
-    Dict,
-    Iterable,
-    List,
-    Optional,
-    Union,
-    cast,
-)
-
-from .common import c_name
-from .error import QAPISemError
-from .parser import QAPIDoc
-from .source import QAPISourceInfo
-
-
-# Deserialized JSON objects as returned by the parser.
-# The values of this mapping are not necessary to exhaustively type
-# here (and also not practical as long as mypy lacks recursive
-# types), because the purpose of this module is to interrogate that
-# type.
-_JSONObject = Dict[str, object]
-
-
-# See check_name_str(), below.
-valid_name = re.compile(r'(__[a-z0-9.-]+_)?'
-                        r'(x-)?'
-                        r'([a-z][a-z0-9_-]*)$', re.IGNORECASE)
-
-
-def check_name_is_str(name: object,
-                      info: QAPISourceInfo,
-                      source: str) -> None:
-    """
-    Ensure that ``name`` is a ``str``.
-
-    :raise QAPISemError: When ``name`` fails validation.
-    """
-    if not isinstance(name, str):
-        raise QAPISemError(info, "%s requires a string name" % source)
-
-
-def check_name_str(name: str, info: QAPISourceInfo, source: str) -> str:
-    """
-    Ensure that ``name`` is a valid QAPI name.
-
-    A valid name consists of ASCII letters, digits, ``-``, and ``_``,
-    starting with a letter.  It may be prefixed by a downstream prefix
-    of the form __RFQDN_, or the experimental prefix ``x-``.  If both
-    prefixes are present, the __RFDQN_ prefix goes first.
-
-    A valid name cannot start with ``q_``, which is reserved.
-
-    :param name: Name to check.
-    :param info: QAPI schema source file information.
-    :param source: Error string describing what ``name`` belongs to.
-
-    :raise QAPISemError: When ``name`` fails validation.
-    :return: The stem of the valid name, with no prefixes.
-    """
-    # Reserve the entire 'q_' namespace for c_name(), and for 'q_empty'
-    # and 'q_obj_*' implicit type names.
-    match = valid_name.match(name)
-    if not match or c_name(name, False).startswith('q_'):
-        raise QAPISemError(info, "%s has an invalid name" % source)
-    return match.group(3)
-
-
-def check_name_upper(name: str, info: QAPISourceInfo, source: str) -> None:
-    """
-    Ensure that ``name`` is a valid event name.
-
-    This means it must be a valid QAPI name as checked by
-    `check_name_str()`, but where the stem prohibits lowercase
-    characters and ``-``.
-
-    :param name: Name to check.
-    :param info: QAPI schema source file information.
-    :param source: Error string describing what ``name`` belongs to.
-
-    :raise QAPISemError: When ``name`` fails validation.
-    """
-    stem = check_name_str(name, info, source)
-    if re.search(r'[a-z-]', stem):
-        raise QAPISemError(
-            info, "name of %s must not use lowercase or '-'" % source)
-
-
-def check_name_lower(name: str, info: QAPISourceInfo, source: str,
-                     permit_upper: bool = False,
-                     permit_underscore: bool = False) -> None:
-    """
-    Ensure that ``name`` is a valid command or member name.
-
-    This means it must be a valid QAPI name as checked by
-    `check_name_str()`, but where the stem prohibits uppercase
-    characters and ``_``.
-
-    :param name: Name to check.
-    :param info: QAPI schema source file information.
-    :param source: Error string describing what ``name`` belongs to.
-    :param permit_upper: Additionally permit uppercase.
-    :param permit_underscore: Additionally permit ``_``.
-
-    :raise QAPISemError: When ``name`` fails validation.
-    """
-    stem = check_name_str(name, info, source)
-    if ((not permit_upper and re.search(r'[A-Z]', stem))
-            or (not permit_underscore and '_' in stem)):
-        raise QAPISemError(
-            info, "name of %s must not use uppercase or '_'" % source)
-
-
-def check_name_camel(name: str, info: QAPISourceInfo, source: str) -> None:
-    """
-    Ensure that ``name`` is a valid user-defined type name.
-
-    This means it must be a valid QAPI name as checked by
-    `check_name_str()`, but where the stem must be in CamelCase.
-
-    :param name: Name to check.
-    :param info: QAPI schema source file information.
-    :param source: Error string describing what ``name`` belongs to.
-
-    :raise QAPISemError: When ``name`` fails validation.
-    """
-    stem = check_name_str(name, info, source)
-    if not re.match(r'[A-Z][A-Za-z0-9]*[a-z][A-Za-z0-9]*$', stem):
-        raise QAPISemError(info, "name of %s must use CamelCase" % source)
-
-
-def check_defn_name_str(name: str, info: QAPISourceInfo, meta: str) -> None:
-    """
-    Ensure that ``name`` is a valid definition name.
-
-    Based on the value of ``meta``, this means that:
-      - 'event' names adhere to `check_name_upper()`.
-      - 'command' names adhere to `check_name_lower()`.
-      - Else, meta is a type, and must pass `check_name_camel()`.
-        These names must not end with ``List``.
-
-    :param name: Name to check.
-    :param info: QAPI schema source file information.
-    :param meta: Meta-type name of the QAPI expression.
-
-    :raise QAPISemError: When ``name`` fails validation.
-    """
-    if meta == 'event':
-        check_name_upper(name, info, meta)
-    elif meta == 'command':
-        check_name_lower(
-            name, info, meta,
-            permit_underscore=name in info.pragma.command_name_exceptions)
-    else:
-        check_name_camel(name, info, meta)
-        if name.endswith('List'):
-            raise QAPISemError(
-                info, "%s name should not end in 'List'" % meta)
-
-
-def check_keys(value: _JSONObject,
-               info: QAPISourceInfo,
-               source: str,
-               required: Collection[str],
-               optional: Collection[str]) -> None:
-    """
-    Ensure that a dict has a specific set of keys.
-
-    :param value: The dict to check.
-    :param info: QAPI schema source file information.
-    :param source: Error string describing this ``value``.
-    :param required: Keys that *must* be present.
-    :param optional: Keys that *may* be present.
-
-    :raise QAPISemError: When unknown keys are present.
-    """
-
-    def pprint(elems: Iterable[str]) -> str:
-        return ', '.join("'" + e + "'" for e in sorted(elems))
-
-    missing = set(required) - set(value)
-    if missing:
-        raise QAPISemError(
-            info,
-            "%s misses key%s %s"
-            % (source, 's' if len(missing) > 1 else '',
-               pprint(missing)))
-    allowed = set(required) | set(optional)
-    unknown = set(value) - allowed
-    if unknown:
-        raise QAPISemError(
-            info,
-            "%s has unknown key%s %s\nValid keys are %s."
-            % (source, 's' if len(unknown) > 1 else '',
-               pprint(unknown), pprint(allowed)))
-
-
-def check_flags(expr: _JSONObject, info: QAPISourceInfo) -> None:
-    """
-    Ensure flag members (if present) have valid values.
-
-    :param expr: The expression to validate.
-    :param info: QAPI schema source file information.
-
-    :raise QAPISemError:
-        When certain flags have an invalid value, or when
-        incompatible flags are present.
-    """
-    for key in ('gen', 'success-response'):
-        if key in expr and expr[key] is not False:
-            raise QAPISemError(
-                info, "flag '%s' may only use false value" % key)
-    for key in ('boxed', 'allow-oob', 'allow-preconfig', 'coroutine'):
-        if key in expr and expr[key] is not True:
-            raise QAPISemError(
-                info, "flag '%s' may only use true value" % key)
-    if 'allow-oob' in expr and 'coroutine' in expr:
-        # This is not necessarily a fundamental incompatibility, but
-        # we don't have a use case and the desired semantics isn't
-        # obvious.  The simplest solution is to forbid it until we get
-        # a use case for it.
-        raise QAPISemError(info, "flags 'allow-oob' and 'coroutine' "
-                                 "are incompatible")
-
-
-def check_if(expr: _JSONObject, info: QAPISourceInfo, source: str) -> None:
-    """
-    Validate the ``if`` member of an object.
-
-    The ``if`` member may be either a ``str`` or a dict.
-
-    :param expr: The expression containing the ``if`` member to validate.
-    :param info: QAPI schema source file information.
-    :param source: Error string describing ``expr``.
-
-    :raise QAPISemError:
-        When the "if" member fails validation, or when there are no
-        non-empty conditions.
-    :return: None
-    """
-
-    def _check_if(cond: Union[str, object]) -> None:
-        if isinstance(cond, str):
-            if not re.fullmatch(r'[A-Z][A-Z0-9_]*', cond):
-                raise QAPISemError(
-                    info,
-                    "'if' condition '%s' of %s is not a valid identifier"
-                    % (cond, source))
-            return
-
-        if not isinstance(cond, dict):
-            raise QAPISemError(
-                info,
-                "'if' condition of %s must be a string or an object" % source)
-        check_keys(cond, info, "'if' condition of %s" % source, [],
-                   ["all", "any", "not"])
-        if len(cond) != 1:
-            raise QAPISemError(
-                info,
-                "'if' condition of %s has conflicting keys" % source)
-
-        if 'not' in cond:
-            _check_if(cond['not'])
-        elif 'all' in cond:
-            _check_infix('all', cond['all'])
-        else:
-            _check_infix('any', cond['any'])
-
-    def _check_infix(operator: str, operands: object) -> None:
-        if not isinstance(operands, list):
-            raise QAPISemError(
-                info,
-                "'%s' condition of %s must be an array"
-                % (operator, source))
-        if not operands:
-            raise QAPISemError(
-                info, "'if' condition [] of %s is useless" % source)
-        for operand in operands:
-            _check_if(operand)
-
-    ifcond = expr.get('if')
-    if ifcond is None:
-        return
-
-    _check_if(ifcond)
-
-
-def normalize_members(members: object) -> None:
-    """
-    Normalize a "members" value.
-
-    If ``members`` is a dict, for every value in that dict, if that
-    value is not itself already a dict, normalize it to
-    ``{'type': value}``.
-
-    :forms:
-      :sugared: ``Dict[str, Union[str, TypeRef]]``
-      :canonical: ``Dict[str, TypeRef]``
-
-    :param members: The members value to normalize.
-
-    :return: None, ``members`` is normalized in-place as needed.
-    """
-    if isinstance(members, dict):
-        for key, arg in members.items():
-            if isinstance(arg, dict):
-                continue
-            members[key] = {'type': arg}
-
-
-def check_type(value: Optional[object],
-               info: QAPISourceInfo,
-               source: str,
-               allow_array: bool = False,
-               allow_dict: Union[bool, str] = False) -> None:
-    """
-    Normalize and validate the QAPI type of ``value``.
-
-    Python types of ``str`` or ``None`` are always allowed.
-
-    :param value: The value to check.
-    :param info: QAPI schema source file information.
-    :param source: Error string describing this ``value``.
-    :param allow_array:
-        Allow a ``List[str]`` of length 1, which indicates an array of
-        the type named by the list element.
-    :param allow_dict:
-        Allow a dict.  Its members can be struct type members or union
-        branches.  When the value of ``allow_dict`` is in pragma
-        ``member-name-exceptions``, the dict's keys may violate the
-        member naming rules.  The dict members are normalized in place.
-
-    :raise QAPISemError: When ``value`` fails validation.
-    :return: None, ``value`` is normalized in-place as needed.
-    """
-    if value is None:
-        return
-
-    # Type name
-    if isinstance(value, str):
-        return
-
-    # Array type
-    if isinstance(value, list):
-        if not allow_array:
-            raise QAPISemError(info, "%s cannot be an array" % source)
-        if len(value) != 1 or not isinstance(value[0], str):
-            raise QAPISemError(info,
-                               "%s: array type must contain single type name" %
-                               source)
-        return
-
-    # Anonymous type
-
-    if not allow_dict:
-        raise QAPISemError(info, "%s should be a type name" % source)
-
-    if not isinstance(value, dict):
-        raise QAPISemError(info,
-                           "%s should be an object or type name" % source)
-
-    permissive = False
-    if isinstance(allow_dict, str):
-        permissive = allow_dict in info.pragma.member_name_exceptions
-
-    # value is a dictionary, check that each member is okay
-    for (key, arg) in value.items():
-        key_source = "%s member '%s'" % (source, key)
-        if key.startswith('*'):
-            key = key[1:]
-        check_name_lower(key, info, key_source,
-                         permit_upper=permissive,
-                         permit_underscore=permissive)
-        if c_name(key, False) == 'u' or c_name(key, False).startswith('has_'):
-            raise QAPISemError(info, "%s uses reserved name" % key_source)
-        check_keys(arg, info, key_source, ['type'], ['if', 'features'])
-        check_if(arg, info, key_source)
-        check_features(arg.get('features'), info)
-        check_type(arg['type'], info, key_source, allow_array=True)
-
-
-def check_features(features: Optional[object],
-                   info: QAPISourceInfo) -> None:
-    """
-    Normalize and validate the ``features`` member.
-
-    ``features`` may be a ``list`` of either ``str`` or ``dict``.
-    Any ``str`` element will be normalized to ``{'name': element}``.
-
-    :forms:
-      :sugared: ``List[Union[str, Feature]]``
-      :canonical: ``List[Feature]``
-
-    :param features: The features member value to validate.
-    :param info: QAPI schema source file information.
-
-    :raise QAPISemError: When ``features`` fails validation.
-    :return: None, ``features`` is normalized in-place as needed.
-    """
-    if features is None:
-        return
-    if not isinstance(features, list):
-        raise QAPISemError(info, "'features' must be an array")
-    features[:] = [f if isinstance(f, dict) else {'name': f}
-                   for f in features]
-    for feat in features:
-        source = "'features' member"
-        assert isinstance(feat, dict)
-        check_keys(feat, info, source, ['name'], ['if'])
-        check_name_is_str(feat['name'], info, source)
-        source = "%s '%s'" % (source, feat['name'])
-        check_name_str(feat['name'], info, source)
-        check_if(feat, info, source)
-
-
-def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None:
-    """
-    Normalize and validate this expression as an ``enum`` definition.
-
-    :param expr: The expression to validate.
-    :param info: QAPI schema source file information.
-
-    :raise QAPISemError: When ``expr`` is not a valid ``enum``.
-    :return: None, ``expr`` is normalized in-place as needed.
-    """
-    name = expr['enum']
-    members = expr['data']
-    prefix = expr.get('prefix')
-
-    if not isinstance(members, list):
-        raise QAPISemError(info, "'data' must be an array")
-    if prefix is not None and not isinstance(prefix, str):
-        raise QAPISemError(info, "'prefix' must be a string")
-
-    permissive = name in info.pragma.member_name_exceptions
-
-    members[:] = [m if isinstance(m, dict) else {'name': m}
-                  for m in members]
-    for member in members:
-        source = "'data' member"
-        check_keys(member, info, source, ['name'], ['if', 'features'])
-        member_name = member['name']
-        check_name_is_str(member_name, info, source)
-        source = "%s '%s'" % (source, member_name)
-        # Enum members may start with a digit
-        if member_name[0].isdigit():
-            member_name = 'd' + member_name  # Hack: hide the digit
-        check_name_lower(member_name, info, source,
-                         permit_upper=permissive,
-                         permit_underscore=permissive)
-        check_if(member, info, source)
-        check_features(member.get('features'), info)
-
-
-def check_struct(expr: _JSONObject, info: QAPISourceInfo) -> None:
-    """
-    Normalize and validate this expression as a ``struct`` definition.
-
-    :param expr: The expression to validate.
-    :param info: QAPI schema source file information.
-
-    :raise QAPISemError: When ``expr`` is not a valid ``struct``.
-    :return: None, ``expr`` is normalized in-place as needed.
-    """
-    name = cast(str, expr['struct'])  # Checked in check_exprs
-    members = expr['data']
-
-    check_type(members, info, "'data'", allow_dict=name)
-    check_type(expr.get('base'), info, "'base'")
-
-
-def check_union(expr: _JSONObject, info: QAPISourceInfo) -> None:
-    """
-    Normalize and validate this expression as a ``union`` definition.
-
-    :param expr: The expression to validate.
-    :param info: QAPI schema source file information.
-
-    :raise QAPISemError: when ``expr`` is not a valid ``union``.
-    :return: None, ``expr`` is normalized in-place as needed.
-    """
-    name = cast(str, expr['union'])  # Checked in check_exprs
-    base = expr['base']
-    discriminator = expr['discriminator']
-    members = expr['data']
-
-    check_type(base, info, "'base'", allow_dict=name)
-    check_name_is_str(discriminator, info, "'discriminator'")
-
-    if not isinstance(members, dict):
-        raise QAPISemError(info, "'data' must be an object")
-
-    for (key, value) in members.items():
-        source = "'data' member '%s'" % key
-        check_keys(value, info, source, ['type'], ['if'])
-        check_if(value, info, source)
-        check_type(value['type'], info, source, allow_array=not base)
-
-
-def check_alternate(expr: _JSONObject, info: QAPISourceInfo) -> None:
-    """
-    Normalize and validate this expression as an ``alternate`` definition.
-
-    :param expr: The expression to validate.
-    :param info: QAPI schema source file information.
-
-    :raise QAPISemError: When ``expr`` is not a valid ``alternate``.
-    :return: None, ``expr`` is normalized in-place as needed.
-    """
-    members = expr['data']
-
-    if not members:
-        raise QAPISemError(info, "'data' must not be empty")
-
-    if not isinstance(members, dict):
-        raise QAPISemError(info, "'data' must be an object")
-
-    for (key, value) in members.items():
-        source = "'data' member '%s'" % key
-        check_name_lower(key, info, source)
-        check_keys(value, info, source, ['type'], ['if'])
-        check_if(value, info, source)
-        check_type(value['type'], info, source, allow_array=True)
-
-
-def check_command(expr: _JSONObject, info: QAPISourceInfo) -> None:
-    """
-    Normalize and validate this expression as a ``command`` definition.
-
-    :param expr: The expression to validate.
-    :param info: QAPI schema source file information.
-
-    :raise QAPISemError: When ``expr`` is not a valid ``command``.
-    :return: None, ``expr`` is normalized in-place as needed.
-    """
-    args = expr.get('data')
-    rets = expr.get('returns')
-    boxed = expr.get('boxed', False)
-
-    if boxed and args is None:
-        raise QAPISemError(info, "'boxed': true requires 'data'")
-    check_type(args, info, "'data'", allow_dict=not boxed)
-    check_type(rets, info, "'returns'", allow_array=True)
-
-
-def check_event(expr: _JSONObject, info: QAPISourceInfo) -> None:
-    """
-    Normalize and validate this expression as an ``event`` definition.
-
-    :param expr: The expression to validate.
-    :param info: QAPI schema source file information.
-
-    :raise QAPISemError: When ``expr`` is not a valid ``event``.
-    :return: None, ``expr`` is normalized in-place as needed.
-    """
-    args = expr.get('data')
-    boxed = expr.get('boxed', False)
-
-    if boxed and args is None:
-        raise QAPISemError(info, "'boxed': true requires 'data'")
-    check_type(args, info, "'data'", allow_dict=not boxed)
-
-
-def check_exprs(exprs: List[_JSONObject]) -> List[_JSONObject]:
-    """
-    Validate and normalize a list of parsed QAPI schema expressions.
-
-    This function accepts a list of expressions and metadata as returned
-    by the parser.  It destructively normalizes the expressions in-place.
-
-    :param exprs: The list of expressions to normalize and validate.
-
-    :raise QAPISemError: When any expression fails validation.
-    :return: The same list of expressions (now modified).
-    """
-    for expr_elem in exprs:
-        # Expression
-        assert isinstance(expr_elem['expr'], dict)
-        for key in expr_elem['expr'].keys():
-            assert isinstance(key, str)
-        expr: _JSONObject = expr_elem['expr']
-
-        # QAPISourceInfo
-        assert isinstance(expr_elem['info'], QAPISourceInfo)
-        info: QAPISourceInfo = expr_elem['info']
-
-        # Optional[QAPIDoc]
-        tmp = expr_elem.get('doc')
-        assert tmp is None or isinstance(tmp, QAPIDoc)
-        doc: Optional[QAPIDoc] = tmp
-
-        if 'include' in expr:
-            continue
-
-        metas = expr.keys() & {'enum', 'struct', 'union', 'alternate',
-                               'command', 'event'}
-        if len(metas) != 1:
-            raise QAPISemError(
-                info,
-                "expression must have exactly one key"
-                " 'enum', 'struct', 'union', 'alternate',"
-                " 'command', 'event'")
-        meta = metas.pop()
-
-        check_name_is_str(expr[meta], info, "'%s'" % meta)
-        name = cast(str, expr[meta])
-        info.set_defn(meta, name)
-        check_defn_name_str(name, info, meta)
-
-        if doc:
-            if doc.symbol != name:
-                raise QAPISemError(
-                    info, "documentation comment is for '%s'" % doc.symbol)
-            doc.check_expr(expr)
-        elif info.pragma.doc_required:
-            raise QAPISemError(info,
-                               "documentation comment required")
-
-        if meta == 'enum':
-            check_keys(expr, info, meta,
-                       ['enum', 'data'], ['if', 'features', 'prefix'])
-            check_enum(expr, info)
-        elif meta == 'union':
-            check_keys(expr, info, meta,
-                       ['union', 'base', 'discriminator', 'data'],
-                       ['if', 'features'])
-            normalize_members(expr.get('base'))
-            normalize_members(expr['data'])
-            check_union(expr, info)
-        elif meta == 'alternate':
-            check_keys(expr, info, meta,
-                       ['alternate', 'data'], ['if', 'features'])
-            normalize_members(expr['data'])
-            check_alternate(expr, info)
-        elif meta == 'struct':
-            check_keys(expr, info, meta,
-                       ['struct', 'data'], ['base', 'if', 'features'])
-            normalize_members(expr['data'])
-            check_struct(expr, info)
-        elif meta == 'command':
-            check_keys(expr, info, meta,
-                       ['command'],
-                       ['data', 'returns', 'boxed', 'if', 'features',
-                        'gen', 'success-response', 'allow-oob',
-                        'allow-preconfig', 'coroutine'])
-            normalize_members(expr.get('data'))
-            check_command(expr, info)
-        elif meta == 'event':
-            check_keys(expr, info, meta,
-                       ['event'], ['data', 'boxed', 'if', 'features'])
-            normalize_members(expr.get('data'))
-            check_event(expr, info)
-        else:
-            assert False, 'unexpected meta type'
-
-        check_if(expr, info, meta)
-        check_features(expr.get('features'), info)
-        check_flags(expr, info)
-
-    return exprs

+ 0 - 339
scripts/qapi/gen.py

@@ -1,339 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# QAPI code generation
-#
-# Copyright (c) 2015-2019 Red Hat Inc.
-#
-# Authors:
-#  Markus Armbruster <armbru@redhat.com>
-#  Marc-André Lureau <marcandre.lureau@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 contextlib import contextmanager
-import os
-import re
-from typing import (
-    Dict,
-    Iterator,
-    Optional,
-    Sequence,
-    Tuple,
-)
-
-from .common import (
-    c_fname,
-    c_name,
-    guardend,
-    guardstart,
-    mcgen,
-)
-from .schema import (
-    QAPISchemaFeature,
-    QAPISchemaIfCond,
-    QAPISchemaModule,
-    QAPISchemaObjectType,
-    QAPISchemaVisitor,
-)
-from .source import QAPISourceInfo
-
-
-def gen_special_features(features: Sequence[QAPISchemaFeature]) -> str:
-    special_features = [f"1u << QAPI_{feat.name.upper()}"
-                        for feat in features if feat.is_special()]
-    return ' | '.join(special_features) or '0'
-
-
-class QAPIGen:
-    def __init__(self, fname: str):
-        self.fname = fname
-        self._preamble = ''
-        self._body = ''
-
-    def preamble_add(self, text: str) -> None:
-        self._preamble += text
-
-    def add(self, text: str) -> None:
-        self._body += text
-
-    def get_content(self) -> str:
-        return self._top() + self._preamble + self._body + self._bottom()
-
-    def _top(self) -> str:
-        # pylint: disable=no-self-use
-        return ''
-
-    def _bottom(self) -> str:
-        # pylint: disable=no-self-use
-        return ''
-
-    def write(self, output_dir: str) -> None:
-        # Include paths starting with ../ are used to reuse modules of the main
-        # schema in specialised schemas. Don't overwrite the files that are
-        # already generated for the main schema.
-        if self.fname.startswith('../'):
-            return
-        pathname = os.path.join(output_dir, self.fname)
-        odir = os.path.dirname(pathname)
-
-        if odir:
-            os.makedirs(odir, exist_ok=True)
-
-        # use os.open for O_CREAT to create and read a non-existant file
-        fd = os.open(pathname, os.O_RDWR | os.O_CREAT, 0o666)
-        with os.fdopen(fd, 'r+', encoding='utf-8') as fp:
-            text = self.get_content()
-            oldtext = fp.read(len(text) + 1)
-            if text != oldtext:
-                fp.seek(0)
-                fp.truncate(0)
-                fp.write(text)
-
-
-def _wrap_ifcond(ifcond: QAPISchemaIfCond, before: str, after: str) -> str:
-    if before == after:
-        return after   # suppress empty #if ... #endif
-
-    assert after.startswith(before)
-    out = before
-    added = after[len(before):]
-    if added[0] == '\n':
-        out += '\n'
-        added = added[1:]
-    out += ifcond.gen_if()
-    out += added
-    out += ifcond.gen_endif()
-    return out
-
-
-def build_params(arg_type: Optional[QAPISchemaObjectType],
-                 boxed: bool,
-                 extra: Optional[str] = None) -> str:
-    ret = ''
-    sep = ''
-    if boxed:
-        assert arg_type
-        ret += '%s arg' % arg_type.c_param_type()
-        sep = ', '
-    elif arg_type:
-        assert not arg_type.variants
-        for memb in arg_type.members:
-            ret += sep
-            sep = ', '
-            if memb.optional:
-                ret += 'bool has_%s, ' % c_name(memb.name)
-            ret += '%s %s' % (memb.type.c_param_type(),
-                              c_name(memb.name))
-    if extra:
-        ret += sep + extra
-    return ret if ret else 'void'
-
-
-class QAPIGenCCode(QAPIGen):
-    def __init__(self, fname: str):
-        super().__init__(fname)
-        self._start_if: Optional[Tuple[QAPISchemaIfCond, str, str]] = None
-
-    def start_if(self, ifcond: QAPISchemaIfCond) -> None:
-        assert self._start_if is None
-        self._start_if = (ifcond, self._body, self._preamble)
-
-    def end_if(self) -> None:
-        assert self._start_if is not None
-        self._body = _wrap_ifcond(self._start_if[0],
-                                  self._start_if[1], self._body)
-        self._preamble = _wrap_ifcond(self._start_if[0],
-                                      self._start_if[2], self._preamble)
-        self._start_if = None
-
-    def get_content(self) -> str:
-        assert self._start_if is None
-        return super().get_content()
-
-
-class QAPIGenC(QAPIGenCCode):
-    def __init__(self, fname: str, blurb: str, pydoc: str):
-        super().__init__(fname)
-        self._blurb = blurb
-        self._copyright = '\n * '.join(re.findall(r'^Copyright .*', pydoc,
-                                                  re.MULTILINE))
-
-    def _top(self) -> str:
-        return mcgen('''
-/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
-
-/*
-%(blurb)s
- *
- * %(copyright)s
- *
- * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-''',
-                     blurb=self._blurb, copyright=self._copyright)
-
-    def _bottom(self) -> str:
-        return mcgen('''
-
-/* Dummy declaration to prevent empty .o file */
-char qapi_dummy_%(name)s;
-''',
-                     name=c_fname(self.fname))
-
-
-class QAPIGenH(QAPIGenC):
-    def _top(self) -> str:
-        return super()._top() + guardstart(self.fname)
-
-    def _bottom(self) -> str:
-        return guardend(self.fname)
-
-
-@contextmanager
-def ifcontext(ifcond: QAPISchemaIfCond, *args: QAPIGenCCode) -> Iterator[None]:
-    """
-    A with-statement context manager that wraps with `start_if()` / `end_if()`.
-
-    :param ifcond: A sequence of conditionals, passed to `start_if()`.
-    :param args: any number of `QAPIGenCCode`.
-
-    Example::
-
-        with ifcontext(ifcond, self._genh, self._genc):
-            modify self._genh and self._genc ...
-
-    Is equivalent to calling::
-
-        self._genh.start_if(ifcond)
-        self._genc.start_if(ifcond)
-        modify self._genh and self._genc ...
-        self._genh.end_if()
-        self._genc.end_if()
-    """
-    for arg in args:
-        arg.start_if(ifcond)
-    yield
-    for arg in args:
-        arg.end_if()
-
-
-class QAPISchemaMonolithicCVisitor(QAPISchemaVisitor):
-    def __init__(self,
-                 prefix: str,
-                 what: str,
-                 blurb: str,
-                 pydoc: str):
-        self._prefix = prefix
-        self._what = what
-        self._genc = QAPIGenC(self._prefix + self._what + '.c',
-                              blurb, pydoc)
-        self._genh = QAPIGenH(self._prefix + self._what + '.h',
-                              blurb, pydoc)
-
-    def write(self, output_dir: str) -> None:
-        self._genc.write(output_dir)
-        self._genh.write(output_dir)
-
-
-class QAPISchemaModularCVisitor(QAPISchemaVisitor):
-    def __init__(self,
-                 prefix: str,
-                 what: str,
-                 user_blurb: str,
-                 builtin_blurb: Optional[str],
-                 pydoc: str):
-        self._prefix = prefix
-        self._what = what
-        self._user_blurb = user_blurb
-        self._builtin_blurb = builtin_blurb
-        self._pydoc = pydoc
-        self._current_module: Optional[str] = None
-        self._module: Dict[str, Tuple[QAPIGenC, QAPIGenH]] = {}
-        self._main_module: Optional[str] = None
-
-    @property
-    def _genc(self) -> QAPIGenC:
-        assert self._current_module is not None
-        return self._module[self._current_module][0]
-
-    @property
-    def _genh(self) -> QAPIGenH:
-        assert self._current_module is not None
-        return self._module[self._current_module][1]
-
-    @staticmethod
-    def _module_dirname(name: str) -> str:
-        if QAPISchemaModule.is_user_module(name):
-            return os.path.dirname(name)
-        return ''
-
-    def _module_basename(self, what: str, name: str) -> str:
-        ret = '' if QAPISchemaModule.is_builtin_module(name) else self._prefix
-        if QAPISchemaModule.is_user_module(name):
-            basename = os.path.basename(name)
-            ret += what
-            if name != self._main_module:
-                ret += '-' + os.path.splitext(basename)[0]
-        else:
-            assert QAPISchemaModule.is_system_module(name)
-            ret += re.sub(r'-', '-' + name[2:] + '-', what)
-        return ret
-
-    def _module_filename(self, what: str, name: str) -> str:
-        return os.path.join(self._module_dirname(name),
-                            self._module_basename(what, name))
-
-    def _add_module(self, name: str, blurb: str) -> None:
-        if QAPISchemaModule.is_user_module(name):
-            if self._main_module is None:
-                self._main_module = name
-        basename = self._module_filename(self._what, name)
-        genc = QAPIGenC(basename + '.c', blurb, self._pydoc)
-        genh = QAPIGenH(basename + '.h', blurb, self._pydoc)
-        self._module[name] = (genc, genh)
-        self._current_module = name
-
-    @contextmanager
-    def _temp_module(self, name: str) -> Iterator[None]:
-        old_module = self._current_module
-        self._current_module = name
-        yield
-        self._current_module = old_module
-
-    def write(self, output_dir: str, opt_builtins: bool = False) -> None:
-        for name, (genc, genh) in self._module.items():
-            if QAPISchemaModule.is_builtin_module(name) and not opt_builtins:
-                continue
-            genc.write(output_dir)
-            genh.write(output_dir)
-
-    def _begin_builtin_module(self) -> None:
-        pass
-
-    def _begin_user_module(self, name: str) -> None:
-        pass
-
-    def visit_module(self, name: str) -> None:
-        if QAPISchemaModule.is_builtin_module(name):
-            if self._builtin_blurb:
-                self._add_module(name, self._builtin_blurb)
-                self._begin_builtin_module()
-            else:
-                # The built-in module has not been created.  No code may
-                # be generated.
-                self._current_module = None
-        else:
-            assert QAPISchemaModule.is_user_module(name)
-            self._add_module(name, self._user_blurb)
-            self._begin_user_module(name)
-
-    def visit_include(self, name: str, info: Optional[QAPISourceInfo]) -> None:
-        relname = os.path.relpath(self._module_filename(self._what, name),
-                                  os.path.dirname(self._genh.fname))
-        self._genh.preamble_add(mcgen('''
-#include "%(relname)s.h"
-''',
-                                      relname=relname))

+ 0 - 390
scripts/qapi/introspect.py

@@ -1,390 +0,0 @@
-"""
-QAPI introspection generator
-
-Copyright (C) 2015-2021 Red Hat, Inc.
-
-Authors:
- Markus Armbruster <armbru@redhat.com>
- John Snow <jsnow@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 typing import (
-    Any,
-    Dict,
-    Generic,
-    List,
-    Optional,
-    Sequence,
-    TypeVar,
-    Union,
-)
-
-from .common import c_name, mcgen
-from .gen import QAPISchemaMonolithicCVisitor
-from .schema import (
-    QAPISchema,
-    QAPISchemaArrayType,
-    QAPISchemaBuiltinType,
-    QAPISchemaEntity,
-    QAPISchemaEnumMember,
-    QAPISchemaFeature,
-    QAPISchemaIfCond,
-    QAPISchemaObjectType,
-    QAPISchemaObjectTypeMember,
-    QAPISchemaType,
-    QAPISchemaVariant,
-    QAPISchemaVariants,
-)
-from .source import QAPISourceInfo
-
-
-# This module constructs a tree data structure that is used to
-# generate the introspection information for QEMU. It is shaped
-# like a JSON value.
-#
-# A complexity over JSON is that our values may or may not be annotated.
-#
-# Un-annotated values may be:
-#     Scalar: str, bool, None.
-#     Non-scalar: List, Dict
-# _value = Union[str, bool, None, Dict[str, JSONValue], List[JSONValue]]
-#
-# With optional annotations, the type of all values is:
-# JSONValue = Union[_Value, Annotated[_Value]]
-#
-# Sadly, mypy does not support recursive types; so the _Stub alias is used to
-# mark the imprecision in the type model where we'd otherwise use JSONValue.
-_Stub = Any
-_Scalar = Union[str, bool, None]
-_NonScalar = Union[Dict[str, _Stub], List[_Stub]]
-_Value = Union[_Scalar, _NonScalar]
-JSONValue = Union[_Value, 'Annotated[_Value]']
-
-# These types are based on structures defined in QEMU's schema, so we
-# lack precise types for them here. Python 3.6 does not offer
-# TypedDict constructs, so they are broadly typed here as simple
-# Python Dicts.
-SchemaInfo = Dict[str, object]
-SchemaInfoEnumMember = Dict[str, object]
-SchemaInfoObject = Dict[str, object]
-SchemaInfoObjectVariant = Dict[str, object]
-SchemaInfoObjectMember = Dict[str, object]
-SchemaInfoCommand = Dict[str, object]
-
-
-_ValueT = TypeVar('_ValueT', bound=_Value)
-
-
-class Annotated(Generic[_ValueT]):
-    """
-    Annotated generally contains a SchemaInfo-like type (as a dict),
-    But it also used to wrap comments/ifconds around scalar leaf values,
-    for the benefit of features and enums.
-    """
-    # TODO: Remove after Python 3.7 adds @dataclass:
-    # pylint: disable=too-few-public-methods
-    def __init__(self, value: _ValueT, ifcond: QAPISchemaIfCond,
-                 comment: Optional[str] = None):
-        self.value = value
-        self.comment: Optional[str] = comment
-        self.ifcond = ifcond
-
-
-def _tree_to_qlit(obj: JSONValue,
-                  level: int = 0,
-                  dict_value: bool = False) -> str:
-    """
-    Convert the type tree into a QLIT C string, recursively.
-
-    :param obj: The value to convert.
-                This value may not be Annotated when dict_value is True.
-    :param level: The indentation level for this particular value.
-    :param dict_value: True when the value being processed belongs to a
-                       dict key; which suppresses the output indent.
-    """
-
-    def indent(level: int) -> str:
-        return level * 4 * ' '
-
-    if isinstance(obj, Annotated):
-        # NB: _tree_to_qlit is called recursively on the values of a
-        # key:value pair; those values can't be decorated with
-        # comments or conditionals.
-        msg = "dict values cannot have attached comments or if-conditionals."
-        assert not dict_value, msg
-
-        ret = ''
-        if obj.comment:
-            ret += indent(level) + f"/* {obj.comment} */\n"
-        if obj.ifcond.is_present():
-            ret += obj.ifcond.gen_if()
-        ret += _tree_to_qlit(obj.value, level)
-        if obj.ifcond.is_present():
-            ret += '\n' + obj.ifcond.gen_endif()
-        return ret
-
-    ret = ''
-    if not dict_value:
-        ret += indent(level)
-
-    # Scalars:
-    if obj is None:
-        ret += 'QLIT_QNULL'
-    elif isinstance(obj, str):
-        ret += f"QLIT_QSTR({to_c_string(obj)})"
-    elif isinstance(obj, bool):
-        ret += f"QLIT_QBOOL({str(obj).lower()})"
-
-    # Non-scalars:
-    elif isinstance(obj, list):
-        ret += 'QLIT_QLIST(((QLitObject[]) {\n'
-        for value in obj:
-            ret += _tree_to_qlit(value, level + 1).strip('\n') + '\n'
-        ret += indent(level + 1) + '{}\n'
-        ret += indent(level) + '}))'
-    elif isinstance(obj, dict):
-        ret += 'QLIT_QDICT(((QLitDictEntry[]) {\n'
-        for key, value in sorted(obj.items()):
-            ret += indent(level + 1) + "{{ {:s}, {:s} }},\n".format(
-                to_c_string(key),
-                _tree_to_qlit(value, level + 1, dict_value=True)
-            )
-        ret += indent(level + 1) + '{}\n'
-        ret += indent(level) + '}))'
-    else:
-        raise NotImplementedError(
-            f"type '{type(obj).__name__}' not implemented"
-        )
-
-    if level > 0:
-        ret += ','
-    return ret
-
-
-def to_c_string(string: str) -> str:
-    return '"' + string.replace('\\', r'\\').replace('"', r'\"') + '"'
-
-
-class QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor):
-
-    def __init__(self, prefix: str, unmask: bool):
-        super().__init__(
-            prefix, 'qapi-introspect',
-            ' * QAPI/QMP schema introspection', __doc__)
-        self._unmask = unmask
-        self._schema: Optional[QAPISchema] = None
-        self._trees: List[Annotated[SchemaInfo]] = []
-        self._used_types: List[QAPISchemaType] = []
-        self._name_map: Dict[str, str] = {}
-        self._genc.add(mcgen('''
-#include "qemu/osdep.h"
-#include "%(prefix)sqapi-introspect.h"
-
-''',
-                             prefix=prefix))
-
-    def visit_begin(self, schema: QAPISchema) -> None:
-        self._schema = schema
-
-    def visit_end(self) -> None:
-        # visit the types that are actually used
-        for typ in self._used_types:
-            typ.visit(self)
-        # generate C
-        name = c_name(self._prefix, protect=False) + 'qmp_schema_qlit'
-        self._genh.add(mcgen('''
-#include "qapi/qmp/qlit.h"
-
-extern const QLitObject %(c_name)s;
-''',
-                             c_name=c_name(name)))
-        self._genc.add(mcgen('''
-const QLitObject %(c_name)s = %(c_string)s;
-''',
-                             c_name=c_name(name),
-                             c_string=_tree_to_qlit(self._trees)))
-        self._schema = None
-        self._trees = []
-        self._used_types = []
-        self._name_map = {}
-
-    def visit_needed(self, entity: QAPISchemaEntity) -> bool:
-        # Ignore types on first pass; visit_end() will pick up used types
-        return not isinstance(entity, QAPISchemaType)
-
-    def _name(self, name: str) -> str:
-        if self._unmask:
-            return name
-        if name not in self._name_map:
-            self._name_map[name] = '%d' % len(self._name_map)
-        return self._name_map[name]
-
-    def _use_type(self, typ: QAPISchemaType) -> str:
-        assert self._schema is not None
-
-        # Map the various integer types to plain int
-        if typ.json_type() == 'int':
-            typ = self._schema.lookup_type('int')
-        elif (isinstance(typ, QAPISchemaArrayType) and
-              typ.element_type.json_type() == 'int'):
-            typ = self._schema.lookup_type('intList')
-        # Add type to work queue if new
-        if typ not in self._used_types:
-            self._used_types.append(typ)
-        # Clients should examine commands and events, not types.  Hide
-        # type names as integers to reduce the temptation.  Also, it
-        # saves a few characters on the wire.
-        if isinstance(typ, QAPISchemaBuiltinType):
-            return typ.name
-        if isinstance(typ, QAPISchemaArrayType):
-            return '[' + self._use_type(typ.element_type) + ']'
-        return self._name(typ.name)
-
-    @staticmethod
-    def _gen_features(features: Sequence[QAPISchemaFeature]
-                      ) -> List[Annotated[str]]:
-        return [Annotated(f.name, f.ifcond) for f in features]
-
-    def _gen_tree(self, name: str, mtype: str, obj: Dict[str, object],
-                  ifcond: QAPISchemaIfCond = QAPISchemaIfCond(),
-                  features: Sequence[QAPISchemaFeature] = ()) -> None:
-        """
-        Build and append a SchemaInfo object to self._trees.
-
-        :param name: The SchemaInfo's name.
-        :param mtype: The SchemaInfo's meta-type.
-        :param obj: Additional SchemaInfo members, as appropriate for
-                    the meta-type.
-        :param ifcond: Conditionals to apply to the SchemaInfo.
-        :param features: The SchemaInfo's features.
-                         Will be omitted from the output if empty.
-        """
-        comment: Optional[str] = None
-        if mtype not in ('command', 'event', 'builtin', 'array'):
-            if not self._unmask:
-                # Output a comment to make it easy to map masked names
-                # back to the source when reading the generated output.
-                comment = f'"{self._name(name)}" = {name}'
-            name = self._name(name)
-        obj['name'] = name
-        obj['meta-type'] = mtype
-        if features:
-            obj['features'] = self._gen_features(features)
-        self._trees.append(Annotated(obj, ifcond, comment))
-
-    def _gen_enum_member(self, member: QAPISchemaEnumMember
-                         ) -> Annotated[SchemaInfoEnumMember]:
-        obj: SchemaInfoEnumMember = {
-            'name': member.name,
-        }
-        if member.features:
-            obj['features'] = self._gen_features(member.features)
-        return Annotated(obj, member.ifcond)
-
-    def _gen_object_member(self, member: QAPISchemaObjectTypeMember
-                           ) -> Annotated[SchemaInfoObjectMember]:
-        obj: SchemaInfoObjectMember = {
-            'name': member.name,
-            'type': self._use_type(member.type)
-        }
-        if member.optional:
-            obj['default'] = None
-        if member.features:
-            obj['features'] = self._gen_features(member.features)
-        return Annotated(obj, member.ifcond)
-
-    def _gen_variant(self, variant: QAPISchemaVariant
-                     ) -> Annotated[SchemaInfoObjectVariant]:
-        obj: SchemaInfoObjectVariant = {
-            'case': variant.name,
-            'type': self._use_type(variant.type)
-        }
-        return Annotated(obj, variant.ifcond)
-
-    def visit_builtin_type(self, name: str, info: Optional[QAPISourceInfo],
-                           json_type: str) -> None:
-        self._gen_tree(name, 'builtin', {'json-type': json_type})
-
-    def visit_enum_type(self, name: str, info: Optional[QAPISourceInfo],
-                        ifcond: QAPISchemaIfCond,
-                        features: List[QAPISchemaFeature],
-                        members: List[QAPISchemaEnumMember],
-                        prefix: Optional[str]) -> None:
-        self._gen_tree(
-            name, 'enum',
-            {'members': [self._gen_enum_member(m) for m in members],
-             'values': [Annotated(m.name, m.ifcond) for m in members]},
-            ifcond, features
-        )
-
-    def visit_array_type(self, name: str, info: Optional[QAPISourceInfo],
-                         ifcond: QAPISchemaIfCond,
-                         element_type: QAPISchemaType) -> None:
-        element = self._use_type(element_type)
-        self._gen_tree('[' + element + ']', 'array', {'element-type': element},
-                       ifcond)
-
-    def visit_object_type_flat(self, name: str, info: Optional[QAPISourceInfo],
-                               ifcond: QAPISchemaIfCond,
-                               features: List[QAPISchemaFeature],
-                               members: List[QAPISchemaObjectTypeMember],
-                               variants: Optional[QAPISchemaVariants]) -> None:
-        obj: SchemaInfoObject = {
-            'members': [self._gen_object_member(m) for m in members]
-        }
-        if variants:
-            obj['tag'] = variants.tag_member.name
-            obj['variants'] = [self._gen_variant(v) for v in variants.variants]
-        self._gen_tree(name, 'object', obj, ifcond, features)
-
-    def visit_alternate_type(self, name: str, info: Optional[QAPISourceInfo],
-                             ifcond: QAPISchemaIfCond,
-                             features: List[QAPISchemaFeature],
-                             variants: QAPISchemaVariants) -> None:
-        self._gen_tree(
-            name, 'alternate',
-            {'members': [Annotated({'type': self._use_type(m.type)},
-                                   m.ifcond)
-                         for m in variants.variants]},
-            ifcond, features
-        )
-
-    def visit_command(self, name: str, info: Optional[QAPISourceInfo],
-                      ifcond: QAPISchemaIfCond,
-                      features: List[QAPISchemaFeature],
-                      arg_type: Optional[QAPISchemaObjectType],
-                      ret_type: Optional[QAPISchemaType], gen: bool,
-                      success_response: bool, boxed: bool, allow_oob: bool,
-                      allow_preconfig: bool, coroutine: bool) -> None:
-        assert self._schema is not None
-
-        arg_type = arg_type or self._schema.the_empty_object_type
-        ret_type = ret_type or self._schema.the_empty_object_type
-        obj: SchemaInfoCommand = {
-            'arg-type': self._use_type(arg_type),
-            'ret-type': self._use_type(ret_type)
-        }
-        if allow_oob:
-            obj['allow-oob'] = allow_oob
-        self._gen_tree(name, 'command', obj, ifcond, features)
-
-    def visit_event(self, name: str, info: Optional[QAPISourceInfo],
-                    ifcond: QAPISchemaIfCond,
-                    features: List[QAPISchemaFeature],
-                    arg_type: Optional[QAPISchemaObjectType],
-                    boxed: bool) -> None:
-        assert self._schema is not None
-
-        arg_type = arg_type or self._schema.the_empty_object_type
-        self._gen_tree(name, 'event', {'arg-type': self._use_type(arg_type)},
-                       ifcond, features)
-
-
-def gen_introspect(schema: QAPISchema, output_dir: str, prefix: str,
-                   opt_unmask: bool) -> None:
-    vis = QAPISchemaGenIntrospectVisitor(prefix, opt_unmask)
-    schema.visit(vis)
-    vis.write(output_dir)

+ 0 - 95
scripts/qapi/main.py

@@ -1,95 +0,0 @@
-# This work is licensed under the terms of the GNU GPL, version 2 or later.
-# See the COPYING file in the top-level directory.
-
-"""
-QAPI Generator
-
-This is the main entry point for generating C code from the QAPI schema.
-"""
-
-import argparse
-import sys
-from typing import Optional
-
-from .commands import gen_commands
-from .common import must_match
-from .error import QAPIError
-from .events import gen_events
-#from .introspect import gen_introspect
-from .schema import QAPISchema
-from .types import gen_types
-from .visit import gen_visit
-
-
-def invalid_prefix_char(prefix: str) -> Optional[str]:
-    match = must_match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', prefix)
-    if match.end() != len(prefix):
-        return prefix[match.end()]
-    return None
-
-
-def generate(schema_file: str,
-             output_dir: str,
-             prefix: str,
-             unmask: bool = False,
-             builtins: bool = False) -> None:
-    """
-    Generate C code for the given schema into the target directory.
-
-    :param schema_file: The primary QAPI schema file.
-    :param output_dir: The output directory to store generated code.
-    :param prefix: Optional C-code prefix for symbol names.
-    :param unmask: Expose non-ABI names through introspection?
-    :param builtins: Generate code for built-in types?
-
-    :raise QAPIError: On failures.
-    """
-    assert invalid_prefix_char(prefix) is None
-
-    schema = QAPISchema(schema_file)
-    gen_types(schema, output_dir, prefix, builtins)
-    gen_visit(schema, output_dir, prefix, builtins)
-    gen_commands(schema, output_dir, prefix)
-    gen_events(schema, output_dir, prefix)
-    #gen_introspect(schema, output_dir, prefix, unmask)
-
-
-def main() -> int:
-    """
-    gapi-gen executable entry point.
-    Expects arguments via sys.argv, see --help for details.
-
-    :return: int, 0 on success, 1 on failure.
-    """
-    parser = argparse.ArgumentParser(
-        description='Generate code from a QAPI schema')
-    parser.add_argument('-b', '--builtins', action='store_true',
-                        help="generate code for built-in types")
-    parser.add_argument('-o', '--output-dir', action='store',
-                        default='',
-                        help="write output to directory OUTPUT_DIR")
-    parser.add_argument('-p', '--prefix', action='store',
-                        default='',
-                        help="prefix for symbols")
-    parser.add_argument('-u', '--unmask-non-abi-names', action='store_true',
-                        dest='unmask',
-                        help="expose non-ABI names in introspection")
-    parser.add_argument('schema', action='store')
-    args = parser.parse_args()
-
-    funny_char = invalid_prefix_char(args.prefix)
-    if funny_char:
-        msg = f"funny character '{funny_char}' in argument of --prefix"
-        print(f"{sys.argv[0]}: {msg}", file=sys.stderr)
-        return 1
-
-    try:
-        generate(args.schema,
-                 output_dir=args.output_dir,
-                 prefix=args.prefix,
-                 unmask=args.unmask,
-                 builtins=args.builtins)
-    except QAPIError as err:
-        print(f"{sys.argv[0]}: {str(err)}", file=sys.stderr)
-        return 1
-    return 0

+ 0 - 810
scripts/qapi/parser.py

@@ -1,810 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# QAPI schema parser
-#
-# Copyright IBM, Corp. 2011
-# Copyright (c) 2013-2019 Red Hat Inc.
-#
-# Authors:
-#  Anthony Liguori <aliguori@us.ibm.com>
-#  Markus Armbruster <armbru@redhat.com>
-#  Marc-André Lureau <marcandre.lureau@redhat.com>
-#  Kevin Wolf <kwolf@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 collections import OrderedDict
-import os
-import re
-from typing import (
-    TYPE_CHECKING,
-    Dict,
-    List,
-    Optional,
-    Set,
-    Union,
-)
-
-from .common import must_match
-from .error import QAPISemError, QAPISourceError
-from .source import QAPISourceInfo
-
-
-if TYPE_CHECKING:
-    # pylint: disable=cyclic-import
-    # TODO: Remove cycle. [schema -> expr -> parser -> schema]
-    from .schema import QAPISchemaFeature, QAPISchemaMember
-
-
-#: Represents a single Top Level QAPI schema expression.
-TopLevelExpr = Dict[str, object]
-
-# Return value alias for get_expr().
-_ExprValue = Union[List[object], Dict[str, object], str, bool]
-
-# FIXME: Consolidate and centralize definitions for TopLevelExpr,
-# _ExprValue, _JSONValue, and _JSONObject; currently scattered across
-# several modules.
-
-
-class QAPIParseError(QAPISourceError):
-    """Error class for all QAPI schema parsing errors."""
-    def __init__(self, parser: 'QAPISchemaParser', msg: str):
-        col = 1
-        for ch in parser.src[parser.line_pos:parser.pos]:
-            if ch == '\t':
-                col = (col + 7) % 8 + 1
-            else:
-                col += 1
-        super().__init__(parser.info, msg, col)
-
-
-class QAPISchemaParser:
-    """
-    Parse QAPI schema source.
-
-    Parse a JSON-esque schema file and process directives.  See
-    qapi-code-gen.txt section "Schema Syntax" for the exact syntax.
-    Grammatical validation is handled later by `expr.check_exprs()`.
-
-    :param fname: Source file name.
-    :param previously_included:
-        The absolute names of previously included source files,
-        if being invoked from another parser.
-    :param incl_info:
-       `QAPISourceInfo` belonging to the parent module.
-       ``None`` implies this is the root module.
-
-    :ivar exprs: Resulting parsed expressions.
-    :ivar docs: Resulting parsed documentation blocks.
-
-    :raise OSError: For problems reading the root schema document.
-    :raise QAPIError: For errors in the schema source.
-    """
-    def __init__(self,
-                 fname: str,
-                 previously_included: Optional[Set[str]] = None,
-                 incl_info: Optional[QAPISourceInfo] = None):
-        self._fname = fname
-        self._included = previously_included or set()
-        self._included.add(os.path.abspath(self._fname))
-        self.src = ''
-
-        # Lexer state (see `accept` for details):
-        self.info = QAPISourceInfo(self._fname, incl_info)
-        self.tok: Union[None, str] = None
-        self.pos = 0
-        self.cursor = 0
-        self.val: Optional[Union[bool, str]] = None
-        self.line_pos = 0
-
-        # Parser output:
-        self.exprs: List[Dict[str, object]] = []
-        self.docs: List[QAPIDoc] = []
-
-        # Showtime!
-        self._parse()
-
-    def _parse(self) -> None:
-        """
-        Parse the QAPI schema document.
-
-        :return: None.  Results are stored in ``.exprs`` and ``.docs``.
-        """
-        cur_doc = None
-
-        # May raise OSError; allow the caller to handle it.
-        with open(self._fname, 'r', encoding='utf-8') as fp:
-            self.src = fp.read()
-        if self.src == '' or self.src[-1] != '\n':
-            self.src += '\n'
-
-        # Prime the lexer:
-        self.accept()
-
-        # Parse until done:
-        while self.tok is not None:
-            info = self.info
-            if self.tok == '#':
-                self.reject_expr_doc(cur_doc)
-                for cur_doc in self.get_doc(info):
-                    self.docs.append(cur_doc)
-                continue
-
-            expr = self.get_expr()
-            if not isinstance(expr, dict):
-                raise QAPISemError(
-                    info, "top-level expression must be an object")
-
-            if 'include' in expr:
-                self.reject_expr_doc(cur_doc)
-                if len(expr) != 1:
-                    raise QAPISemError(info, "invalid 'include' directive")
-                include = expr['include']
-                if not isinstance(include, str):
-                    raise QAPISemError(info,
-                                       "value of 'include' must be a string")
-                incl_fname = os.path.join(os.path.dirname(self._fname),
-                                          include)
-                self.exprs.append({'expr': {'include': incl_fname},
-                                   'info': info})
-                exprs_include = self._include(include, info, incl_fname,
-                                              self._included)
-                if exprs_include:
-                    self.exprs.extend(exprs_include.exprs)
-                    self.docs.extend(exprs_include.docs)
-            elif "pragma" in expr:
-                self.reject_expr_doc(cur_doc)
-                if len(expr) != 1:
-                    raise QAPISemError(info, "invalid 'pragma' directive")
-                pragma = expr['pragma']
-                if not isinstance(pragma, dict):
-                    raise QAPISemError(
-                        info, "value of 'pragma' must be an object")
-                for name, value in pragma.items():
-                    self._pragma(name, value, info)
-            else:
-                expr_elem = {'expr': expr,
-                             'info': info}
-                if cur_doc:
-                    if not cur_doc.symbol:
-                        raise QAPISemError(
-                            cur_doc.info, "definition documentation required")
-                    expr_elem['doc'] = cur_doc
-                self.exprs.append(expr_elem)
-            cur_doc = None
-        self.reject_expr_doc(cur_doc)
-
-    @staticmethod
-    def reject_expr_doc(doc: Optional['QAPIDoc']) -> None:
-        if doc and doc.symbol:
-            raise QAPISemError(
-                doc.info,
-                "documentation for '%s' is not followed by the definition"
-                % doc.symbol)
-
-    @staticmethod
-    def _include(include: str,
-                 info: QAPISourceInfo,
-                 incl_fname: str,
-                 previously_included: Set[str]
-                 ) -> Optional['QAPISchemaParser']:
-        incl_abs_fname = os.path.abspath(incl_fname)
-        # catch inclusion cycle
-        inf: Optional[QAPISourceInfo] = info
-        while inf:
-            if incl_abs_fname == os.path.abspath(inf.fname):
-                raise QAPISemError(info, "inclusion loop for %s" % include)
-            inf = inf.parent
-
-        # skip multiple include of the same file
-        if incl_abs_fname in previously_included:
-            return None
-
-        try:
-            return QAPISchemaParser(incl_fname, previously_included, info)
-        except OSError as err:
-            raise QAPISemError(
-                info,
-                f"can't read include file '{incl_fname}': {err.strerror}"
-            ) from err
-
-    @staticmethod
-    def _pragma(name: str, value: object, info: QAPISourceInfo) -> None:
-
-        def check_list_str(name: str, value: object) -> List[str]:
-            if (not isinstance(value, list) or
-                    any(not isinstance(elt, str) for elt in value)):
-                raise QAPISemError(
-                    info,
-                    "pragma %s must be a list of strings" % name)
-            return value
-
-        pragma = info.pragma
-
-        if name == 'doc-required':
-            if not isinstance(value, bool):
-                raise QAPISemError(info,
-                                   "pragma 'doc-required' must be boolean")
-            pragma.doc_required = value
-        elif name == 'command-name-exceptions':
-            pragma.command_name_exceptions = check_list_str(name, value)
-        elif name == 'command-returns-exceptions':
-            pragma.command_returns_exceptions = check_list_str(name, value)
-        elif name == 'member-name-exceptions':
-            pragma.member_name_exceptions = check_list_str(name, value)
-        else:
-            raise QAPISemError(info, "unknown pragma '%s'" % name)
-
-    def accept(self, skip_comment: bool = True) -> None:
-        """
-        Read and store the next token.
-
-        :param skip_comment:
-            When false, return COMMENT tokens ("#").
-            This is used when reading documentation blocks.
-
-        :return:
-            None.  Several instance attributes are updated instead:
-
-            - ``.tok`` represents the token type.  See below for values.
-            - ``.info`` describes the token's source location.
-            - ``.val`` is the token's value, if any.  See below.
-            - ``.pos`` is the buffer index of the first character of
-              the token.
-
-        * Single-character tokens:
-
-            These are "{", "}", ":", ",", "[", and "]".
-            ``.tok`` holds the single character and ``.val`` is None.
-
-        * Multi-character tokens:
-
-          * COMMENT:
-
-            This token is not normally returned by the lexer, but it can
-            be when ``skip_comment`` is False.  ``.tok`` is "#", and
-            ``.val`` is a string including all chars until end-of-line,
-            including the "#" itself.
-
-          * STRING:
-
-            ``.tok`` is "'", the single quote.  ``.val`` contains the
-            string, excluding the surrounding quotes.
-
-          * TRUE and FALSE:
-
-            ``.tok`` is either "t" or "f", ``.val`` will be the
-            corresponding bool value.
-
-          * EOF:
-
-            ``.tok`` and ``.val`` will both be None at EOF.
-        """
-        while True:
-            self.tok = self.src[self.cursor]
-            self.pos = self.cursor
-            self.cursor += 1
-            self.val = None
-
-            if self.tok == '#':
-                if self.src[self.cursor] == '#':
-                    # Start of doc comment
-                    skip_comment = False
-                self.cursor = self.src.find('\n', self.cursor)
-                if not skip_comment:
-                    self.val = self.src[self.pos:self.cursor]
-                    return
-            elif self.tok in '{}:,[]':
-                return
-            elif self.tok == "'":
-                # Note: we accept only printable ASCII
-                string = ''
-                esc = False
-                while True:
-                    ch = self.src[self.cursor]
-                    self.cursor += 1
-                    if ch == '\n':
-                        raise QAPIParseError(self, "missing terminating \"'\"")
-                    if esc:
-                        # Note: we recognize only \\ because we have
-                        # no use for funny characters in strings
-                        if ch != '\\':
-                            raise QAPIParseError(self,
-                                                 "unknown escape \\%s" % ch)
-                        esc = False
-                    elif ch == '\\':
-                        esc = True
-                        continue
-                    elif ch == "'":
-                        self.val = string
-                        return
-                    if ord(ch) < 32 or ord(ch) >= 127:
-                        raise QAPIParseError(
-                            self, "funny character in string")
-                    string += ch
-            elif self.src.startswith('true', self.pos):
-                self.val = True
-                self.cursor += 3
-                return
-            elif self.src.startswith('false', self.pos):
-                self.val = False
-                self.cursor += 4
-                return
-            elif self.tok == '\n':
-                if self.cursor == len(self.src):
-                    self.tok = None
-                    return
-                self.info = self.info.next_line()
-                self.line_pos = self.cursor
-            elif not self.tok.isspace():
-                # Show up to next structural, whitespace or quote
-                # character
-                match = must_match('[^[\\]{}:,\\s\'"]+',
-                                   self.src[self.cursor-1:])
-                raise QAPIParseError(self, "stray '%s'" % match.group(0))
-
-    def get_members(self) -> Dict[str, object]:
-        expr: Dict[str, object] = OrderedDict()
-        if self.tok == '}':
-            self.accept()
-            return expr
-        if self.tok != "'":
-            raise QAPIParseError(self, "expected string or '}'")
-        while True:
-            key = self.val
-            assert isinstance(key, str)  # Guaranteed by tok == "'"
-
-            self.accept()
-            if self.tok != ':':
-                raise QAPIParseError(self, "expected ':'")
-            self.accept()
-            if key in expr:
-                raise QAPIParseError(self, "duplicate key '%s'" % key)
-            expr[key] = self.get_expr()
-            if self.tok == '}':
-                self.accept()
-                return expr
-            if self.tok != ',':
-                raise QAPIParseError(self, "expected ',' or '}'")
-            self.accept()
-            if self.tok != "'":
-                raise QAPIParseError(self, "expected string")
-
-    def get_values(self) -> List[object]:
-        expr: List[object] = []
-        if self.tok == ']':
-            self.accept()
-            return expr
-        if self.tok not in tuple("{['tf"):
-            raise QAPIParseError(
-                self, "expected '{', '[', ']', string, or boolean")
-        while True:
-            expr.append(self.get_expr())
-            if self.tok == ']':
-                self.accept()
-                return expr
-            if self.tok != ',':
-                raise QAPIParseError(self, "expected ',' or ']'")
-            self.accept()
-
-    def get_expr(self) -> _ExprValue:
-        expr: _ExprValue
-        if self.tok == '{':
-            self.accept()
-            expr = self.get_members()
-        elif self.tok == '[':
-            self.accept()
-            expr = self.get_values()
-        elif self.tok in tuple("'tf"):
-            assert isinstance(self.val, (str, bool))
-            expr = self.val
-            self.accept()
-        else:
-            raise QAPIParseError(
-                self, "expected '{', '[', string, or boolean")
-        return expr
-
-    def get_doc(self, info: QAPISourceInfo) -> List['QAPIDoc']:
-        if self.val != '##':
-            raise QAPIParseError(
-                self, "junk after '##' at start of documentation comment")
-
-        docs = []
-        cur_doc = QAPIDoc(self, info)
-        self.accept(False)
-        while self.tok == '#':
-            assert isinstance(self.val, str)
-            if self.val.startswith('##'):
-                # End of doc comment
-                if self.val != '##':
-                    raise QAPIParseError(
-                        self,
-                        "junk after '##' at end of documentation comment")
-                cur_doc.end_comment()
-                docs.append(cur_doc)
-                self.accept()
-                return docs
-            if self.val.startswith('# ='):
-                if cur_doc.symbol:
-                    raise QAPIParseError(
-                        self,
-                        "unexpected '=' markup in definition documentation")
-                if cur_doc.body.text:
-                    cur_doc.end_comment()
-                    docs.append(cur_doc)
-                    cur_doc = QAPIDoc(self, info)
-            cur_doc.append(self.val)
-            self.accept(False)
-
-        raise QAPIParseError(self, "documentation comment must end with '##'")
-
-
-class QAPIDoc:
-    """
-    A documentation comment block, either definition or free-form
-
-    Definition documentation blocks consist of
-
-    * a body section: one line naming the definition, followed by an
-      overview (any number of lines)
-
-    * argument sections: a description of each argument (for commands
-      and events) or member (for structs, unions and alternates)
-
-    * features sections: a description of each feature flag
-
-    * additional (non-argument) sections, possibly tagged
-
-    Free-form documentation blocks consist only of a body section.
-    """
-
-    class Section:
-        # pylint: disable=too-few-public-methods
-        def __init__(self, parser: QAPISchemaParser,
-                     name: Optional[str] = None, indent: int = 0):
-
-            # parser, for error messages about indentation
-            self._parser = parser
-            # optional section name (argument/member or section name)
-            self.name = name
-            self.text = ''
-            # the expected indent level of the text of this section
-            self._indent = indent
-
-        def append(self, line: str) -> None:
-            # Strip leading spaces corresponding to the expected indent level
-            # Blank lines are always OK.
-            if line:
-                indent = must_match(r'\s*', line).end()
-                if indent < self._indent:
-                    raise QAPIParseError(
-                        self._parser,
-                        "unexpected de-indent (expected at least %d spaces)" %
-                        self._indent)
-                line = line[self._indent:]
-
-            self.text += line.rstrip() + '\n'
-
-    class ArgSection(Section):
-        def __init__(self, parser: QAPISchemaParser,
-                     name: str, indent: int = 0):
-            super().__init__(parser, name, indent)
-            self.member: Optional['QAPISchemaMember'] = None
-
-        def connect(self, member: 'QAPISchemaMember') -> None:
-            self.member = member
-
-    class NullSection(Section):
-        """
-        Immutable dummy section for use at the end of a doc block.
-        """
-        # pylint: disable=too-few-public-methods
-        def append(self, line: str) -> None:
-            assert False, "Text appended after end_comment() called."
-
-    def __init__(self, parser: QAPISchemaParser, info: QAPISourceInfo):
-        # self._parser is used to report errors with QAPIParseError.  The
-        # resulting error position depends on the state of the parser.
-        # It happens to be the beginning of the comment.  More or less
-        # servicable, but action at a distance.
-        self._parser = parser
-        self.info = info
-        self.symbol: Optional[str] = None
-        self.body = QAPIDoc.Section(parser)
-        # dicts mapping parameter/feature names to their ArgSection
-        self.args: Dict[str, QAPIDoc.ArgSection] = OrderedDict()
-        self.features: Dict[str, QAPIDoc.ArgSection] = OrderedDict()
-        self.sections: List[QAPIDoc.Section] = []
-        # the current section
-        self._section = self.body
-        self._append_line = self._append_body_line
-
-    def has_section(self, name: str) -> bool:
-        """Return True if we have a section with this name."""
-        for i in self.sections:
-            if i.name == name:
-                return True
-        return False
-
-    def append(self, line: str) -> None:
-        """
-        Parse a comment line and add it to the documentation.
-
-        The way that the line is dealt with depends on which part of
-        the documentation we're parsing right now:
-        * The body section: ._append_line is ._append_body_line
-        * An argument section: ._append_line is ._append_args_line
-        * A features section: ._append_line is ._append_features_line
-        * An additional section: ._append_line is ._append_various_line
-        """
-        line = line[1:]
-        if not line:
-            self._append_freeform(line)
-            return
-
-        if line[0] != ' ':
-            raise QAPIParseError(self._parser, "missing space after #")
-        line = line[1:]
-        self._append_line(line)
-
-    def end_comment(self) -> None:
-        self._switch_section(QAPIDoc.NullSection(self._parser))
-
-    @staticmethod
-    def _is_section_tag(name: str) -> bool:
-        return name in ('Returns:', 'Since:',
-                        # those are often singular or plural
-                        'Note:', 'Notes:',
-                        'Example:', 'Examples:',
-                        'TODO:')
-
-    def _append_body_line(self, line: str) -> None:
-        """
-        Process a line of documentation text in the body section.
-
-        If this a symbol line and it is the section's first line, this
-        is a definition documentation block for that symbol.
-
-        If it's a definition documentation block, another symbol line
-        begins the argument section for the argument named by it, and
-        a section tag begins an additional section.  Start that
-        section and append the line to it.
-
-        Else, append the line to the current section.
-        """
-        name = line.split(' ', 1)[0]
-        # FIXME not nice: things like '#  @foo:' and '# @foo: ' aren't
-        # recognized, and get silently treated as ordinary text
-        if not self.symbol and not self.body.text and line.startswith('@'):
-            if not line.endswith(':'):
-                raise QAPIParseError(self._parser, "line should end with ':'")
-            self.symbol = line[1:-1]
-            # Invalid names are not checked here, but the name provided MUST
-            # match the following definition, which *is* validated in expr.py.
-            if not self.symbol:
-                raise QAPIParseError(
-                    self._parser, "name required after '@'")
-        elif self.symbol:
-            # This is a definition documentation block
-            if name.startswith('@') and name.endswith(':'):
-                self._append_line = self._append_args_line
-                self._append_args_line(line)
-            elif line == 'Features:':
-                self._append_line = self._append_features_line
-            elif self._is_section_tag(name):
-                self._append_line = self._append_various_line
-                self._append_various_line(line)
-            else:
-                self._append_freeform(line)
-        else:
-            # This is a free-form documentation block
-            self._append_freeform(line)
-
-    def _append_args_line(self, line: str) -> None:
-        """
-        Process a line of documentation text in an argument section.
-
-        A symbol line begins the next argument section, a section tag
-        section or a non-indented line after a blank line begins an
-        additional section.  Start that section and append the line to
-        it.
-
-        Else, append the line to the current section.
-
-        """
-        name = line.split(' ', 1)[0]
-
-        if name.startswith('@') and name.endswith(':'):
-            # If line is "@arg:   first line of description", find
-            # the index of 'f', which is the indent we expect for any
-            # following lines.  We then remove the leading "@arg:"
-            # from line and replace it with spaces so that 'f' has the
-            # same index as it did in the original line and can be
-            # handled the same way we will handle following lines.
-            indent = must_match(r'@\S*:\s*', line).end()
-            line = line[indent:]
-            if not line:
-                # Line was just the "@arg:" header; following lines
-                # are not indented
-                indent = 0
-            else:
-                line = ' ' * indent + line
-            self._start_args_section(name[1:-1], indent)
-        elif self._is_section_tag(name):
-            self._append_line = self._append_various_line
-            self._append_various_line(line)
-            return
-        elif (self._section.text.endswith('\n\n')
-              and line and not line[0].isspace()):
-            if line == 'Features:':
-                self._append_line = self._append_features_line
-            else:
-                self._start_section()
-                self._append_line = self._append_various_line
-                self._append_various_line(line)
-            return
-
-        self._append_freeform(line)
-
-    def _append_features_line(self, line: str) -> None:
-        name = line.split(' ', 1)[0]
-
-        if name.startswith('@') and name.endswith(':'):
-            # If line is "@arg:   first line of description", find
-            # the index of 'f', which is the indent we expect for any
-            # following lines.  We then remove the leading "@arg:"
-            # from line and replace it with spaces so that 'f' has the
-            # same index as it did in the original line and can be
-            # handled the same way we will handle following lines.
-            indent = must_match(r'@\S*:\s*', line).end()
-            line = line[indent:]
-            if not line:
-                # Line was just the "@arg:" header; following lines
-                # are not indented
-                indent = 0
-            else:
-                line = ' ' * indent + line
-            self._start_features_section(name[1:-1], indent)
-        elif self._is_section_tag(name):
-            self._append_line = self._append_various_line
-            self._append_various_line(line)
-            return
-        elif (self._section.text.endswith('\n\n')
-              and line and not line[0].isspace()):
-            self._start_section()
-            self._append_line = self._append_various_line
-            self._append_various_line(line)
-            return
-
-        self._append_freeform(line)
-
-    def _append_various_line(self, line: str) -> None:
-        """
-        Process a line of documentation text in an additional section.
-
-        A symbol line is an error.
-
-        A section tag begins an additional section.  Start that
-        section and append the line to it.
-
-        Else, append the line to the current section.
-        """
-        name = line.split(' ', 1)[0]
-
-        if name.startswith('@') and name.endswith(':'):
-            raise QAPIParseError(self._parser,
-                                 "'%s' can't follow '%s' section"
-                                 % (name, self.sections[0].name))
-        if self._is_section_tag(name):
-            # If line is "Section:   first line of description", find
-            # the index of 'f', which is the indent we expect for any
-            # following lines.  We then remove the leading "Section:"
-            # from line and replace it with spaces so that 'f' has the
-            # same index as it did in the original line and can be
-            # handled the same way we will handle following lines.
-            indent = must_match(r'\S*:\s*', line).end()
-            line = line[indent:]
-            if not line:
-                # Line was just the "Section:" header; following lines
-                # are not indented
-                indent = 0
-            else:
-                line = ' ' * indent + line
-            self._start_section(name[:-1], indent)
-
-        self._append_freeform(line)
-
-    def _start_symbol_section(
-            self,
-            symbols_dict: Dict[str, 'QAPIDoc.ArgSection'],
-            name: str,
-            indent: int) -> None:
-        # FIXME invalid names other than the empty string aren't flagged
-        if not name:
-            raise QAPIParseError(self._parser, "invalid parameter name")
-        if name in symbols_dict:
-            raise QAPIParseError(self._parser,
-                                 "'%s' parameter name duplicated" % name)
-        assert not self.sections
-        new_section = QAPIDoc.ArgSection(self._parser, name, indent)
-        self._switch_section(new_section)
-        symbols_dict[name] = new_section
-
-    def _start_args_section(self, name: str, indent: int) -> None:
-        self._start_symbol_section(self.args, name, indent)
-
-    def _start_features_section(self, name: str, indent: int) -> None:
-        self._start_symbol_section(self.features, name, indent)
-
-    def _start_section(self, name: Optional[str] = None,
-                       indent: int = 0) -> None:
-        if name in ('Returns', 'Since') and self.has_section(name):
-            raise QAPIParseError(self._parser,
-                                 "duplicated '%s' section" % name)
-        new_section = QAPIDoc.Section(self._parser, name, indent)
-        self._switch_section(new_section)
-        self.sections.append(new_section)
-
-    def _switch_section(self, new_section: 'QAPIDoc.Section') -> None:
-        text = self._section.text = self._section.text.strip()
-
-        # Only the 'body' section is allowed to have an empty body.
-        # All other sections, including anonymous ones, must have text.
-        if self._section != self.body and not text:
-            # We do not create anonymous sections unless there is
-            # something to put in them; this is a parser bug.
-            assert self._section.name
-            raise QAPIParseError(
-                self._parser,
-                "empty doc section '%s'" % self._section.name)
-
-        self._section = new_section
-
-    def _append_freeform(self, line: str) -> None:
-        match = re.match(r'(@\S+:)', line)
-        if match:
-            raise QAPIParseError(self._parser,
-                                 "'%s' not allowed in free-form documentation"
-                                 % match.group(1))
-        self._section.append(line)
-
-    def connect_member(self, member: 'QAPISchemaMember') -> None:
-        if member.name not in self.args:
-            # Undocumented TODO outlaw
-            self.args[member.name] = QAPIDoc.ArgSection(self._parser,
-                                                        member.name)
-        self.args[member.name].connect(member)
-
-    def connect_feature(self, feature: 'QAPISchemaFeature') -> None:
-        if feature.name not in self.features:
-            raise QAPISemError(feature.info,
-                               "feature '%s' lacks documentation"
-                               % feature.name)
-        self.features[feature.name].connect(feature)
-
-    def check_expr(self, expr: TopLevelExpr) -> None:
-        if self.has_section('Returns') and 'command' not in expr:
-            raise QAPISemError(self.info,
-                               "'Returns:' is only valid for commands")
-
-    def check(self) -> None:
-
-        def check_args_section(
-                args: Dict[str, QAPIDoc.ArgSection], what: str
-        ) -> None:
-            bogus = [name for name, section in args.items()
-                     if not section.member]
-            if bogus:
-                raise QAPISemError(
-                    self.info,
-                    "documented %s%s '%s' %s not exist" % (
-                        what,
-                        "s" if len(bogus) > 1 else "",
-                        "', '".join(bogus),
-                        "do" if len(bogus) > 1 else "does"
-                    ))
-
-        check_args_section(self.args, 'member')
-        check_args_section(self.features, 'feature')

+ 0 - 1189
scripts/qapi/schema.py

@@ -1,1189 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# QAPI schema internal representation
-#
-# Copyright (c) 2015-2019 Red Hat Inc.
-#
-# Authors:
-#  Markus Armbruster <armbru@redhat.com>
-#  Eric Blake <eblake@redhat.com>
-#  Marc-André Lureau <marcandre.lureau@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2.
-# See the COPYING file in the top-level directory.
-
-# TODO catching name collisions in generated code would be nice
-
-from collections import OrderedDict
-import os
-import re
-from typing import Optional
-
-from .common import (
-    POINTER_SUFFIX,
-    c_name,
-    cgen_ifcond,
-    docgen_ifcond,
-    gen_endif,
-    gen_if,
-)
-from .error import QAPIError, QAPISemError, QAPISourceError
-from .expr import check_exprs
-from .parser import QAPISchemaParser
-
-
-class QAPISchemaIfCond:
-    def __init__(self, ifcond=None):
-        self.ifcond = ifcond
-
-    def _cgen(self):
-        return cgen_ifcond(self.ifcond)
-
-    def gen_if(self):
-        return gen_if(self._cgen())
-
-    def gen_endif(self):
-        return gen_endif(self._cgen())
-
-    def docgen(self):
-        return docgen_ifcond(self.ifcond)
-
-    def is_present(self):
-        return bool(self.ifcond)
-
-
-class QAPISchemaEntity:
-    meta: Optional[str] = None
-
-    def __init__(self, name: str, info, doc, ifcond=None, features=None):
-        assert name is None or isinstance(name, str)
-        for f in features or []:
-            assert isinstance(f, QAPISchemaFeature)
-            f.set_defined_in(name)
-        self.name = name
-        self._module = None
-        # For explicitly defined entities, info points to the (explicit)
-        # definition.  For builtins (and their arrays), info is None.
-        # For implicitly defined entities, info points to a place that
-        # triggered the implicit definition (there may be more than one
-        # such place).
-        self.info = info
-        self.doc = doc
-        self._ifcond = ifcond or QAPISchemaIfCond()
-        self.features = features or []
-        self._checked = False
-
-    def c_name(self):
-        return c_name(self.name)
-
-    def check(self, schema):
-        assert not self._checked
-        seen = {}
-        for f in self.features:
-            f.check_clash(self.info, seen)
-        self._checked = True
-
-    def connect_doc(self, doc=None):
-        doc = doc or self.doc
-        if doc:
-            for f in self.features:
-                doc.connect_feature(f)
-
-    def check_doc(self):
-        if self.doc:
-            self.doc.check()
-
-    def _set_module(self, schema, info):
-        assert self._checked
-        fname = info.fname if info else QAPISchemaModule.BUILTIN_MODULE_NAME
-        self._module = schema.module_by_fname(fname)
-        self._module.add_entity(self)
-
-    def set_module(self, schema):
-        self._set_module(schema, self.info)
-
-    @property
-    def ifcond(self):
-        assert self._checked
-        return self._ifcond
-
-    def is_implicit(self):
-        return not self.info
-
-    def visit(self, visitor):
-        assert self._checked
-
-    def describe(self):
-        assert self.meta
-        return "%s '%s'" % (self.meta, self.name)
-
-
-class QAPISchemaVisitor:
-    def visit_begin(self, schema):
-        pass
-
-    def visit_end(self):
-        pass
-
-    def visit_module(self, name):
-        pass
-
-    def visit_needed(self, entity):
-        # Default to visiting everything
-        return True
-
-    def visit_include(self, name, info):
-        pass
-
-    def visit_builtin_type(self, name, info, json_type):
-        pass
-
-    def visit_enum_type(self, name, info, ifcond, features, members, prefix):
-        pass
-
-    def visit_array_type(self, name, info, ifcond, element_type):
-        pass
-
-    def visit_object_type(self, name, info, ifcond, features,
-                          base, members, variants):
-        pass
-
-    def visit_object_type_flat(self, name, info, ifcond, features,
-                               members, variants):
-        pass
-
-    def visit_alternate_type(self, name, info, ifcond, features, variants):
-        pass
-
-    def visit_command(self, name, info, ifcond, features,
-                      arg_type, ret_type, gen, success_response, boxed,
-                      allow_oob, allow_preconfig, coroutine):
-        pass
-
-    def visit_event(self, name, info, ifcond, features, arg_type, boxed):
-        pass
-
-
-class QAPISchemaModule:
-
-    BUILTIN_MODULE_NAME = './builtin'
-
-    def __init__(self, name):
-        self.name = name
-        self._entity_list = []
-
-    @staticmethod
-    def is_system_module(name: str) -> bool:
-        """
-        System modules are internally defined modules.
-
-        Their names start with the "./" prefix.
-        """
-        return name.startswith('./')
-
-    @classmethod
-    def is_user_module(cls, name: str) -> bool:
-        """
-        User modules are those defined by the user in qapi JSON files.
-
-        They do not start with the "./" prefix.
-        """
-        return not cls.is_system_module(name)
-
-    @classmethod
-    def is_builtin_module(cls, name: str) -> bool:
-        """
-        The built-in module is a single System module for the built-in types.
-
-        It is always "./builtin".
-        """
-        return name == cls.BUILTIN_MODULE_NAME
-
-    def add_entity(self, ent):
-        self._entity_list.append(ent)
-
-    def visit(self, visitor):
-        visitor.visit_module(self.name)
-        for entity in self._entity_list:
-            if visitor.visit_needed(entity):
-                entity.visit(visitor)
-
-
-class QAPISchemaInclude(QAPISchemaEntity):
-    def __init__(self, sub_module, info):
-        super().__init__(None, info, None)
-        self._sub_module = sub_module
-
-    def visit(self, visitor):
-        super().visit(visitor)
-        visitor.visit_include(self._sub_module.name, self.info)
-
-
-class QAPISchemaType(QAPISchemaEntity):
-    # Return the C type for common use.
-    # For the types we commonly box, this is a pointer type.
-    def c_type(self):
-        pass
-
-    # Return the C type to be used in a parameter list.
-    def c_param_type(self):
-        return self.c_type()
-
-    # Return the C type to be used where we suppress boxing.
-    def c_unboxed_type(self):
-        return self.c_type()
-
-    def json_type(self):
-        pass
-
-    def alternate_qtype(self):
-        json2qtype = {
-            'null':    'QTYPE_QNULL',
-            'string':  'QTYPE_QSTRING',
-            'number':  'QTYPE_QNUM',
-            'int':     'QTYPE_QNUM',
-            'boolean': 'QTYPE_QBOOL',
-            'array':   'QTYPE_QLIST',
-            'object':  'QTYPE_QDICT'
-        }
-        return json2qtype.get(self.json_type())
-
-    def doc_type(self):
-        if self.is_implicit():
-            return None
-        return self.name
-
-    def check(self, schema):
-        QAPISchemaEntity.check(self, schema)
-        for feat in self.features:
-            if feat.is_special():
-                raise QAPISemError(
-                    self.info,
-                    f"feature '{feat.name}' is not supported for types")
-
-    def describe(self):
-        assert self.meta
-        return "%s type '%s'" % (self.meta, self.name)
-
-
-class QAPISchemaBuiltinType(QAPISchemaType):
-    meta = 'built-in'
-
-    def __init__(self, name, json_type, c_type):
-        super().__init__(name, None, None)
-        assert not c_type or isinstance(c_type, str)
-        assert json_type in ('string', 'number', 'int', 'boolean', 'null',
-                             'value')
-        self._json_type_name = json_type
-        self._c_type_name = c_type
-
-    def c_name(self):
-        return self.name
-
-    def c_type(self):
-        return self._c_type_name
-
-    def c_param_type(self):
-        if self.name == 'str':
-            return 'const ' + self._c_type_name
-        return self._c_type_name
-
-    def json_type(self):
-        return self._json_type_name
-
-    def doc_type(self):
-        return self.json_type()
-
-    def visit(self, visitor):
-        super().visit(visitor)
-        visitor.visit_builtin_type(self.name, self.info, self.json_type())
-
-
-class QAPISchemaEnumType(QAPISchemaType):
-    meta = 'enum'
-
-    def __init__(self, name, info, doc, ifcond, features, members, prefix):
-        super().__init__(name, info, doc, ifcond, features)
-        for m in members:
-            assert isinstance(m, QAPISchemaEnumMember)
-            m.set_defined_in(name)
-        assert prefix is None or isinstance(prefix, str)
-        self.members = members
-        self.prefix = prefix
-
-    def check(self, schema):
-        super().check(schema)
-        seen = {}
-        for m in self.members:
-            m.check_clash(self.info, seen)
-
-    def connect_doc(self, doc=None):
-        super().connect_doc(doc)
-        doc = doc or self.doc
-        for m in self.members:
-            m.connect_doc(doc)
-
-    def is_implicit(self):
-        # See QAPISchema._def_predefineds()
-        return self.name == 'QType'
-
-    def c_type(self):
-        return c_name(self.name)
-
-    def member_names(self):
-        return [m.name for m in self.members]
-
-    def json_type(self):
-        return 'string'
-
-    def visit(self, visitor):
-        super().visit(visitor)
-        visitor.visit_enum_type(
-            self.name, self.info, self.ifcond, self.features,
-            self.members, self.prefix)
-
-
-class QAPISchemaArrayType(QAPISchemaType):
-    meta = 'array'
-
-    def __init__(self, name, info, element_type):
-        super().__init__(name, info, None)
-        assert isinstance(element_type, str)
-        self._element_type_name = element_type
-        self.element_type = None
-
-    def check(self, schema):
-        super().check(schema)
-        self.element_type = schema.resolve_type(
-            self._element_type_name, self.info,
-            self.info and self.info.defn_meta)
-        assert not isinstance(self.element_type, QAPISchemaArrayType)
-
-    def set_module(self, schema):
-        self._set_module(schema, self.element_type.info)
-
-    @property
-    def ifcond(self):
-        assert self._checked
-        return self.element_type.ifcond
-
-    def is_implicit(self):
-        return True
-
-    def c_type(self):
-        return c_name(self.name) + POINTER_SUFFIX
-
-    def json_type(self):
-        return 'array'
-
-    def doc_type(self):
-        elt_doc_type = self.element_type.doc_type()
-        if not elt_doc_type:
-            return None
-        return 'array of ' + elt_doc_type
-
-    def visit(self, visitor):
-        super().visit(visitor)
-        visitor.visit_array_type(self.name, self.info, self.ifcond,
-                                 self.element_type)
-
-    def describe(self):
-        assert self.meta
-        return "%s type ['%s']" % (self.meta, self._element_type_name)
-
-
-class QAPISchemaObjectType(QAPISchemaType):
-    def __init__(self, name, info, doc, ifcond, features,
-                 base, local_members, variants):
-        # struct has local_members, optional base, and no variants
-        # union has base, variants, and no local_members
-        super().__init__(name, info, doc, ifcond, features)
-        self.meta = 'union' if variants else 'struct'
-        assert base is None or isinstance(base, str)
-        for m in local_members:
-            assert isinstance(m, QAPISchemaObjectTypeMember)
-            m.set_defined_in(name)
-        if variants is not None:
-            assert isinstance(variants, QAPISchemaVariants)
-            variants.set_defined_in(name)
-        self._base_name = base
-        self.base = None
-        self.local_members = local_members
-        self.variants = variants
-        self.members = None
-
-    def check(self, schema):
-        # This calls another type T's .check() exactly when the C
-        # struct emitted by gen_object() contains that T's C struct
-        # (pointers don't count).
-        if self.members is not None:
-            # A previous .check() completed: nothing to do
-            return
-        if self._checked:
-            # Recursed: C struct contains itself
-            raise QAPISemError(self.info,
-                               "object %s contains itself" % self.name)
-
-        super().check(schema)
-        assert self._checked and self.members is None
-
-        seen = OrderedDict()
-        if self._base_name:
-            self.base = schema.resolve_type(self._base_name, self.info,
-                                            "'base'")
-            if (not isinstance(self.base, QAPISchemaObjectType)
-                    or self.base.variants):
-                raise QAPISemError(
-                    self.info,
-                    "'base' requires a struct type, %s isn't"
-                    % self.base.describe())
-            self.base.check(schema)
-            self.base.check_clash(self.info, seen)
-        for m in self.local_members:
-            m.check(schema)
-            m.check_clash(self.info, seen)
-        members = seen.values()
-
-        if self.variants:
-            self.variants.check(schema, seen)
-            self.variants.check_clash(self.info, seen)
-
-        self.members = members  # mark completed
-
-    # Check that the members of this type do not cause duplicate JSON members,
-    # and update seen to track the members seen so far. Report any errors
-    # on behalf of info, which is not necessarily self.info
-    def check_clash(self, info, seen):
-        assert self._checked
-        assert not self.variants       # not implemented
-        for m in self.members:
-            m.check_clash(info, seen)
-
-    def connect_doc(self, doc=None):
-        super().connect_doc(doc)
-        doc = doc or self.doc
-        if self.base and self.base.is_implicit():
-            self.base.connect_doc(doc)
-        for m in self.local_members:
-            m.connect_doc(doc)
-
-    def is_implicit(self):
-        # See QAPISchema._make_implicit_object_type(), as well as
-        # _def_predefineds()
-        return self.name.startswith('q_')
-
-    def is_empty(self):
-        assert self.members is not None
-        return not self.members and not self.variants
-
-    def c_name(self):
-        assert self.name != 'q_empty'
-        return super().c_name()
-
-    def c_type(self):
-        assert not self.is_implicit()
-        return c_name(self.name) + POINTER_SUFFIX
-
-    def c_unboxed_type(self):
-        return c_name(self.name)
-
-    def json_type(self):
-        return 'object'
-
-    def visit(self, visitor):
-        super().visit(visitor)
-        visitor.visit_object_type(
-            self.name, self.info, self.ifcond, self.features,
-            self.base, self.local_members, self.variants)
-        visitor.visit_object_type_flat(
-            self.name, self.info, self.ifcond, self.features,
-            self.members, self.variants)
-
-
-class QAPISchemaAlternateType(QAPISchemaType):
-    meta = 'alternate'
-
-    def __init__(self, name, info, doc, ifcond, features, variants):
-        super().__init__(name, info, doc, ifcond, features)
-        assert isinstance(variants, QAPISchemaVariants)
-        assert variants.tag_member
-        variants.set_defined_in(name)
-        variants.tag_member.set_defined_in(self.name)
-        self.variants = variants
-
-    def check(self, schema):
-        super().check(schema)
-        self.variants.tag_member.check(schema)
-        # Not calling self.variants.check_clash(), because there's nothing
-        # to clash with
-        self.variants.check(schema, {})
-        # Alternate branch names have no relation to the tag enum values;
-        # so we have to check for potential name collisions ourselves.
-        seen = {}
-        types_seen = {}
-        for v in self.variants.variants:
-            v.check_clash(self.info, seen)
-            qtype = v.type.alternate_qtype()
-            if not qtype:
-                raise QAPISemError(
-                    self.info,
-                    "%s cannot use %s"
-                    % (v.describe(self.info), v.type.describe()))
-            conflicting = set([qtype])
-            if qtype == 'QTYPE_QSTRING':
-                if isinstance(v.type, QAPISchemaEnumType):
-                    for m in v.type.members:
-                        if m.name in ['on', 'off']:
-                            conflicting.add('QTYPE_QBOOL')
-                        if re.match(r'[-+0-9.]', m.name):
-                            # lazy, could be tightened
-                            conflicting.add('QTYPE_QNUM')
-                else:
-                    conflicting.add('QTYPE_QNUM')
-                    conflicting.add('QTYPE_QBOOL')
-            for qt in conflicting:
-                if qt in types_seen:
-                    raise QAPISemError(
-                        self.info,
-                        "%s can't be distinguished from '%s'"
-                        % (v.describe(self.info), types_seen[qt]))
-                types_seen[qt] = v.name
-
-    def connect_doc(self, doc=None):
-        super().connect_doc(doc)
-        doc = doc or self.doc
-        for v in self.variants.variants:
-            v.connect_doc(doc)
-
-    def c_type(self):
-        return c_name(self.name) + POINTER_SUFFIX
-
-    def json_type(self):
-        return 'value'
-
-    def visit(self, visitor):
-        super().visit(visitor)
-        visitor.visit_alternate_type(
-            self.name, self.info, self.ifcond, self.features, self.variants)
-
-
-class QAPISchemaVariants:
-    def __init__(self, tag_name, info, tag_member, variants):
-        # Unions pass tag_name but not tag_member.
-        # Alternates pass tag_member but not tag_name.
-        # After check(), tag_member is always set.
-        assert bool(tag_member) != bool(tag_name)
-        assert (isinstance(tag_name, str) or
-                isinstance(tag_member, QAPISchemaObjectTypeMember))
-        for v in variants:
-            assert isinstance(v, QAPISchemaVariant)
-        self._tag_name = tag_name
-        self.info = info
-        self.tag_member = tag_member
-        self.variants = variants
-
-    def set_defined_in(self, name):
-        for v in self.variants:
-            v.set_defined_in(name)
-
-    def check(self, schema, seen):
-        if self._tag_name:      # union
-            self.tag_member = seen.get(c_name(self._tag_name))
-            base = "'base'"
-            # Pointing to the base type when not implicit would be
-            # nice, but we don't know it here
-            if not self.tag_member or self._tag_name != self.tag_member.name:
-                raise QAPISemError(
-                    self.info,
-                    "discriminator '%s' is not a member of %s"
-                    % (self._tag_name, base))
-            # Here we do:
-            base_type = schema.lookup_type(self.tag_member.defined_in)
-            assert base_type
-            if not base_type.is_implicit():
-                base = "base type '%s'" % self.tag_member.defined_in
-            if not isinstance(self.tag_member.type, QAPISchemaEnumType):
-                raise QAPISemError(
-                    self.info,
-                    "discriminator member '%s' of %s must be of enum type"
-                    % (self._tag_name, base))
-            if self.tag_member.optional:
-                raise QAPISemError(
-                    self.info,
-                    "discriminator member '%s' of %s must not be optional"
-                    % (self._tag_name, base))
-            if self.tag_member.ifcond.is_present():
-                raise QAPISemError(
-                    self.info,
-                    "discriminator member '%s' of %s must not be conditional"
-                    % (self._tag_name, base))
-        else:                   # alternate
-            assert isinstance(self.tag_member.type, QAPISchemaEnumType)
-            assert not self.tag_member.optional
-            assert not self.tag_member.ifcond.is_present()
-        if self._tag_name:      # union
-            # branches that are not explicitly covered get an empty type
-            cases = {v.name for v in self.variants}
-            for m in self.tag_member.type.members:
-                if m.name not in cases:
-                    v = QAPISchemaVariant(m.name, self.info,
-                                          'q_empty', m.ifcond)
-                    v.set_defined_in(self.tag_member.defined_in)
-                    self.variants.append(v)
-        if not self.variants:
-            raise QAPISemError(self.info, "union has no branches")
-        for v in self.variants:
-            v.check(schema)
-            # Union names must match enum values; alternate names are
-            # checked separately. Use 'seen' to tell the two apart.
-            if seen:
-                if v.name not in self.tag_member.type.member_names():
-                    raise QAPISemError(
-                        self.info,
-                        "branch '%s' is not a value of %s"
-                        % (v.name, self.tag_member.type.describe()))
-                if (not isinstance(v.type, QAPISchemaObjectType)
-                        or v.type.variants):
-                    raise QAPISemError(
-                        self.info,
-                        "%s cannot use %s"
-                        % (v.describe(self.info), v.type.describe()))
-                v.type.check(schema)
-
-    def check_clash(self, info, seen):
-        for v in self.variants:
-            # Reset seen map for each variant, since qapi names from one
-            # branch do not affect another branch
-            v.type.check_clash(info, dict(seen))
-
-
-class QAPISchemaMember:
-    """ Represents object members, enum members and features """
-    role = 'member'
-
-    def __init__(self, name, info, ifcond=None):
-        assert isinstance(name, str)
-        self.name = name
-        self.info = info
-        self.ifcond = ifcond or QAPISchemaIfCond()
-        self.defined_in = None
-
-    def set_defined_in(self, name):
-        assert not self.defined_in
-        self.defined_in = name
-
-    def check_clash(self, info, seen):
-        cname = c_name(self.name)
-        if cname in seen:
-            raise QAPISemError(
-                info,
-                "%s collides with %s"
-                % (self.describe(info), seen[cname].describe(info)))
-        seen[cname] = self
-
-    def connect_doc(self, doc):
-        if doc:
-            doc.connect_member(self)
-
-    def describe(self, info):
-        role = self.role
-        defined_in = self.defined_in
-        assert defined_in
-
-        if defined_in.startswith('q_obj_'):
-            # See QAPISchema._make_implicit_object_type() - reverse the
-            # mapping there to create a nice human-readable description
-            defined_in = defined_in[6:]
-            if defined_in.endswith('-arg'):
-                # Implicit type created for a command's dict 'data'
-                assert role == 'member'
-                role = 'parameter'
-            elif defined_in.endswith('-base'):
-                # Implicit type created for a union's dict 'base'
-                role = 'base ' + role
-            else:
-                assert False
-        elif defined_in != info.defn_name:
-            return "%s '%s' of type '%s'" % (role, self.name, defined_in)
-        return "%s '%s'" % (role, self.name)
-
-
-class QAPISchemaEnumMember(QAPISchemaMember):
-    role = 'value'
-
-    def __init__(self, name, info, ifcond=None, features=None):
-        super().__init__(name, info, ifcond)
-        for f in features or []:
-            assert isinstance(f, QAPISchemaFeature)
-            f.set_defined_in(name)
-        self.features = features or []
-
-    def connect_doc(self, doc):
-        super().connect_doc(doc)
-        if doc:
-            for f in self.features:
-                doc.connect_feature(f)
-
-
-class QAPISchemaFeature(QAPISchemaMember):
-    role = 'feature'
-
-    def is_special(self):
-        return self.name in ('deprecated', 'unstable')
-
-
-class QAPISchemaObjectTypeMember(QAPISchemaMember):
-    def __init__(self, name, info, typ, optional, ifcond=None, features=None):
-        super().__init__(name, info, ifcond)
-        assert isinstance(typ, str)
-        assert isinstance(optional, bool)
-        for f in features or []:
-            assert isinstance(f, QAPISchemaFeature)
-            f.set_defined_in(name)
-        self._type_name = typ
-        self.type = None
-        self.optional = optional
-        self.features = features or []
-
-    def check(self, schema):
-        assert self.defined_in
-        self.type = schema.resolve_type(self._type_name, self.info,
-                                        self.describe)
-        seen = {}
-        for f in self.features:
-            f.check_clash(self.info, seen)
-
-    def connect_doc(self, doc):
-        super().connect_doc(doc)
-        if doc:
-            for f in self.features:
-                doc.connect_feature(f)
-
-
-class QAPISchemaVariant(QAPISchemaObjectTypeMember):
-    role = 'branch'
-
-    def __init__(self, name, info, typ, ifcond=None):
-        super().__init__(name, info, typ, False, ifcond)
-
-
-class QAPISchemaCommand(QAPISchemaEntity):
-    meta = 'command'
-
-    def __init__(self, name, info, doc, ifcond, features,
-                 arg_type, ret_type,
-                 gen, success_response, boxed, allow_oob, allow_preconfig,
-                 coroutine):
-        super().__init__(name, info, doc, ifcond, features)
-        assert not arg_type or isinstance(arg_type, str)
-        assert not ret_type or isinstance(ret_type, str)
-        self._arg_type_name = arg_type
-        self.arg_type = None
-        self._ret_type_name = ret_type
-        self.ret_type = None
-        self.gen = gen
-        self.success_response = success_response
-        self.boxed = boxed
-        self.allow_oob = allow_oob
-        self.allow_preconfig = allow_preconfig
-        self.coroutine = coroutine
-
-    def check(self, schema):
-        super().check(schema)
-        if self._arg_type_name:
-            self.arg_type = schema.resolve_type(
-                self._arg_type_name, self.info, "command's 'data'")
-            if not isinstance(self.arg_type, QAPISchemaObjectType):
-                raise QAPISemError(
-                    self.info,
-                    "command's 'data' cannot take %s"
-                    % self.arg_type.describe())
-            if self.arg_type.variants and not self.boxed:
-                raise QAPISemError(
-                    self.info,
-                    "command's 'data' can take %s only with 'boxed': true"
-                    % self.arg_type.describe())
-        if self._ret_type_name:
-            self.ret_type = schema.resolve_type(
-                self._ret_type_name, self.info, "command's 'returns'")
-            if self.name not in self.info.pragma.command_returns_exceptions:
-                typ = self.ret_type
-                if isinstance(typ, QAPISchemaArrayType):
-                    typ = self.ret_type.element_type
-                    assert typ
-                if not isinstance(typ, QAPISchemaObjectType):
-                    raise QAPISemError(
-                        self.info,
-                        "command's 'returns' cannot take %s"
-                        % self.ret_type.describe())
-
-    def connect_doc(self, doc=None):
-        super().connect_doc(doc)
-        doc = doc or self.doc
-        if doc:
-            if self.arg_type and self.arg_type.is_implicit():
-                self.arg_type.connect_doc(doc)
-
-    def visit(self, visitor):
-        super().visit(visitor)
-        visitor.visit_command(
-            self.name, self.info, self.ifcond, self.features,
-            self.arg_type, self.ret_type, self.gen, self.success_response,
-            self.boxed, self.allow_oob, self.allow_preconfig,
-            self.coroutine)
-
-
-class QAPISchemaEvent(QAPISchemaEntity):
-    meta = 'event'
-
-    def __init__(self, name, info, doc, ifcond, features, arg_type, boxed):
-        super().__init__(name, info, doc, ifcond, features)
-        assert not arg_type or isinstance(arg_type, str)
-        self._arg_type_name = arg_type
-        self.arg_type = None
-        self.boxed = boxed
-
-    def check(self, schema):
-        super().check(schema)
-        if self._arg_type_name:
-            self.arg_type = schema.resolve_type(
-                self._arg_type_name, self.info, "event's 'data'")
-            if not isinstance(self.arg_type, QAPISchemaObjectType):
-                raise QAPISemError(
-                    self.info,
-                    "event's 'data' cannot take %s"
-                    % self.arg_type.describe())
-            if self.arg_type.variants and not self.boxed:
-                raise QAPISemError(
-                    self.info,
-                    "event's 'data' can take %s only with 'boxed': true"
-                    % self.arg_type.describe())
-
-    def connect_doc(self, doc=None):
-        super().connect_doc(doc)
-        doc = doc or self.doc
-        if doc:
-            if self.arg_type and self.arg_type.is_implicit():
-                self.arg_type.connect_doc(doc)
-
-    def visit(self, visitor):
-        super().visit(visitor)
-        visitor.visit_event(
-            self.name, self.info, self.ifcond, self.features,
-            self.arg_type, self.boxed)
-
-
-class QAPISchema:
-    def __init__(self, fname):
-        self.fname = fname
-
-        try:
-            parser = QAPISchemaParser(fname)
-        except OSError as err:
-            raise QAPIError(
-                f"can't read schema file '{fname}': {err.strerror}"
-            ) from err
-
-        exprs = check_exprs(parser.exprs)
-        self.docs = parser.docs
-        self._entity_list = []
-        self._entity_dict = {}
-        self._module_dict = OrderedDict()
-        self._schema_dir = os.path.dirname(fname)
-        self._make_module(QAPISchemaModule.BUILTIN_MODULE_NAME)
-        self._make_module(fname)
-        self._predefining = True
-        self._def_predefineds()
-        self._predefining = False
-        self._def_exprs(exprs)
-        self.check()
-
-    def _def_entity(self, ent):
-        # Only the predefined types are allowed to not have info
-        assert ent.info or self._predefining
-        self._entity_list.append(ent)
-        if ent.name is None:
-            return
-        # TODO reject names that differ only in '_' vs. '.'  vs. '-',
-        # because they're liable to clash in generated C.
-        other_ent = self._entity_dict.get(ent.name)
-        if other_ent:
-            if other_ent.info:
-                where = QAPISourceError(other_ent.info, "previous definition")
-                raise QAPISemError(
-                    ent.info,
-                    "'%s' is already defined\n%s" % (ent.name, where))
-            raise QAPISemError(
-                ent.info, "%s is already defined" % other_ent.describe())
-        self._entity_dict[ent.name] = ent
-
-    def lookup_entity(self, name, typ=None):
-        ent = self._entity_dict.get(name)
-        if typ and not isinstance(ent, typ):
-            return None
-        return ent
-
-    def lookup_type(self, name):
-        return self.lookup_entity(name, QAPISchemaType)
-
-    def resolve_type(self, name, info, what):
-        typ = self.lookup_type(name)
-        if not typ:
-            if callable(what):
-                what = what(info)
-            raise QAPISemError(
-                info, "%s uses unknown type '%s'" % (what, name))
-        return typ
-
-    def _module_name(self, fname: str) -> str:
-        if QAPISchemaModule.is_system_module(fname):
-            return fname
-        return os.path.relpath(fname, self._schema_dir)
-
-    def _make_module(self, fname):
-        name = self._module_name(fname)
-        if name not in self._module_dict:
-            self._module_dict[name] = QAPISchemaModule(name)
-        return self._module_dict[name]
-
-    def module_by_fname(self, fname):
-        name = self._module_name(fname)
-        return self._module_dict[name]
-
-    def _def_include(self, expr, info, doc):
-        include = expr['include']
-        assert doc is None
-        self._def_entity(QAPISchemaInclude(self._make_module(include), info))
-
-    def _def_builtin_type(self, name, json_type, c_type):
-        self._def_entity(QAPISchemaBuiltinType(name, json_type, c_type))
-        # Instantiating only the arrays that are actually used would
-        # be nice, but we can't as long as their generated code
-        # (qapi-builtin-types.[ch]) may be shared by some other
-        # schema.
-        self._make_array_type(name, None)
-
-    def _def_predefineds(self):
-        for t in [('str',    'string',  'char' + POINTER_SUFFIX),
-                  ('number', 'number',  'double'),
-                  ('int',    'int',     'int64_t'),
-                  ('int8',   'int',     'int8_t'),
-                  ('int16',  'int',     'int16_t'),
-                  ('int32',  'int',     'int32_t'),
-                  ('int64',  'int',     'int64_t'),
-                  ('uint8',  'int',     'uint8_t'),
-                  ('uint16', 'int',     'uint16_t'),
-                  ('uint32', 'int',     'uint32_t'),
-                  ('uint64', 'int',     'uint64_t'),
-                  ('size',   'int',     'uint64_t'),
-                  ('bool',   'boolean', 'bool'),
-                  ('any',    'value',   'CFTypeRef'),
-                  ('null',   'null',    'CFNullRef')]:
-            self._def_builtin_type(*t)
-        self.the_empty_object_type = QAPISchemaObjectType(
-            'q_empty', None, None, None, None, None, [], None)
-        self._def_entity(self.the_empty_object_type)
-
-        qtypes = ['none', 'qnull', 'qnum', 'qstring', 'qdict', 'qlist',
-                  'qbool']
-        qtype_values = self._make_enum_members(
-            [{'name': n} for n in qtypes], None)
-
-        self._def_entity(QAPISchemaEnumType('QType', None, None, None, None,
-                                            qtype_values, 'QTYPE'))
-
-    def _make_features(self, features, info):
-        if features is None:
-            return []
-        return [QAPISchemaFeature(f['name'], info,
-                                  QAPISchemaIfCond(f.get('if')))
-                for f in features]
-
-    def _make_enum_member(self, name, ifcond, features, info):
-        return QAPISchemaEnumMember(name, info,
-                                    QAPISchemaIfCond(ifcond),
-                                    self._make_features(features, info))
-
-    def _make_enum_members(self, values, info):
-        return [self._make_enum_member(v['name'], v.get('if'),
-                                       v.get('features'), info)
-                for v in values]
-
-    def _make_array_type(self, element_type, info):
-        name = element_type + 'List'    # reserved by check_defn_name_str()
-        if not self.lookup_type(name):
-            self._def_entity(QAPISchemaArrayType(name, info, element_type))
-        return name
-
-    def _make_implicit_object_type(self, name, info, ifcond, role, members):
-        if not members:
-            return None
-        # See also QAPISchemaObjectTypeMember.describe()
-        name = 'q_obj_%s-%s' % (name, role)
-        typ = self.lookup_entity(name, QAPISchemaObjectType)
-        if typ:
-            # The implicit object type has multiple users.  This can
-            # only be a duplicate definition, which will be flagged
-            # later.
-            pass
-        else:
-            self._def_entity(QAPISchemaObjectType(
-                name, info, None, ifcond, None, None, members, None))
-        return name
-
-    def _def_enum_type(self, expr, info, doc):
-        name = expr['enum']
-        data = expr['data']
-        prefix = expr.get('prefix')
-        ifcond = QAPISchemaIfCond(expr.get('if'))
-        features = self._make_features(expr.get('features'), info)
-        self._def_entity(QAPISchemaEnumType(
-            name, info, doc, ifcond, features,
-            self._make_enum_members(data, info), prefix))
-
-    def _make_member(self, name, typ, ifcond, features, info):
-        optional = False
-        if name.startswith('*'):
-            name = name[1:]
-            optional = True
-        if isinstance(typ, list):
-            assert len(typ) == 1
-            typ = self._make_array_type(typ[0], info)
-        return QAPISchemaObjectTypeMember(name, info, typ, optional, ifcond,
-                                          self._make_features(features, info))
-
-    def _make_members(self, data, info):
-        return [self._make_member(key, value['type'],
-                                  QAPISchemaIfCond(value.get('if')),
-                                  value.get('features'), info)
-                for (key, value) in data.items()]
-
-    def _def_struct_type(self, expr, info, doc):
-        name = expr['struct']
-        base = expr.get('base')
-        data = expr['data']
-        ifcond = QAPISchemaIfCond(expr.get('if'))
-        features = self._make_features(expr.get('features'), info)
-        self._def_entity(QAPISchemaObjectType(
-            name, info, doc, ifcond, features, base,
-            self._make_members(data, info),
-            None))
-
-    def _make_variant(self, case, typ, ifcond, info):
-        if isinstance(typ, list):
-             assert len(typ) == 1
-             typ = self._make_array_type(typ[0], info)
-        return QAPISchemaVariant(case, info, typ, ifcond)
-
-    def _def_union_type(self, expr, info, doc):
-        name = expr['union']
-        base = expr['base']
-        tag_name = expr['discriminator']
-        data = expr['data']
-        ifcond = QAPISchemaIfCond(expr.get('if'))
-        features = self._make_features(expr.get('features'), info)
-        if isinstance(base, dict):
-            base = self._make_implicit_object_type(
-                name, info, ifcond,
-                'base', self._make_members(base, info))
-        variants = [
-            self._make_variant(key, value['type'],
-                               QAPISchemaIfCond(value.get('if')),
-                               info)
-            for (key, value) in data.items()]
-        members = []
-        self._def_entity(
-            QAPISchemaObjectType(name, info, doc, ifcond, features,
-                                 base, members,
-                                 QAPISchemaVariants(
-                                     tag_name, info, None, variants)))
-
-    def _def_alternate_type(self, expr, info, doc):
-        name = expr['alternate']
-        data = expr['data']
-        ifcond = QAPISchemaIfCond(expr.get('if'))
-        features = self._make_features(expr.get('features'), info)
-        variants = [
-            self._make_variant(key, value['type'],
-                               QAPISchemaIfCond(value.get('if')),
-                               info)
-            for (key, value) in data.items()]
-        tag_member = QAPISchemaObjectTypeMember('type', info, 'QType', False)
-        self._def_entity(
-            QAPISchemaAlternateType(name, info, doc, ifcond, features,
-                                    QAPISchemaVariants(
-                                        None, info, tag_member, variants)))
-
-    def _def_command(self, expr, info, doc):
-        name = expr['command']
-        data = expr.get('data')
-        rets = expr.get('returns')
-        gen = expr.get('gen', True)
-        success_response = expr.get('success-response', True)
-        boxed = expr.get('boxed', False)
-        allow_oob = expr.get('allow-oob', False)
-        allow_preconfig = expr.get('allow-preconfig', False)
-        coroutine = expr.get('coroutine', False)
-        ifcond = QAPISchemaIfCond(expr.get('if'))
-        features = self._make_features(expr.get('features'), info)
-        if isinstance(data, OrderedDict):
-            data = self._make_implicit_object_type(
-                name, info, ifcond,
-                'arg', self._make_members(data, info))
-        if isinstance(rets, list):
-            assert len(rets) == 1
-            rets = self._make_array_type(rets[0], info)
-        self._def_entity(QAPISchemaCommand(name, info, doc, ifcond, features,
-                                           data, rets,
-                                           gen, success_response,
-                                           boxed, allow_oob, allow_preconfig,
-                                           coroutine))
-
-    def _def_event(self, expr, info, doc):
-        name = expr['event']
-        data = expr.get('data')
-        boxed = expr.get('boxed', False)
-        ifcond = QAPISchemaIfCond(expr.get('if'))
-        features = self._make_features(expr.get('features'), info)
-        if isinstance(data, OrderedDict):
-            data = self._make_implicit_object_type(
-                name, info, ifcond,
-                'arg', self._make_members(data, info))
-        self._def_entity(QAPISchemaEvent(name, info, doc, ifcond, features,
-                                         data, boxed))
-
-    def _def_exprs(self, exprs):
-        for expr_elem in exprs:
-            expr = expr_elem['expr']
-            info = expr_elem['info']
-            doc = expr_elem.get('doc')
-            if 'enum' in expr:
-                self._def_enum_type(expr, info, doc)
-            elif 'struct' in expr:
-                self._def_struct_type(expr, info, doc)
-            elif 'union' in expr:
-                self._def_union_type(expr, info, doc)
-            elif 'alternate' in expr:
-                self._def_alternate_type(expr, info, doc)
-            elif 'command' in expr:
-                self._def_command(expr, info, doc)
-            elif 'event' in expr:
-                self._def_event(expr, info, doc)
-            elif 'include' in expr:
-                self._def_include(expr, info, doc)
-            else:
-                assert False
-
-    def check(self):
-        for ent in self._entity_list:
-            ent.check(self)
-            ent.connect_doc()
-            ent.check_doc()
-        for ent in self._entity_list:
-            ent.set_module(self)
-
-    def visit(self, visitor):
-        visitor.visit_begin(self)
-        for mod in self._module_dict.values():
-            mod.visit(visitor)
-        visitor.visit_end()

+ 0 - 71
scripts/qapi/source.py

@@ -1,71 +0,0 @@
-#
-# QAPI frontend source file info
-#
-# Copyright (c) 2019 Red Hat Inc.
-#
-# Authors:
-#  Markus Armbruster <armbru@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2.
-# See the COPYING file in the top-level directory.
-
-import copy
-from typing import List, Optional, TypeVar
-
-
-class QAPISchemaPragma:
-    # Replace with @dataclass in Python 3.7+
-    # pylint: disable=too-few-public-methods
-
-    def __init__(self) -> None:
-        # Are documentation comments required?
-        self.doc_required = False
-        # Commands whose names may use '_'
-        self.command_name_exceptions: List[str] = []
-        # Commands allowed to return a non-dictionary
-        self.command_returns_exceptions: List[str] = []
-        # Types whose member names may violate case conventions
-        self.member_name_exceptions: List[str] = []
-
-
-class QAPISourceInfo:
-    T = TypeVar('T', bound='QAPISourceInfo')
-
-    def __init__(self, fname: str, parent: Optional['QAPISourceInfo']):
-        self.fname = fname
-        self.line = 1
-        self.parent = parent
-        self.pragma: QAPISchemaPragma = (
-            parent.pragma if parent else QAPISchemaPragma()
-        )
-        self.defn_meta: Optional[str] = None
-        self.defn_name: Optional[str] = None
-
-    def set_defn(self, meta: str, name: str) -> None:
-        self.defn_meta = meta
-        self.defn_name = name
-
-    def next_line(self: T) -> T:
-        info = copy.copy(self)
-        info.line += 1
-        return info
-
-    def loc(self) -> str:
-        return f"{self.fname}:{self.line}"
-
-    def in_defn(self) -> str:
-        if self.defn_name:
-            return "%s: In %s '%s':\n" % (self.fname,
-                                          self.defn_meta, self.defn_name)
-        return ''
-
-    def include_path(self) -> str:
-        ret = ''
-        parent = self.parent
-        while parent:
-            ret = 'In file included from %s:\n' % parent.loc() + ret
-            parent = parent.parent
-        return ret
-
-    def __str__(self) -> str:
-        return self.include_path() + self.in_defn() + self.loc()

+ 0 - 383
scripts/qapi/types.py

@@ -1,383 +0,0 @@
-"""
-QAPI types generator
-
-Copyright IBM, Corp. 2011
-Copyright (c) 2013-2018 Red Hat Inc.
-
-Authors:
- Anthony Liguori <aliguori@us.ibm.com>
- Michael Roth <mdroth@linux.vnet.ibm.com>
- Markus Armbruster <armbru@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 typing import List, Optional
-
-from .common import c_enum_const, c_name, mcgen
-from .gen import QAPISchemaModularCVisitor, gen_special_features, ifcontext
-from .schema import (
-    QAPISchema,
-    QAPISchemaEnumMember,
-    QAPISchemaFeature,
-    QAPISchemaIfCond,
-    QAPISchemaObjectType,
-    QAPISchemaObjectTypeMember,
-    QAPISchemaType,
-    QAPISchemaVariants,
-)
-from .source import QAPISourceInfo
-
-
-# variants must be emitted before their container; track what has already
-# been output
-objects_seen = set()
-
-
-def gen_enum_lookup(name: str,
-                    members: List[QAPISchemaEnumMember],
-                    prefix: Optional[str] = None) -> str:
-    max_index = c_enum_const(name, '_MAX', prefix)
-    feats = ''
-    ret = mcgen('''
-
-const QEnumLookup %(c_name)s_lookup = {
-    .array = (const char *const[]) {
-''',
-                c_name=c_name(name))
-    for memb in members:
-        ret += memb.ifcond.gen_if()
-        index = c_enum_const(name, memb.name, prefix)
-        ret += mcgen('''
-        [%(index)s] = "%(name)s",
-''',
-                     index=index, name=memb.name)
-        ret += memb.ifcond.gen_endif()
-
-        special_features = gen_special_features(memb.features)
-        if special_features != '0':
-            feats += mcgen('''
-        [%(index)s] = %(special_features)s,
-''',
-                           index=index, special_features=special_features)
-
-    if feats:
-        ret += mcgen('''
-    },
-    .special_features = (const unsigned char[%(max_index)s]) {
-''',
-                     max_index=max_index)
-        ret += feats
-
-    ret += mcgen('''
-    },
-    .size = %(max_index)s
-};
-''',
-                 max_index=max_index)
-    return ret
-
-
-def gen_enum(name: str,
-             members: List[QAPISchemaEnumMember],
-             prefix: Optional[str] = None) -> str:
-    # append automatically generated _MAX value
-    enum_members = members + [QAPISchemaEnumMember('_MAX', None)]
-
-    ret = mcgen('''
-
-typedef enum %(c_name)s {
-''',
-                c_name=c_name(name))
-
-    for memb in enum_members:
-        ret += memb.ifcond.gen_if()
-        ret += mcgen('''
-    %(c_enum)s,
-''',
-                     c_enum=c_enum_const(name, memb.name, prefix))
-        ret += memb.ifcond.gen_endif()
-
-    ret += mcgen('''
-} %(c_name)s;
-''',
-                 c_name=c_name(name))
-
-    ret += mcgen('''
-
-#define %(c_name)s_str(val) \\
-    qapi_enum_lookup(&%(c_name)s_lookup, (val))
-
-extern const QEnumLookup %(c_name)s_lookup;
-''',
-                 c_name=c_name(name))
-    return ret
-
-
-def gen_fwd_object_or_array(name: str) -> str:
-    return mcgen('''
-
-typedef struct %(c_name)s %(c_name)s;
-''',
-                 c_name=c_name(name))
-
-
-def gen_array(name: str, element_type: QAPISchemaType) -> str:
-    return mcgen('''
-
-struct %(c_name)s {
-    %(c_name)s *next;
-    %(c_type)s value;
-};
-''',
-                 c_name=c_name(name), c_type=element_type.c_type())
-
-
-def gen_struct_members(members: List[QAPISchemaObjectTypeMember]) -> str:
-    ret = ''
-    for memb in members:
-        ret += memb.ifcond.gen_if()
-        if memb.optional:
-            ret += mcgen('''
-    bool has_%(c_name)s;
-''',
-                         c_name=c_name(memb.name))
-        ret += mcgen('''
-    %(c_type)s %(c_name)s;
-''',
-                     c_type=memb.type.c_type(), c_name=c_name(memb.name))
-        ret += memb.ifcond.gen_endif()
-    return ret
-
-
-def gen_object(name: str, ifcond: QAPISchemaIfCond,
-               base: Optional[QAPISchemaObjectType],
-               members: List[QAPISchemaObjectTypeMember],
-               variants: Optional[QAPISchemaVariants]) -> str:
-    if name in objects_seen:
-        return ''
-    objects_seen.add(name)
-
-    ret = ''
-    for var in variants.variants if variants else ():
-        obj = var.type
-        if not isinstance(obj, QAPISchemaObjectType):
-            continue
-        ret += gen_object(obj.name, obj.ifcond, obj.base,
-                          obj.local_members, obj.variants)
-
-    ret += mcgen('''
-
-''')
-    ret += ifcond.gen_if()
-    ret += mcgen('''
-struct %(c_name)s {
-''',
-                 c_name=c_name(name))
-
-    if base:
-        if not base.is_implicit():
-            ret += mcgen('''
-    /* Members inherited from %(c_name)s: */
-''',
-                         c_name=base.c_name())
-        ret += gen_struct_members(base.members)
-        if not base.is_implicit():
-            ret += mcgen('''
-    /* Own members: */
-''')
-    ret += gen_struct_members(members)
-
-    if variants:
-        ret += gen_variants(variants)
-
-    # Make sure that all structs have at least one member; this avoids
-    # potential issues with attempting to malloc space for zero-length
-    # structs in C, and also incompatibility with C++ (where an empty
-    # struct is size 1).
-    if (not base or base.is_empty()) and not members and not variants:
-        ret += mcgen('''
-    char qapi_dummy_for_empty_struct;
-''')
-
-    ret += mcgen('''
-};
-''')
-    ret += ifcond.gen_endif()
-
-    return ret
-
-
-def gen_upcast(name: str, base: QAPISchemaObjectType) -> str:
-    # C makes const-correctness ugly.  We have to cast away const to let
-    # this function work for both const and non-const obj.
-    return mcgen('''
-
-static inline %(base)s *qapi_%(c_name)s_base(const %(c_name)s *obj)
-{
-    return (%(base)s *)obj;
-}
-''',
-                 c_name=c_name(name), base=base.c_name())
-
-
-def gen_variants(variants: QAPISchemaVariants) -> str:
-    ret = mcgen('''
-    union { /* union tag is @%(c_name)s */
-''',
-                c_name=c_name(variants.tag_member.name))
-
-    for var in variants.variants:
-        if var.type.name == 'q_empty':
-            continue
-        ret += var.ifcond.gen_if()
-        ret += mcgen('''
-        %(c_type)s %(c_name)s;
-''',
-                     c_type=var.type.c_unboxed_type(),
-                     c_name=c_name(var.name))
-        ret += var.ifcond.gen_endif()
-
-    ret += mcgen('''
-    } u;
-''')
-
-    return ret
-
-
-def gen_type_cleanup_decl(name: str) -> str:
-    ret = mcgen('''
-
-void qapi_free_%(c_name)s(%(c_name)s *obj);
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(%(c_name)s, qapi_free_%(c_name)s)
-''',
-                c_name=c_name(name))
-    return ret
-
-
-def gen_type_cleanup(name: str) -> str:
-    ret = mcgen('''
-
-void qapi_free_%(c_name)s(%(c_name)s *obj)
-{
-    Visitor *v;
-
-    if (!obj) {
-        return;
-    }
-
-    v = qapi_dealloc_visitor_new();
-    visit_type_%(c_name)s(v, NULL, &obj, NULL);
-    visit_free(v);
-}
-''',
-                c_name=c_name(name))
-    return ret
-
-
-class QAPISchemaGenTypeVisitor(QAPISchemaModularCVisitor):
-
-    def __init__(self, prefix: str):
-        super().__init__(
-            prefix, 'qapi-types', ' * Schema-defined QAPI types',
-            ' * Built-in QAPI types', __doc__)
-
-    def _begin_builtin_module(self) -> None:
-        self._genc.preamble_add(mcgen('''
-#include "qemu-compat.h"
-#include "dealloc-visitor.h"
-#include "qapi-builtin-types.h"
-#include "qapi-builtin-visit.h"
-'''))
-        self._genh.preamble_add(mcgen('''
-#include "util.h"
-'''))
-
-    def _begin_user_module(self, name: str) -> None:
-        types = self._module_basename('qapi-types', name)
-        visit = self._module_basename('qapi-visit', name)
-        self._genc.preamble_add(mcgen('''
-#include "qemu-compat.h"
-#include "dealloc-visitor.h"
-#include "%(types)s.h"
-#include "%(visit)s.h"
-''',
-                                      types=types, visit=visit))
-        self._genh.preamble_add(mcgen('''
-#include "qapi-builtin-types.h"
-'''))
-
-    def visit_begin(self, schema: QAPISchema) -> None:
-        # gen_object() is recursive, ensure it doesn't visit the empty type
-        objects_seen.add(schema.the_empty_object_type.name)
-
-    def _gen_type_cleanup(self, name: str) -> None:
-        self._genh.add(gen_type_cleanup_decl(name))
-        self._genc.add(gen_type_cleanup(name))
-
-    def visit_enum_type(self,
-                        name: str,
-                        info: Optional[QAPISourceInfo],
-                        ifcond: QAPISchemaIfCond,
-                        features: List[QAPISchemaFeature],
-                        members: List[QAPISchemaEnumMember],
-                        prefix: Optional[str]) -> None:
-        with ifcontext(ifcond, self._genh, self._genc):
-            self._genh.preamble_add(gen_enum(name, members, prefix))
-            self._genc.add(gen_enum_lookup(name, members, prefix))
-
-    def visit_array_type(self,
-                         name: str,
-                         info: Optional[QAPISourceInfo],
-                         ifcond: QAPISchemaIfCond,
-                         element_type: QAPISchemaType) -> None:
-        with ifcontext(ifcond, self._genh, self._genc):
-            self._genh.preamble_add(gen_fwd_object_or_array(name))
-            self._genh.add(gen_array(name, element_type))
-            self._gen_type_cleanup(name)
-
-    def visit_object_type(self,
-                          name: str,
-                          info: Optional[QAPISourceInfo],
-                          ifcond: QAPISchemaIfCond,
-                          features: List[QAPISchemaFeature],
-                          base: Optional[QAPISchemaObjectType],
-                          members: List[QAPISchemaObjectTypeMember],
-                          variants: Optional[QAPISchemaVariants]) -> None:
-        # Nothing to do for the special empty builtin
-        if name == 'q_empty':
-            return
-        with ifcontext(ifcond, self._genh):
-            self._genh.preamble_add(gen_fwd_object_or_array(name))
-        self._genh.add(gen_object(name, ifcond, base, members, variants))
-        with ifcontext(ifcond, self._genh, self._genc):
-            if base and not base.is_implicit():
-                self._genh.add(gen_upcast(name, base))
-            # TODO Worth changing the visitor signature, so we could
-            # directly use rather than repeat type.is_implicit()?
-            #if not name.startswith('q_'):
-                # implicit types won't be directly allocated/freed
-            self._gen_type_cleanup(name)
-
-    def visit_alternate_type(self,
-                             name: str,
-                             info: QAPISourceInfo,
-                             ifcond: QAPISchemaIfCond,
-                             features: List[QAPISchemaFeature],
-                             variants: QAPISchemaVariants) -> None:
-        with ifcontext(ifcond, self._genh):
-            self._genh.preamble_add(gen_fwd_object_or_array(name))
-        self._genh.add(gen_object(name, ifcond, None,
-                                  [variants.tag_member], variants))
-        with ifcontext(ifcond, self._genh, self._genc):
-            self._gen_type_cleanup(name)
-
-
-def gen_types(schema: QAPISchema,
-              output_dir: str,
-              prefix: str,
-              opt_builtins: bool) -> None:
-    vis = QAPISchemaGenTypeVisitor(prefix)
-    schema.visit(vis)
-    vis.write(output_dir, opt_builtins)

+ 0 - 410
scripts/qapi/visit.py

@@ -1,410 +0,0 @@
-"""
-QAPI visitor generator
-
-Copyright IBM, Corp. 2011
-Copyright (C) 2014-2018 Red Hat, Inc.
-
-Authors:
- Anthony Liguori <aliguori@us.ibm.com>
- Michael Roth    <mdroth@linux.vnet.ibm.com>
- Markus Armbruster <armbru@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 typing import List, Optional
-
-from .common import (
-    c_enum_const,
-    c_name,
-    indent,
-    mcgen,
-)
-from .gen import QAPISchemaModularCVisitor, gen_special_features, ifcontext
-from .schema import (
-    QAPISchema,
-    QAPISchemaEnumMember,
-    QAPISchemaEnumType,
-    QAPISchemaFeature,
-    QAPISchemaIfCond,
-    QAPISchemaObjectType,
-    QAPISchemaObjectTypeMember,
-    QAPISchemaType,
-    QAPISchemaVariants,
-)
-from .source import QAPISourceInfo
-
-
-def gen_visit_decl(name: str, scalar: bool = False) -> str:
-    c_type = c_name(name) + ' *'
-    if not scalar:
-        c_type += '*'
-    return mcgen('''
-
-bool visit_type_%(c_name)s(Visitor *v, const char *name,
-                 %(c_type)sobj, Error **errp);
-''',
-                 c_name=c_name(name), c_type=c_type)
-
-
-def gen_visit_members_decl(name: str) -> str:
-    return mcgen('''
-
-bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp);
-''',
-                 c_name=c_name(name))
-
-
-def gen_visit_object_members(name: str,
-                             base: Optional[QAPISchemaObjectType],
-                             members: List[QAPISchemaObjectTypeMember],
-                             variants: Optional[QAPISchemaVariants]) -> str:
-    ret = mcgen('''
-
-bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
-{
-''',
-                c_name=c_name(name))
-
-    if base:
-        ret += mcgen('''
-    if (!visit_type_%(c_type)s_members(v, (%(c_type)s *)obj, errp)) {
-        return false;
-    }
-''',
-                     c_type=base.c_name())
-
-    for memb in members:
-        ret += memb.ifcond.gen_if()
-        if memb.optional:
-            ret += mcgen('''
-    if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) {
-''',
-                         name=memb.name, c_name=c_name(memb.name))
-            indent.increase()
-        special_features = gen_special_features(memb.features)
-        if special_features != '0':
-            ret += mcgen('''
-    if (visit_policy_reject(v, "%(name)s", %(special_features)s, errp)) {
-        return false;
-    }
-    if (!visit_policy_skip(v, "%(name)s", %(special_features)s)) {
-''',
-                         name=memb.name, special_features=special_features)
-            indent.increase()
-        ret += mcgen('''
-    if (!visit_type_%(c_type)s(v, "%(name)s", &obj->%(c_name)s, errp)) {
-        return false;
-    }
-''',
-                     c_type=memb.type.c_name(), name=memb.name,
-                     c_name=c_name(memb.name))
-        if special_features != '0':
-            indent.decrease()
-            ret += mcgen('''
-    }
-''')
-        if memb.optional:
-            indent.decrease()
-            ret += mcgen('''
-    }
-''')
-        ret += memb.ifcond.gen_endif()
-
-    if variants:
-        tag_member = variants.tag_member
-        assert isinstance(tag_member.type, QAPISchemaEnumType)
-
-        ret += mcgen('''
-    switch (obj->%(c_name)s) {
-''',
-                     c_name=c_name(tag_member.name))
-
-        for var in variants.variants:
-            case_str = c_enum_const(tag_member.type.name, var.name,
-                                    tag_member.type.prefix)
-            ret += var.ifcond.gen_if()
-            if var.type.name == 'q_empty':
-                # valid variant and nothing to do
-                ret += mcgen('''
-    case %(case)s:
-        break;
-''',
-                             case=case_str)
-            else:
-                ret += mcgen('''
-    case %(case)s:
-        return visit_type_%(c_type)s_members(v, &obj->u.%(c_name)s, errp);
-''',
-                             case=case_str,
-                             c_type=var.type.c_name(), c_name=c_name(var.name))
-
-            ret += var.ifcond.gen_endif()
-        ret += mcgen('''
-    default:
-        abort();
-    }
-''')
-
-    ret += mcgen('''
-    return true;
-}
-''')
-    return ret
-
-
-def gen_visit_list(name: str, element_type: QAPISchemaType) -> str:
-    return mcgen('''
-
-bool visit_type_%(c_name)s(Visitor *v, const char *name,
-                 %(c_name)s **obj, Error **errp)
-{
-    bool ok = false;
-    %(c_name)s *tail;
-    size_t size = sizeof(**obj);
-
-    if (!visit_start_list(v, name, (GenericList **)obj, size, errp)) {
-        return false;
-    }
-
-    for (tail = *obj; tail;
-         tail = (%(c_name)s *)visit_next_list(v, (GenericList *)tail, size)) {
-        if (!visit_type_%(c_elt_type)s(v, NULL, &tail->value, errp)) {
-            goto out_obj;
-        }
-    }
-
-    ok = visit_check_list(v, errp);
-out_obj:
-    visit_end_list(v, (void **)obj);
-    if (!ok && visit_is_input(v)) {
-        qapi_free_%(c_name)s(*obj);
-        *obj = NULL;
-    }
-    return ok;
-}
-''',
-                 c_name=c_name(name), c_elt_type=element_type.c_name())
-
-
-def gen_visit_enum(name: str) -> str:
-    return mcgen('''
-
-bool visit_type_%(c_name)s(Visitor *v, const char *name,
-                 %(c_name)s *obj, Error **errp)
-{
-    int value = *obj;
-    bool ok = visit_type_enum(v, name, &value, &%(c_name)s_lookup, errp);
-    *obj = value;
-    return ok;
-}
-''',
-                 c_name=c_name(name))
-
-
-def gen_visit_alternate(name: str, variants: QAPISchemaVariants) -> str:
-    ret = mcgen('''
-
-bool visit_type_%(c_name)s(Visitor *v, const char *name,
-                 %(c_name)s **obj, Error **errp)
-{
-    bool ok = false;
-
-    if (!visit_start_alternate(v, name, (GenericAlternate **)obj,
-                               sizeof(**obj), errp)) {
-        return false;
-    }
-    if (!*obj) {
-        /* incomplete */
-        assert(visit_is_dealloc(v));
-        ok = true;
-        goto out_obj;
-    }
-    switch ((*obj)->type) {
-''',
-                c_name=c_name(name))
-
-    for var in variants.variants:
-        ret += var.ifcond.gen_if()
-        ret += mcgen('''
-    case %(case)s:
-''',
-                     case=var.type.alternate_qtype())
-        if isinstance(var.type, QAPISchemaObjectType):
-            ret += mcgen('''
-        if (!visit_start_struct(v, name, NULL, 0, errp)) {
-            break;
-        }
-        if (visit_type_%(c_type)s_members(v, &(*obj)->u.%(c_name)s, errp)) {
-            ok = visit_check_struct(v, errp);
-        }
-        visit_end_struct(v, NULL);
-''',
-                         c_type=var.type.c_name(),
-                         c_name=c_name(var.name))
-        else:
-            ret += mcgen('''
-        ok = visit_type_%(c_type)s(v, name, &(*obj)->u.%(c_name)s, errp);
-''',
-                         c_type=var.type.c_name(),
-                         c_name=c_name(var.name))
-        ret += mcgen('''
-        break;
-''')
-        ret += var.ifcond.gen_endif()
-
-    ret += mcgen('''
-    case QTYPE_NONE:
-        abort();
-    default:
-        assert(visit_is_input(v));
-        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
-                   "%(name)s");
-        /* Avoid passing invalid *obj to qapi_free_%(c_name)s() */
-        g_free(*obj);
-        *obj = NULL;
-    }
-out_obj:
-    visit_end_alternate(v, (void **)obj);
-    if (!ok && visit_is_input(v)) {
-        qapi_free_%(c_name)s(*obj);
-        *obj = NULL;
-    }
-    return ok;
-}
-''',
-                 name=name, c_name=c_name(name))
-
-    return ret
-
-
-def gen_visit_object(name: str) -> str:
-    return mcgen('''
-
-bool visit_type_%(c_name)s(Visitor *v, const char *name,
-                 %(c_name)s **obj, Error **errp)
-{
-    bool ok = false;
-
-    if (!visit_start_struct(v, name, (void **)obj, sizeof(%(c_name)s), errp)) {
-        return false;
-    }
-    if (!*obj) {
-        /* incomplete */
-        assert(visit_is_dealloc(v));
-        ok = true;
-        goto out_obj;
-    }
-    if (!visit_type_%(c_name)s_members(v, *obj, errp)) {
-        goto out_obj;
-    }
-    ok = visit_check_struct(v, errp);
-out_obj:
-    visit_end_struct(v, (void **)obj);
-    if (!ok && visit_is_input(v)) {
-        qapi_free_%(c_name)s(*obj);
-        *obj = NULL;
-    }
-    return ok;
-}
-''',
-                 c_name=c_name(name))
-
-
-class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisitor):
-
-    def __init__(self, prefix: str):
-        super().__init__(
-            prefix, 'qapi-visit', ' * Schema-defined QAPI visitors',
-            ' * Built-in QAPI visitors', __doc__)
-
-    def _begin_builtin_module(self) -> None:
-        self._genc.preamble_add(mcgen('''
-#include "qemu-compat.h"
-#include "error.h"
-#include "qapi-builtin-visit.h"
-'''))
-        self._genh.preamble_add(mcgen('''
-#include "visitor.h"
-#include "qapi-builtin-types.h"
-
-'''))
-
-    def _begin_user_module(self, name: str) -> None:
-        types = self._module_basename('qapi-types', name)
-        visit = self._module_basename('qapi-visit', name)
-        self._genc.preamble_add(mcgen('''
-#include "qemu-compat.h"
-#include "error.h"
-#include "qerror.h"
-#include "%(visit)s.h"
-''',
-                                      visit=visit))
-        self._genh.preamble_add(mcgen('''
-#include "qapi-builtin-visit.h"
-#include "%(types)s.h"
-
-''',
-                                      types=types))
-
-    def visit_enum_type(self,
-                        name: str,
-                        info: QAPISourceInfo,
-                        ifcond: QAPISchemaIfCond,
-                        features: List[QAPISchemaFeature],
-                        members: List[QAPISchemaEnumMember],
-                        prefix: Optional[str]) -> None:
-        with ifcontext(ifcond, self._genh, self._genc):
-            self._genh.add(gen_visit_decl(name, scalar=True))
-            self._genc.add(gen_visit_enum(name))
-
-    def visit_array_type(self,
-                         name: str,
-                         info: Optional[QAPISourceInfo],
-                         ifcond: QAPISchemaIfCond,
-                         element_type: QAPISchemaType) -> None:
-        with ifcontext(ifcond, self._genh, self._genc):
-            self._genh.add(gen_visit_decl(name))
-            self._genc.add(gen_visit_list(name, element_type))
-
-    def visit_object_type(self,
-                          name: str,
-                          info: Optional[QAPISourceInfo],
-                          ifcond: QAPISchemaIfCond,
-                          features: List[QAPISchemaFeature],
-                          base: Optional[QAPISchemaObjectType],
-                          members: List[QAPISchemaObjectTypeMember],
-                          variants: Optional[QAPISchemaVariants]) -> None:
-        # Nothing to do for the special empty builtin
-        if name == 'q_empty':
-            return
-        with ifcontext(ifcond, self._genh, self._genc):
-            self._genh.add(gen_visit_members_decl(name))
-            self._genc.add(gen_visit_object_members(name, base,
-                                                    members, variants))
-            # TODO Worth changing the visitor signature, so we could
-            # directly use rather than repeat type.is_implicit()?
-            #if not name.startswith('q_'):
-                # only explicit types need an allocating visit
-            self._genh.add(gen_visit_decl(name))
-            self._genc.add(gen_visit_object(name))
-
-    def visit_alternate_type(self,
-                             name: str,
-                             info: QAPISourceInfo,
-                             ifcond: QAPISchemaIfCond,
-                             features: List[QAPISchemaFeature],
-                             variants: QAPISchemaVariants) -> None:
-        with ifcontext(ifcond, self._genh, self._genc):
-            self._genh.add(gen_visit_decl(name))
-            self._genc.add(gen_visit_alternate(name, variants))
-
-
-def gen_visit(schema: QAPISchema,
-              output_dir: str,
-              prefix: str,
-              opt_builtins: bool) -> None:
-    vis = QAPISchemaGenVisitVisitor(prefix)
-    schema.visit(vis)
-    vis.write(output_dir, opt_builtins)