aboutsummaryrefslogtreecommitdiffstats
path: root/python/vhdl_langserver/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/vhdl_langserver/main.py')
-rw-r--r--python/vhdl_langserver/main.py125
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)