# Path: sibyl/learn/generator/generator.py
# class Generator(object):
#     '''
#     Abstract class used to represent a generator
#     A generator is a class that create a test from a snapshot
#     Here a test is a sibyl test init function and a sibyl test check function
#     '''
# 
#     def __init__(self, testcreator):
#         '''
#         @testcreator: TestCreator instance with associated information
#         '''
#         self.trace = testcreator.trace
#         self.prototype = testcreator.prototype
#         self.learnexceptiontext = testcreator.learnexceptiontext
#         self.types = testcreator.types
#         self.printer = Printer()
#         self.headerfile = testcreator.headerfile
#         self.ira = Machine(testcreator.machine).ira()
#         self.ptr_size = self.ira.sizeof_pointer()/8
#         self.logger = testcreator.logger
# 
#     def generate_test(self):
#         '''Abstract method that should return the string corresponding to the code of the init test'''
#         raise NotImplementedError("Abstract method")
# 
# Path: sibyl/learn/generator/templates.py

# 
# Path: sibyl/learn/trace.py
# class MemoryAccess(object):
#     '''Represent a memory block, read or write by the learned function'''
# 
#     def __init__(self, size, data, access):
# 
#         self.size = size
#         self.data = data
#         self.access = access
# 
#     def __str__(self):
#         str_access = ""
#         if self.access & PAGE_READ:
#             str_access += "READ"
#         if self.access & PAGE_WRITE:
#             if str_access != "":
#                 str_access += " "
#             str_access += "WRITE"
# 
#         return "size: " + str(self.size) + ", data: " + repr(self.data) + ", access: " + str_access
# 
#     def __repr__(self):
#         return "<" + str(self) + ">"
# 
# Path: sibyl/commons.py
# def objc_is_dereferenceable(target_type):
#     """Return True if target_type may be used as a pointer
#     @target_type: ObjC"""
#     return isinstance(target_type, (ObjCPtr, ObjCArray))


import struct
from sibyl.learn.generator.generator import Generator
from sibyl.learn.generator import templates as TPL
from sibyl.learn.trace import MemoryAccess
from miasm2.ir.ir import AssignBlock
from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
from miasm2.expression.expression import *
from miasm2.expression.simplifications import expr_simp
from sibyl.commons import objc_is_dereferenceable
        for var in to_save:
            self.printer.add_block('self.%s = %s\n' % (var, var))
        self.printer.sub_lvl()


    def generate_check(self, snapshot, number):
        '''Return the string corresponding to the code of the check function'''

        self.printer.add_block(funcDefTemplate.format("check", number))
        self.printer.add_lvl()

        memory_out = snapshot.memory_out
        c_handler = snapshot.c_handler
        typed_C_ids = snapshot.typed_C_ids
        arguments_symbols = snapshot.arguments_symbols
        output_value = snapshot.output_value

        # Sanitize memory accesses
        memory_out, filled_out = self.sanitize_memory_accesses(
            memory_out,
            c_handler,
            typed_C_ids,
        )

        fixed = self.fixed
        bases_to_C = self.bases_to_C

        self.printer.add_block("return all((\n")
        self.printer.add_lvl()


# Path: sibyl/learn/generator/generator.py
# class Generator(object):
#     '''
#     Abstract class used to represent a generator
#     A generator is a class that create a test from a snapshot
#     Here a test is a sibyl test init function and a sibyl test check function
#     '''
# 
#     def __init__(self, testcreator):
#         '''
#         @testcreator: TestCreator instance with associated information
#         '''
#         self.trace = testcreator.trace
#         self.prototype = testcreator.prototype
#         self.learnexceptiontext = testcreator.learnexceptiontext
#         self.types = testcreator.types
#         self.printer = Printer()
#         self.headerfile = testcreator.headerfile
#         self.ira = Machine(testcreator.machine).ira()
#         self.ptr_size = self.ira.sizeof_pointer()/8
#         self.logger = testcreator.logger
# 
#     def generate_test(self):
#         '''Abstract method that should return the string corresponding to the code of the init test'''
#         raise NotImplementedError("Abstract method")
# 
# Path: sibyl/learn/generator/templates.py

# 
# Path: sibyl/learn/trace.py
# class MemoryAccess(object):
#     '''Represent a memory block, read or write by the learned function'''
# 
#     def __init__(self, size, data, access):
# 
#         self.size = size
#         self.data = data
#         self.access = access
# 
#     def __str__(self):
#         str_access = ""
#         if self.access & PAGE_READ:
#             str_access += "READ"
#         if self.access & PAGE_WRITE:
#             if str_access != "":
#                 str_access += " "
#             str_access += "WRITE"
# 
#         return "size: " + str(self.size) + ", data: " + repr(self.data) + ", access: " + str_access
# 
#     def __repr__(self):
#         return "<" + str(self) + ">"
# 
# Path: sibyl/commons.py
# def objc_is_dereferenceable(target_type):
#     """Return True if target_type may be used as a pointer
#     @target_type: ObjC"""
#     return isinstance(target_type, (ObjCPtr, ObjCArray))


# Path: sibyl/learn/generator/pythongenerator.py
import struct
from sibyl.learn.generator.generator import Generator
from sibyl.learn.generator import templates as TPL
from sibyl.learn.trace import MemoryAccess
from miasm2.ir.ir import AssignBlock
from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
from miasm2.expression.expression import *
from miasm2.expression.simplifications import expr_simp
from sibyl.commons import objc_is_dereferenceable

        for var in to_save:
            self.printer.add_block('self.%s = %s\n' % (var, var))
        self.printer.sub_lvl()


    def generate_check(self, snapshot, number):
        '''Return the string corresponding to the code of the check function'''

        self.printer.add_block(funcDefTemplate.format("check", number))
        self.printer.add_lvl()

        memory_out = snapshot.memory_out
        c_handler = snapshot.c_handler
        typed_C_ids = snapshot.typed_C_ids
        arguments_symbols = snapshot.arguments_symbols
        output_value = snapshot.output_value

        # Sanitize memory accesses
        memory_out, filled_out = self.sanitize_memory_accesses(
            memory_out,
            c_handler,
            typed_C_ids,
        )

        fixed = self.fixed
        bases_to_C = self.bases_to_C

        self.printer.add_block("return all((\n")
        self.printer.add_lvl()


        if objc_is_dereferenceable(self.prototype.func_type):