# 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
def argListStr(t):
    '''Return a string representing t which can be a tuple or an int'''
    return "(0x%x, %i)" % (t[0], t[1]) if isinstance(t, tuple) else str(t)


def accessToStr(access):
    '''Return a string representing the access right given in argument'''
    ret = ""
    if access & PAGE_READ:
        ret += "PAGE_READ | "
    if access & PAGE_WRITE:
        ret += "PAGE_WRITE"
    return ret.rstrip(" |")


def addrTupleStr(t):
    '''Return a string representing the memory aera given in argument'''
    ((offset, seg), value, access) = t
    return "((0x%x, %i), %r, %s)" % (offset, seg, value, accessToStr(access))


class PythonGenerator(Generator):

    def generate_test(self):
        self.printer.add_block(TPL.imports)
        self.printer.add_empty_line()

        self.printer.add_block(TPL.classDef.format(funcname=self.prototype.func_name))
        self.printer.add_empty_line()


# 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

def argListStr(t):
    '''Return a string representing t which can be a tuple or an int'''
    return "(0x%x, %i)" % (t[0], t[1]) if isinstance(t, tuple) else str(t)


def accessToStr(access):
    '''Return a string representing the access right given in argument'''
    ret = ""
    if access & PAGE_READ:
        ret += "PAGE_READ | "
    if access & PAGE_WRITE:
        ret += "PAGE_WRITE"
    return ret.rstrip(" |")


def addrTupleStr(t):
    '''Return a string representing the memory aera given in argument'''
    ((offset, seg), value, access) = t
    return "((0x%x, %i), %r, %s)" % (offset, seg, value, accessToStr(access))


class PythonGenerator(Generator):

    def generate_test(self):
        self.printer.add_block(TPL.imports)
        self.printer.add_empty_line()

        self.printer.add_block(TPL.classDef.format(funcname=self.prototype.func_name))
        self.printer.add_empty_line()


        self.printer.add_block(TPL.classAttrib.format(funcname=self.prototype.func_name,