예제 #1
0
    def _run_esqloc(self, file_path):
        """
        Run the esqloc process and returns it's exit code and
        output (both stderr and stdout).

        :param file_path: .sqb path.
        :return: int, str, str
        """
        path = os.path.dirname(file_path)
        source = os.path.split(file_path)[1]
        destination = os.path.splitext(source)[0] + '.cob'
        pgm, options = self.make_command(source, destination)
        process = QtCore.QProcess()
        process.setWorkingDirectory(path)
        process.setProcessChannelMode(QtCore.QProcess.MergedChannels)
        cmd = '%s %s' % (pgm, ' '.join(options))
        _logger().info('command: %s', cmd)
        _logger().debug('working directory: %s', path)
        _logger().debug('system environment: %s', process.systemEnvironment())
        process.start(pgm, options)
        self.started.emit(cmd)
        process.waitForFinished()
        status = process.exitCode()
        try:
            output = process.readAllStandardOutput().data().decode(
                locale.getpreferredencoding())
        except UnicodeDecodeError:
            output = 'Failed to decode esqloc output with encoding: ' % \
                locale.getpreferredencoding()
        self.output_available.emit(output)
        return output, status, destination
예제 #2
0
    def _run_command(pgm, args):
        if ' ' in pgm:
            pgm = '"%s"' % pgm

        p = QtCore.QProcess()
        p.setProcessChannelMode(QtCore.QProcess.MergedChannels)
        p.setProcessEnvironment(GnuCobolCompiler.setup_process_environment())
        p.start(pgm, args)
        p.waitForFinished()

        # determine exit code (handle crashed processes)
        if p.exitStatus() != p.Crashed:
            status = p.exitCode()
        else:
            status = 139

        # get compiler output
        try:
            output = p.readAllStandardOutput().data().decode(
                locale.getpreferredencoding()).replace('\r\n', '\n')
        except UnicodeDecodeError:
            output = 'Failed to decode compiler output with encoding %s' % \
                     locale.getpreferredencoding()

        return status, output
예제 #3
0
 def _check_compiler(self, *_):
     self.apply()
     pth = self.lineEditCompilerPath.text()
     if os.path.exists(pth) or system.which(pth) is not None:
         p = QtCore.QProcess()
         p.start(pth, ['--version'])
         p.waitForFinished()
         output = bytes(p.readAllStandardOutput()).decode(
             locale.getpreferredencoding())
         DlgCheckCompiler.check(self, pth, output)
     else:
         QtWidgets.QMessageBox.warning(
             self, 'Invalid compiler path',
             'Not a valid compiler path, path does not exists: %s!' % pth)
예제 #4
0
def lint(request_data):
    """
    Performs linting of a COBOL document.

    This method will perform on the pyqode backend.

    :param request_data: work request data (dict)
    :return: status, messages
    """
    print('running open_cobol_ide.linter.lint')
    code = request_data['code']
    path = request_data['path']
    extension = os.path.splitext(path)[1]
    print(('valid compiler extensions: %r' %
           settings.Settings().cobc_extensions))
    messages = []
    if extension.lower() in settings.Settings().cobc_extensions:
        # code might not have been saved yet, run cobc on a tmp file
        # we use a time stamp to avoid overwriting the file another cobc
        # instance might be compiling.
        file_name = os.path.split(path)[1]
        file_name, ext = os.path.splitext(file_name)
        tmp_name = '%s.%s%s' % (file_name, str(int(time.time())), ext)
        tmp_pth = os.path.join(tempfile.gettempdir(), tmp_name)
        print(('writing code to temporary file: %r' % tmp_pth))
        with open(tmp_pth, 'w') as f:
            f.write(code)
        compiler = GnuCobolCompiler()
        pgm, args = make_linter_command(tmp_name, path)
        print(('linter command: %s %s' % (pgm, ' '.join(args))))
        process = QtCore.QProcess()
        process.setProcessEnvironment(
            GnuCobolCompiler.setup_process_environment())
        process.setWorkingDirectory(os.path.dirname(tmp_pth))
        process.setProcessChannelMode(QtCore.QProcess.MergedChannels)
        print('running compiler process')
        print(('working directory: %s' % process.workingDirectory()))
        process.start(pgm, args)
        print('waiting for compilation to finish...')
        process.waitForFinished()
        output = process.readAllStandardOutput().data().decode(
            locale.getpreferredencoding())
        print(('linter raw output: %s' % output))
        messages = compiler.parse_output(output, process.workingDirectory())
        print(('linter parsed output: %r' % messages))
        print('removing temporary file...')
        os.remove(tmp_pth)
    return messages
예제 #5
0
    def check_compiler(cls, compiler):
        if Settings().vcvars32:
            try:
                VisualStudioWrapperBatch.generate()
            except OSError as e:
                _logger().exception('failed to generate visual studio wrapper '
                                    'batch')
                return str(e), 1
            compiler = VisualStudioWrapperBatch.path()

        from open_cobol_ide.view.dialogs.preferences import DEFAULT_TEMPLATE
        cbl_path = os.path.join(tempfile.gettempdir(), 'test.cbl')
        with open(cbl_path, 'w') as f:
            f.write(DEFAULT_TEMPLATE)
        dest = os.path.join(tempfile.gettempdir(),
                            'test' + ('.exe' if system.windows else ''))
        p = QtCore.QProcess()
        args = ['-x', '-o', dest, cbl_path]
        p.start(compiler, args)
        _logger().debug('check compiler')
        _logger().debug('process environment: %r',
                        p.processEnvironment().toStringList())
        _logger().debug('command: %s %s', compiler, ' '.join(args))
        p.waitForFinished()
        try:
            stdout = bytes(p.readAllStandardOutput()).decode(
                locale.getpreferredencoding())
            stderr = bytes(p.readAllStandardError()).decode(
                locale.getpreferredencoding())
        except UnicodeDecodeError:
            # something is wrong in the output, the compiler might be broker
            output = None
        else:
            output = stderr + stdout
        if p.exitStatus() == p.Crashed or output is None:
            exit_code = 139
        else:
            exit_code = p.exitCode()
        _logger().debug('process output: %r', output)
        _logger().debug('process exit code: %r', exit_code)
        _logger().info('GnuCOBOL compiler check: %s',
                       'success' if exit_code == 0 else 'fail')
        try:
            os.remove(dest)
            os.remove(cbl_path)
        except OSError:
            pass
        return output, p.exitCode()
예제 #6
0
    def run_pip_command(self, interpreter, worker_function, package,
                        operation):
        """
        Run a pip command. The command is run on the backend for the current
        interpreter.

        :param interpreter: Interpreter which is going to run the backend
        :param worker_function: The worker function to execute.
        :param package: The list of packages to install, as a string where each
            item is separated by a space.
        :param operation: Operation title (used for the info label)
        """
        self.stop_backend()
        self.ui.lblInfos.setText(operation)
        self._worker = worker_function
        self._package = package
        self.stop_backend()
        self.backend = BackendManager(self)
        process = BackendProcess(self.parent())
        process.finished.connect(self._on_process_finished)
        self.backend._process = process
        server_script = server.__file__.replace('.pyc', '.py')
        port = self.backend.pick_free_port()
        self.backend._port = port
        if LINUX and self._need_root_perms(interpreter):
            _logger().info('running pip command with root privileges')
            auth = get_authentication_program()
            if 'kdesu' in auth:
                # no quotes around command when using kdesu
                cmd = '%s %s %s %s --syspath %s'
            else:
                # gksu requires quotes around command
                cmd = '%s "%s %s %s --syspath %s"'
            cmd = cmd % (auth, interpreter, server_script, str(port),
                         get_library_zip_path())
            process.start(cmd)
        elif DARWIN and self._need_root_perms(interpreter):
            cmd = 'sudo %s %s %s --syspath %s' % (
                interpreter, server_script, str(port), get_library_zip_path())
            auth_process = QtCore.QProcess()
            auth_process.start('pseudo')
            auth_process.waitForFinished()
            process.start(cmd)
        else:
            self.backend.start(server.__file__,
                               interpreter=interpreter,
                               args=['-s'] + [get_library_zip_path()])
        QtCore.QTimer.singleShot(100, self._run_command)
예제 #7
0
 def _check_compiler(self, *_):
     from open_cobol_ide.app import Application
     self.apply()
     Application.init_env()
     pth = self.lineEditCompilerPath.text()
     if os.path.exists(pth):
         p = QtCore.QProcess()
         p.start(pth, ['--version'])
         p.waitForFinished()
         output = bytes(p.readAllStandardOutput()).decode(
             locale.getpreferredencoding())
         DlgCheckCompiler.check(self, pth, output)
     else:
         QtWidgets.QMessageBox.warning(
             self, 'Invalid compiler path',
             'Not a valid compiler path, path does not exists: %s!' % pth)
예제 #8
0
def run_command(pgm, args, working_dir=''):
    if ' ' in pgm:
        pgm = '"%s"' % pgm

    path_cpy = os.environ['PATH']

    p_env = GnuCobolCompiler.setup_process_environment()
    os.environ['PATH'] = p_env.value('PATH')
    p = QtCore.QProcess()
    p.setProcessChannelMode(QtCore.QProcess.MergedChannels)
    if working_dir:
        p.setWorkingDirectory(working_dir)
    p.setProcessEnvironment(p_env)
    _logger().debug('command: %s', ' '.join([pgm] + args))
    _logger().debug('working directory: %s', working_dir)
    _logger().debug('environment: %s', p.processEnvironment().toStringList())
    p.start(pgm, args)

    print(' '.join([pgm] + args))

    p.waitForFinished()

    # determine exit code (handle crashed processes)
    if p.exitStatus() != p.Crashed:
        status = p.exitCode()
    else:
        status = 139

    # get compiler output
    raw_output = p.readAllStandardOutput().data()
    try:
        output = raw_output.decode(locale.getpreferredencoding())
    except UnicodeDecodeError:
        # This is a hack to get a meaningful output when compiling a file
        # from UNC path using a batch file on some systems, see
        # https://github.com/OpenCobolIDE/OpenCobolIDE/issues/188
        output = str(raw_output).replace("b'", '')[:-1].replace(
            '\\r\\n', '\n').replace('\\\\', '\\')

    _logger().debug('output: %r', output)
    _logger().debug('exit code: %r', status)

    os.environ['PATH'] = path_cpy

    print(output)

    return status, output
예제 #9
0
def run_command(pgm, args, working_dir=''):
    if ' ' in pgm:
        pgm = '"%s"' % pgm

    path_cpy = os.environ['PATH']

    p_env = GnuCobolCompiler.setup_process_environment()
    os.environ['PATH'] = p_env.value('PATH')
    p = QtCore.QProcess()
    p.setProcessChannelMode(QtCore.QProcess.MergedChannels)
    if working_dir:
        p.setWorkingDirectory(working_dir)
    p.setProcessEnvironment(p_env)
    _logger().debug('command: %s', ' '.join([pgm] + args))
    _logger().debug('working directory: %s', working_dir)
    _logger().debug('environment: %s', p.processEnvironment().toStringList())
    p.start(pgm, args)
    p.waitForFinished()

    # determine exit code (handle crashed processes)
    if p.exitStatus() != p.Crashed:
        status = p.exitCode()
    else:
        status = 139

    # get compiler output
    raw_output = p.readAllStandardOutput().data()
    try:
        output = raw_output.decode(locale.getpreferredencoding()).replace(
            '\r\n', '\n')
    except UnicodeDecodeError:
        output = 'Failed to decode compiler output with encoding %s' % \
                     locale.getpreferredencoding()
        _logger().exception('failed to decode compiler output: %r' %
                            raw_output)

    _logger().debug('output: %r', output)
    _logger().debug('exit code: %r', status)

    os.environ['PATH'] = path_cpy

    return status, output
예제 #10
0
    def compile(self, file_path, file_type):
        """
        Compiles a file. This is a blocking function, it returns only when
        the compiler process finished.

        :param file_path: Path of the file to compile.
        :param file_type: File type (exe or dll)
        :return: status, list of checker messages

        """
        _logger().info('compiling %s' % file_path)
        path, filename = os.path.split(file_path)
        # ensure bin dir exists
        self.make_bin_dir(path)
        # run command using qt process api, this is blocking.
        pgm, options = self.make_command(filename, file_type)
        process = QtCore.QProcess()
        process.setWorkingDirectory(path)
        process.setProcessChannelMode(QtCore.QProcess.MergedChannels)
        _logger().info('command: %s %s', pgm, ' '.join(options))
        _logger().debug('working directory: %s', path)
        _logger().debug('system environment: %s', process.systemEnvironment())
        process.start(pgm, options)
        process.waitForFinished()
        status = process.exitCode()
        output = process.readAllStandardOutput().data().decode('utf-8')
        messages = self.parse_output(output, file_path)
        _logger().info('output: %s', output)
        if status != 0 and not len(messages):
            # compilation failed but the parser failed to extract cobol related
            # messages, there might be an issue at the C level or at the
            # linker level
            messages.append((output, CheckerMessages.ERROR, - 1, 0,
                             None, None, file_path))
        _logger().debug('compile results: %r - %r', status, messages)
        return status, messages
예제 #11
0
    def compile(self, file_path, file_type, object_files=None,
                additional_options=None, output_dir=None):
        """
        Compiles a file. This is a blocking function, it returns only when
        the compiler process finished.

        :param file_path: Path of the file to compile.
        :param file_type: File type (exe or dll)
        :param output_dir: Output directory, if None, the directory set in the
                           application directory will be used.
        :return: status, list of checker messages
        """
        _logger().info('compiling %s' % file_path)
        path, filename = os.path.split(file_path)
        if output_dir is None:
            output_dir = Settings().output_directory
        if not os.path.isabs(output_dir):
            output_dir = os.path.abspath(os.path.join(path, output_dir))
        # run command using qt process api, this is blocking.
        if object_files:
            inputs = [filename] + object_files
        else:
            inputs = [filename]
        # ensure bin dir exists
        output_full_path = os.path.join(
            output_dir, self._get_output_filename(inputs, file_type))
        if os.path.exists(output_full_path) and \
            os.path.getmtime(file_path) <= \
                os.path.getmtime(output_full_path):
            desc = 'compilation skipped, up to date...'
            self.output_available.emit('%s: %s' % (file_path, desc))
            msg = (desc, CheckerMessages.INFO, -1, 0, None, None, file_path)
            return 0, [msg]

        self.prepare_bin_dir(output_dir, output_full_path)

        pgm, options = self.make_command(inputs, file_type, output_dir,
                                         additional_options)
        process = QtCore.QProcess()
        process.setWorkingDirectory(path)
        process.setProcessChannelMode(QtCore.QProcess.MergedChannels)
        process.setProcessEnvironment(self.setup_process_environment())
        cmd = '%s %s' % (pgm, ' '.join(options))
        _logger().info('command: %s', cmd)
        _logger().debug('working directory: %s', path)
        _logger().debug('system environment: %s', process.systemEnvironment())
        process.start(pgm, options)
        self.started.emit(cmd)
        process.waitForFinished()
        if process.exitStatus() != process.Crashed:
            status = process.exitCode()
        else:
            status = 139
        raw_output = process.readAllStandardOutput().data()
        try:
            output = raw_output.decode(
                locale.getpreferredencoding()).replace('\r', '\n')
        except UnicodeDecodeError:
            output = 'Failed to decode compiler output with encoding %s' % \
                     locale.getpreferredencoding()
            _logger().exception('failed to decode compiler output: %r' %
                                raw_output)
        self.output_available.emit(output)
        messages = self.parse_output(output, process.workingDirectory())
        binary_created = os.path.exists(output_full_path)
        _logger().info('compiler process exit code: %d', status)
        _logger().info('compiler process output: %s', output)
        _logger().info('binary file (%s) created:  %r',
                       output_full_path, binary_created)
        if not len(messages) and (status != 0 or not binary_created):
            # compilation failed but the parser failed to extract COBOL related
            # messages, there might be an issue at the C level or at the
            # linker level
            messages.append((output, CheckerMessages.ERROR, - 1, 0,
                             None, None, file_path))
        _logger().debug('compile results: %r - %r', status, messages)

        return status, messages