utils.py 3.91 KB
import os

multi_line_comments = ["'''", '"""']

def remove_string(line):
    strIn = False
    strCh = None
    result = ''
    i = 0
    L = len(line)

    while i < L:
        if i + 3 < L:
            if line[i:i+3] in multi_line_comments:
                if not strIn:
                    strIn = True
                    strCh = line[i:i+3]
                elif line[i:i+3] == strCh:
                    strIn = False

                i += 2
                continue

        c = line[i]
        i += 1

        if c == '\'' or c == '\"':
            if not strIn:
                strIn = True
                strCh = c
            elif c == strCh:
                strIn = False
            continue

        if strIn:
            continue

        result += c

    return result

def using_multi_string(line, index):
    line = line.strip()
    for comment in multi_line_comments:
        if line.find(comment, index) > 0:
            return True
    return False

def remove_unnecessary_comments(lines):
    # Warning : cannot detect all multi-line comments, because it exactly is multi-line string.

    #TODO: multi line string parser will not work well when using strings (and comments, also) more than one.
    # ex) a = ''' d ''' + '''
    #     abc ''' + '''
    #     x'''

    result = []
    multi_line = False
    multi_string = False
    strCh = None

    for line in lines:
        find_str_index = 0
        if multi_string:
            if strCh in line:
                find_str_index = line.find(strCh) + 3
                multi_string = False
                strCh = None
            
            result.append(line)
            continue

        if multi_line: # parsing multi-line comments
            if strCh in line:
                multi_line = False
                strCh = None
            continue

        if using_multi_string(line, find_str_index):
            i1 = line.find(multi_line_comments[0])
            i2 = line.find(multi_line_comments[1])

            if i1 < 0:
                i1 = len(line) + 1
            if i2 < 0:
                i2 = len(line) + 1

            if i1 < i2:
                strCh = multi_line_comments[0]
            else:
                strCh = multi_line_comments[1]

            result.append(line)
            if line.count(strCh) % 2 != 0:
                multi_string = True
            continue

        code = line.strip()

        if code[:3] in multi_line_comments: # detect in-out of multi-line comments
            if code.count(code[:3]) % 2 != 0: # comment count in odd numbers (start or end of comment is in the line)
                multi_line = True
                strCh = code[:3]
            continue

        comment_index = line.find('#')
        if comment_index >= 0: # one line comment found
            line = line[:comment_index]
        line = line.rstrip() # remove rightmost spaces

        if len(line) == 0: # no code in this line
            continue

        result.append(line) # add to results

    return result

def is_extension(f, ext):
    return os.path.splitext(f)[1][1:] == ext

def _readdir_r(dirpath): # readdir for recursive
    ret = []
    for f in os.listdir(dirpath):
        ret.append(os.path.join(dirpath, f))
        
    return ret

def readdir(path): # read files from the directory
    pathList = [path]
    result = []
    i = 0
    
    while i < len(pathList):
        f = pathList[i]
        if os.path.isdir(f):
            pathList += _readdir_r(f)
        else:
            result.append(f)
            
        i += 1

    return result

def read_file(path):
    f = open(path, 'r', encoding='utf8')
    ret = f.readlines()
    f.close()
    return ret

def write_file(path, lines):
    f = open(path, 'w', encoding='utf8')

    for line in lines:
        if '\n' in line:
            f.write(line)
        else:
            f.write(line + '\n')
    f.close()

def readAll(path):
    f = open(path, 'r', encoding='utf8')
    ret = f.read()
    f.close()
    return ret