aboutsummaryrefslogtreecommitdiffstats
path: root/pyGHDL/lsp/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'pyGHDL/lsp/main.py')
-rw-r--r--pyGHDL/lsp/main.py129
1 files changed, 129 insertions, 0 deletions
diff --git a/pyGHDL/lsp/main.py b/pyGHDL/lsp/main.py
new file mode 100644
index 000000000..7cfe06683
--- /dev/null
+++ b/pyGHDL/lsp/main.py
@@ -0,0 +1,129 @@
+#!/usr/bin/env python
+from __future__ import absolute_import
+
+import argparse
+import logging
+import sys
+import os
+
+import pyGHDL.libghdl as libghdl
+
+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.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)