<commit_before># This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2014 <NAME> <<EMAIL>>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Debugging of a nit program using sockets.
module debugger_socket

intrude import debugger
import websocket

redef class ToolContext
	# --socket
	var opt_socket_mode = new OptionBool("Launches the target program with raw output on the network via sockets", "--socket")

	# --websocket
	var opt_websocket_mode = new OptionBool("Launches the target program with output on the network via websockets", "--websocket")

	# --port
	var opt_debug_port: OptionInt = new OptionInt("Sets the debug port (Defaults to 22125) - Must be contained between 0 and 65535", 22125, "--port")

	redef init
	do
		super
		self.option_context.add_option(self.opt_socket_mode)
		self.option_context.add_option(self.opt_websocket_mode)
		self.option_context.add_option(self.opt_debug_port)
	end
end

redef class ModelBuilder
	# Execute the program from the entry point (Sys::main) of the `mainmodule`
	# `arguments` are the command-line arguments in order
	# REQUIRE that:
	#   1. the AST is fully loaded.
	#   2. the model is fully built.
	#   3. the instructions are fully analysed.
	redef fun run_debugger(mainmodule: MModule, arguments: Array[String])
	do
		var time0 = get_time
		self.toolcontext.info("*** START INTERPRETING ***", 1)

		var interpreter = new Debugger(self, mainmodule, arguments)

		set_stdstreams

		interpreter.start(mainmodule)

		close_stdstreams

		var time1 = get_time
		self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
	end

	redef fun run_debugger_autorun(mainmodule: MModule, arguments: Array[String])
	do
		var time0 = get_time
		self.toolcontext.info("*** START INTERPRETING ***", 1)

		var interpreter = new Debugger(self, mainmodule, arguments)
		interpreter.autocontinue = true

		set_stdstreams

		interpreter.start(mainmodule)

		close_stdstreams

		var time1 = get_time
		self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
	end

	redef fun run_naive_interpreter(mmod, args)
	do
		set_stdstreams
		super
	end

	fun set_stdstreams
	do
		if self.toolcontext.opt_socket_mode.value then
			var sock = new TCPServer(toolcontext.opt_debug_port.value)
			sock.listen 1
			var ns = sock.accept
			assert ns != null
			sock.close
			sys.set_io(ns,ns,ns)
		else if self.toolcontext.opt_websocket_mode.value then
			var websock = new WebSocket(toolcontext.opt_debug_port.value, 1)
			websock.accept
			sys.set_io(websock,websock,websock)
		end
	end

	fun close_stdstreams
	do
		if sys.stdin isa WebSocket or sys.stdin isa TCPStream then
			sys.stdin.close
			sys.stdout.close
			sys.stderr.close
		end
	end
end

redef class Sys
	private fun set_io(istream: PollableIStream, ostream: OStream, errstream: OStream)
	do
		self.stdin = istream
		self.stdout = ostream
		self.stderr = ostream
	end
end<commit_msg>debugger: Updated to support new Websockets<commit_after># This file is part of NIT ( http://www.nitlanguage.org ).
#
# Copyright 2014 <NAME> <<EMAIL>>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Debugging of a nit program using sockets.
module debugger_socket

intrude import debugger
import websocket

redef class ToolContext
	# --socket
	var opt_socket_mode = new OptionBool("Launches the target program with raw output on the network via sockets", "--socket")

	# --websocket
	var opt_websocket_mode = new OptionBool("Launches the target program with output on the network via websockets", "--websocket")

	# --port
	var opt_debug_port: OptionInt = new OptionInt("Sets the debug port (Defaults to 22125) - Must be contained between 0 and 65535", 22125, "--port")

	redef init
	do
		super
		self.option_context.add_option(self.opt_socket_mode)
		self.option_context.add_option(self.opt_websocket_mode)
		self.option_context.add_option(self.opt_debug_port)
	end
end

redef class ModelBuilder
	# Execute the program from the entry point (Sys::main) of the `mainmodule`
	# `arguments` are the command-line arguments in order
	# REQUIRE that:
	#   1. the AST is fully loaded.
	#   2. the model is fully built.
	#   3. the instructions are fully analysed.
	redef fun run_debugger(mainmodule: MModule, arguments: Array[String])
	do
		var time0 = get_time
		self.toolcontext.info("*** START INTERPRETING ***", 1)

		var interpreter = new Debugger(self, mainmodule, arguments)

		set_stdstreams

		interpreter.start(mainmodule)

		close_stdstreams

		var time1 = get_time
		self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
	end

	redef fun run_debugger_autorun(mainmodule: MModule, arguments: Array[String])
	do
		var time0 = get_time
		self.toolcontext.info("*** START INTERPRETING ***", 1)

		var interpreter = new Debugger(self, mainmodule, arguments)
		interpreter.autocontinue = true

		set_stdstreams

		interpreter.start(mainmodule)

		close_stdstreams

		var time1 = get_time
		self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
	end

	redef fun run_naive_interpreter(mmod, args)
	do
		set_stdstreams
		super
	end

	fun set_stdstreams
	do
		if self.toolcontext.opt_socket_mode.value then
			var sock = new TCPServer(toolcontext.opt_debug_port.value)
			sock.listen 1
			var ns = sock.accept
			assert ns != null
			sock.close
			sys.set_io(ns,ns,ns)
		else if self.toolcontext.opt_websocket_mode.value then
			var websock = new WebSocketListener(toolcontext.opt_debug_port.value, 1)
			var cli = websock.accept
			websock.close
			sys.set_io(cli,cli,cli)
		end
	end

	fun close_stdstreams
	do
		if sys.stdin isa TCPStream then
			sys.stdin.close
			sys.stdout.close
			sys.stderr.close
		end
	end
end

redef class Sys
	private fun set_io(istream: PollableIStream, ostream: OStream, errstream: OStream)
	do
		self.stdin = istream
		self.stdout = ostream
		self.stderr = errstream
	end
end
{'fraction_non_alphanumeric': 0.08604038630377524, 'fraction_numerical': 0.01199882938249927, 'mean_word_length': 4.197718631178708, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2746441', 'n_tokens_mistral': 2416, 'n_tokens_neox': 2192, 'n_words': 715}