Example #1
0
def get_file_type(path):
    """
    Detects file type. If the file contains 'PROCEDURE DIVISION USING', then it
    is considered as a module else it is considered as an executable.

    :param path: file path
    :return: FileType
    """
    encoding = _get_encoding(path)
    _logger().debug('detecting file type: %s - %s', path, encoding)
    try:
        from .settings import Settings
        ftype = Settings().get_file_type(path)
    except KeyError:
        ftype = FileType.EXECUTABLE
        with open(path, 'r', encoding=encoding) as f:
            content = f.read().upper()
        if re.match(r'.*PROCEDURE[\s\n]+DIVISION[\s\n]+USING', content,
                    re.DOTALL):
            ftype = FileType.MODULE
    _logger().debug('file type: %r', ftype)
    return ftype
Example #2
0
 def get_version(include_all=True):
     """
     Returns the GnuCOBOL compiler version as a string
     """
     compiler = Settings().compiler_path
     cmd = compiler, '--version'
     if not compiler:
         return 'compiler not found'
     _logger().debug('getting cobc version: %s' % ' '.join(cmd))
     status, output = run_command(cmd[0], [cmd[1]])
     if status == 0 and output:
         if include_all:
             return output
         else:
             _logger().debug('parsing version line: %s' % output)
             m = re.match(r'cobc\s\([\w\s]*\).*$', output, re.MULTILINE)
             if m:
                 return m.group(0)
             else:
                 return "failed to extract version from output"
     else:
         return output
Example #3
0
    def setup_process_environment():
        env = QtCore.QProcessEnvironment()
        for k, v in os.environ.items():
            env.insert(k, v)

        s = Settings()

        PATH = ''
        if s.path_enabled:
            PATH = s.path

        if not s.vcvarsall:
            PATH = PATH + os.pathsep + os.environ['PATH']
        else:
            for k, v in msvc.get_vc_vars(s.vcvarsall,
                                         s.vcvarsall_arch).items():
                if k == 'PATH':
                    PATH = PATH + os.pathsep + v
                else:
                    env.insert(k, v)

        env.insert('PATH', PATH)

        _logger().debug('PATH=%s', PATH)

        if s.cob_config_dir_enabled and s.cob_config_dir:
            env.insert('COB_CONFIG_DIR', s.cob_config_dir)

        if s.cob_copy_dir_enabled and s.cob_copy_dir:
            env.insert('COB_COPY_DIR', s.cob_copy_dir)

        if s.cob_include_path_enabled and s.cob_copy_dir:
            env.insert('COB_INCLUDE_PATH', s.cob_include_path)

        if s.cob_lib_path and s.cob_copy_dir:
            env.insert('COB_LIB_PATH', s.cob_lib_path)

        return env
Example #4
0
 def get_version():
     """
     Returns the GnuCOBOL compiler version as a string
     """
     cmd = [Settings().compiler_path, '--version']
     try:
         _logger().debug('getting cobc version: %s' % ' '.join(cmd))
         if sys.platform == 'win32':
             startupinfo = subprocess.STARTUPINFO()
             startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
             p = subprocess.Popen(cmd,
                                  shell=False,
                                  startupinfo=startupinfo,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  stdin=subprocess.PIPE)
         else:
             p = subprocess.Popen(cmd,
                                  shell=False,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE)
     except (OSError, TypeError):
         _logger().exception('GnuCOBOL compiler not found (command: %s)' %
                             cmd)
         return 'Not installed'
     else:
         stdout, stderr = p.communicate()
         try:
             stdout = str(stdout.decode(locale.getpreferredencoding()))
         except UnicodeDecodeError:
             stdout = None
             lversion = 'Failed to parse cobc output'
         else:
             lversion = stdout.splitlines()[0]
             lversion = lversion.replace('cobc (', '').replace(')', '')
             _logger().debug('parsing version line: %s' % lversion)
         return lversion
Example #5
0
    def _run_in_external_terminal(self, program, wd, file_type):
        """
        Runs a program in an external terminal.

        :param program: program to run
        :param wd: working directory
        """
        self.ui.consoleOutput.append("Launched in external terminal")
        pyqode_console = system.which('pyqode-console')
        if file_type == FileType.MODULE:
            program = QtCore.QFileInfo(program).baseName()
        if system.windows:
            cmd = [pyqode_console, program]
            if file_type == FileType.MODULE:
                cmd.insert(1, system.which('cobcrun'))
            subprocess.Popen(cmd,
                             cwd=wd,
                             creationflags=subprocess.CREATE_NEW_CONSOLE)
        elif system.darwin:
            cmd = ['open', program]
            if file_type == FileType.MODULE:
                cmd.insert(1, system.which('cobcrun'))
            subprocess.Popen(cmd, cwd=wd)
        else:
            if file_type == FileType.EXECUTABLE:
                cmd = ['"%s %s"' % (pyqode_console, program)]
            else:
                cmd = [
                    '"%s %s %s"' %
                    (pyqode_console, system.which('cobcrun'), program)
                ]
            cmd = (Settings().external_terminal_command.strip().split(' ') +
                   cmd)
            subprocess.Popen(' '.join(cmd), cwd=wd, shell=True)
        _logger().info('running program in external terminal: %s',
                       ' '.join(cmd))
Example #6
0
    def get_dependencies(cls, filename, recursive=True):
        """
        Gets the dependencies of a cobol program/module.

        :param filename: path of the file to analyse.
        :param recursive: True to perform recursive analysis (analyses
            dependencies of dependencies recursively).
        :return: The set of dependencies that needs to be compiled to compile
            and use the requested program/module.
        """
        encoding = _get_encoding(filename)
        directory = os.path.dirname(filename)
        dependencies = []
        prog = re.compile(r'(^(\s|\d|\w)*CALL[\s\n]*.*".*")', re.MULTILINE)
        with open(filename, 'r', encoding=encoding) as f:
            content = f.read()
            for m in prog.findall(content):
                for m in m:
                    try:
                        module_base_name = re.findall('"(.*)"', m)[0]
                    except IndexError:
                        continue
                    # try to see if the module can be found in the current
                    # directory
                    for ext in Settings().all_extensions:
                        pth = os.path.join(directory, module_base_name + ext)
                        if os.path.exists(pth) and \
                                pth.lower() not in dependencies:
                            if filename != pth:
                                dependencies.append(os.path.normpath(pth))
                                if recursive:
                                    dependencies += cls.get_dependencies(pth)

        dependencies = list(set(dependencies))
        _logger().debug('dependencies of %s: %r', filename, dependencies)
        return dependencies
Example #7
0
def update_editor_settings(editor):
    from open_cobol_ide.settings import Settings
    settings = Settings()
    # general settings for all editors
    editor.tab_length = settings.tab_len
    editor.font_name = settings.font
    editor.font_size = settings.font_size
    editor.show_whitespaces = settings.show_whitespaces
    editor.syntax_highlighter.color_scheme = ColorScheme(settings.color_scheme)
    editor.panels.get('FoldingPanel').native_look = not settings.dark_style
    try:
        # cobol editor specific settings
        editor.backspace_mode.enabled = settings.enable_smart_backspace
        editor.comment_indicator = settings.comment_indicator
        editor.free_format = settings.free_format
        editor.caret_line_mode.enabled = settings.highlight_caret
        editor.auto_indent_mode.enabled = settings.enable_autoindent
        editor.code_completion_mode.trigger_length = \
            settings.code_completion_trigger_len
        editor.line_nbr_panel.enabled = settings.display_lines
        editor.line_nbr_panel.setVisible(settings.display_lines)
        editor.linter_mode.enabled = settings.show_errors
    except AttributeError:
        editor.syntax_highlighter.pygments_style = settings.color_scheme
Example #8
0
    def _generate_param_file(self, source_path):
        """
        Generate the bin/EXECUTABLE.param file based on the settings defined in
        the preferences dialog.

        :param source_path: path of the .scb file.
        """
        name = os.path.splitext(os.path.split(source_path)[1])[0] + '.param'
        content = PARAM_FILE_CONTENT % {
            'host': Settings().dbhost,
            'user': Settings().dbuser,
            'pswd': Settings().dbpasswd,
            'dbname': Settings().dbname,
            'port': Settings().dbport,
            'socket': Settings().dbsocket
        }
        output_dir = Settings().output_directory
        if not os.path.isabs(output_dir):
            output_dir = os.path.abspath(os.path.join(source_path, output_dir))
        path = os.path.join(output_dir, name)
        if not os.path.exists(path):
            _logger().info('creating %s', name)
            with open(path, 'w') as f:
                f.write(content)
Example #9
0
 def toggle_fullscreen(self):
     if self.ui.actionFullscreen.isChecked():
         self.main_window.showFullScreen()
     else:
         self.main_window.showNormal()
     Settings().fullscreen = self.ui.actionFullscreen.isChecked()
Example #10
0
    def _run_in_external_terminal(self, program, wd, file_type):
        """
        Runs a program in an external terminal.

        :param program: program to run
        :param wd: working directory
        """
        pyqode_console = system.which('pyqode-console')
        cobc_run_insert_pos = 1
        if pyqode_console is None:
            from pyqode.core.tools import console
            pyqode_console = [sys.executable, console.__file__]
            cobc_run_insert_pos = 2
        else:
            pyqode_console = [pyqode_console]
        env = os.environ.copy()
        for k, v in list(Settings().run_environemnt.items()):
            env[k] = v
        if 'PATH' not in list(Settings().run_environemnt.keys()):
            env['PATH'] = GnuCobolCompiler.setup_process_environment().value(
                'PATH')
        if file_type == FileType.MODULE:
            program = QtCore.QFileInfo(program).baseName()
        if system.windows:
            cmd = pyqode_console + [program]
            if file_type == FileType.MODULE:
                cmd.insert(cobc_run_insert_pos, system.which('cobcrun'))
            try:
                _logger().debug(
                    "running program in external terminal: %r, %r, %r" %
                    (cmd, wd, env))
                subprocess.Popen(cmd,
                                 cwd=wd,
                                 creationflags=subprocess.CREATE_NEW_CONSOLE,
                                 env=env)
            except (OSError, subprocess.CalledProcessError):
                msg = "Failed to launch program in external terminal (cmd=%s) " % ' '.join(
                    cmd)
                _logger().exception(msg)
                self.ui.consoleOutput.appendPlainText(msg)
                return
        elif system.darwin:
            if file_type == FileType.MODULE:
                create_script(PATH_RUN_MODULE_SCRIPT, RUN_MODULE_SCRIPT,
                              (wd, system.which('cobcrun'), program))
                cmd = [
                    'open', '-n', '-a', 'Terminal', '--args',
                    PATH_RUN_MODULE_SCRIPT
                ]
            else:
                create_script(PATH_RUN_PROGRAM_SCRIPT, RUN_PROGRAM_SCRIPT,
                              (wd, program))
                cmd = [
                    'open', '-n', '-a', 'Terminal', '--args',
                    PATH_RUN_PROGRAM_SCRIPT
                ]
            try:
                subprocess.Popen(cmd, cwd=wd, env=env)
            except (OSError, subprocess.CalledProcessError):
                msg = "Failed to launch program in external terminal (cmd=%s) " % ' '.join(
                    cmd)
                _logger().exception(msg)
                self.ui.consoleOutput.appendPlainText(msg)
                return
        else:
            if file_type == FileType.EXECUTABLE:
                cmd = ['"%s %s"' % (' '.join(pyqode_console), program)]
            else:
                cmd = [
                    '"%s %s %s"' % (' '.join(pyqode_console),
                                    system.which('cobcrun'), program)
                ]
            cmd = system.shell_split(
                Settings().external_terminal_command.strip()) + cmd
            try:
                subprocess.Popen(' '.join(cmd), cwd=wd, shell=True, env=env)
            except (OSError, subprocess.CalledProcessError):
                msg = "Failed to launch program in external terminal (cmd=%s) " % ' '.join(
                    cmd)
                _logger().exception(msg)
                self.ui.consoleOutput.appendPlainText(msg)
                return
        _logger().info('running program in external terminal: %s',
                       ' '.join(cmd))
        self.ui.consoleOutput.appendPlainText(
            "Launched in external terminal: %s" % ' '.join(cmd))
Example #11
0
 def __init__(self):
     super().__init__()
     self.esqloc_path = os.path.join(Settings().esqloc, 'esqlOC.exe')
 def save_state(dlg):
     s = Settings()
     s.preferences_width = dlg.width()
     s.preferences_height = dlg.height()
Example #13
0
 def __init__(self, dbpre_path=None):
     super().__init__()
     if dbpre_path is None:
         dbpre_path = Settings().dbpre
     self.dbpre_path = dbpre_path
Example #14
0
 def restore_defaults(self):
     settings = Settings()
     index = self.tabWidget.currentIndex()
     # Editor
     if index == 0:
         settings.show_cursor_pos_in_bytes = False
         settings.show_error = True
         settings.display_lines = True
         settings.highlight_caret = True
         settings.show_whitespaces = False
         settings.tab_len = 4
         settings.enable_autoindent = True
         settings.code_completion_trigger_len = 1
         settings.comment_indicator = '*> '
         settings.enable_smart_backspace = False
         settings.lower_case_keywords = False
         settings.autodetect_eol = True
         settings.preferred_eol = 0
         settings.code_completion_trigger_len = 1
         settings.margin_positions = [7, 11, 72, 79]
         settings.margin_colors = ['red'] * 4
     # Style
     elif index == 1:
         settings.dark_style = False
         settings.icon_theme = ''
         settings.font = 'Source Code Pro'
         settings.font_size = 11
         settings.colorScheme = 'qt'
     # run
     elif index == 3:
         settings.external_terminal = False
         settings.external_terminal_command = None
         settings.run_environemnt = {}
         settings.working_dir = ''
     # compiler
     elif index == 2:
         settings.autodetect_submodules = True
         settings.output_directory = 'bin'
         settings.copy_runtime_dlls = False
         settings.free_format = False
         settings.cobol_standard = GnuCobolStandard.default
         settings.compiler_path = 'cobc.exe' if system.windows else 'cobc'
         settings.compiler_flags = ['-debug', '-Wall']
         settings.copybook_paths = ''
         settings.library_search_path = ''
         settings.libraries = ''
         settings.cobc_extensions = ['.cob', '.cbl', '.pco', '.lst']
         if system.windows:
             settings.vcvarsall = ''
             settings.vcvarsall_arch = 'x86'
         settings.path = settings.default_path()
         settings.path_enabled = True
         settings.cob_config_dir = settings.default_config_dir()
         settings.cob_config_dir_enabled = system.windows
         settings.cob_copy_dir = settings.default_copy_dir()
         settings.cob_copy_dir_enabled = system.windows
         settings.cob_include_path = settings.default_include_dir()
         settings.cob_include_path_enabled = system.windows
         settings.cob_lib_path = settings.default_lib_path()
         settings.cob_lib_path_enabled = system.windows
     elif index == 4:
         settings.dbpre = ''
         settings.dbpre_extensions = ['.scb']
         settings.dbpre_framework = ''
         settings.cobmysqlapi = ''
         settings.dbhost = 'localhost'
         settings.dbuser = ''
         settings.dbpasswd = ''
         settings.dbname = ''
         settings.dbport = '03306'
         settings.dbsocket = 'null'
         settings.esqloc = ''
         settings.esqloc_extensions = ['.sqb']
     self.reset()
Example #15
0
 def restore_state(dlg):
     s = Settings()
     dlg.resize(s.preferences_width, s.preferences_height)
     dlg.tabWidget.setCurrentIndex(s.preferences_index)
Example #16
0
 def file_type(self, ftype):
     Settings().set_file_type(self.file.path, ftype)
Example #17
0
    def reset(self, all_tabs=False):
        settings = Settings()
        # Editor
        if self.tabWidget.currentIndex() == 0 or all_tabs:
            self.cb_cursor_pos_in_bytes.setChecked(
                settings.show_cursor_pos_in_bytes)
            self.checkBoxShowErrors.setChecked(settings.show_errors)
            self.checkBoxViewLineNumber.setChecked(settings.display_lines)
            self.checkBoxHighlightCurrentLine.setChecked(
                settings.highlight_caret)
            self.checkBoxHighlightWhitespaces.setChecked(
                settings.show_whitespaces)
            self.spinBoxEditorTabLen.setValue(settings.tab_len)
            self.checkBoxEditorAutoIndent.setChecked(
                settings.enable_autoindent)
            self.spinBoxEditorCCTriggerLen.setValue(
                settings.code_completion_trigger_len)
            self.rbLowerCaseKwds.setChecked(settings.lower_case_keywords)
            self.rbUpperCaseKwds.setChecked(not settings.lower_case_keywords)
            self.lineEditCommentIndicator.setText(settings.comment_indicator)
            self.checkBoxSmartBackspace.setChecked(
                settings.enable_smart_backspace)
            self.checkBoxAutodetectEOL.setChecked(settings.autodetect_eol)
            self.comboBoxPreferredEOL.setCurrentIndex(settings.preferred_eol)
            self.comboCcFilterMode.setCurrentIndex(
                settings.completion_filter_mode)
            for pos, spin_box, color, picker in zip(
                    settings.margin_positions, self._margin_spin_boxes,
                    settings.margin_colors, self._margin_color_pickers):
                spin_box.setValue(pos + 1)
                picker.color = QtGui.QColor(color)
        # Style
        if self.tabWidget.currentIndex() == 1 or all_tabs:
            rb = (self.radioButtonColorDark
                  if settings.dark_style else self.radioButtonColorWhite)
            rb.setChecked(True)
            index = self.comboBoxIconTheme.findText(QtGui.QIcon.themeName())
            if index != -1:
                self.comboBoxIconTheme.setCurrentIndex(index)
            self.fontComboBox.setCurrentFont(QtGui.QFont(settings.font))
            self.spinBoxFontSize.setValue(settings.font_size)
            self.listWidgetColorSchemes.clear()
            current_index = None
            self.listWidgetColorSchemes.clear()
            for style in PYGMENTS_STYLES:
                self.listWidgetColorSchemes.addItem(style)
                if style == settings.color_scheme:
                    current_index = self.listWidgetColorSchemes.count() - 1
            if current_index:
                self.listWidgetColorSchemes.setCurrentRow(current_index)
        # Run
        if self.tabWidget.currentIndex() == 3 or all_tabs:
            self.checkBoxRunExtTerm.setChecked(settings.external_terminal)
            self.lineEditRunTerm.setVisible(sys.platform != 'win32')
            self.lbl_external_terminal_command.setVisible(
                sys.platform != 'win32')
            self.lineEditRunTerm.setEnabled(settings.external_terminal)
            self.lineEditRunTerm.setText(settings.external_terminal_command)
            self.tw_run_env.clearContents()
            self.tw_run_env.setRowCount(0)
            for key, value in Settings().run_environemnt.items():
                index = self.tw_run_env.rowCount()
                self.tw_run_env.insertRow(index)
                self.tw_run_env.setItem(index, 0,
                                        QtWidgets.QTableWidgetItem(key))
                self.tw_run_env.setItem(index, 1,
                                        QtWidgets.QTableWidgetItem(value))
            self.edit_working_dir.setText(settings.working_dir)
        # compiler
        if self.tabWidget.currentIndex() == 2 or all_tabs:
            self.cbAutoDetectSublmodules.setChecked(
                Settings().autodetect_submodules)
            self.cb_copy_runtime_dlls.setVisible(sys.platform == 'win32')
            self.cb_copy_runtime_dlls.setChecked(Settings().copy_runtime_dlls)
            self.lineEditOutputDirectory.setText(Settings().output_directory)
            self.lineEditCobcExts.setText(';'.join(Settings().cobc_extensions))
            self.checkBoxFreeFormat.setChecked(settings.free_format)
            self.comboBoxStandard.setCurrentIndex(int(settings.cobol_standard))
            self.lineEditCompilerPath.setText(settings.compiler_path)
            flags = Settings().compiler_flags
            self.cb_debugging_line.setChecked(
                self.cb_debugging_line.text() in flags)
            self.cb_ftrace.setChecked(
                self.cb_ftrace.text().replace('&', '') in flags)
            self.cb_ftraceall.setChecked(
                self.cb_ftraceall.text().replace('&', '') in flags)
            self.cb_g.setChecked(self.cb_g.text().replace('&', '') in flags)
            self.cb_static.setChecked(
                self.cb_static.text().replace('&', '') in flags)
            self.cb_debug.setChecked(
                self.cb_debug.text().replace('&', '') in flags)
            self.cb_w.setChecked(self.cb_w.text().replace('&', '') in flags)
            self.cb_wall.setChecked(
                self.cb_wall.text().replace('&', '') in flags)
            for v in self.flags_in_checkbox:
                try:
                    flags.remove(v)
                except ValueError:
                    pass
            self.lineEditLibs.setText(settings.libraries)
            self.listWidgetLibPaths.addItems([
                pth for pth in settings.library_search_path.split(';') if pth
            ])
            self.listWidgetCopyPaths.addItems(
                [pth for pth in settings.copybook_paths.split(';') if pth])
            self.le_compiler_flags.setText(' '.join(flags))
            if system.windows:
                self.lineEditVCVARS.setText(settings.vcvarsall)
                self.combo_arch.setCurrentIndex(1 if settings.vcvarsall_arch ==
                                                'x64' else 0)
            self.PATH.setText(settings.path)
            self.cbPATH.setChecked(settings.path_enabled)
            self.COB_CONFIG_DIR.setText(settings.cob_config_dir)
            self.cbCOB_CONFIG_DIR.setChecked(settings.cob_config_dir_enabled)
            self.COB_COPY_DIR.setText(settings.cob_copy_dir)
            self.cbCOB_COPY_DIR.setChecked(settings.cob_copy_dir_enabled)
            self.COB_INCLUDE_PATH.setText(settings.cob_include_path)
            self.cbCOB_INCLUDE_PATH.setChecked(
                settings.cob_include_path_enabled)
            self.COB_LIB_PATH.setText(settings.cob_lib_path)
            self.cbCOB_LIB_PATH.setChecked(settings.cob_lib_path_enabled)

        # SQL Cobol
        if self.tabWidget.currentIndex() == 4 or all_tabs:
            self.lineEditDbpreExts.setText(';'.join(
                Settings().dbpre_extensions))
            self.lineEditDbpre.setText(settings.dbpre)
            self.lineEditDbpreFramework.setText(settings.dbpre_framework)
            self.lineEditCobmysqlapi.setText(settings.cobmysqlapi)
            self.lineEditDBHOST.setText(settings.dbhost)
            self.lineEditDBUSER.setText(settings.dbuser)
            self.lineEditDBPASSWD.setText(settings.dbpasswd)
            self.lineEditDBNAME.setText(settings.dbname)
            self.lineEditDBPORT.setText(settings.dbport)
            self.lineEditDBSOCKET.setText(settings.dbsocket)
            self.labelDbpreVersion.setText(compilers.DbpreCompiler(
            ).get_version() if Settings().dbpre != '' else '')
            self.lineEditESQLOC.setText(settings.esqloc)
            self.lineEditesqlOcExts.setText(';'.join(
                Settings().esqloc_extensions))
Example #18
0
 def generate(cls):
     print(cls.path())
     with open(cls.path(), 'w') as f:
         f.write(
             cls.CODE_TEMPLATE.format(os.path.dirname(Settings().vcvars32),
                                      Settings().compiler_path))
Example #19
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
            original_output_dir = output_dir
        if not os.path.isabs(output_dir):
            output_dir = os.path.abspath(os.path.join(path, output_dir))
        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)
            _logger().info(desc)

            return 0, [msg]

        self.prepare_bin_dir(output_dir, output_full_path)

        pgm, options = self.make_command(inputs, file_type,
                                         original_output_dir,
                                         additional_options)
        self.started.emit(' '.join([pgm] + options))
        status, output = run_command(pgm, options, working_dir=path)
        self.output_available.emit(output)
        messages = self.parse_output(output, path)
        binary_created = os.path.exists(output_full_path)
        _logger().info('binary file %r 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().info('compile results: %r - %r', status, messages)

        return status, messages
Example #20
0
    def __init__(self, parse_args=True):
        super().__init__()
        if system.darwin:
            Application._osx_init()
        self._reported_tracebacks = []
        self._old_except_hook = sys.excepthook
        sys.excepthook = self._except_hook
        self._report_exception_requested.connect(self._report_exception)
        if hasattr(sys, 'frozen') and sys.platform == 'win32':
            sys.stdout = open(
                os.path.join(system.get_cache_directory(), 'ocide_stdout.log'),
                'w')
            sys.stderr = open(
                os.path.join(system.get_cache_directory(), 'ocide_stderr.log'),
                'w')
        self.app = QtWidgets.QApplication(sys.argv)
        if parse_args and not system.darwin:
            args = self.parse_args()
            verbose = args.verbose
            files = args.files
        else:
            verbose = False
            files = []
        logger.setup_logging(__version__, debug=verbose or Settings().verbose)
        self.name = 'OpenCobolIDE'
        self.version = __version__
        self.title = '%s %s' % (self.name, self.version)

        self.apply_mimetypes_preferences()

        self.win = MainWindow()
        self.win.setWindowTitle(self.title)
        self.file = FileController(self)
        self.view = ViewController(self)
        self.home = HomeController(self)
        self.edit = EditController(self)
        self.cobol = CobolController(self)
        self.help = HelpController(self)

        self.view.show_perspective(Settings().perspective)
        self.view.show_home_page()

        self.update_app_style()

        try:
            check_compiler()
        except CompilerNotFound:
            msg = 'Failed to find a working GnuCOBOL compiler!\n' \
                "The IDE will continue to work but you won't be able to " \
                'compile...'
            if system.windows:
                msg += '\n\nTip: Ensure that there is no additional ' \
                    'installation of MinGW in %s:\MinGW' % sys.executable[0]
            QtWidgets.QMessageBox.warning(
                self.win, 'COBOL compiler not found or not working', msg)
        else:
            _logger().info('GnuCOBOL version: %s',
                           GnuCobolCompiler.get_version())
        # open specified files
        for f in files:
            self.file.open_file(f)
Example #21
0
 def toggle_perspective(self):
     self.show_perspective(
         'minimal' if Settings().perspective == 'default' else 'default')
Example #22
0
 def setPlainText(self, txt, mime_type, encoding):
     super().setPlainText(txt, mime_type, encoding)
     self.control_panel.setVisible(Settings().perspective == 'minimal')
Example #23
0
 def show_main_menu_as_context_menu(self, pos):
     if Settings().perspective == 'minimal':
         self.make_main_menu().exec_(
             self.ui.tabWidgetEditors.mapToGlobal(pos))
 def restore_state(dlg):
     s = Settings()
     dlg.resize(s.preferences_width, s.preferences_height)
Example #25
0
    def __init__(self, parent):
        super().__init__(
            parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint
            | QtCore.Qt.WindowCloseButtonHint)
        self.setupUi(self)
        self._help_dlg = None
        themes = system.icon_themes()
        if themes:
            self.comboBoxIconTheme.addItems(themes)
        else:
            self.comboBoxIconTheme.hide()
            self.lblIconTheme.hide()
        self.tabWidget.setTabIcon(
            0,
            QtGui.QIcon.fromTheme(
                'accessories-text-editor',
                QtGui.QIcon(':/ide-icons/rc/cobol-mimetype.png')))
        theme = 'application-x-executable'
        if QtGui.QIcon.hasThemeIcon('run-build'):
            theme = 'run-build'
        self.tabWidget.setTabIcon(
            2,
            QtGui.QIcon.fromTheme(
                theme,
                QtGui.QIcon(':/ide-icons/rc/application-x-executable.png')))
        self.tabWidget.setTabIcon(
            1,
            QtGui.QIcon.fromTheme(
                'applications-graphics',
                QtGui.QIcon(':/ide-icons/rc/applications-graphics.png')))
        self.tabWidget.setTabIcon(
            3,
            QtGui.QIcon.fromTheme(
                'media-playback-start',
                QtGui.QIcon(':/ide-icons/rc/media-playback-start.png')))
        icon_add = QtGui.QIcon.fromTheme(
            'list-add', QtGui.QIcon(':/ide-icons/rc/list-add.png'))
        icon_remove = QtGui.QIcon.fromTheme(
            'list-remove', QtGui.QIcon(':/ide-icons/rc/list-remove.png'))
        icon_open_folder = QtGui.QIcon.fromTheme(
            'folder-open', QtGui.QIcon(':/ide-icons/rc/document-open.png'))
        icon_clear = QtGui.QIcon.fromTheme(
            'edit-clear', QtGui.QIcon(':/ide-icons/rc/edit-clear.png'))
        self.bt_add_run_env.setIcon(icon_add)
        self.bt_rm_run_env.setIcon(icon_remove)
        self.bt_clear_run_env.setIcon(icon_clear)
        self.btAddAbsoluteCopyPath.setIcon(icon_open_folder)
        self.btAddRelativeCopyPath.setIcon(icon_add)
        self.btRemoveCopyPath.setIcon(icon_remove)
        self.toolButtonAddLibPath.setIcon(icon_open_folder)
        self.toolButtonAddRelativeLibPath.setIcon(icon_add)
        self.toolButtonRemoveLibPath.setIcon(icon_remove)
        self.toolButtonCheckCompiler.setIcon(
            QtGui.QIcon.fromTheme(
                'emblem-checked',
                QtGui.QIcon(':/ide-icons/rc/emblem-checked.png')))

        self.buttonBox.button(self.buttonBox.Reset).clicked.connect(self.reset)
        self.buttonBox.button(self.buttonBox.RestoreDefaults).clicked.connect(
            self.restore_defaults)
        self.checkBoxRunExtTerm.toggled.connect(
            self.lineEditRunTerm.setEnabled)
        self.listWidgetColorSchemes.currentItemChanged.connect(
            self.update_color_scheme_preview)
        self.plainTextEdit.setPlainText(DEFAULT_TEMPLATE, '', '')
        self.lineEditDbpre.setReadOnly(True)
        self.lineEditDbpreFramework.setReadOnly(True)
        self.lineEditCobmysqlapi.setReadOnly(True)
        self.toolButtonDbpre.clicked.connect(self._select_dbpre)
        self.toolButtonDbpreFramework.clicked.connect(
            self._select_dbpre_framework)
        self.toolButtonCobMySqlApiPath.clicked.connect(
            self._select_cobmysqlapi)
        self.checkBoxShowDbPass.stateChanged.connect(
            self._on_show_pass_state_changed)
        self.toolButtonVCVARS.clicked.connect(self._select_vcvarsall)
        self.toolButtonCustomCompilerPath.clicked.connect(
            self._select_custom_compiler_path)
        self.toolButtonAddLibPath.clicked.connect(self._add_lib_path)
        self.toolButtonAddRelativeLibPath.clicked.connect(
            self._add_rel_lib_path)
        self.toolButtonRemoveLibPath.clicked.connect(self._rm_lib_path)
        self.btAddAbsoluteCopyPath.clicked.connect(self._add_copy_path)
        self.btAddRelativeCopyPath.clicked.connect(self._add_rel_copy_path)
        self.btRemoveCopyPath.clicked.connect(self._rm_copy_path)
        self.toolButtonESQLOC.clicked.connect(self._select_esqloc)
        self.btCompilerFlagsHelp.clicked.connect(self._show_gnu_cobol_help)
        if not system.windows:
            self.labelVCVARS.hide()
            self.lineEditVCVARS.hide()
            self.toolButtonVCVARS.hide()
            self.combo_arch.hide()
            self.stackedWidgetSQL.setCurrentIndex(0)
        else:
            self.stackedWidgetSQL.setCurrentIndex(1)
        self.toolButtonCheckCompiler.clicked.connect(self._check_compiler)
        self.cbPATH.stateChanged.connect(self.PATH.setEnabled)
        self.cbCOB_CONFIG_DIR.stateChanged.connect(
            self.COB_CONFIG_DIR.setEnabled)
        self.cbCOB_COPY_DIR.stateChanged.connect(self.COB_COPY_DIR.setEnabled)
        self.cbCOB_INCLUDE_PATH.stateChanged.connect(
            self.COB_INCLUDE_PATH.setEnabled)
        self.cbCOB_LIB_PATH.stateChanged.connect(self.COB_LIB_PATH.setEnabled)

        self.PATH.setEnabled(self.cbPATH.isChecked())
        self.COB_CONFIG_DIR.setEnabled(self.cbCOB_CONFIG_DIR.isChecked())
        self.COB_COPY_DIR.setEnabled(self.cbCOB_COPY_DIR.isChecked())
        self.COB_INCLUDE_PATH.setEnabled(self.cbCOB_INCLUDE_PATH.isChecked())
        self.COB_LIB_PATH.setEnabled(self.cbCOB_LIB_PATH.isChecked())

        self.bt_add_run_env.clicked.connect(self._add_run_env_variable)
        self.bt_rm_run_env.clicked.connect(self._rm_run_env_variable)
        self.bt_clear_run_env.clicked.connect(self._clear_run_env)

        self._margin_spin_boxes = [
            self.spin_box_margin_1, self.spin_box_margin_2,
            self.spin_box_margin_3, self.spin_box_margin_4
        ]

        self._margin_color_pickers = [
            self.color_picker_1, self.color_picker_2, self.color_picker_3,
            self.color_picker_4
        ]

        self.bt_working_dir.clicked.connect(self._select_working_dir)

        self.initial_settings = Settings().export_to_dict()
        self.reset(all_tabs=True)
Example #26
0
 def apply_mimetypes_preferences(self):
     for ext in Settings().all_extensions:
         mimetypes.add_type('text/x-cobol', ext)
         mimetypes.add_type('text/x-cobol', ext.upper())
Example #27
0
    def apply(self):
        # force next check (otherwise the cached result will be used)
        compilers.GnuCobolCompiler.check_compiler.reset()
        settings = Settings()
        settings.show_cursor_pos_in_bytes = \
            self.cb_cursor_pos_in_bytes.isChecked()
        settings.display_lines = self.checkBoxViewLineNumber.isChecked()
        settings.highlight_caret = self.checkBoxHighlightCurrentLine.isChecked(
        )
        settings.show_whitespaces = \
            self.checkBoxHighlightWhitespaces.isChecked()
        settings.tab_len = self.spinBoxEditorTabLen.value()
        settings.enable_autoindent = self.checkBoxEditorAutoIndent.isChecked()
        settings.code_completion_trigger_len = \
            self.spinBoxEditorCCTriggerLen.value()
        settings.preferred_eol = self.comboBoxPreferredEOL.currentIndex()
        settings.autodetect_eol = self.checkBoxAutodetectEOL.isChecked()
        settings.dark_style = self.radioButtonColorDark.isChecked()
        settings.font = self.fontComboBox.currentFont().family()
        settings.font_size = self.spinBoxFontSize.value()
        settings.color_scheme = self.listWidgetColorSchemes.currentItem().text(
        )
        settings.external_terminal = self.checkBoxRunExtTerm.isChecked()
        settings.external_terminal_command = self.lineEditRunTerm.text()
        settings.lower_case_keywords = self.rbLowerCaseKwds.isChecked()
        settings.compiler_path = self.lineEditCompilerPath.text()
        settings.vcvarsall = self.lineEditVCVARS.text()
        settings.vcvarsall_arch = self.combo_arch.currentText()
        settings.path = self.PATH.text()
        settings.path_enabled = self.cbPATH.isChecked()
        settings.cob_config_dir = self.COB_CONFIG_DIR.text()
        settings.cob_config_dir_enabled = self.cbCOB_CONFIG_DIR.isChecked()
        settings.cob_copy_dir = self.COB_COPY_DIR.text()
        settings.cob_copy_dir_enabled = self.cbCOB_COPY_DIR.isChecked()
        settings.cob_include_path = self.COB_INCLUDE_PATH.text()
        settings.cob_include_path_enabled = self.cbCOB_INCLUDE_PATH.isChecked()
        settings.cob_lib_path = self.COB_LIB_PATH.text()
        settings.cob_lib_path_enabled = self.cbCOB_LIB_PATH.isChecked()
        settings.free_format = self.checkBoxFreeFormat.isChecked()
        settings.comment_indicator = self.lineEditCommentIndicator.text()
        settings.autodetect_submodules = \
            self.cbAutoDetectSublmodules.isChecked()
        settings.cobol_standard = GnuCobolStandard(
            self.comboBoxStandard.currentIndex())
        settings.icon_theme = self.comboBoxIconTheme.currentText()
        settings.show_errors = self.checkBoxShowErrors.isChecked()
        settings.enable_smart_backspace = \
            self.checkBoxSmartBackspace.isChecked()
        paths = []
        for i in range(self.listWidgetLibPaths.count()):
            paths.append(self.listWidgetLibPaths.item(i).text())
        settings.library_search_path = ';'.join(paths)
        paths = []
        for i in range(self.listWidgetCopyPaths.count()):
            paths.append(self.listWidgetCopyPaths.item(i).text())
        settings.copybook_paths = ';'.join(paths)
        settings.libraries = self.lineEditLibs.text()
        settings.output_directory = self.lineEditOutputDirectory.text()
        settings.copy_runtime_dlls = self.cb_copy_runtime_dlls.isChecked()
        cb_flags = [
            self.cb_g, self.cb_ftrace, self.cb_ftraceall,
            self.cb_debugging_line, self.cb_static, self.cb_debug, self.cb_w,
            self.cb_wall
        ]
        flags = [cb.text() for cb in cb_flags if cb.isChecked()]
        flags += system.shell_split(self.le_compiler_flags.text())
        settings.compiler_flags = flags
        # sql
        settings.dbpre = self.lineEditDbpre.text()
        settings.dbpre_framework = self.lineEditDbpreFramework.text()
        settings.cobmysqlapi = self.lineEditCobmysqlapi.text()
        settings.dbhost = self.lineEditDBHOST.text()
        settings.dbuser = self.lineEditDBUSER.text()
        settings.dbpasswd = self.lineEditDBPASSWD.text()
        settings.dbname = self.lineEditDBNAME.text()
        settings.dbport = self.lineEditDBPORT.text()
        settings.dbsocket = self.lineEditDBSOCKET.text()
        settings.esqloc = self.lineEditESQLOC.text()
        settings.completion_filter_mode = \
            self.comboCcFilterMode.currentIndex()
        settings.cobc_extensions = [
            ext.lower() for ext in self.lineEditCobcExts.text().split(';')
            if ext
        ]
        settings.dbpre_extensions = [
            ext.lower() for ext in self.lineEditDbpreExts.text().split(';')
            if ext
        ]
        settings.esqloc_extensions = [
            ext for ext in self.lineEditesqlOcExts.text().split(';') if ext
        ]

        colors = []
        positions = []
        for spin_box, picker in zip(self._margin_spin_boxes,
                                    self._margin_color_pickers):
            positions.append(spin_box.value() - 1)
            colors.append(picker.color.name())
        settings.margin_positions = positions
        settings.margin_colors = colors

        env = {}
        for i in range(self.tw_run_env.rowCount()):
            env[self.tw_run_env.item(i, 0).text()] = self.tw_run_env.item(
                i, 1).text()
        settings.run_environemnt = env
        settings.working_dir = self.edit_working_dir.text()
Example #28
0
def which(cmd, mode=os.F_OK | os.X_OK, path=None, include_settings_path=True):
    """Given a command, mode, and a PATH string, return the path which
    conforms to the given mode on the PATH, or None if there is no such
    file.

    `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
    of os.environ.get("PATH"), or can be overridden with a custom search
    path.

    TAKEN from the shutil module (cause it is not available on python <= 3.3)
    """
    from open_cobol_ide.settings import Settings

    # Check that a given file can be accessed with the correct mode.
    # Additionally check that `file` is not a directory, as on Windows
    # directories pass the os.access check.
    def _access_check(fn, mode):
        return (os.path.exists(fn) and os.access(fn, mode)
                and not os.path.isdir(fn))

    # If we're given a path with a directory part, look it up directly rather
    # than referring to PATH directories. This includes checking relative to the
    # current directory, e.g. ./script
    if os.path.dirname(cmd):
        if _access_check(cmd, mode):
            return cmd
        return None

    if path is None:
        path = os.environ.get("PATH", os.defpath)
    if not path:
        return None

    path = path.split(os.pathsep)
    if include_settings_path and Settings().path:
        path = Settings().path.split(os.pathsep) + path

    if sys.platform == "win32":
        # The current directory takes precedence on Windows.
        if not os.curdir in path:
            path.insert(0, os.curdir)

        # PATHEXT is necessary to check on Windows.
        pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
        # See if the given file matches any of the expected path extensions.
        # This will allow us to short circuit when given "python.exe".
        # If it does match, only test that one, otherwise we have to try
        # others.
        if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
            files = [cmd]
        else:
            files = [cmd + ext for ext in pathext]
    else:
        # On other platforms you don't have things like PATHEXT to tell you
        # what file suffixes are executable, so just pass on cmd as-is.
        files = [cmd]

    seen = set()

    for dir in path:
        normdir = os.path.normcase(dir)
        if not normdir in seen:
            seen.add(normdir)
            for thefile in files:
                name = os.path.join(dir, thefile)
                if _access_check(name, mode):
                    return name
    return None
Example #29
0
 def save_state(dlg):
     s = Settings()
     s.preferences_width = dlg.width()
     s.preferences_height = dlg.height()
     s.preferences_index = dlg.tabWidget.currentIndex()
Example #30
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