<gh_stars>0
import os
import sys
import re
import mimetypes
import shutil
import datetime
import tempfile
from pathlib import Path
from ctrans.basefile import BaseFile
from ctrans.ctransfile import CTransFile
import ctrans.constants

class CTransManager:
    """CTranslation manager class"""

    def __init__(self, extention_list, replacedir_list):

        self.name = "CTranslation manager"

        # file extensions to be translated
        exts = []
        for each in extention_list:
            if len(each) > 0 and each[0] != '.':
                each = '.' + each
            exts.append(each)
        self.extentions = exts

        # replacement for directories (no error processing..)
        replace_dict = {}
        pattern = "^([^:]+):([^:]+)$"
        for each in replacedir_list:
            result = re.match(pattern, each)
            if result != None:
                replace_dict[result.group(1)] = result.group(2)
        self.replace_dict = replace_dict

    def create_ctransfiles(self, srcdir, outdir):

        self.srcdir = srcdir
        self.outdir = outdir

        for path in sorted(Path(srcdir).iterdir()):
            self.create_ctransfile(path, outdir)

    def create_ctransfile(self, srcpath, outdir):

        # If srcpath is a directory
        if srcpath.is_dir():

            if srcpath.name == outdir:
                return

            # Return if "dot" directory
            if srcpath.name[0] == '.':
                return

            srcpath_name = srcpath.name
            for k, v in self.replace_dict.items():
                pattern = "^"+k+"$"
                result = re.match(pattern, srcpath_name)
                if result != None:
                    srcpath_name = srcpath_name.replace(k, v)
            transdir = os.path.join(outdir, srcpath_name)

            # Execute child paths recursively
            for child_path in sorted(srcpath.iterdir()):
                self.create_ctransfile(child_path, transdir)

        # If srcpath is a file (not a directory)
        else:

            type, subtype = mimetypes.guess_type(srcpath, strict=True)
            if type in ctrans.constants.excl_list:
                return

            srcpath_root, srcpath_ext = os.path.splitext(srcpath)
            if not srcpath_ext in self.extentions:
                return

            os.makedirs(outdir, exist_ok=True)
            ctrans_path = os.path.join(outdir, srcpath)
            if not os.path.isfile(ctrans_path):
                ctransfile = CTransFile()
                ctransfile.create(srcpath, outdir)

    def create_ctranslation_files(self, srcdir, transdir, outdir):

        self.srcdir   = srcdir
        self.transdir = transdir
        self.outdir   = outdir

        exit_code = 0
        for child_path in sorted(Path(srcdir).iterdir()):
            flag = self.create_ctranslation_file(child_path, transdir, outdir)
            if flag == False:
                exit_code = 1

        return exit_code

    def create_ctranslation_file(self, srcpath, transdir, outdir):

        flag = True
        last_flag = True

        # If srcpath is a directory
        if srcpath.is_dir():

            if srcpath.name == outdir:
                return last_flag

            # Return if "dot" directory
            if srcpath.name[0] == '.':
                return last_flag

            # Replace directories when speficied -r option.
            curr_srcpath = srcpath.name
            for k, v in self.replace_dict.items():
                pattern = "^"+k+"$"
                result = re.match(pattern, curr_srcpath)
                if result != None:
                    curr_srcpath = curr_srcpath.replace(k, v)

            curr_transdir = os.path.join(transdir, curr_srcpath)
            curr_outdir   = os.path.join(outdir, srcpath.name)

            # Execute this method for child paths recursively
            for child in sorted(Path(srcpath).iterdir()):
                flag = self.create_ctranslation_file(child, curr_transdir, curr_outdir)
                if flag == False:
                    last_flag = False

        # If srcpath is a file (not a directory)
        else:

            type, subtype = mimetypes.guess_type(srcpath, strict=True)
            if type in ctrans.constants.excl_list:

                if self.filenewer2(srcpath, outdir):
                    self.copy2(srcpath, outdir)
                    print('Copied ' + srcpath.name + ' because of exclude_ext')
                return True

            transpath = os.path.join(transdir, srcpath.name + ctrans.constants.ctrans_ext)

            # If ctrans file not exist
            if not os.path.isfile(transpath):

                if self.filenewer2(srcpath, outdir):
                    self.copy2(srcpath, outdir)
                    print('Copied ' + srcpath.name + ' because of no ctrans file')

            else:
                if self.filenewer3(srcpath, transdir, outdir):
                    flag = self.output_ctranslation_file(srcpath, transdir, outdir)

                    if flag == True:
                        outpath = os.path.join(outdir, srcpath.name)
                    else:
                        last_flag = False

        return last_flag

    def filenewer2(self, srcpath, outdir):

        outpath = os.path.join(outdir, srcpath.name)
        if not os.path.isfile(outpath):
            return True

        mtime1 = os.path.getmtime(srcpath)
        mtime2 = os.path.getmtime(outpath)

        return mtime1 > mtime2

    def filenewer3(self, srcpath, transdir, outdir):

        transpath = os.path.join(transdir, srcpath.name + ctrans.constants.ctrans_ext)
        outpath = os.path.join(outdir, srcpath.name)

        if not os.path.isfile(outpath):
            return True

        mtime1 = os.path.getmtime(srcpath)
        mtime2 = os.path.getmtime(transpath)
        mtime3 = os.path.getmtime(outpath)

        return (mtime2 > mtime3) | (mtime1 > mtime3)

    def output_ctranslation_file(self, srcpath, transdir, outdir):

        srcfile = BaseFile()
        srcfile.open(srcpath, 'r')

        outpath = os.path.join(outdir, srcpath.name)
        if not os.path.isdir(outdir):
            os.makedirs(outdir, exist_ok=True)

        transpath = os.path.join(transdir, srcpath.name + ctrans.constants.ctrans_ext)
        ctransfile = CTransFile()
        ctransfile.open(transpath, 'r')

        outfile = BaseFile()
        outfile.open(outpath, 'w')
        flag = self.output_lines(srcfile, ctransfile, outfile)

        outfile.close()

        if flag != True:
            os.remove(outpath)
        ctransfile.close()
        srcfile.close()

        return flag

    def output_lines(self, srcfile, ctransfile, outfile):

        line_ctrans = ""
        dummy, start_token_pos = ctransfile.read_until_next_start_token()

        # If next start token position is not -1 (next start token found)
        if start_token_pos != -1:

            # Get first source part in ctranslation file
            line_ctrans = ctransfile.get_current_line()

        # Get one line from source file
        line_src = srcfile.get_current_line()
        old_line_src_pos = srcfile.get_curr_line_num()

        # In case srcfile may have no contents
        if srcfile.status == srcfile.STATUS_NORMAL:
            return 0;

        error_not_occurred = True
        proc_continue = True
        src_retry = False
        while srcfile.get_curr_line_num() <= srcfile.get_line_count() and proc_continue:

            if srcfile.is_error():
                if ctransfile.is_normal() and line_ctrans != "":
                    print("--------+-", file=sys.stderr)
                    print('Error: Source part in "%s" not matched.\n(L.%d) %s'
                          % (ctransfile.pathname, ctransfile.get_curr_line_num(), line_ctrans.rstrip('\n')),
                          file=sys.stderr)

                    # In case current ctrans line does not match any src line.
                    # So src line position set back next paragraph.
                    srcfile.set_line_num(old_line_src_pos)
                    line_src = srcfile.get_current_line()
                    old_line_src_pos = srcfile.get_curr_line_num()
                    line_src_list = []
                    line_src_list.append(line_src)

                    #print('line_src   (l%d/E%d): %s' % (srcfile.get_curr_line_num(), err, line_src.rstrip('\n')), file=sys.stderr)
                    #print('line_ctrans (l%d/E%d): %s' % (ctransfile.get_curr_line_num(), err1, line_ctrans.rstrip('\n')), file=sys.stderr)

                    pattern = "^$"
                    while True:
                        result = re.match(pattern, line_src)
                        if result == None: # and line_src != line_ctrans:
                            #line_src, err = srcfile.get_current_line()
                            line_src = srcfile.get_current_line()
                            line_src_list.append(line_src)
                        else:
                            line_src_list.pop(-1)
                            break

                    old_line_src_pos = srcfile.get_curr_line_num()
                    if len(line_ctrans_list) == 0:
                        line_ctrans_list.append(line_ctrans)

                    # And also skip ctrans line to next start token
                    line_ctrans_skip, err2 = ctransfile.read_until_next_start_token()
                    line_ctrans = ctransfile.get_current_line()
                    line_ctrans_list.extend(line_ctrans_skip)

                    error_not_occurred = False
                    self.output_diff(srcfile, ctransfile, line_src_list, line_ctrans_list)
                    line_src_list = []
                    line_ctrans_list = []
                    proc_continue = True
                    src_retry = False
                    continue
                else:
                    #print('Unknown error', file=sys.stderr)
                    #print('line_src   (l%d/E%d): %s' % (srcfile.get_curr_line_num(), err, line_src.rstrip('\n')), file=sys.stderr)
                    #print('line_ctrans (l%d/E%d): %s' % (ctransfile.get_curr_line_num(), err1, line_ctrans.rstrip('\n')), file=sys.stderr)
                    break

            # In case source line in ctrans file did not exist in source file
            # and is not between ctrans tokens, it should be output as is.
            elif line_ctrans != "" and line_src != line_ctrans:
                outfile.add_line(line_src)
                line_src = srcfile.get_current_line()

            # In case source line in ctrans file existed in source file
            elif line_ctrans != "" and line_src == line_ctrans:

                line_src_list   = []
                line_ctrans_list = []
                line_src_list.append(line_src)
                line_ctrans_list.append(line_ctrans)

                while True:

                    line_src    = srcfile.get_current_line()
                    line_ctrans = ctransfile.get_current_line()

                    line_src_list.append(line_src)
                    line_ctrans_list.append(line_ctrans)

                    #print('  line_src    (l%d/E%d): %s' % (srcfile.get_curr_line_num(), err, line_src.rstrip('\n')), file=sys.stderr)
                    #print('  line_ctrans (l%d/E%d): %s' % (ctransfile.get_curr_line_num(), err1, line_ctrans.rstrip('\n')), file=sys.stderr)

                    if line_src != line_ctrans:
                        len_token = len(ctrans.constants.ctrans_trans)

                        # If current line in ctrans file is ctrans_trans token
                        if len(line_ctrans)>=len_token and line_ctrans[0:len_token]==ctrans.constants.ctrans_trans:
                            old_line_src_pos = srcfile.get_curr_line_num()
                            break

                        else:
                            # Lines between source file and source part in ctrans file do not match
                            print("----------", file=sys.stderr)
                            print('Error: Source part in "%s" not matched.\n(L.%d) %s'
                                % (ctransfile.pathname, ctransfile.get_curr_line_num(), line_ctrans.rstrip('\n')),
                                file=sys.stderr)

                            # Skip ctransfile line to next token potision
                            # Also append lines to next token to line list for error (diff) message
                            line_ctrans_skip, err2 = ctransfile.read_until_next_start_token()
                            if len(line_ctrans_skip) != 0:
                                line_ctrans_list.extend(line_ctrans_skip)
                            line_ctrans = ctransfile.get_current_line()

                            line_src_list = self.get_srcs_when_error(srcfile, line_src, line_src_list)

                            error_not_occurred = False
                            self.output_diff(srcfile, ctransfile, line_src_list, line_ctrans_list)
                            proc_continue = True
                            break

                if proc_continue == False:
                    self.output_diff(srcfile, ctransfile, line_src_list, line_ctrans_list)
                    proc_continue = True

                else:
                    src_retry = False
                    len_end = len(ctrans.constants.ctrans_end)

                    # Output translation part of ctransfile into outfile
                    while True:

                        line_ctrans = ctransfile.get_current_line()
                        if err1 != 0:
                            break
                        elif len(line_ctrans)>=len_end and line_ctrans[0:len_end]==ctrans.constants.ctrans_end:
                            break
                        else:
                            outfile.add_line(line_ctrans)

                    old_ctrans_list = line_ctrans_list
                    # Proceed position of ctransfile to next start token
                    dummy, err1 = ctransfile.read_until_next_start_token()

                    if err1 != -1:
                        line_ctrans = ctransfile.get_current_line()
                        line_ctrans_list = []
                    else:
                        proc_continue = True

            elif len(line_src.rstrip('\n')) == 0 and len(line_ctrans.rstrip('\n')) == 0:
                return True

            elif err1 != 1:
                return False
            else:
                print("Unknown error", file=sys.stderr)
                print("srcfile: %s" % srcfile.pathname)
                print('line_src    (L.%d/E%d): |%s|' % (srcfile.get_curr_line_num(), err, line_src.rstrip('\n')), file=sys.stderr)
                print('line_ctrans (L.%d/E%d): |%s|' % (ctransfile.get_curr_line_num(), err1, line_ctrans.rstrip('\n')), file=sys.stderr)
                return False

        #if error_not_occurred == False:
        #    os.remove(outfile.pathname)
        return error_not_occurred

    def copy2(self, srcpath, outdir):

        outpath = os.path.join(outdir, srcpath.name)
        dir_and_base = os.path.split(outpath)
        dirname = dir_and_base[0]
        if not os.path.exists(dirname):
            os.makedirs(dirname, exist_ok=True)
        shutil.copy(srcpath, outdir)

    def output_diff(self, srcfile, ctransfile, line_src_list, line_ctrans_list):

        tmpdir = tempfile.TemporaryDirectory()
        tmpname = tmpdir.name
        #tmpname = tempfile.mkdtemp()
        fp_src    = open(tmpname+'/src.txt', 'w', encoding='utf-8')
        fp_ctrans = open(tmpname+'/ctrans.txt', 'w', encoding='utf-8')

        for line_src in line_src_list:
            fp_src.write(line_src)
        for line_ctran in line_ctrans_list:
            fp_ctrans.write(line_ctran)
        fp_ctrans.close()
        fp_src.close()

        os.system("diff -au "+tmpname+"/ctrans.txt "+tmpname+"/src.txt > "+tmpname+"/diff.txt")
        t_src = os.path.getmtime(srcfile.pathname)
        d_src = str(datetime.datetime.fromtimestamp(t_src))
        t_ctrans = os.path.getmtime(ctransfile.pathname)
        d_ctrans = str(datetime.datetime.fromtimestamp(t_ctrans))
        s = "sed -i -e \"s|\-\-\- .*$|--- a/"+str(ctransfile.pathname)+"\t"+str(d_ctrans)+"|\" "
        s = s +    "-e \"s|+++ .*$|+++ b/"+str(srcfile.pathname)+"\t"+str(d_src)+"|\" "
        s = s + tmpname+"/diff.txt"
        os.system(s)
        fp_diff = open(tmpname+'/diff.txt', 'r', encoding='utf-8')
        lines_diff = fp_diff.readlines()
        print("Pseudo diff:", file=sys.stderr)
        for line_diff in lines_diff:
            print("%s" % line_diff.replace("\n",""), file=sys.stderr)

        fp_diff.close()
        tmpdir.cleanup()

    def get_srcs_when_error(self, srcfile, line_src, line_src_list):

        # Skip srcfile line to next non-blank line
        # Also append the line to list for error (diff) message
        pattern = "^$"
        while True:
            result = re.match(pattern, line_src)
            if result == None:
                line_src = srcfile.get_current_line()
                line_src_list.append(line_src)
            else:
                line_src_list.pop(-1)
                break
        return line_src_list

import os
import sys
import re
import mimetypes
import shutil
import datetime
import tempfile
from pathlib import Path
from ctrans.basefile import BaseFile
from ctrans.ctransfile import CTransFile
import ctrans.constants

class CTransManager:
    """CTranslation manager class"""

    def __init__(self, extention_list, replacedir_list):

        self.name = "CTranslation manager"

        # file extensions to be translated
        exts = []
        for each in extention_list:
            if len(each) > 0 and each[0] != '.':
                each = '.' + each
            exts.append(each)
        self.extentions = exts

        # replacement for directories (no error processing..)
        replace_dict = {}
        pattern = "^([^:]+):([^:]+)$"
        for each in replacedir_list:
            result = re.match(pattern, each)
            if result != None:
                replace_dict[result.group(1)] = result.group(2)
        self.replace_dict = replace_dict

    def create_ctransfiles(self, srcdir, outdir):

        self.srcdir = srcdir
        self.outdir = outdir

        for path in sorted(Path(srcdir).iterdir()):
            self.create_ctransfile(path, outdir)

    def create_ctransfile(self, srcpath, outdir):

        # If srcpath is a directory
        if srcpath.is_dir():

            if srcpath.name == outdir:
                return

            # Return if "dot" directory
            if srcpath.name[0] == '.':
                return

            srcpath_name = srcpath.name
            for k, v in self.replace_dict.items():
                pattern = "^"+k+"$"
                result = re.match(pattern, srcpath_name)
                if result != None:
                    srcpath_name = srcpath_name.replace(k, v)
            transdir = os.path.join(outdir, srcpath_name)

            # Execute child paths recursively
            for child_path in sorted(srcpath.iterdir()):
                self.create_ctransfile(child_path, transdir)

        # If srcpath is a file (not a directory)
        else:

            type, subtype = mimetypes.guess_type(srcpath, strict=True)
            if type in ctrans.constants.excl_list:
                return

            srcpath_root, srcpath_ext = os.path.splitext(srcpath)
            if not srcpath_ext in self.extentions:
                return

            os.makedirs(outdir, exist_ok=True)
            ctrans_path = os.path.join(outdir, srcpath)
            if not os.path.isfile(ctrans_path):
                ctransfile = CTransFile()
                ctransfile.create(srcpath, outdir)

    def create_ctranslation_files(self, srcdir, transdir, outdir):

        self.srcdir   = srcdir
        self.transdir = transdir
        self.outdir   = outdir

        exit_code = 0
        for child_path in sorted(Path(srcdir).iterdir()):
            flag = self.create_ctranslation_file(child_path, transdir, outdir)
            if flag == False:
                exit_code = 1

        return exit_code

    def create_ctranslation_file(self, srcpath, transdir, outdir):

        flag = True
        last_flag = True

        # If srcpath is a directory
        if srcpath.is_dir():

            if srcpath.name == outdir:
                return last_flag

            # Return if "dot" directory
            if srcpath.name[0] == '.':
                return last_flag

            # Replace directories when speficied -r option.
            curr_srcpath = srcpath.name
            for k, v in self.replace_dict.items():
                pattern = "^"+k+"$"
                result = re.match(pattern, curr_srcpath)
                if result != None:
                    curr_srcpath = curr_srcpath.replace(k, v)

            curr_transdir = os.path.join(transdir, curr_srcpath)
            curr_outdir   = os.path.join(outdir, srcpath.name)

            # Execute this method for child paths recursively
            for child in sorted(Path(srcpath).iterdir()):
                flag = self.create_ctranslation_file(child, curr_transdir, curr_outdir)
                if flag == False:
                    last_flag = False

        # If srcpath is a file (not a directory)
        else:

            type, subtype = mimetypes.guess_type(srcpath, strict=True)
            if type in ctrans.constants.excl_list:

                if self.filenewer2(srcpath, outdir):
                    self.copy2(srcpath, outdir)
                    print('Copied ' + srcpath.name + ' because of exclude_ext')
                return True

            transpath = os.path.join(transdir, srcpath.name + ctrans.constants.ctrans_ext)

            # If ctrans file not exist
            if not os.path.isfile(transpath):

                if self.filenewer2(srcpath, outdir):
                    self.copy2(srcpath, outdir)
                    print('Copied ' + srcpath.name + ' because of no ctrans file')

            else:
                if self.filenewer3(srcpath, transdir, outdir):
                    flag = self.output_ctranslation_file(srcpath, transdir, outdir)

                    if flag == True:
                        outpath = os.path.join(outdir, srcpath.name)
                    else:
                        last_flag = False

        return last_flag

    def filenewer2(self, srcpath, outdir):

        outpath = os.path.join(outdir, srcpath.name)
        if not os.path.isfile(outpath):
            return True

        mtime1 = os.path.getmtime(srcpath)
        mtime2 = os.path.getmtime(outpath)

        return mtime1 > mtime2

    def filenewer3(self, srcpath, transdir, outdir):

        transpath = os.path.join(transdir, srcpath.name + ctrans.constants.ctrans_ext)
        outpath = os.path.join(outdir, srcpath.name)

        if not os.path.isfile(outpath):
            return True

        mtime1 = os.path.getmtime(srcpath)
        mtime2 = os.path.getmtime(transpath)
        mtime3 = os.path.getmtime(outpath)

        return (mtime2 > mtime3) | (mtime1 > mtime3)

    def output_ctranslation_file(self, srcpath, transdir, outdir):

        srcfile = BaseFile()
        srcfile.open(srcpath, 'r')

        outpath = os.path.join(outdir, srcpath.name)
        if not os.path.isdir(outdir):
            os.makedirs(outdir, exist_ok=True)

        transpath = os.path.join(transdir, srcpath.name + ctrans.constants.ctrans_ext)
        ctransfile = CTransFile()
        ctransfile.open(transpath, 'r')

        outfile = BaseFile()
        outfile.open(outpath, 'w')
        flag = self.output_lines(srcfile, ctransfile, outfile)

        outfile.close()

        if flag != True:
            os.remove(outpath)
        ctransfile.close()
        srcfile.close()

        return flag

    def output_lines(self, srcfile, ctransfile, outfile):

        line_ctrans = ""
        dummy, start_token_pos = ctransfile.read_until_next_start_token()

        # If next start token position is not -1 (next start token found)
        if start_token_pos != -1:

            # Get first source part in ctranslation file
            line_ctrans = ctransfile.get_current_line()

        # Get one line from source file
        line_src = srcfile.get_current_line()
        old_line_src_pos = srcfile.get_curr_line_num()

        # In case srcfile may have no contents
        if srcfile.status == srcfile.STATUS_NORMAL:
            return 0;

        error_not_occurred = True
        proc_continue = True
        src_retry = False
        while srcfile.get_curr_line_num() <= srcfile.get_line_count() and proc_continue:

            if srcfile.is_error():
                if ctransfile.is_normal() and line_ctrans != "":
                    print("--------+-", file=sys.stderr)
                    print('Error: Source part in "%s" not matched.\n(L.%d) %s'
                          % (ctransfile.pathname, ctransfile.get_curr_line_num(), line_ctrans.rstrip('\n')),
                          file=sys.stderr)

                    # In case current ctrans line does not match any src line.
                    # So src line position set back next paragraph.
                    srcfile.set_line_num(old_line_src_pos)
                    line_src = srcfile.get_current_line()
                    old_line_src_pos = srcfile.get_curr_line_num()
                    line_src_list = []
                    line_src_list.append(line_src)

                    #print('line_src   (l%d/E%d): %s' % (srcfile.get_curr_line_num(), err, line_src.rstrip('\n')), file=sys.stderr)
                    #print('line_ctrans (l%d/E%d): %s' % (ctransfile.get_curr_line_num(), err1, line_ctrans.rstrip('\n')), file=sys.stderr)

                    pattern = "^$"
                    while True:
                        result = re.match(pattern, line_src)
                        if result == None: # and line_src != line_ctrans:
                            #line_src, err = srcfile.get_current_line()
                            line_src = srcfile.get_current_line()
                            line_src_list.append(line_src)
                        else:
                            line_src_list.pop(-1)
                            break

                    old_line_src_pos = srcfile.get_curr_line_num()
                    if len(line_ctrans_list) == 0:
                        line_ctrans_list.append(line_ctrans)

                    # And also skip ctrans line to next start token
                    line_ctrans_skip, err2 = ctransfile.read_until_next_start_token()
                    line_ctrans = ctransfile.get_current_line()
                    line_ctrans_list.extend(line_ctrans_skip)

                    error_not_occurred = False
                    self.output_diff(srcfile, ctransfile, line_src_list, line_ctrans_list)
                    line_src_list = []
                    line_ctrans_list = []
                    proc_continue = True
                    src_retry = False
                    continue
                else:
                    #print('Unknown error', file=sys.stderr)
                    #print('line_src   (l%d/E%d): %s' % (srcfile.get_curr_line_num(), err, line_src.rstrip('\n')), file=sys.stderr)
                    #print('line_ctrans (l%d/E%d): %s' % (ctransfile.get_curr_line_num(), err1, line_ctrans.rstrip('\n')), file=sys.stderr)
                    break

            # In case source line in ctrans file did not exist in source file
            # and is not between ctrans tokens, it should be output as is.
            elif line_ctrans != "" and line_src != line_ctrans:
                outfile.add_line(line_src)
                line_src = srcfile.get_current_line()

            # In case source line in ctrans file existed in source file
            elif line_ctrans != "" and line_src == line_ctrans:

                line_src_list   = []
                line_ctrans_list = []
                line_src_list.append(line_src)
                line_ctrans_list.append(line_ctrans)

                while True:

                    line_src    = srcfile.get_current_line()
                    line_ctrans = ctransfile.get_current_line()

                    line_src_list.append(line_src)
                    line_ctrans_list.append(line_ctrans)

                    #print('  line_src    (l%d/E%d): %s' % (srcfile.get_curr_line_num(), err, line_src.rstrip('\n')), file=sys.stderr)
                    #print('  line_ctrans (l%d/E%d): %s' % (ctransfile.get_curr_line_num(), err1, line_ctrans.rstrip('\n')), file=sys.stderr)

                    if line_src != line_ctrans:
                        len_token = len(ctrans.constants.ctrans_trans)

                        # If current line in ctrans file is ctrans_trans token
                        if len(line_ctrans)>=len_token and line_ctrans[0:len_token]==ctrans.constants.ctrans_trans:
                            old_line_src_pos = srcfile.get_curr_line_num()
                            break

                        else:
                            # Lines between source file and source part in ctrans file do not match
                            print("----------", file=sys.stderr)
                            print('Error: Source part in "%s" not matched.\n(L.%d) %s'
                                % (ctransfile.pathname, ctransfile.get_curr_line_num(), line_ctrans.rstrip('\n')),
                                file=sys.stderr)

                            # Skip ctransfile line to next token potision
                            # Also append lines to next token to line list for error (diff) message
                            line_ctrans_skip, err2 = ctransfile.read_until_next_start_token()
                            if len(line_ctrans_skip) != 0:
                                line_ctrans_list.extend(line_ctrans_skip)
                            line_ctrans = ctransfile.get_current_line()

                            line_src_list = self.get_srcs_when_error(srcfile, line_src, line_src_list)

                            error_not_occurred = False
                            self.output_diff(srcfile, ctransfile, line_src_list, line_ctrans_list)
                            proc_continue = True
                            break

                if proc_continue == False:
                    self.output_diff(srcfile, ctransfile, line_src_list, line_ctrans_list)
                    proc_continue = True

                else:
                    src_retry = False
                    len_end = len(ctrans.constants.ctrans_end)

                    # Output translation part of ctransfile into outfile
                    while True:

                        line_ctrans = ctransfile.get_current_line()
                        if err1 != 0:
                            break
                        elif len(line_ctrans)>=len_end and line_ctrans[0:len_end]==ctrans.constants.ctrans_end:
                            break
                        else:
                            outfile.add_line(line_ctrans)

                    old_ctrans_list = line_ctrans_list
                    # Proceed position of ctransfile to next start token
                    dummy, err1 = ctransfile.read_until_next_start_token()

                    if err1 != -1:
                        line_ctrans = ctransfile.get_current_line()
                        line_ctrans_list = []
                    else:
                        proc_continue = True

            elif len(line_src.rstrip('\n')) == 0 and len(line_ctrans.rstrip('\n')) == 0:
                return True

            elif err1 != 1:
                return False
            else:
                print("Unknown error", file=sys.stderr)
                print("srcfile: %s" % srcfile.pathname)
                print('line_src    (L.%d/E%d): |%s|' % (srcfile.get_curr_line_num(), err, line_src.rstrip('\n')), file=sys.stderr)
                print('line_ctrans (L.%d/E%d): |%s|' % (ctransfile.get_curr_line_num(), err1, line_ctrans.rstrip('\n')), file=sys.stderr)
                return False

        #if error_not_occurred == False:
        #    os.remove(outfile.pathname)
        return error_not_occurred

    def copy2(self, srcpath, outdir):

        outpath = os.path.join(outdir, srcpath.name)
        dir_and_base = os.path.split(outpath)
        dirname = dir_and_base[0]
        if not os.path.exists(dirname):
            os.makedirs(dirname, exist_ok=True)
        shutil.copy(srcpath, outdir)

    def output_diff(self, srcfile, ctransfile, line_src_list, line_ctrans_list):

        tmpdir = tempfile.TemporaryDirectory()
        tmpname = tmpdir.name
        #tmpname = tempfile.mkdtemp()
        fp_src    = open(tmpname+'/src.txt', 'w', encoding='utf-8')
        fp_ctrans = open(tmpname+'/ctrans.txt', 'w', encoding='utf-8')

        for line_src in line_src_list:
            fp_src.write(line_src)
        for line_ctran in line_ctrans_list:
            fp_ctrans.write(line_ctran)
        fp_ctrans.close()
        fp_src.close()

        os.system("diff -au "+tmpname+"/ctrans.txt "+tmpname+"/src.txt > "+tmpname+"/diff.txt")
        t_src = os.path.getmtime(srcfile.pathname)
        d_src = str(datetime.datetime.fromtimestamp(t_src))
        t_ctrans = os.path.getmtime(ctransfile.pathname)
        d_ctrans = str(datetime.datetime.fromtimestamp(t_ctrans))
        s = "sed -i -e \"s|\-\-\- .*$|--- a/"+str(ctransfile.pathname)+"\t"+str(d_ctrans)+"|\" "
        s = s +    "-e \"s|+++ .*$|+++ b/"+str(srcfile.pathname)+"\t"+str(d_src)+"|\" "
        s = s + tmpname+"/diff.txt"
        os.system(s)
        fp_diff = open(tmpname+'/diff.txt', 'r', encoding='utf-8')
        lines_diff = fp_diff.readlines()
        print("Pseudo diff:", file=sys.stderr)
        for line_diff in lines_diff:
            print("%s" % line_diff.replace("\n",""), file=sys.stderr)

        fp_diff.close()
        tmpdir.cleanup()

    def get_srcs_when_error(self, srcfile, line_src, line_src_list):

        # Skip srcfile line to next non-blank line
        # Also append the line to list for error (diff) message
        pattern = "^$"
        while True:
            result = re.match(pattern, line_src)
            if result == None:
                line_src = srcfile.get_current_line()
                line_src_list.append(line_src)
            else:
                line_src_list.pop(-1)
                break
        return line_src_list
CTranslation manager class # file extensions to be translated # replacement for directories (no error processing..) # If srcpath is a directory # Return if "dot" directory # Execute child paths recursively # If srcpath is a file (not a directory) # If srcpath is a directory # Return if "dot" directory # Replace directories when speficied -r option. # Execute this method for child paths recursively # If srcpath is a file (not a directory) # If ctrans file not exist # If next start token position is not -1 (next start token found) # Get first source part in ctranslation file # Get one line from source file # In case srcfile may have no contents # In case current ctrans line does not match any src line. # So src line position set back next paragraph. #print('line_src   (l%d/E%d): %s' % (srcfile.get_curr_line_num(), err, line_src.rstrip('\n')), file=sys.stderr) #print('line_ctrans (l%d/E%d): %s' % (ctransfile.get_curr_line_num(), err1, line_ctrans.rstrip('\n')), file=sys.stderr) # and line_src != line_ctrans: #line_src, err = srcfile.get_current_line() # And also skip ctrans line to next start token #print('Unknown error', file=sys.stderr) #print('line_src   (l%d/E%d): %s' % (srcfile.get_curr_line_num(), err, line_src.rstrip('\n')), file=sys.stderr) #print('line_ctrans (l%d/E%d): %s' % (ctransfile.get_curr_line_num(), err1, line_ctrans.rstrip('\n')), file=sys.stderr) # In case source line in ctrans file did not exist in source file # and is not between ctrans tokens, it should be output as is. # In case source line in ctrans file existed in source file #print('  line_src    (l%d/E%d): %s' % (srcfile.get_curr_line_num(), err, line_src.rstrip('\n')), file=sys.stderr) #print('  line_ctrans (l%d/E%d): %s' % (ctransfile.get_curr_line_num(), err1, line_ctrans.rstrip('\n')), file=sys.stderr) # If current line in ctrans file is ctrans_trans token # Lines between source file and source part in ctrans file do not match # Skip ctransfile line to next token potision # Also append lines to next token to line list for error (diff) message # Output translation part of ctransfile into outfile # Proceed position of ctransfile to next start token #if error_not_occurred == False: #    os.remove(outfile.pathname) #tmpname = tempfile.mkdtemp() # Skip srcfile line to next non-blank line # Also append the line to list for error (diff) message