Пример #1
0
 def generate_input_for_struct(self, type_name, var_name, code, recursive_count):
     """Generate input for struct fields.
     """
     self.struct_limit -= 1
     if self.struct_limit < 0:
         return ''
     type_component = typeutil.parse_type(type_name)
     base = type_component['base']
     _,fields = syntaxutil.parse_struct_code(code)
     result = ''
     for field_type_name,field_var_name in fields:
         if field_var_name not in self.needed_fields: continue
         field_type_component = typeutil.parse_type(field_type_name)
         if not type_component['pointer']:
             new_field_name = var_name + '.' + field_var_name
         else:
             new_field_name = '(' + type_component['pointer'][1:] + var_name + ')->' + field_var_name
         if self.is_same_struct(field_type_component['base'], type_component['base']):
             if recursive_count > 0:
                 result += self.generate_input(field_type_name , new_field_name, recursive_count=recursive_count-1)
             else:
                 result += new_field_name + '= NULL;\n'
             continue
         result += self.generate_input(field_type_name, new_field_name)
     return result
Пример #2
0
def generate_alloc_string(type_name, var_name):
    """Generate allocate string for the type_name.
    :pre-condition type_name.count('*') >0
    If there are more than one '*', will create temp variables for allocate.
    struct A **var;
    struct A *tmp = (struct A *)malloc(sizeof(struct A))
    tmp->a = malloc()
    tmp->b = malloc()
    var = &tmp;
    """
    # green('generate alloc string for '+type_name + var_name)
    def get_uuid_tmp_name(name, idx):
        # if it is A->b, then we need to use b_tmp1 instead of A->b_tmp1
        return name.replace('(','').replace(')','').replace('->','_').replace('.','_') + '_tmp'+str(idx)
    result = ''
    type_component = typeutil.parse_type(type_name)
    base = type_component['base']
    pointer_level = type_component['pointer'].count('*')
    if pointer_level == 1:
        result += var_name + ' = ' +\
        '(' + base + '*)malloc(sizeof(' + base + '));\n'
    else:
        # allocate for the tmp variable
        result += base + ' *'+get_uuid_tmp_name(var_name, 1) +\
            ' = ('+base+'*)malloc(sizeof('+base+'));\n'
        # allocate for all level
        for i in range(pointer_level-2):
            var_name_tmp = get_uuid_tmp_name(var_name, i+2)
            last_name_tmp = get_uuid_tmp_name(var_name, i+1)
            result += type_name + ' ' + '*'*(i+2) + var_name_tmp+'=&'+last_name_tmp+';\n'
        result += var_name + '=&' + get_uuid_tmp_name(var_name, pointer_level-1)+';\n'
    return result
Пример #3
0
def generate_primitive_output(type_name, var_name):
    """do not generate output for void
    """
    if 'void' in type_name: return ''
    type_component = typeutil.parse_type(type_name)
    base = type_component['base']
    pointer = type_component['pointer']
    result = 'printf("%' + typeutil.parse_primitive_type(base) + ' ", '
    result += '*'*pointer.count('*') + var_name
    result += ');\n'
    return result
Пример #4
0
def generate_primitive_input(type_name, var_name):
    """generate init string for primitive type variables
    """
    type_component = typeutil.parse_type(type_name)
    formatter = typeutil.parse_primitive_type(type_component['base'])
    result = 'scanf("%' + formatter + '", '
    if not type_component['pointer']:
        result += '&' + var_name
    else:
        result += type_component['pointer'][1:] + var_name
    result += ');\n'
    return result
Пример #5
0
 def generate_input(self, type_name, var_name, recursive_count=1):
     result = ''
     type_component = typeutil.parse_type(type_name)
     base = type_component['base']
     pointer = type_component['pointer']
     array = type_component['array']
     if array:
         if config.get('handle_array') == 'true':
             return self.generate_input_for_array(type_name, var_name)
         else:
             return ''
     # alloc
     if pointer:
         # char array should be treated separately
         if config.get('handle_array') == 'true' and base == 'char':
             result += self.generate_input_for_array('char[]', var_name+'_array')
             result += var_name +' = '+var_name + '_array;\n'
             return result;
         result += generate_alloc_string(type_name, var_name)
     # init
     if typeutil.is_primitive_type(base):
         result += generate_primitive_input(type_name, var_name)
     elif local.check_struct_or_typedef(base.replace('struct','').strip()):
         if config.get('handle_struct') != 'true': return ''
         code = local.resolve_single_simple(base.replace('struct','').strip(), t='st')
         if '{' in code.strip() and code.strip().startswith('typedef struct'):
             code = code.replace('typedef','').strip()
             code = code[:code.rfind('}')+1] + ';'
             result += self.generate_input_for_struct(type_name, var_name, code, recursive_count)
         elif code.strip().startswith('struct'):
             result += self.generate_input_for_struct(type_name, var_name, code, recursive_count)
         elif code.startswith('typedef'):
             if code.startswith('typedef struct'):
                 code = local.resolve_single_simple(base.replace('struct', '').strip(), t='s')
                 if code:
                     result += self.generate_input_for_struct(type_name, var_name, code, recursive_count)
             else:
                 _,original = syntaxutil.parse_typedef_code(code)
                 result += self.generate_input(original+pointer+array, var_name, recursive_count)
         else:
             logger.warning('Not recognized code for generate input')
     else:
         sys_type = systype.resolve(base)
         if sys_type:
             result += self.generate_input(sys_type+pointer+array, var_name)
         else:
             logger.warning('the type '+type_name+' is not solved for init')
     return result
Пример #6
0
def build(function_node):
    _,func_name, fields = syntaxutil.parse_function(function_node)
    code = ''
    function_code = domutil.get_text_content(function_node)
    instrumented_function = function_code[:function_code.find('{')+1]+'\nprintf("%d ", 1);\n'+function_code[function_code.find('{')+1:]
    code += includes
    code += instrumented_function
    code += '\nint main() {\n'
    for type_name, var_name in fields:
        code += type_name + ' ' + var_name + ';\n'
        # if typeutil.is_primitive_type(type_name)
        type_component = typeutil.parse_type(type_name)
        if typeutil.is_primitive_type(type_component['base']):
            code += instrumenter.generate_primitive_input(type_name, var_name)
    code += func_name + '(' + ','.join([var for _,var in fields]) + ');\n'
    code += '}\n'
    return code
Пример #7
0
 def generate_input_for_array(self, type_name, var_name):
     result = ''
     type_component = typeutil.parse_type(type_name)
     base = type_component['base']
     # now only support primitive type
     if not typeutil.is_primitive_type(base):
         return result
     # now only support char array
     if base != 'char':
         return result
     # Only support one dimension array
     if not self.helium_size_defined:
         result += 'int helium_size;\n'
         self.helium_size_defined = True
     result += 'scanf("%d", &helium_size);\n'
     result += base +' '+ var_name + '[helium_size];\n'
     # result += 'for (int i=0;i<helium_size;i++) {\n'
     # var_name = var_name + '[i]'
     # result += self.generate_input(base, var_name)
     # result += '}\n'
     result += 'scanf("%s", '+var_name+');\n'
     return result
Пример #8
0
 def generate(self):
     os.makedirs(self.output_folder, exist_ok=True)
     with open(self.output_folder + "/generate.c", "w") as f:
         f.write('#include "support.h"\n')
         # main
         f.write("int main() {\n")
         f.write("//@HeliumInput\n")
         for var_name in self.inputs:
             type_name = self.inputs[var_name]
             type_component = typeutil.parse_type(type_name)
             base = type_component["base"]
             array = type_component["array"]
             pointer = type_component["pointer"]
             f.write(base + pointer + " " + var_name + array + ";\n")
         f.write("//@HeliumInputEnd\n")
         f.write("/**********Context********/\n")
         context_size = 0
         function_size = 0
         context_text = ""
         for node in self.context:
             context_text += domutil.get_text_content(node)
         context_text = re.sub(r"\breturn\b[^;\n]*;", "return 0;", context_text)
         if config.get("show_context") == "true":
             print(context_text)
         context_size = context_text.count("\n") + 1
         f.write(context_text)
         f.write("\n}\n")
         # functions
         for function in self.functions.values():
             text = domutil.get_text_content(function)
             function_size += text.count("\n")
             f.write(text)
             f.write("\n")
         if config.get("show_context_size") == "true":
             print("context size: " + str(context_size))
             if function_size != 0:
                 print("context function size: " + str(function_size))
     f.close()
Пример #9
0
 def generate_output_for_array(self, type_name, var_name):
     result = ''
     type_component = typeutil.parse_type(type_name)
     base = type_component['base']
     result += 'printf("%ld ", sizeof('+var_name+')/sizeof('+base+'));\n'
     return result