Python-小练习

小练习,内部使用。

main.py

#! /usr/bin/env python

import os
import sys
import string 

import patch_parser
import result_parser

''''
Get all the content of the file of the specified text file. 

Input: filename - the filename of the text file  
Return: content - string. all the content of filename.  
        If the filename not a valid regular file, then return None, and error information is printed. 
'''  
def get_text_file(file_name):  
    if not is_file_exist(file_name):
        return None  

    f = open(file_name, "r")
    content = f.read()  
    f.close()  

    return content  

'''
If file_name is a regular file's name, return true. Or return false.
'''
def is_file_exist(file_name):
    if not os.path.exists(file_name):  
        print("ERROR: file not exit: %s" % (file_name))  
        return False  

    if not os.path.isfile(file_name):  
        print("ERROR: %s not a file name." % (file_name))  
        return False 

    return True  

# (key, value) data structure is not used here. Because of multiple same file will be occured.
def parse_patch_file(patch_file):
    '''
    return: list of [(modified_filename, start_row, end_row), (...), ... ]
    '''
    content = get_text_file(patch_file)

    items = patch_parser.parse(content, True)
    if len(items) == 0:
        return None

    records = []
    for item in items:
        _, filename, old_start_row_s, old_line_count_s, new_start_row_s, new_line_count_s = item
        old_start_row = string.atoi(old_start_row_s)
        old_line_count = string.atoi(old_line_count_s)
        new_start_row = string.atoi(new_start_row_s)
        new_line_count = string.atoi(new_line_count_s)

        # TODO Delete some row. How to deal with this case????
        if (new_line_count < old_line_count):
            continue 

        # If it is indeed to subtract the old line count.
        temp = (filename, new_start_row, new_start_row + new_line_count - old_line_count - 1)
        records.append(temp)

    return records

def parse_result_file(result_file):
    '''
    return: list of [(filename, line_number), (...), ... ]
    '''
    content = get_text_file(result_file)
    items = result_parser.parse(content)
    if len(items) == 0:
        return None

    records = []
    for item in items:
        filename, line_number_s = item 
        line_number = string.atoi(line_number_s)
        temp = (filename, line_number)
        records.append(temp)

    return records

'''
For example: 
    patch_filename: /core/abc.java 
    result_filename: frameworks/base/core/abc.java

We only check the 'core/abc.java', i.e., if the last part of the two filename is all the same,
then the two file stands for the same file. In this case, this function return True.
'''
def is_same_file(patch_filename, result_filename):
    '''
    Check whether these two file stands for the same file.
    '''
    #if patch_filename == result_filename:
    #   return True 
    patch_filename_len = len(patch_filename)
    result_filename_len = len(result_filename)

    if (result_filename_len < patch_filename_len):
        return False 

    temp = result_filename[result_filename_len - patch_filename_len : ]
    if temp == patch_filename:
        return True 
    else:
        return False 

'''
Ooh, very poor readable codes now.
'''
def fall_in(patch_records, item):
    file_name, line_number = item 
    for record in patch_records:
        fn, start, end = record 
        if is_same_file(file_name, fn) and line_number >= start and line_number <= end:
            return True 

    return False

'''
It's too late. I will just write a ugly algorithm here.
'''
def Report(patch_records, modified_records):
    '''
    Check the two records, and generate the final report.

    To be done.

    '''
    ret = []
    for item in modified_records:
        if fall_in(patch_records, item):
            ret.append(item)

    return ret  

if __name__ == '__main__':
    if len(sys.argv) != 3:
        print "ERROR! Usage: %s patch_file result_file" % (sys.argv[0])
        sys.exit(1)

    patch_file = sys.argv[1]
    result_file = sys.argv[2]

    #print "patch file:", patch_file
    #print "result file:", result_file

    if not is_file_exist(patch_file) or not is_file_exist(result_file):
        print "Error! The file name is error!"
        sys.exit(1)

    patch_records = parse_patch_file(patch_file)
    modified_records = parse_result_file(result_file)

    print "patch records:", patch_records
    print "modified records:", modified_records

    report = Report(patch_records, modified_records)
    print "REPORT:"
    print report

    print "DONE!!!"

patch_parser.py

#!/usr/bin/env python

import re

def debug_matches(result):
    count = len(result)
    if count == 0:
        print "No match item."
        return 

    for item in result:
        first_filename, second_filename, old_start_line, old_line_count, new_start_line, new_line_count = item

        print "first file:", first_filename, 
        print ", second file:", second_filename,
        print ", old file start line:", old_start_line,
        print ", old file line count:", old_line_count,
        print ", new file start line:", new_start_line,
        print ", new file line count:", new_line_count  

def parse(content, verbose = False):
    '''
    List of (old_filename, new_filename, old_file_start, old_file_count, new_file_start, new_file_count).
    '''
    result = re.findall("--- a([^\n]+)\n--- b([^\n]+)\n@@ -(\d+),(\d+)\ \+(\d+),(\d+)\ ", content)
    if result is not None: # or if result:   
        if verbose:
            print result
            debug_matches(result)
        return result
    else:  
        print "FAIL" 
        return None

if __name__ == '__main__':
    content = '''
index 98d2cfb..50d2a32 100644
--- a/arch/arm/boot/dts/qcom/filename1.dtsi
--- b/arch/arm/boot/dts/qcom/filename1.dtsi
@@ -419,6 +419,12 @@
                qcom,warm-bat-decidegc = <450>;
                qcom,cool-bat-decidegc = <100>;
                qcom,warm-bat-decidegc = <0>;
+               xyz,batt-cold-percentage = <80>;
+               xyz,batt-hot-percentage = <25>;
diff --git a/drivers/hwmon/filename2.c b/drivers/hwmon/filename2.c
index fba252e..9179239 100644
--- a/drivers/hwmon/filename2.c
--- b/drivers/hwmon/filename2.c
@@ -419,6 +429,22 @@    
'''

    ret = parse(content)
    print ret

result_parser.py

#!/usr/bin/env python

import re

def debug_matches(result):
    count = len(result)
    if count == 0:
        print "No match item."
        return 

    for item in result:
        filename, line_number = item

        print "file name", filename, 
        print ", line number:", line_number  

def parse(content, verbose = False):
    result = re.findall("([^\s]+):(\d+):\ CID\ \d+", content)
    if result is not None: # or if result:   
        if verbose:
            print result
            debug_matches(result)
        return result
    else:  
        print "FAIL" 
        return None

if __name__ == '__main__':   
    content = '''
    kernel/msm-3.18/drivers/power/xyz-hall.c:64: CID 18856 (#1 of 4):
      Type: Improper use of negative value (NEGATIVE_RETURNS)
      Classification: Unclassified
    Kernel/msm-3.18/drivers/power/zte-hall.c:224:
      1. path: Condition "err", taking false branch.
    kernel/msm-3.18/drivers/power/zte-hallc:228:
      2. negative_return_fn: Function "get_hall_sysnumber_byname("hall_en")" returns a negative number
    kernel/msm-3.18/drivers/power/zte-hall.c:72:
      2.1. path: Condition "i < 16", takng true branch.
    kernel/msm-3.18/drivers/power/xyz-fall.c:74: CID 18866 (#1 of 4):
    '''

    ret = parse(content)
    print "ret:", ret

测试文件:patch.txt

index 98d2cfb..50d2a32 100644
— a/arch/arm/boot/dts/qcom/filename1.dtsi
— b/arch/arm/boot/dts/qcom/filename1.dtsi
@@ -419,6 +419,12 @@
qcom,warm-bat-decidegc = <450>;
qcom,cool-bat-decidegc = <100>;
qcom,warm-bat-decidegc = <0>;
+ xyz,batt-cold-percentage = <80>;
+ xyz,batt-hot-percentage = <25>;
diff –git a/drivers/hwmon/filename2.c b/drivers/hwmon/filename2.c
index fba252e..9179239 100644
— a/drivers/hwmon/filename2.c
— b/drivers/hwmon/filename2.c
@@ -419,6 +429,22 @@

测试文件:result.txt

kernel/msm-3.18/drivers/power/xyz-hall.c:64: CID 18856 (#1 of 4):
Type: Improper use of negative value (NEGATIVE_RETURNS)
Classification: Unclassified
Kernel/msm-3.18/drivers/power/zte-hall.c:224:
1. path: Condition “err”, taking false branch.
kernel/msm-3.18/drivers/power/zte-hallc:228:
2. negative_return_fn: Function “get_hall_sysnumber_byname(“hall_en”)” returns a negative number
kernel/msm-3.18/drivers/power/zte-hall.c:72:
2.1. path: Condition “i < 16”, takng true branch.
kernel/msm-3.18/drivers/power/xyz-fall.c:74: CID 18866 (#1 of 4):
/arch/arm/boot/dts/qcom/filename1.dtsi:420: CID 18866 (#1 of 4):

运行示例结果

把main.py第48行的True改成False,即关闭部分调试打印:

patch_parser.parse(content, True)

改成:

patch_parser.parse(content, False)

运行结果:

$ ./main.py patch.txt result.txt 
patch records: [('/arch/arm/boot/dts/qcom/filename1.dtsi', 419, 424), ('/drivers/hwmon/filename2.c', 429, 444)]
modified records: [('kernel/msm-3.18/drivers/power/xyz-hall.c', 64), ('kernel/msm-3.18/drivers/power/xyz-fall.c', 74), ('/arch/arm/boot/dts/qcom/filename1.dtsi', 420)]
REPORT:
[('/arch/arm/boot/dts/qcom/filename1.dtsi', 420)]
DONE!!!
$ 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值