aboutsummaryrefslogtreecommitdiff
path: root/src/main.odin
blob: b4aad6fa7319f0a9550a084c1a85468f9d1fea93 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package main

import "base:intrinsics"

import "core:fmt"
import "core:log"
import "core:mem"
import "core:os"
import "core:thread"

import "src:common"
import "src:server"

VERSION := #config(VERSION, "dev")

os_read :: proc(handle: rawptr, data: []byte) -> (int, int) {
	ptr := cast(^os.Handle)handle
	a, b := os.read(ptr^, data)
	return a, cast(int)(b != nil)
}

os_write :: proc(handle: rawptr, data: []byte) -> (int, int) {
	ptr := cast(^os.Handle)handle
	a, b := os.write(ptr^, data)
	return a, cast(int)(b != nil)
}

//Note(Daniel, Should look into handling errors without crashing from parsing)

request_thread: ^thread.Thread

logger: ^log.Logger


run :: proc(reader: ^server.Reader, writer: ^server.Writer) {
	common.config.collections = make(map[string]string)
	common.config.running = true

	logger = new(log.Logger)

	request_thread_data := server.RequestThreadData {
		reader = reader,
		writer = writer,
		logger = logger,
	}

	/*
	tracking_allocator: mem.Tracking_Allocator
    mem.tracking_allocator_init(&tracking_allocator, context.allocator)
    context.allocator = mem.tracking_allocator(&tracking_allocator)
	*/

	server.requests = make([dynamic]server.Request, context.allocator)
	server.deletings = make([dynamic]server.Request, context.allocator)

	request_thread = thread.create_and_start_with_data(cast(rawptr)&request_thread_data, server.thread_request_main)

	logger^ = server.create_lsp_logger(writer, log.Level.Error)

	{
		context.logger = logger^
		log.error("Starting Odin Language Server", VERSION)
	}

	for common.config.running {
		if common.config.verbose {
			//Currently letting verbose use error, since some ast prints causes crashes - most likely a bug in core:fmt.
			logger^ = server.create_lsp_logger(writer, log.Level.Error)
		} else {
			logger^ = server.create_lsp_logger(writer, log.Level.Error)
		}

		context.logger = logger^

		server.consume_requests(&common.config, writer)
	}

	for k, v in common.config.collections {
		delete(k)
		delete(v)
	}

	delete(common.config.collections)
	delete(common.config.workspace_folders)

	server.document_storage_shutdown()

	server.free_index()

	/*
    for key, value in tracking_allocator.allocation_map {
        log.errorf("%v: Leaked %v bytes\n", value.location, value.size)
    }	
	*/
}

end :: proc() {
}

main :: proc() {
	if len(os.args) > 1 && os.args[1] == "version" {
		fmt.println("ols version", VERSION)
		os.exit(0)
	}
	reader := server.make_reader(os_read, cast(rawptr)&os.stdin)
	writer := server.make_writer(os_write, cast(rawptr)&os.stdout)

	/*
	fh, err := os.open("log.txt", os.O_RDWR|os.O_CREATE) 
	
	if err != os.ERROR_NONE {
		return
	}
	
	context.logger = log.create_file_logger(fh, log.Level.Info)
	*/

	init_global_temporary_allocator(mem.Megabyte * 100)

	run(&reader, &writer)
}