diff options
Diffstat (limited to 'python/vhdl_langserver/main.py')
-rw-r--r-- | python/vhdl_langserver/main.py | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/python/vhdl_langserver/main.py b/python/vhdl_langserver/main.py new file mode 100644 index 000000000..4831000fc --- /dev/null +++ b/python/vhdl_langserver/main.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python +from __future__ import absolute_import + +import argparse +import logging +import sys +import os + +import libghdl +import libghdl.thin.errorout_console + +from . import version +from . import lsp +from . import vhdl_ls + +logger = logging.getLogger('ghdl-ls') + +class LSPConnTrace(object): + """Wrapper class to save in and out packets""" + def __init__(self, basename, conn): + self.conn = conn + self.trace_in = open(basename + '.in', 'w') + self.trace_out = open(basename + '.out', 'w') + + def readline(self): + res = self.conn.readline() + self.trace_in.write(res) + return res + + def read(self, size): + res = self.conn.read(size) + self.trace_in.write(res) + self.trace_in.flush() + return res + + def write(self, out): + self.conn.write(out) + self.trace_out.write(out) + self.trace_out.flush() + + +def rotate_log_files(basename, num): + for i in range(num, 0, -1): + oldfile = '{}.{}'.format(basename, i - 1) + if os.path.isfile(oldfile): + os.rename(oldfile, '{}.{}'.format(basename, i)) + if os.path.isfile(basename): + os.rename(basename, '{}.0'.format(basename)) + +def main(): + parser = argparse.ArgumentParser( + description='VHDL Language Protocol Server') + parser.add_argument( + '--version', '-V', action='version', version='%(prog)s ' + version.__version__) + parser.add_argument( + '--verbose', '-v', action='count', default=0, + help='Show debug output') + parser.add_argument( + '--log-file', + help="Redirect logs to the given file instead of stderr") + parser.add_argument( + '--trace-file', + help="Save rpc data to FILE.in and FILE.out") + parser.add_argument( + '--input', '-i', + help="Read request from file") + parser.add_argument( + '--disp-config', action='store_true', help="Disp installation configuration and exit") + + args = parser.parse_args() + + if args.disp_config: + libghdl.thin.errorout_console.Install_Handler() + libghdl.disp_config() + return + + # Setup logging + if args.verbose >= 2: + loglevel = logging.DEBUG + elif args.verbose >= 1: + loglevel = logging.INFO + else: + loglevel = logging.ERROR + + if args.log_file: + rotate_log_files(args.log_file, 5) + logstream = open(args.log_file, 'w') + else: + logstream = sys.stderr + logging.basicConfig(format='%(asctime)-15s [%(levelname)s] %(message)s', + stream=logstream, level=loglevel) + + if args.verbose != 0: + sys.stderr.write('Args: {}\n'.format(sys.argv)) + sys.stderr.write('Current directory: {}\n'.format(os.getcwd())) + + logger.info('Args: %s', sys.argv) + logger.info('Current directory is %s', os.getcwd()) + + # Connection + instream = sys.stdin.buffer + if args.input is not None: + instream = open(args.input, 'rb') + + conn = lsp.LSPConn(instream, sys.stdout.buffer) + + trace_file = args.trace_file + if trace_file is None: + trace_file = os.environ.get('GHDL_LS_TRACE') + if trace_file is not None: + if args.input is None: + rotate_log_files(trace_file + '.in', 5) + rotate_log_files(trace_file + '.out', 5) + conn = LSPConnTrace(trace_file, conn) + else: + logger.info('Traces disabled when -i/--input') + + handler = vhdl_ls.VhdlLanguageServer() + + try: + server = lsp.LanguageProtocolServer(handler, conn) + server.run() + except Exception: + logger.exception('Uncaught error') + sys.exit(1) |