예제 #1
0
def run(fs: VFs, target, cmd, cwd, env):
    recursive = False
    force = True
    file_list = list()
    if len(cmd) < 2:
        raise Exception('rm: missing arguments')
    for arg in cmd[1:]:
        if arg[:2] == '--':
            flag = arg[2:]
            if flag == 'recursive':
                recursive = True
            elif flag == 'force':
                force = True
            elif flag in ('help', 'version'):
                return None, None
            else:
                raise NotImplementedError(
                    'rm: flag --{:s} not implemented'.format(flag))
        elif arg[0] == '-':
            for flag in arg[1:]:
                if flag in ('r', 'R'):
                    recursive = True
                elif flag == 'f':
                    force = True
                elif flag == 'v':
                    pass
                else:
                    raise NotImplementedError(
                        'rm: flag -{:s} not implemented'.format(flag))
        else:
            file_list.append(join(cwd, arg))
    for file in file_list:
        fs.rm(file, recursive, force)
    return None, None
예제 #2
0
def run(fs: VFs, target, cmd, cwd, env):
    parents = False
    dir_list = list()
    for arg in cmd[1:]:
        if arg[:2] == '--':
            flag = arg[2:]
            if flag == 'parents':
                parents = True
            elif flag in ('mode', 'verbose'):
                pass
            elif flag in ('help', 'version'):
                return None, None
            else:
                raise NotImplementedError(
                    'mkdir: flag --{:s} not implemented'.format(flag))
        elif arg[0] == '-':
            for flag in arg[1:]:
                if flag == 'p':
                    parents = True
                elif flag in ('m', 'v'):
                    pass
                else:
                    raise NotImplementedError(
                        'mkdir: flag -{:s} not implemented'.format(flag))
        else:
            dir_list.append(join(cwd, arg))
    if not dir_list:
        raise Exception('mkdir: missing arguments')
    for path in dir_list:
        if parents:
            fs.mkdirs(path)
        else:
            fs.mkdir(path)
    return None, None
예제 #3
0
def _get_dir_handler(fs, cwd, path):
    file_path = join(cwd, path)
    file, is_new_file = fs.get_current_dir(file_path, create_as_is=True)
    if is_new_file:
        print('WARNING: creating missing dir: {:s}'.format(
            file.get_full_path()),
              flush=True)
    return file
예제 #4
0
def _parse_output(fs: VFs, config: GccConfig, argv, pos):
    path = None
    if argv[pos] == '-o':
        pos += 1
        if pos < len(argv):
            path = argv[pos]
    else:
        path = argv[pos][2:]
    if not path:
        raise ValueError("missing filename after '-o'")
    path = join(config._cwd, path)
    file = fs.create_new_file(path, create_dirs=True)
    config._output_file = (file.get_full_path(), file.get_version())
    config._output_file_handler = file
    return pos + 1
예제 #5
0
 def get_current_file(self, path, cwd=None, create_as_is=False):
     file_path = join(cwd, path)
     file = None
     try:
         file = self._get_file(file_path, VFS_FILE, False, False, False)
     except PathNotExist:
         pass
     if not file and create_as_is:
         return self.create_new_file(file_path, create_dirs=True), True
     elif file:
         if create_as_is:
             return VFileHandler(file), False
         else:
             return VFileHandler(file)
     else:
         raise PathNotExist
예제 #6
0
def _parse_library(fs: VFs, config: GccConfig, argv, pos):
    path = None
    if argv[pos] == '-L':
        pos += 1
        if pos < len(argv):
            path = argv[pos]
    else:
        path = argv[pos][2:]
    if not path:
        raise ValueError("missing path after '-L'")
    if path[0] == '=':
        path = join(config._sysroot, path[1:])
    rpath = _get_dir_handler(fs, config._cwd, path).get_full_path()
    if rpath not in config._library_dirs_set:
        config._library_dirs.append(rpath)
        config._library_dirs_set.add(rpath)
    return pos + 1
예제 #7
0
def _parse_sys_include(fs: VFs, config: GccConfig, argv, pos):
    path = None
    if argv[pos] == '-isystem':
        pos += 1
        if pos < len(argv):
            path = argv[pos]
    else:
        path = argv[pos][8:]
    if not path:
        raise ValueError("missing path after '-isystem'")
    if path[0] == '=':
        path = join(config._sysroot, path[1:])
    rpath = _get_dir_handler(fs, config._cwd, path).get_full_path()
    if (rpath not in config._default_sys_include_dirs_set) and (
            rpath not in config._sys_include_dirs_set):
        config._sys_include_dirs.append(rpath)
        config._sys_include_dirs_set.add(rpath)
    return pos + 1
예제 #8
0
def _cp(fs,
        cwd,
        src,
        dst,
        dereference=False,
        dereference_command_line=False,
        recursive=False):
    src = get_abs_path(join(cwd, src))
    dst = get_abs_path(join(cwd, dst))
    dst_type = fs.get_type(dst)
    # dst exist
    if dst_type:
        if dst_type == VFS_SYMLINK:
            dst = fs.realpath(dst)
            dst_type = fs.get_type(dst)
        if dst_type == VFS_DIR:
            dst = join(dst, get_base_name(src))
        dst_type = fs.get_type(dst)
        if dst_type:
            if dst_type == VFS_SYMLINK:
                dst = fs.realpath(dst)
                dst_type = fs.get_type(dst)
    src_type = fs.get_type(src)
    if not src_type:
        fs.create_new_file(src, None, True)
        src_type = VFS_FILE
        print('WARNING: creating missing file: {:s}'.format(src), flush=True)
        # raise PathNotExist('cp: file {:s} not exist.'.format(src))
    if src_type == VFS_SYMLINK:
        if dereference or dereference_command_line:
            src = fs.realpath(src)
            src_type = fs.get_type(src)
            if not src_type:
                fs.create_new_file(src, None, True)
                src_type = VFS_FILE
                print('WARNING: creating missing file: {:s}'.format(src),
                      flush=True)
                # raise PathNotExist('cp: file {:s} not exist.'.format(src))
        else:
            if dst_type:
                if dst_type != VFS_FILE:
                    raise Exception(
                        'cp: cannot overwrite dir {:s} with non-dir.'.format(
                            dst))
            fs.rm(dst, force=True)
            fs.mklink(dst, fs.readlink(src))
            return None, None
    if src_type == VFS_DIR:
        if recursive:
            if not dst_type or dst_type == VFS_DIR:
                file_list = fs.list_dir(src)
                src_list = list()
                dst_list = list()
                if not dst_type:
                    fs.mkdir(dst)
                for file in file_list:
                    dep = _cp(fs, None, file.get_full_path(),
                              join(dst, file.get_base_name()), dereference,
                              False, True)
                    if dep[0]:
                        src_list.extend(dep[0])
                        dst_list.extend(dep[1])
                return tuple(src_list), tuple(dst_list)
            else:
                raise Exception(
                    'cp: cannot overwrite dir {:s} with non-dir.'.format(dst))
        return None, None
    else:
        if dst_type and dst_type != VFS_FILE:
            raise Exception(
                'cp: cannot overwrite dir {:s} with non-dir.'.format(dst))
        else:
            fs.mkdirs(get_dir_name(dst))
            fs.copy(src, dst)
            sfile = fs.get_current_file(src)
            dfile = fs.get_current_file(dst)
            return ((dfile.get_full_path(),
                     dfile.get_version()), ), ((sfile.get_full_path(),
                                                sfile.get_version()), )
예제 #9
0
def run(fs: VFs, target, cmd, cwd, env):
    dereference = False
    dereference_command_line = True
    recursive = False
    file_list = list()
    for arg in cmd[1:]:
        if arg[0] == '-':
            if arg[:2] == '--':
                flags = [arg[2:]]
            else:
                flags = arg[1:]
            for flag in flags:
                if '=' in flag:
                    flag = flag.split('=')[0]
                if flag in ('r', 'R', 'recursive'):
                    recursive = True
                elif flag in ('d', 'P', 'no-dereference'):
                    dereference = False
                    dereference_command_line = False
                elif flag in ('L', 'dereference'):
                    dereference = True
                elif flag == 'H':
                    dereference_command_line = True
                elif flag in ('a', 'archive'):
                    dereference = False
                    dereference_command_line = False
                    recursive = True
                elif flag in ('p', 'f', 'v', 'force', 'verbose', 'preserve'):
                    pass
                elif flag in ('help', 'version'):
                    return None, None
                else:
                    raise NotImplementedError(
                        'cp: flag {:s} not implemented'.format(flag))
        else:
            file_list.append(arg)
    if len(file_list) < 2:
        raise Exception('cp: missing destination file operand')
    destination_file = file_list[-1]
    file_list = file_list[:-1]
    # cp [OPTION]... [-T] SOURCE DEST
    if len(file_list) == 1:
        return _cp(fs, cwd, file_list[0], destination_file, dereference,
                   dereference_command_line, recursive)
    else:
        dst_dir = get_abs_path(join(cwd, destination_file))
        dst_type = fs.get_type(dst_dir)
        if not dst_type:
            fs.mkdirs(dst_dir)
            dst_type = VFS_DIR
        if dst_type != VFS_DIR:
            raise Exception(
                'cp: destination is not dir or not exist: {:s}'.format(
                    destination_file))
        src_list = list()
        dst_list = list()
        for file in file_list:
            dep = _cp(fs, cwd, file, join(destination_file, file), dereference,
                      False, True)
            if dep[0]:
                src_list.extend(dep[0])
                dst_list.extend(dep[1])
        return tuple(src_list), tuple(dst_list)
예제 #10
0
def run(fs: VFs, target, cmd, cwd, env):
    no_target_directory = False
    sym_link = False
    force = False
    file_list = list()
    for arg in cmd[1:]:
        if arg[:2] == '--':
            flag = arg[2:]
            if flag == 'symbolic':
                sym_link = True
            elif flag == 'force':
                force = True
            elif flag == 'no-target-directory':
                no_target_directory = True
            elif flag in ('mode', 'verbose'):
                pass
            elif flag in ('help', 'version'):
                return None, None
            else:
                raise NotImplementedError('ln: flag --{:s} not implemented'.format(flag))
        elif arg[0] == '-':
            for flag in arg[1:]:
                if flag == 's':
                    sym_link = True
                elif flag == 'f':
                    force = True
                elif flag == 'T':
                    no_target_directory = True
                elif flag in ('m', 'v'):
                    pass
                else:
                    raise NotImplementedError('ln: flag -{:s} not implemented'.format(flag))
        else:
            file_list.append(arg)
    if not file_list:
        raise Exception('ln: missing arguments')
    if not sym_link:
        raise NotImplementedError('ln: hard link not implemented')
    file_count = len(file_list)
    # ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
    # ln [OPTION]... TARGET                  (2nd form)
    if file_count <= 2:
        target = file_list[0]
        # 1st form
        if file_count == 2:
            path = join(cwd, file_list[1])
            # path is dir or is link to dir and create in dir
            if fs.get_real_type(path) == VFS_DIR and not no_target_directory:
                path = join(path, get_base_name(target))
        # 2nd form
        else:
            path = join(cwd, get_base_name(target))
        _mklink(fs, path, target, force)
    # ln [OPTION]... TARGET... DIRECTORY     (3rd form)
    elif not no_target_directory:
        targets = file_list[:-1]
        dir_path = join(cwd, file_list[-1])
        path_type = fs.get_real_type(dir_path)
        if not path_type or path_type != VFS_DIR:
            raise Exception('ln: target `{:s}` is not a directory'.format(dir_path))
        for target in targets:
            path = join(dir_path, get_base_name(target))
            _mklink(fs, path, target, force)
    else:
        raise Exception('ln: extra operand `{:s}`'.format(file_list[2]))
    return None, None
예제 #11
0
def run(fs: VFs, target, cmd, cwd, env):
    config = GccConfig()
    config._cwd = cwd
    config._command = target
    c_type = 'c'
    # start parsing
    pos = 1
    argc = len(cmd)
    while pos < argc:
        key, handler = _handlers.longest_prefix(cmd[pos])
        if handler:
            # call option parser
            pos = handler(fs, config, cmd, pos)
        else:
            # is input file
            input_file = cmd[pos]
            if c_type == 'c' and input_file.endswith(('.cpp', '.cxx', '.cc')):
                c_type = 'c++'
            file = _get_file_handler(fs, cwd, input_file)
            file_id = (file.get_full_path(), file.get_version())
            if file_id not in config._input_files_set:
                config._input_files.append(file_id)
                config._input_files_set.add(file_id)
            pos += 1
    default_include_dirs = None
    default_sys_include_dirs = None
    if target in _init_default_include_dirs:
        default_include_dirs = _init_default_include_dirs[target]
        default_sys_include_dirs = _init_default_sys_include_dirs[target]
    elif os.path.exists(target):
        default_include_dirs, default_sys_include_dirs, default_macros = _get_gcc_default_config(
            fs, target, c_type)
        _init_default_include_dirs[target] = default_include_dirs
        _init_default_sys_include_dirs[target] = default_sys_include_dirs
        _init_default_macros[target] = default_macros
    if default_include_dirs:
        for inc_dir in default_include_dirs:
            if inc_dir not in config._default_include_dirs_set:
                config._default_include_dirs.append(inc_dir)
                config._default_include_dirs_set.add(inc_dir)
    if default_sys_include_dirs:
        for inc_dir in default_sys_include_dirs:
            if inc_dir not in config._default_sys_include_dirs_set:
                config._default_sys_include_dirs.append(inc_dir)
                config._default_sys_include_dirs_set.add(inc_dir)
    if config._sysroot:
        for sys_inc_dir in ('usr/local/include', 'usr/include'):
            inc_dir = join(config._sysroot, sys_inc_dir)
            if inc_dir not in config._default_sys_include_dirs_set:
                config._default_sys_include_dirs.append(inc_dir)
                config._default_sys_include_dirs_set.add(inc_dir)
    for inc_dir in config._default_include_dirs_set:
        if inc_dir in config._include_dirs_set:
            config._include_dirs.remove(inc_dir)
    for inc_dir in config._default_sys_include_dirs_set:
        if inc_dir in config._sys_include_dirs_set:
            config._sys_include_dirs.remove(inc_dir)

    config._input_files = tuple(config._input_files)
    config._include_files = tuple(config._include_files)
    config._linked_libs = tuple(config._linked_libs)
    config._include_dirs = tuple(config._include_dirs)
    config._sys_include_dirs = tuple(config._sys_include_dirs)
    config._library_dirs = tuple(config._library_dirs)
    config._define_undef = tuple(config._define_undef)
    config._other_options = tuple(config._other_options)
    config._linker_options = tuple(config._linker_options)
    config._default_include_dirs = tuple(config._default_include_dirs)
    config._default_sys_include_dirs = tuple(config._default_sys_include_dirs)

    if config._only_do_preprocessing:
        if config._input_from_stdin:
            return None, None
        else:
            return None, config._input_files
    if not config._output_file:
        # default output file
        file = fs.create_new_file(join(cwd, 'a.out'))
        file.get_extra_data_ref().value = config
        config._output_file = (file.get_full_path(), file.get_version())
    else:
        config._output_file_handler.get_extra_data_ref().value = config
        config._output_file_handler = None
    if config._input_from_stdin:
        return (config._output_file, ), None
    else:
        return (config._output_file, ), config._input_files
예제 #12
0
 def cd(self, path):
     new_path = join(self.cwd, path)
     if self.fs.isdir(self.fs.realpath(new_path)):
         self.cwd = new_path
     else:
         print('{:s} is not dir.'.format(path))
예제 #13
0
 def get(self, path=None):
     if path:
         return join(self.cwd, path)
     else:
         return self.cwd
예제 #14
0
 def _get_file(self,
               path,
               file_type,
               create,
               overwrite,
               create_dirs,
               override_to_dir=False):
     ptr_node = self._root
     abs_path = get_abs_path(path)
     if abs_path == '/':
         if file_type & VFS_DIR:
             if create and overwrite:
                 raise FileExist('file {:s} exists.'.format(abs_path))
             else:
                 return self._root.values[-1]
         else:
             raise FileTypeNotMatch(
                 '{:s} file type {:s} not match {:s}'.format(
                     abs_path, _type_to_string(self._root.values[-1].type),
                     _type_to_string(file_type)))
     if not abs_path.startswith('/'):
         raise ValueError(
             'path `{:s}` not absolute or not valid'.format(abs_path))
     path_elements = abs_path.split('/')
     # loop through dirs
     element_count = 0
     for item in path_elements[:-1]:
         element_count += 1
         if not item:
             continue
         # 1. current node exists
         # 2. current node is dir
         current_dir = ptr_node.values[-1]
         # if item node is exist
         if item in ptr_node.children:
             item_node = ptr_node.children[item]
             item_file = item_node.values[-1]
             # if item exists and is dir
             if item_node.exist and item_file.type == VFS_DIR:
                 # move to dir
                 ptr_node = item_node
                 continue
             # - item not exists
             elif not item_node.exist:
                 # if we will create it
                 if create_dirs:
                     # create a new dir
                     item_node.values.append(
                         VDir(item_node, len(item_node.values),
                              current_dir.version))
                     item_node.exist = True
                     # move to dir
                     ptr_node = item_node
                     continue
                 # - error: path not exist
                 else:
                     raise PathNotExist('path {:s} is not exist.'.format(
                         join(ptr_node.path, item)))
             # - item exists and is symlink
             elif item_file.type == VFS_SYMLINK:
                 target = join(ptr_node.path, item_file.target,
                               *path_elements[element_count:])
                 # if symlink to itself
                 if target == abs_path:
                     raise PathNotExist('path {:s} is not exist.'.format(
                         join(ptr_node.path, item)))
                 # follow symlink
                 return self._get_file(target, file_type, create, overwrite,
                                       create_dirs)
             # - error: item exists but is not dir or symlink
             else:
                 # if override to dir
                 if override_to_dir:
                     item_node.values.append(
                         VDir(item_node, len(item_node.values),
                              current_dir.version))
                     # move to dir
                     ptr_node = item_node
                     continue
                 raise PathNotExist('{:s} is not a dir.'.format(
                     item_node.path))
         # - item node is not exist but we will create it
         elif create_dirs:
             # create new dir node and add to current node
             item_node = Node(ptr_node, item)
             ptr_node.children[item] = item_node
             # create VDir for item node
             item_node.values.append(VDir(item_node, 0,
                                          current_dir.version))
             # move to dir
             ptr_node = item_node
             continue
         # - error: path not exist
         else:
             raise PathNotExist('path {:s} is not exist.'.format(
                 join(ptr_node.path, item)))
     # try get file in target dir
     file = path_elements[-1]
     current_dir = ptr_node.values[-1]
     # if file node is exist
     if file in ptr_node.children:
         file_node = ptr_node.children[file]
         file_value = file_node.values[-1]
         # if file is exist
         if file_node.exist:
             current_file = file_node.values[-1]
             # if we should overwrite current file
             if create and overwrite:
                 # if current is file and overwrite type is file
                 if file_type == VFS_FILE and current_file.type == VFS_FILE:
                     # create a new file
                     file_value = VFile(file_node, len(file_node.values),
                                        current_dir.version)
                     file_node.values.append(file_value)
                 # - current is symlink and overwrite type is not symlink
                 elif not file_type & VFS_SYMLINK and current_file.type == VFS_SYMLINK:
                     target = join(ptr_node.path, file_value.target)
                     # if symlink to itself
                     if target == abs_path:
                         raise PathNotExist(
                             'path {:s} is not exist.'.format(abs_path))
                     # follow symlink
                     return self._get_file(target, file_type, create,
                                           overwrite, create_dirs)
                 # - current is symlink and overwrite type is symlink
                 # - current is file and overwrite type is not file
                 # - current is dir and try to overwrite
                 else:
                     raise FileExist('file {:s} exists.'.format(abs_path))
             # - current is symlink and create not overwrite
             elif create and current_file.type == VFS_SYMLINK:
                 target = join(ptr_node.path, file_value.target)
                 # if symlink to itself
                 if target == abs_path:
                     raise PathNotExist(
                         'path {:s} is not exist.'.format(abs_path))
                 # follow symlink
                 return self._get_file(target, file_type, create, overwrite,
                                       create_dirs)
             # if file is what we want
             if file_value.type & file_type:
                 return file_value
             # - file is symlink
             elif file_value.type == VFS_SYMLINK:
                 target = join(ptr_node.path, file_value.target)
                 # if symlink to itself
                 if target == abs_path:
                     raise PathNotExist(
                         'path {:s} is not exist.'.format(abs_path))
                 # follow symlink
                 return self._get_file(target, file_type, create, overwrite,
                                       create_dirs)
             # - error: file type not match
             else:
                 raise FileTypeNotMatch(
                     '{:s} file type {:s} not match {:s}'.format(
                         abs_path, _type_to_string(file_value.type),
                         _type_to_string(file_type)))
         # - file is not exist
         else:
             # if we will create it
             if create:
                 # create a new file
                 file_value = _create_file(file_type, file_node,
                                           len(file_node.values),
                                           current_dir.version)
                 file_node.values.append(file_value)
                 file_node.exist = True
                 return file_value
             # - error: path not exist
             else:
                 raise PathNotExist('path {:s} is not exist.'.format(
                     join(ptr_node.path, file)))
     # - file node is not exist but we will create it
     elif create:
         # create new file node and add to current node
         file_node = Node(ptr_node, file)
         ptr_node.children[file] = file_node
         # create new file for item node
         file_value = _create_file(file_type, file_node, 0,
                                   current_dir.version)
         file_node.values.append(file_value)
         return file_value
     # - error: path not exist
     else:
         raise PathNotExist('path {:s} is not exist.'.format(
             join(ptr_node.path, file)))
예제 #15
0
 def create_new_file(self, path, cwd=None, create_dirs=False):
     return VFileHandler(
         self._get_file(join(cwd, path), VFS_FILE, True, True, create_dirs,
                        create_dirs))